{
  "$schema": "https://ds.lema.ufpb.br/docs/components.schema.json",
  "generatedAt": "2026-09-14T14:36:57.077Z",
  "version": "1.11.0",
  "totalComponents": 374,
  "components": [
    {
      "name": "accordion",
      "title": "Accordion",
      "description": "A vertically stacked set of interactive headings that each reveal a section of content.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/accordion",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/accordion.tsx"
      ],
      "storyTitle": "Shadcn UI/Accordion",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Single-selection mode with three FAQ-style items, where the first item is expanded by default.",
          "args": "{\n    type: \"single\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Single-selection mode with three FAQ-style items, where the first item is expanded by default.\",\n      },\n    },\n  },\n  render: () => (\n    <Accordion type=\"single\" defaultValue=\"item-1\" className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>What is this component?</AccordionTrigger>\n        <AccordionContent>\n          This is an accordion component that allows you to collapse and expand\n          content sections.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>How does it work?</AccordionTrigger>\n        <AccordionContent>\n          Click on the trigger to expand or collapse the content. Only one item\n          can be open at a time.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-3\">\n        <AccordionTrigger>Can I customize it?</AccordionTrigger>\n        <AccordionContent>\n          Yes, you can customize the styling using Tailwind CSS classes and\n          semantic color tokens.\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  ),",
          "code": "<Accordion type=\"single\" defaultValue=\"item-1\" className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>What is this component?</AccordionTrigger>\n        <AccordionContent>\n          This is an accordion component that allows you to collapse and expand\n          content sections.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>How does it work?</AccordionTrigger>\n        <AccordionContent>\n          Click on the trigger to expand or collapse the content. Only one item\n          can be open at a time.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-3\">\n        <AccordionTrigger>Can I customize it?</AccordionTrigger>\n        <AccordionContent>\n          Yes, you can customize the styling using Tailwind CSS classes and\n          semantic color tokens.\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>"
        },
        {
          "name": "Multiple",
          "description": "Multiple-selection mode allowing several sections to remain open at the same time.",
          "args": "{\n    type: \"multiple\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Multiple-selection mode allowing several sections to remain open at the same time.\",\n      },\n    },\n  },\n  render: () => (\n    <Accordion type=\"multiple\" className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>Section 1</AccordionTrigger>\n        <AccordionContent>\n          Content for section 1. You can have multiple sections open at once.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Section 2</AccordionTrigger>\n        <AccordionContent>\n          Content for section 2. Another section that can be independently\n          toggled.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-3\">\n        <AccordionTrigger>Section 3</AccordionTrigger>\n        <AccordionContent>\n          Content for section 3. More collapsible content here.\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  ),",
          "code": "<Accordion type=\"multiple\" className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>Section 1</AccordionTrigger>\n        <AccordionContent>\n          Content for section 1. You can have multiple sections open at once.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Section 2</AccordionTrigger>\n        <AccordionContent>\n          Content for section 2. Another section that can be independently\n          toggled.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-3\">\n        <AccordionTrigger>Section 3</AccordionTrigger>\n        <AccordionContent>\n          Content for section 3. More collapsible content here.\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>"
        },
        {
          "name": "Collapsible",
          "description": "Collapsible mode where the open item can be closed by clicking its trigger again.",
          "args": "{\n    type: \"single\",\n    collapsible: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Collapsible mode where the open item can be closed by clicking its trigger again.\",\n      },\n    },\n  },\n  render: () => (\n    <Accordion type=\"single\" collapsible className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>Click to expand</AccordionTrigger>\n        <AccordionContent>\n          This item can be collapsed by clicking on the trigger again.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Another item</AccordionTrigger>\n        <AccordionContent>\n          This one can also be collapsed. All items are independently\n          collapsible.\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  ),",
          "code": "<Accordion type=\"single\" collapsible className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>Click to expand</AccordionTrigger>\n        <AccordionContent>\n          This item can be collapsed by clicking on the trigger again.\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Another item</AccordionTrigger>\n        <AccordionContent>\n          This one can also be collapsed. All items are independently\n          collapsible.\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>"
        },
        {
          "name": "DefaultOpen",
          "description": "Single-selection accordion with the second item pre-expanded via the `defaultValue` prop.",
          "args": "{\n    type: \"single\",\n    defaultValue: \"item-2\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Single-selection accordion with the second item pre-expanded via the `defaultValue` prop.\",\n      },\n    },\n  },\n  render: () => (\n    <Accordion type=\"single\" defaultValue=\"item-2\" className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>First item (closed)</AccordionTrigger>\n        <AccordionContent>This content is hidden by default.</AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Second item (open)</AccordionTrigger>\n        <AccordionContent>\n          This content is visible initially because it&apos;s set as the default\n          value.\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  ),",
          "code": "<Accordion type=\"single\" defaultValue=\"item-2\" className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>First item (closed)</AccordionTrigger>\n        <AccordionContent>This content is hidden by default.</AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Second item (open)</AccordionTrigger>\n        <AccordionContent>\n          This content is visible initially because it&apos;s set as the default\n          value.\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>"
        },
        {
          "name": "RichContent",
          "description": "Demonstrates complex content inside accordion panels including lists, links, and multiple paragraphs.",
          "args": "{\n    type: \"single\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates complex content inside accordion panels including lists, links, and multiple paragraphs.\",\n      },\n    },\n  },\n  render: () => (\n    <Accordion type=\"single\" defaultValue=\"item-1\" className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>Features</AccordionTrigger>\n        <AccordionContent>\n          <ul className=\"list-disc pl-4\">\n            <li>Keyboard navigation support</li>\n            <li>Accessible by default</li>\n            <li>Animated transitions</li>\n            <li>Customizable styling</li>\n          </ul>\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Links and formatting</AccordionTrigger>\n        <AccordionContent>\n          <p>\n            You can include <a href=\"#\">links</a> and various text formatting.\n          </p>\n          <p className=\"mt-2\">\n            Multiple paragraphs are supported with proper spacing.\n          </p>\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  ),",
          "code": "<Accordion type=\"single\" defaultValue=\"item-1\" className=\"w-full\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>Features</AccordionTrigger>\n        <AccordionContent>\n          <ul className=\"list-disc pl-4\">\n            <li>Keyboard navigation support</li>\n            <li>Accessible by default</li>\n            <li>Animated transitions</li>\n            <li>Customizable styling</li>\n          </ul>\n        </AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Links and formatting</AccordionTrigger>\n        <AccordionContent>\n          <p>\n            You can include <a href=\"#\">links</a> and various text formatting.\n          </p>\n          <p className=\"mt-2\">\n            Multiple paragraphs are supported with proper spacing.\n          </p>\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>"
        }
      ]
    },
    {
      "name": "alert",
      "title": "Alert",
      "description": "A contextual notification banner for displaying feedback messages with title, description, and optional action.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/alert",
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/alert.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"destructive\"",
          "options": [
            "default",
            "destructive"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Alert",
      "stories": [
        {
          "name": "Default",
          "description": "Default alert with terminal icon, a title, and a brief description for general notifications.",
          "args": "{\n    variant: \"default\",\n    children: (\n      <>\n        <TerminalIcon />\n        <AlertTitle>Heads up!</AlertTitle>\n        <AlertDescription>\n          You can add components to your app using the CLI.\n        </AlertDescription>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default alert with terminal icon, a title, and a brief description for general notifications.\",\n      },\n    },\n  },"
        },
        {
          "name": "Variants",
          "description": "Side-by-side comparison of the default and destructive alert variants.",
          "code": "<div className=\"flex flex-col gap-4\">\n      <Alert variant=\"default\">\n        <TerminalIcon />\n        <AlertTitle>Default Alert</AlertTitle>\n        <AlertDescription>This is a default alert message.</AlertDescription>\n      </Alert>\n      <Alert variant=\"destructive\">\n        <TriangleAlertIcon />\n        <AlertTitle>Destructive Alert</AlertTitle>\n        <AlertDescription>\n          This is a destructive alert message indicating an error.\n        </AlertDescription>\n      </Alert>\n    </div>"
        },
        {
          "name": "WithAction",
          "description": "Default alert with an action slot — a ghost close button positioned at the top-right corner.",
          "code": "<Alert variant=\"default\">\n      <TerminalIcon />\n      <AlertTitle>Update available</AlertTitle>\n      <AlertDescription>\n        A new version is ready to install. Restart the application to apply\n        changes.\n      </AlertDescription>\n      <AlertAction>\n        <Button variant=\"ghost\" size=\"icon-xs\" aria-label=\"Close\">\n          <XIcon />\n        </Button>\n      </AlertAction>\n    </Alert>"
        },
        {
          "name": "Destructive",
          "description": "Destructive variant with a triangle alert icon, used to communicate errors or critical issues.",
          "args": "{\n    variant: \"destructive\",\n    children: (\n      <>\n        <TriangleAlertIcon />\n        <AlertTitle>Error</AlertTitle>\n        <AlertDescription>\n          Your session has expired. Please log in again.\n        </AlertDescription>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Destructive variant with a triangle alert icon, used to communicate errors or critical issues.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithoutIcon",
          "description": "Default alert rendered without a leading icon, showing only the title and description.",
          "code": "<Alert variant=\"default\">\n      <AlertTitle>No icon alert</AlertTitle>\n      <AlertDescription>\n        This alert does not include an icon in its layout.\n      </AlertDescription>\n    </Alert>"
        }
      ]
    },
    {
      "name": "alert-dialog",
      "title": "Alert Dialog",
      "description": "A modal dialog that interrupts users with urgent information, actions, or confirmation prompts.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/alert-dialog",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ui/alert-dialog.tsx"
      ],
      "storyTitle": "Shadcn UI/Alert Dialog",
      "props": [
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "default",
            "sm"
          ],
          "description": "Content sizing preset — affects header/footer layout",
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Default-sized confirmation dialog with a warning icon media area, cancel and delete actions.",
          "args": "{\n    size: \"default\",\n  },"
        },
        {
          "name": "WithoutMedia",
          "description": "Confirmation dialog without the media icon section, reducing visual weight for simpler confirmations.",
          "code": "<AlertDialog defaultOpen>\n      <AlertDialogTrigger asChild>\n        <Button variant=\"outline\">Discard changes</Button>\n      </AlertDialogTrigger>\n      <AlertDialogContent size=\"default\">\n        <AlertDialogHeader>\n          <AlertDialogTitle>Discard changes?</AlertDialogTitle>\n          <AlertDialogDescription>\n            You have unsaved changes that will be lost.\n          </AlertDialogDescription>\n        </AlertDialogHeader>\n        <AlertDialogFooter>\n          <AlertDialogCancel>Keep editing</AlertDialogCancel>\n          <AlertDialogAction>Discard</AlertDialogAction>\n        </AlertDialogFooter>\n      </AlertDialogContent>\n    </AlertDialog>"
        },
        {
          "name": "Small",
          "description": "Compact dialog with `size=\"sm\"` for shorter confirmation flows that require less vertical space.",
          "code": "<AlertDialog defaultOpen>\n      <AlertDialogTrigger asChild>\n        <Button variant=\"outline\">Clear all</Button>\n      </AlertDialogTrigger>\n      <AlertDialogContent size=\"sm\">\n        <AlertDialogHeader>\n          <AlertDialogTitle>Clear all items?</AlertDialogTitle>\n          <AlertDialogDescription>\n            This will remove all items from your list.\n          </AlertDialogDescription>\n        </AlertDialogHeader>\n        <AlertDialogFooter>\n          <AlertDialogCancel>Cancel</AlertDialogCancel>\n          <AlertDialogAction>Clear</AlertDialogAction>\n        </AlertDialogFooter>\n      </AlertDialogContent>\n    </AlertDialog>"
        }
      ]
    },
    {
      "name": "aspect-ratio",
      "title": "Aspect Ratio",
      "description": "A wrapper that maintains a consistent aspect ratio for its child content.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/aspect-ratio",
      "dependencies": [
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/aspect-ratio.tsx"
      ],
      "storyTitle": "Shadcn UI/Aspect Ratio",
      "props": [
        {
          "name": "ratio",
          "control": "number",
          "description": "Width-to-height ratio (e.g. 16/9, 4/3, 1)"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "16:9 widescreen aspect ratio applied to a landscape image inside a 400px container.",
          "code": "<div className=\"w-[400px]\">\n      <AspectRatio ratio={16 / 9}>\n        {/* eslint-disable-next-line @next/next/no-img-element */}\n        <img\n          src=\"https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80\"\n          alt=\"Abstract landscape\"\n          className=\"size-full rounded-xl object-cover\"\n        />\n      </AspectRatio>\n    </div>"
        },
        {
          "name": "Square",
          "description": "1:1 square aspect ratio in a compact 200px container for profile images or thumbnails.",
          "code": "<div className=\"w-[200px]\">\n      <AspectRatio ratio={1}>\n        {/* eslint-disable-next-line @next/next/no-img-element */}\n        <img\n          src=\"https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=400&dpr=2&q=80\"\n          alt=\"Square crop placeholder\"\n          className=\"size-full rounded-xl object-cover\"\n        />\n      </AspectRatio>\n    </div>"
        },
        {
          "name": "Wide",
          "description": "21:9 ultrawide aspect ratio in a 600px container for cinematic banners and hero images.",
          "code": "<div className=\"w-[600px]\">\n      <AspectRatio ratio={21 / 9}>\n        {/* eslint-disable-next-line @next/next/no-img-element */}\n        <img\n          src=\"https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=1200&dpr=2&q=80\"\n          alt=\"Wide aspect placeholder\"\n          className=\"size-full rounded-xl object-cover\"\n        />\n      </AspectRatio>\n    </div>"
        }
      ]
    },
    {
      "name": "attachment",
      "title": "Attachment",
      "description": "A file attachment component with support for media preview, title, description, actions, trigger overlay, and group layout. Composed of AttachmentGroup, AttachmentMedia, AttachmentContent, AttachmentTitle, AttachmentDescription, AttachmentActions, AttachmentAction, and AttachmentTrigger sub-components.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/attachment",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ui/attachment.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "\"default\" | \"sm\" | \"xs\"",
          "options": [
            "default",
            "sm",
            "xs"
          ]
        },
        {
          "name": "orientation",
          "required": false,
          "type": "\"horizontal\" | \"vertical\"",
          "options": [
            "horizontal",
            "vertical"
          ]
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"icon\" | \"image\"",
          "options": [
            "icon",
            "image"
          ],
          "default": "icon"
        }
      ],
      "storyTitle": "Shadcn UI/Attachment",
      "stories": [
        {
          "name": "Default",
          "description": "Horizontal attachment with a file icon, title, description, and a remove action.",
          "code": "<Attachment>\n      <AttachmentMedia>\n        <FileIcon />\n      </AttachmentMedia>\n      <AttachmentContent>\n        <AttachmentTitle>report.pdf</AttachmentTitle>\n        <AttachmentDescription>2.4 MB</AttachmentDescription>\n      </AttachmentContent>\n      <AttachmentActions>\n        <AttachmentAction aria-label=\"Remove file\">\n          <XIcon />\n        </AttachmentAction>\n      </AttachmentActions>\n    </Attachment>"
        },
        {
          "name": "Vertical",
          "description": "Vertical orientation attachment showing a media preview with title and description stacked below.",
          "code": "<Attachment orientation=\"vertical\">\n      <AttachmentMedia variant=\"image\">\n        {/* eslint-disable-next-line @next/next/no-img-element */}\n        <img\n          src=\"https://images.unsplash.com/photo-1575936123452-b67c3203c357?w=120&h=120&fit=crop\"\n          alt=\"Preview\"\n        />\n      </AttachmentMedia>\n      <AttachmentContent>\n        <AttachmentTitle>photo.jpg</AttachmentTitle>\n        <AttachmentDescription>1.8 MB</AttachmentDescription>\n      </AttachmentContent>\n      <AttachmentActions>\n        <AttachmentAction aria-label=\"Remove file\">\n          <XIcon />\n        </AttachmentAction>\n      </AttachmentActions>\n    </Attachment>"
        },
        {
          "name": "AllVariants",
          "description": "All attachment states displayed side by side: idle, uploading, processing, error, and done.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Attachment state=\"idle\">\n        <AttachmentMedia>\n          <ImageIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>Select file</AttachmentTitle>\n          <AttachmentDescription>Click or drag to upload</AttachmentDescription>\n        </AttachmentContent>\n      </Attachment>\n      <Attachment state=\"uploading\">\n        <AttachmentMedia>\n          <LoaderCircleIcon className=\"animate-spin\" />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>uploading.zip</AttachmentTitle>\n          <AttachmentDescription>Uploading…</AttachmentDescription>\n        </AttachmentContent>\n      </Attachment>\n      <Attachment state=\"processing\">\n        <AttachmentMedia>\n          <FileIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>processing.zip</AttachmentTitle>\n          <AttachmentDescription>Processing…</AttachmentDescription>\n        </AttachmentContent>\n      </Attachment>\n      <Attachment state=\"error\">\n        <AttachmentMedia>\n          <AlertCircleIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>failed.zip</AttachmentTitle>\n          <AttachmentDescription>Upload failed</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Retry\">\n            <DownloadIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n      <Attachment state=\"done\">\n        <AttachmentMedia>\n          <FileIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>completed.pdf</AttachmentTitle>\n          <AttachmentDescription>100% done</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Remove file\">\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison of all three size presets — default, sm, and xs — in horizontal orientation.",
          "code": "<div className=\"flex flex-wrap items-center gap-4\">\n      <Attachment size=\"default\">\n        <AttachmentMedia>\n          <FileIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>document.pdf</AttachmentTitle>\n          <AttachmentDescription>2.4 MB</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Remove\">\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n      <Attachment size=\"sm\">\n        <AttachmentMedia>\n          <FileIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>document.pdf</AttachmentTitle>\n          <AttachmentDescription>2.4 MB</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Remove\">\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n      <Attachment size=\"xs\">\n        <AttachmentMedia>\n          <FileIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>document.pdf</AttachmentTitle>\n          <AttachmentDescription>2.4 MB</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Remove\">\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n    </div>"
        },
        {
          "name": "Loading",
          "description": "Uploading and processing states representing active loading feedback with shimmer on title text.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Attachment state=\"uploading\">\n        <AttachmentMedia>\n          <Spinner />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>uploading.zip</AttachmentTitle>\n          <AttachmentDescription>Uploading… 45%</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Cancel\" disabled>\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n      <Attachment state=\"processing\">\n        <AttachmentMedia>\n          <Spinner />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>processing.zip</AttachmentTitle>\n          <AttachmentDescription>Processing…</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Cancel\" disabled>\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n    </div>"
        },
        {
          "name": "Error",
          "description": "Error state with destructive styling and a retry action button.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Attachment state=\"error\">\n        <AttachmentMedia>\n          <AlertCircleIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>failed_upload.pdf</AttachmentTitle>\n          <AttachmentDescription>\n            Upload failed — network error\n          </AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Retry\">\n            <DownloadIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n    </div>"
        },
        {
          "name": "WithTrigger",
          "description": "Attachment with an invisible trigger overlay, making the entire area clickable.",
          "code": "<Attachment state=\"idle\" orientation=\"vertical\">\n      <AttachmentTrigger asChild>\n        <button type=\"button\" aria-label=\"Upload file\" />\n      </AttachmentTrigger>\n      <AttachmentMedia variant=\"icon\">\n        <ImageIcon />\n      </AttachmentMedia>\n      <AttachmentContent>\n        <AttachmentTitle>Click to upload</AttachmentTitle>\n        <AttachmentDescription>PNG, JPG up to 10MB</AttachmentDescription>\n      </AttachmentContent>\n    </Attachment>"
        },
        {
          "name": "Group",
          "description": "AttachmentGroup with multiple attachments in a horizontal scrollable row.",
          "code": "<AttachmentGroup>\n      <Attachment>\n        <AttachmentMedia>\n          <FileIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>document.pdf</AttachmentTitle>\n          <AttachmentDescription>2.4 MB</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Remove\">\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n      <Attachment>\n        <AttachmentMedia variant=\"image\">\n          {/* eslint-disable-next-line @next/next/no-img-element */}\n          <img\n            src=\"https://images.unsplash.com/photo-1575936123452-b67c3203c357?w=120&h=120&fit=crop\"\n            alt=\"Preview\"\n          />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>photo.jpg</AttachmentTitle>\n          <AttachmentDescription>1.8 MB</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Remove\">\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n      <Attachment>\n        <AttachmentMedia>\n          <FileIcon />\n        </AttachmentMedia>\n        <AttachmentContent>\n          <AttachmentTitle>archive.zip</AttachmentTitle>\n          <AttachmentDescription>4.2 MB</AttachmentDescription>\n        </AttachmentContent>\n        <AttachmentActions>\n          <AttachmentAction aria-label=\"Remove\">\n            <XIcon />\n          </AttachmentAction>\n        </AttachmentActions>\n      </Attachment>\n    </AttachmentGroup>"
        }
      ]
    },
    {
      "name": "avatar",
      "title": "Avatar",
      "description": "An image element representing a user or entity, with a fallback display for when the image fails to load.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/avatar",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/avatar.tsx"
      ],
      "storyTitle": "Shadcn UI/Avatar",
      "props": [
        {
          "name": "className",
          "control": "text"
        },
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "default",
            "sm",
            "lg"
          ],
          "description": "Avatar size preset",
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Single avatar with a successfully loaded image and initials fallback for accessibility.",
          "code": "<Avatar>\n      <AvatarImage src=\"https://github.com/shadcn.png\" alt=\"@shadcn\" />\n      <AvatarFallback>CN</AvatarFallback>\n    </Avatar>"
        },
        {
          "name": "Fallback",
          "description": "Avatar with an empty image source URL, demonstrating the initials fallback display.",
          "code": "<Avatar>\n      <AvatarImage src=\"\" alt=\"@shadcn\" />\n      <AvatarFallback>JD</AvatarFallback>\n    </Avatar>"
        },
        {
          "name": "Sizes",
          "description": "Three avatars at 32px (sm), 48px (md), and 64px (lg) showcasing size customization via className.",
          "code": "<div className=\"flex items-center gap-4\">\n      <Avatar className=\"size-8\">\n        <AvatarImage src=\"https://github.com/shadcn.png\" alt=\"@shadcn\" />\n        <AvatarFallback>SM</AvatarFallback>\n      </Avatar>\n      <Avatar className=\"size-12\">\n        <AvatarImage src=\"https://github.com/shadcn.png\" alt=\"@shadcn\" />\n        <AvatarFallback>MD</AvatarFallback>\n      </Avatar>\n      <Avatar className=\"size-16\">\n        <AvatarImage src=\"https://github.com/shadcn.png\" alt=\"@shadcn\" />\n        <AvatarFallback>LG</AvatarFallback>\n      </Avatar>\n    </div>"
        }
      ]
    },
    {
      "name": "badge",
      "title": "Badge",
      "description": "A small visual indicator for categorization, counts, or status labels.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/badge",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/badge.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"secondary\" | \"destructive\" | \"outline\" | \"ghost\" | \"link\"",
          "options": [
            "default",
            "secondary",
            "destructive",
            "outline",
            "ghost",
            "link"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Badge",
      "stories": [
        {
          "name": "Default",
          "description": "Primary variant badge with the label \"Badge\" for standard categorization.",
          "args": "{\n    children: \"Badge\",\n    variant: \"default\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'Primary variant badge with the label \"Badge\" for standard categorization.',\n      },\n    },\n  },"
        },
        {
          "name": "Variants",
          "description": "All six badge variants (default, secondary, destructive, outline, ghost, link) displayed side by side.",
          "code": "<div className=\"flex flex-wrap gap-2\">\n      <Badge variant=\"default\">Default</Badge>\n      <Badge variant=\"secondary\">Secondary</Badge>\n      <Badge variant=\"destructive\">Destructive</Badge>\n      <Badge variant=\"outline\">Outline</Badge>\n      <Badge variant=\"ghost\">Ghost</Badge>\n      <Badge variant=\"link\">Link</Badge>\n    </div>"
        },
        {
          "name": "WithIcon",
          "description": "Badges with inline-start and inline-end icon positions across different variants.",
          "code": "<div className=\"flex flex-wrap gap-2\">\n      <Badge variant=\"default\">\n        <StarIcon data-icon=\"inline-start\" className=\"size-3\" />\n        Star\n      </Badge>\n      <Badge variant=\"secondary\">\n        <CheckIcon data-icon=\"inline-start\" className=\"size-3\" />\n        Verified\n      </Badge>\n      <Badge variant=\"destructive\">\n        Alert\n        <StarIcon data-icon=\"inline-end\" className=\"size-3\" />\n      </Badge>\n    </div>"
        },
        {
          "name": "AsChild",
          "description": "Badge rendered as an anchor link using the `asChild` composition pattern.",
          "code": "<Badge asChild>\n      <a href=\"#\">Link Badge</a>\n    </Badge>"
        }
      ]
    },
    {
      "name": "breadcrumb",
      "title": "Breadcrumb",
      "description": "A navigation aid showing the user's location in a hierarchical page structure with separators and ellipsis.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/breadcrumb",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/breadcrumb.tsx"
      ],
      "storyTitle": "Shadcn UI/Breadcrumb",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Three-level breadcrumb trail with Home, Components links and the current Breadcrumb page.",
          "code": "<Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Home</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>"
        },
        {
          "name": "WithEllipsis",
          "description": "Breadcrumb using BreadcrumbEllipsis to collapse intermediate navigation levels.",
          "code": "<Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Home</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbEllipsis />\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>"
        },
        {
          "name": "WithCustomSeparator",
          "description": "Breadcrumb with a custom text separator (\"/\") instead of the default icon-based separator.",
          "code": "<Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Home</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator>/</BreadcrumbSeparator>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator>/</BreadcrumbSeparator>\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>"
        },
        {
          "name": "WithDropdown",
          "description": "Interactive breadcrumb with a DropdownMenu for collapsed navigation, showing nested page options.",
          "code": "<Breadcrumb>\n      <BreadcrumbList>\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Home</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button variant=\"ghost\" size=\"icon-xs\" aria-label=\"Show more\">\n                <BreadcrumbEllipsis />\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"start\">\n              <DropdownMenuItem>Documentation</DropdownMenuItem>\n              <DropdownMenuItem>Themes</DropdownMenuItem>\n              <DropdownMenuItem>GitHub</DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbLink href=\"#\">Components</BreadcrumbLink>\n        </BreadcrumbItem>\n        <BreadcrumbSeparator />\n        <BreadcrumbItem>\n          <BreadcrumbPage>Breadcrumb</BreadcrumbPage>\n        </BreadcrumbItem>\n      </BreadcrumbList>\n    </Breadcrumb>"
        }
      ]
    },
    {
      "name": "bubble",
      "title": "Bubble",
      "description": "A chat bubble component with support for sent/received variants, tail indicators, and group layout. Composed of BubbleGroup sub-component.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/bubble",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/bubble.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"secondary\" | \"muted\" | \"tinted\" | \"outline\" | \"ghost\" | \"destructive\"",
          "options": [
            "default",
            "secondary",
            "muted",
            "tinted",
            "outline",
            "ghost",
            "destructive"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Bubble",
      "stories": [
        {
          "name": "Default",
          "description": "Default primary variant bubble aligned to the start with a sample message.",
          "code": "<Bubble>\n      <BubbleContent>Hey, how are you doing?</BubbleContent>\n    </Bubble>"
        },
        {
          "name": "Variants",
          "description": "All bubble variants (default, secondary, muted, tinted, outline, ghost, destructive) displayed in a column.",
          "code": "<div className=\"flex flex-col gap-3\">\n      <Bubble variant=\"default\">\n        <BubbleContent>Default bubble</BubbleContent>\n      </Bubble>\n      <Bubble variant=\"secondary\">\n        <BubbleContent>Secondary bubble</BubbleContent>\n      </Bubble>\n      <Bubble variant=\"muted\">\n        <BubbleContent>Muted bubble</BubbleContent>\n      </Bubble>\n      <Bubble variant=\"tinted\">\n        <BubbleContent>Tinted bubble</BubbleContent>\n      </Bubble>\n      <Bubble variant=\"outline\">\n        <BubbleContent>Outline bubble</BubbleContent>\n      </Bubble>\n      <Bubble variant=\"ghost\">\n        <BubbleContent>Ghost bubble</BubbleContent>\n      </Bubble>\n      <Bubble variant=\"destructive\">\n        <BubbleContent>Destructive bubble</BubbleContent>\n      </Bubble>\n    </div>"
        },
        {
          "name": "Alignment",
          "description": "Bubbles aligned to start and end within a conversation layout.",
          "code": "<div className=\"flex max-w-md flex-col gap-3\">\n      <Bubble align=\"start\" variant=\"secondary\">\n        <BubbleContent>Hello! How can I help you?</BubbleContent>\n      </Bubble>\n      <Bubble align=\"end\">\n        <BubbleContent>Hi! I need some assistance.</BubbleContent>\n      </Bubble>\n      <Bubble align=\"start\" variant=\"secondary\">\n        <BubbleContent>Sure, what do you need?</BubbleContent>\n      </Bubble>\n      <Bubble align=\"end\">\n        <BubbleContent>I need help with my account.</BubbleContent>\n      </Bubble>\n    </div>"
        },
        {
          "name": "WithReactions",
          "description": "Bubble with reaction badges displayed at the bottom-end corner.",
          "code": "<div className=\"flex max-w-md flex-col gap-3 pt-6\">\n      <Bubble align=\"start\" variant=\"secondary\">\n        <BubbleContent>\n          That&apos;s great news! Let me know if you need anything else.\n        </BubbleContent>\n        <BubbleReactions side=\"bottom\" align=\"end\">\n          <button\n            type=\"button\"\n            aria-label=\"Like\"\n            className=\"flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs transition-colors hover:bg-muted-foreground/10\"\n          >\n            <ThumbsUpIcon className=\"size-3.5\" />\n          </button>\n          <button\n            type=\"button\"\n            aria-label=\"Love\"\n            className=\"flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs transition-colors hover:bg-muted-foreground/10\"\n          >\n            <HeartIcon className=\"size-3.5\" />\n          </button>\n        </BubbleReactions>\n      </Bubble>\n      <Bubble align=\"end\">\n        <BubbleContent>Thanks, will do! 😊</BubbleContent>\n        <BubbleReactions side=\"bottom\" align=\"start\">\n          <button\n            type=\"button\"\n            aria-label=\"Smile\"\n            className=\"flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs transition-colors hover:bg-muted-foreground/10\"\n          >\n            <SmileIcon className=\"size-3.5\" />\n          </button>\n        </BubbleReactions>\n      </Bubble>\n    </div>"
        },
        {
          "name": "Group",
          "description": "Related bubbles grouped together using BubbleGroup with consecutive messages from the same sender.",
          "code": "<div className=\"flex max-w-md flex-col gap-4\">\n      <BubbleGroup>\n        <Bubble align=\"start\" variant=\"secondary\">\n          <BubbleContent>I have a few options for you.</BubbleContent>\n        </Bubble>\n        <Bubble align=\"start\" variant=\"secondary\">\n          <BubbleContent>\n            Option A: Standard plan with all basic features.\n          </BubbleContent>\n        </Bubble>\n        <Bubble align=\"start\" variant=\"secondary\">\n          <BubbleContent>\n            Option B: Premium plan with additional support.\n          </BubbleContent>\n        </Bubble>\n      </BubbleGroup>\n      <Bubble align=\"end\">\n        <BubbleContent>Let me go with Option B, please.</BubbleContent>\n      </Bubble>\n    </div>"
        }
      ]
    },
    {
      "name": "button",
      "title": "Button",
      "description": "An interactive button control used to trigger actions, submit forms, or navigate.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/button",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/button.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"outline\" | \"secondary\" | \"ghost\" | \"destructive\" | \"link\"",
          "options": [
            "default",
            "outline",
            "secondary",
            "ghost",
            "destructive",
            "link"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"default\" | \"xs\" | \"sm\" | \"lg\" | \"icon\" | \"icon-xs\" | \"icon-sm\" | \"icon-lg\"",
          "options": [
            "default",
            "xs",
            "sm",
            "lg",
            "icon",
            "icon-xs",
            "icon-sm",
            "icon-lg"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Button",
      "stories": [
        {
          "name": "Default",
          "description": "Primary variant with default size and the label \"Button\" for standard action triggers.",
          "args": "{\n    children: \"Button\",\n    variant: \"default\",\n    size: \"default\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'Primary variant with default size and the label \"Button\" for standard action triggers.',\n      },\n    },\n  },"
        },
        {
          "name": "Variants",
          "description": "All six button variants (default, outline, secondary, ghost, destructive, link) displayed together.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Button variant=\"default\">Default</Button>\n      <Button variant=\"outline\">Outline</Button>\n      <Button variant=\"secondary\">Secondary</Button>\n      <Button variant=\"ghost\">Ghost</Button>\n      <Button variant=\"destructive\">Destructive</Button>\n      <Button variant=\"link\">Link</Button>\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "Button size presets from xs to lg compared side by side with text labels.",
          "code": "<div className=\"flex items-center gap-4\">\n      <Button size=\"xs\">Extra Small</Button>\n      <Button size=\"sm\">Small</Button>\n      <Button size=\"default\">Default</Button>\n      <Button size=\"lg\">Large</Button>\n    </div>"
        },
        {
          "name": "IconSizes",
          "description": "Icon-only buttons at icon-xs, icon-sm, icon, and icon-lg sizes with an outline variant.",
          "code": "<div className=\"flex items-center gap-4\">\n      <Button size=\"icon-xs\" variant=\"outline\" aria-label=\"Extra small icon\">\n        <StarIcon data-icon=\"inline-start\" />\n      </Button>\n      <Button size=\"icon-sm\" variant=\"outline\" aria-label=\"Small icon\">\n        <StarIcon data-icon=\"inline-start\" />\n      </Button>\n      <Button size=\"icon\" variant=\"outline\" aria-label=\"Default icon\">\n        <StarIcon data-icon=\"inline-start\" />\n      </Button>\n      <Button size=\"icon-lg\" variant=\"outline\" aria-label=\"Large icon\">\n        <StarIcon data-icon=\"inline-start\" />\n      </Button>\n    </div>"
        },
        {
          "name": "Icons",
          "description": "Buttons with icons positioned at inline-start and inline-end of the text label.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Button>\n        <StarIcon data-icon=\"inline-start\" />\n        With Icon Start\n      </Button>\n      <Button>\n        With Icon End\n        <StarIcon data-icon=\"inline-end\" />\n      </Button>\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "Disabled state demonstrated across default, outline, and secondary variants.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Button disabled>Disabled</Button>\n      <Button disabled variant=\"outline\">\n        Disabled Outline\n      </Button>\n      <Button disabled variant=\"secondary\">\n        Disabled Secondary\n      </Button>\n    </div>"
        },
        {
          "name": "Loading",
          "description": "Loading state with an animated spinner icon positioned inline-start, shown in default, outline, and disabled variants.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Button>\n        <Loader2Icon data-icon=\"inline-start\" className=\"animate-spin\" />\n        Loading\n      </Button>\n      <Button variant=\"outline\">\n        <Loader2Icon data-icon=\"inline-start\" className=\"animate-spin\" />\n        Loading\n      </Button>\n      <Button disabled>\n        <Loader2Icon data-icon=\"inline-start\" className=\"animate-spin\" />\n        Loading\n      </Button>\n    </div>"
        },
        {
          "name": "AsChild",
          "description": "Button component rendered as an anchor element using the `asChild` composition API.",
          "code": "<Button asChild>\n      <a href=\"#\">Link as Button</a>\n    </Button>"
        }
      ]
    },
    {
      "name": "button-group",
      "title": "Button Group",
      "description": "A container that groups related buttons or inputs with connected or separated styling.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/button-group",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "separator"
      ],
      "files": [
        "components/ui/button-group.tsx"
      ],
      "props": [
        {
          "name": "orientation",
          "required": false,
          "type": "\"horizontal\" | \"vertical\"",
          "options": [
            "horizontal",
            "vertical"
          ],
          "default": "horizontal"
        }
      ],
      "storyTitle": "Shadcn UI/Button Group",
      "stories": [
        {
          "name": "Default",
          "description": "Horizontal button group with outline buttons for bold, italic, and underline formatting actions.",
          "args": "{\n    orientation: \"horizontal\",\n  },"
        },
        {
          "name": "WithSeparator",
          "description": "Two tool groups (alignment and formatting) separated by a visual divider.",
          "code": "<ButtonGroup>\n      <Button variant=\"outline\" size=\"sm\" aria-label=\"Align left\">\n        <AlignLeftIcon />\n      </Button>\n      <Button variant=\"outline\" size=\"sm\" aria-label=\"Align center\">\n        <AlignCenterIcon />\n      </Button>\n      <Button variant=\"outline\" size=\"sm\" aria-label=\"Align right\">\n        <AlignRightIcon />\n      </Button>\n      <ButtonGroupSeparator />\n      <Button variant=\"outline\" size=\"sm\" aria-label=\"Bold\">\n        <BoldIcon />\n      </Button>\n      <Button variant=\"outline\" size=\"sm\" aria-label=\"Italic\">\n        <ItalicIcon />\n      </Button>\n      <Button variant=\"outline\" size=\"sm\" aria-label=\"Underline\">\n        <UnderlineIcon />\n      </Button>\n    </ButtonGroup>"
        },
        {
          "name": "Vertical",
          "description": "Vertically stacked button group with search, settings, and user icon buttons.",
          "code": "<div className=\"flex justify-center\">\n      <ButtonGroup orientation=\"vertical\">\n        <Button variant=\"outline\" size=\"sm\" aria-label=\"Search\">\n          <SearchIcon />\n        </Button>\n        <Button variant=\"outline\" size=\"sm\" aria-label=\"Settings\">\n          <SettingsIcon />\n        </Button>\n        <Button variant=\"outline\" size=\"sm\" aria-label=\"User\">\n          <UserIcon />\n        </Button>\n      </ButtonGroup>\n    </div>"
        },
        {
          "name": "WithTextSegment",
          "description": "Button group combining a static text label segment with an actionable button.",
          "code": "<ButtonGroup>\n      <ButtonGroupText>Label</ButtonGroupText>\n      <Button variant=\"outline\" size=\"sm\">\n        Action\n      </Button>\n    </ButtonGroup>"
        },
        {
          "name": "IconOnly",
          "description": "Compact icon-only button group using icon-sm size, suitable for toolbars.",
          "code": "<ButtonGroup>\n      <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Bold\">\n        <BoldIcon />\n      </Button>\n      <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Italic\">\n        <ItalicIcon />\n      </Button>\n      <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"Underline\">\n        <UnderlineIcon />\n      </Button>\n    </ButtonGroup>"
        }
      ]
    },
    {
      "name": "calendar",
      "title": "Calendar",
      "description": "A date picker with day selection, range support, and dropdown navigation.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/calendar",
      "dependencies": [
        "cn",
        "react-day-picker",
        "lucide-react"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ui/calendar.tsx"
      ],
      "storyTitle": "Shadcn UI/Calendar",
      "props": [
        {
          "name": "captionLayout",
          "control": "inline-radio",
          "options": [
            "label",
            "dropdown"
          ],
          "description": "How the month/year caption is displayed",
          "default": "label"
        },
        {
          "name": "showOutsideDays",
          "control": "boolean",
          "description": "Show days from adjacent months",
          "default": "true"
        },
        {
          "name": "buttonVariant",
          "control": "select",
          "options": [
            "default",
            "outline",
            "secondary",
            "ghost",
            "destructive",
            "link"
          ],
          "description": "Variant for the previous/next navigation buttons",
          "default": "ghost"
        },
        {
          "name": "mode",
          "control": "inline-radio",
          "options": [
            "single",
            "multiple",
            "range"
          ],
          "description": "Selection mode",
          "default": "single"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Single date selection with today's date pre-selected and the default label caption."
        },
        {
          "name": "WithDropdownCaption",
          "description": "Calendar with dropdown-based month and year selectors replacing the default label caption.",
          "code": "<Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        captionLayout=\"dropdown\"\n      />"
        },
        {
          "name": "RangeSelection",
          "description": "Range selection mode with a five-day span pre-selected from today.",
          "code": "<Calendar\n        mode=\"range\"\n        selected={range}\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        onSelect={setRange as any}\n      />"
        },
        {
          "name": "MultipleMonths",
          "description": "Two months displayed side by side using the `numberOfMonths` prop for broader date visibility.",
          "code": "<Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        numberOfMonths={2}\n      />"
        },
        {
          "name": "WithWeekNumbers",
          "description": "Calendar with week number indicators displayed along the left column for ISO week tracking.",
          "code": "<Calendar\n        mode=\"single\"\n        selected={date}\n        onSelect={setDate}\n        showWeekNumber\n      />"
        }
      ]
    },
    {
      "name": "card",
      "title": "Card",
      "description": "A versatile card container with sub-components for header, title, action buttons, descriptions, body content, and footer actions.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/card",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/card.tsx"
      ],
      "storyTitle": "Shadcn UI/Card",
      "props": [
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "default",
            "sm"
          ],
          "description": "Controls the card's internal padding and gap sizing.",
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Standard card with header, title, description, body content, and a footer action button.",
          "args": "{\n    size: \"default\",\n    children: (\n      <>\n        <CardHeader>\n          <CardTitle>Card Title</CardTitle>\n          <CardDescription>\n            Card Description and secondary details.\n          </CardDescription>\n        </CardHeader>\n        <CardContent>\n          <p className=\"text-muted-foreground\">\n            This is the main body content of the card. You can render any\n            elements here, including charts, forms, or paragraph blocks.\n          </p>\n        </CardContent>\n        <CardFooter className=\"border-t pt-6\">\n          <div className=\"flex w-full items-center justify-between\">\n            <span className=\"text-xs text-muted-foreground\">\n              Last updated 5m ago\n            </span>\n            <Button size=\"sm\">Action</Button>\n          </div>\n        </CardFooter>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard card with header, title, description, body content, and a footer action button.\",\n      },\n    },\n  },"
        },
        {
          "name": "Small",
          "description": "Compact card with `size=\"sm\"` for reduced padding, suitable for dashboard widgets.",
          "args": "{\n    size: \"sm\",\n    children: (\n      <>\n        <CardHeader>\n          <CardTitle>Small Variant</CardTitle>\n          <CardDescription>\n            Using size=&quot;sm&quot; for compact UI cards.\n          </CardDescription>\n        </CardHeader>\n        <CardContent>\n          <p className=\"text-muted-foreground\">\n            Compact padding and narrower gaps between header and body contents.\n            Useful for dashboard widgets.\n          </p>\n        </CardContent>\n        <CardFooter className=\"border-t pt-4\">\n          <Button size=\"sm\" variant=\"outline\" className=\"w-full\">\n            Confirm\n          </Button>\n        </CardFooter>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'Compact card with `size=\"sm\"` for reduced padding, suitable for dashboard widgets.',\n      },\n    },\n  },"
        },
        {
          "name": "WithAction",
          "description": "Card with a contextual action button positioned in the top-right corner of the header via CardAction.",
          "args": "{\n    size: \"default\",\n    children: (\n      <>\n        <CardHeader>\n          <CardTitle>Project Settings</CardTitle>\n          <CardDescription>Manage your workspace preferences.</CardDescription>\n          <CardAction>\n            <Button size=\"icon-sm\" variant=\"ghost\" aria-label=\"More options\">\n              <MoreHorizontal className=\"size-4\" />\n            </Button>\n          </CardAction>\n        </CardHeader>\n        <CardContent>\n          <p className=\"text-muted-foreground\">\n            Click the action menu in the top-right corner to perform\n            context-specific actions on this card.\n          </p>\n        </CardContent>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Card with a contextual action button positioned in the top-right corner of the header via CardAction.\",\n      },\n    },\n  },"
        },
        {
          "name": "StatusBadge",
          "description": "Card header with an inline status badge next to the title for indicating live state.",
          "args": "{\n    size: \"default\",\n    children: (\n      <>\n        <CardHeader>\n          <div className=\"flex items-center justify-between\">\n            <CardTitle>API Integration</CardTitle>\n            <Badge variant=\"secondary\">Active</Badge>\n          </div>\n          <CardDescription>\n            Webhook connections and data payloads.\n          </CardDescription>\n        </CardHeader>\n        <CardContent>\n          <p className=\"text-muted-foreground\">\n            Monitor API endpoints, latency charts, and event dispatches from\n            this central view.\n          </p>\n        </CardContent>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Card header with an inline status badge next to the title for indicating live state.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "card-stat-shared",
      "title": "Card Stat Shared",
      "description": "Shared utilities, CVA variants, and helper components (TrendBadge, CardStatEmptySlot) for the card-stat family.",
      "type": "registry:ui",
      "category": "lib",
      "importPath": "@/lib/card-stats-shared",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "format-utils"
      ],
      "files": [
        "lib/card-stats-shared.tsx"
      ]
    },
    {
      "name": "carousel",
      "title": "Carousel",
      "description": "A sliding carousel for cycling through elements with previous/next navigation using Embla.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/carousel",
      "dependencies": [
        "cn",
        "embla-carousel-react",
        "lucide-react"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ui/carousel.tsx"
      ],
      "storyTitle": "Shadcn UI/Carousel",
      "props": [
        {
          "name": "orientation",
          "control": "inline-radio",
          "options": [
            "horizontal",
            "vertical"
          ],
          "description": "Scroll direction",
          "default": "horizontal"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Horizontal carousel with responsive slide widths (1/2 on md, 1/3 on lg) and navigation arrows.",
          "args": "{\n    orientation: \"horizontal\",\n  },"
        },
        {
          "name": "SingleSlide",
          "description": "Carousel showing one full slide at a time with navigation arrows for browsing.",
          "code": "<Carousel className=\"mx-16\">\n      <CarouselContent>\n        {Array.from({ length: 6 }).map((_, i) => (\n          <CarouselItem key={i}>\n            <div className={slideStyles[0]}>{i + 1}</div>\n          </CarouselItem>\n        ))}\n      </CarouselContent>\n      <CarouselPrevious />\n      <CarouselNext />\n    </Carousel>"
        },
        {
          "name": "Vertical",
          "description": "Vertically oriented carousel with constrained 320px height for sidebar-like layouts.",
          "code": "<div className=\"flex justify-center\">\n      <Carousel orientation=\"vertical\" className=\"h-80 w-64\">\n        <CarouselContent>\n          {Array.from({ length: 6 }).map((_, i) => (\n            <CarouselItem key={i}>\n              <div className={slideStyles[0]}>{i + 1}</div>\n            </CarouselItem>\n          ))}\n        </CarouselContent>\n        <CarouselPrevious />\n        <CarouselNext />\n      </Carousel>\n    </div>"
        },
        {
          "name": "WithCustomOpts",
          "description": "Carousel configured with start-aligned slides and infinite looping enabled via opts.",
          "code": "<Carousel className=\"mx-16\" opts={{ align: \"start\", loop: true }}>\n      <CarouselContent>\n        {Array.from({ length: 6 }).map((_, i) => (\n          <CarouselItem key={i} className=\"md:basis-1/3\">\n            <div className={slideStyles[0]}>{i + 1}</div>\n          </CarouselItem>\n        ))}\n      </CarouselContent>\n      <CarouselPrevious />\n      <CarouselNext />\n    </Carousel>"
        }
      ]
    },
    {
      "name": "chart",
      "title": "Chart",
      "description": "A charting container with config-driven tooltips, legends, and CSS variable styling integration for Recharts.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/chart",
      "dependencies": [
        "cn",
        "recharts"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/chart.tsx"
      ],
      "storyTitle": "Shadcn UI/Chart",
      "props": [],
      "stories": [
        {
          "name": "BarChartStory",
          "description": "Bar chart comparing monthly revenue and expenses with dot indicator tooltip and legend.",
          "code": "<ChartContainer config={barConfig}>\n      <BarChart data={monthlyData} accessibilityLayer>\n        <CartesianGrid vertical={false} />\n        <XAxis\n          dataKey=\"month\"\n          tickLine={false}\n          tickMargin={8}\n          axisLine={false}\n        />\n        <YAxis tickLine={false} axisLine={false} tickMargin={8} />\n        <ChartTooltip\n          cursor={false}\n          content={<ChartTooltipContent indicator=\"dot\" />}\n        />\n        <ChartLegend content={<ChartLegendContent />} />\n        <RechartsBar\n          dataKey=\"revenue\"\n          fill=\"var(--color-revenue)\"\n          radius={[4, 4, 0, 0]}\n        />\n        <RechartsBar\n          dataKey=\"expenses\"\n          fill=\"var(--color-expenses)\"\n          radius={[4, 4, 0, 0]}\n        />\n      </BarChart>\n    </ChartContainer>"
        },
        {
          "name": "LineChartStory",
          "description": "Line chart tracking profit trends over six months with monotone interpolation and no dots.",
          "code": "<ChartContainer config={barConfig}>\n      <LineChart data={monthlyData} accessibilityLayer>\n        <CartesianGrid vertical={false} />\n        <XAxis\n          dataKey=\"month\"\n          tickLine={false}\n          tickMargin={8}\n          axisLine={false}\n        />\n        <YAxis tickLine={false} axisLine={false} tickMargin={8} />\n        <ChartTooltip\n          cursor={false}\n          content={<ChartTooltipContent indicator=\"line\" />}\n        />\n        <ChartLegend content={<ChartLegendContent />} />\n        <RechartsLine\n          type=\"monotone\"\n          dataKey=\"profit\"\n          stroke=\"var(--color-profit)\"\n          strokeWidth={2}\n          dot={false}\n        />\n      </LineChart>\n    </ChartContainer>"
        },
        {
          "name": "PieChartStory",
          "description": "Donut chart showing category distribution with custom inner radius and color-coded cells.",
          "code": "<div className=\"flex justify-center\">\n      <ChartContainer\n        config={pieConfig}\n        className=\"aspect-square max-h-[320px] min-h-[200px]\"\n      >\n        <PieChart>\n          <ChartTooltip\n            cursor={false}\n            content={<ChartTooltipContent hideLabel />}\n          />\n          <RechartsPie\n            data={pieData}\n            dataKey=\"value\"\n            nameKey=\"category\"\n            innerRadius={60}\n            strokeWidth={2}\n          >\n            {pieData.map((entry) => (\n              <Cell\n                key={entry.category}\n                fill={`var(--color-${entry.category.toLowerCase()})`}\n              />\n            ))}\n          </RechartsPie>\n        </PieChart>\n      </ChartContainer>\n    </div>"
        },
        {
          "name": "DashedIndicator",
          "description": "Bar chart using the dashed line indicator style in the tooltip for visual distinction.",
          "code": "<ChartContainer config={barConfig}>\n      <BarChart data={monthlyData} accessibilityLayer>\n        <CartesianGrid vertical={false} />\n        <XAxis\n          dataKey=\"month\"\n          tickLine={false}\n          tickMargin={8}\n          axisLine={false}\n        />\n        <YAxis tickLine={false} axisLine={false} tickMargin={8} />\n        <ChartTooltip\n          cursor={false}\n          content={<ChartTooltipContent indicator=\"dashed\" />}\n        />\n        <ChartLegend content={<ChartLegendContent />} />\n        <RechartsBar\n          dataKey=\"revenue\"\n          fill=\"var(--color-revenue)\"\n          radius={[4, 4, 0, 0]}\n        />\n        <RechartsBar\n          dataKey=\"expenses\"\n          fill=\"var(--color-expenses)\"\n          radius={[4, 4, 0, 0]}\n        />\n      </BarChart>\n    </ChartContainer>"
        },
        {
          "name": "HideLabel",
          "description": "Bar chart tooltip configured with `hideLabel` to display values only without the series label.",
          "code": "<ChartContainer config={barConfig}>\n      <BarChart data={monthlyData} accessibilityLayer>\n        <CartesianGrid vertical={false} />\n        <XAxis\n          dataKey=\"month\"\n          tickLine={false}\n          tickMargin={8}\n          axisLine={false}\n        />\n        <YAxis tickLine={false} axisLine={false} tickMargin={8} />\n        <ChartTooltip\n          cursor={false}\n          content={<ChartTooltipContent indicator=\"dot\" hideLabel />}\n        />\n        <ChartLegend content={<ChartLegendContent />} />\n        <RechartsBar\n          dataKey=\"revenue\"\n          fill=\"var(--color-revenue)\"\n          radius={[4, 4, 0, 0]}\n        />\n        <RechartsBar\n          dataKey=\"expenses\"\n          fill=\"var(--color-expenses)\"\n          radius={[4, 4, 0, 0]}\n        />\n      </BarChart>\n    </ChartContainer>"
        }
      ]
    },
    {
      "name": "chart-axis-width",
      "title": "Chart Axis Width",
      "description": "Canvas-based text measurement that sizes a numeric Recharts axis to fit its actual formatted tick labels (currency, abbreviated units), instead of a fixed guess that wraps or clips long values.",
      "type": "registry:lib",
      "category": "lib",
      "importPath": "@/lib/chart-axis-width",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "lib/chart-axis-width.ts"
      ]
    },
    {
      "name": "checkbox",
      "title": "Checkbox",
      "description": "A form control for selecting one or more options from a set.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/checkbox",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/checkbox.tsx"
      ],
      "storyTitle": "Shadcn UI/Checkbox",
      "props": [
        {
          "name": "checked",
          "control": "inline-radio",
          "options": [
            "indeterminate"
          ],
          "description": "The controlled checked state",
          "default": "false"
        },
        {
          "name": "disabled",
          "control": "boolean",
          "default": "false"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Controlled checkbox with label and state management showing unchecked and checked states.",
          "code": "<div className=\"flex items-center gap-2\">\n        <Checkbox\n          id=\"terms\"\n          checked={checked}\n          onCheckedChange={(v) => typeof v === \"boolean\" && setChecked(v)}\n        />\n        <Label htmlFor=\"terms\">Accept terms and conditions</Label>\n      </div>"
        },
        {
          "name": "Checked",
          "description": "Checkbox pre-checked by default to demonstrate the checked visual state.",
          "code": "<div className=\"flex items-center gap-2\">\n      <Checkbox id=\"checked-demo\" checked />\n      <Label htmlFor=\"checked-demo\">Option enabled</Label>\n    </div>"
        },
        {
          "name": "Indeterminate",
          "description": "Checkbox in indeterminate state indicating a partial selection within a group.",
          "code": "<div className=\"flex items-center gap-2\">\n      <Checkbox id=\"indeterminate-demo\" checked=\"indeterminate\" />\n      <Label htmlFor=\"indeterminate-demo\">Some selected</Label>\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "Disabled checkboxes in both unchecked and checked states with dimmed label styling.",
          "code": "<div className=\"flex flex-col gap-3\">\n      <div className=\"flex items-center gap-2\">\n        <Checkbox id=\"disabled-unchecked\" disabled />\n        <Label htmlFor=\"disabled-unchecked\" className=\"text-muted-foreground\">\n          Unavailable option\n        </Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <Checkbox id=\"disabled-checked\" disabled checked />\n        <Label htmlFor=\"disabled-checked\" className=\"text-muted-foreground\">\n          Locked selection\n        </Label>\n      </div>\n    </div>"
        },
        {
          "name": "WithLabel",
          "description": "Simple uncontrolled checkbox paired with a label using the `htmlFor` attribute.",
          "code": "<div className=\"flex items-center gap-2\">\n      <Checkbox id=\"label-demo\" />\n      <Label htmlFor=\"label-demo\">Subscribe to newsletter</Label>\n    </div>"
        }
      ]
    },
    {
      "name": "collapsible",
      "title": "Collapsible",
      "description": "An expandable/collapsible section with trigger and content regions.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/collapsible",
      "dependencies": [
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/collapsible.tsx"
      ],
      "storyTitle": "Shadcn UI/Collapsible",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Collapsible section with an outline button trigger and an animated chevron icon that rotates on open.",
          "code": "<Collapsible className=\"w-80\">\n      <CollapsibleTrigger asChild>\n        <Button variant=\"outline\" className=\"flex w-full items-center gap-2\">\n          <span>Toggle Content</span>\n          <ChevronDownIcon\n            data-icon=\"inline-start\"\n            className=\"transition-transform group-data-open/collapsible:rotate-180\"\n          />\n        </Button>\n      </CollapsibleTrigger>\n      <CollapsibleContent className=\"mt-2 rounded-3xl bg-muted p-4 text-sm text-muted-foreground\">\n        This content is collapsible. Click the trigger to show or hide it.\n      </CollapsibleContent>\n    </Collapsible>"
        }
      ]
    },
    {
      "name": "combobox",
      "title": "Combobox",
      "description": "An autocomplete combobox built on @base-ui/react with search, groups, multi-select chips, and keyboard navigation.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/combobox",
      "dependencies": [
        "@base-ui/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "input-group"
      ],
      "files": [
        "components/ui/combobox.tsx"
      ],
      "storyTitle": "Shadcn UI/Combobox",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Single-select combobox filtering through a list of frameworks with a text input and dropdown."
        },
        {
          "name": "WithClear",
          "description": "Combobox with a clear button to reset the selected value back to empty."
        },
        {
          "name": "Disabled",
          "description": "Combobox input rendered in a disabled state with a placeholder indicating it cannot be interacted with."
        },
        {
          "name": "WithGroups",
          "description": "Combobox with items organized into labeled groups (Library and Meta-framework) for structured browsing."
        },
        {
          "name": "MultiSelect",
          "description": "Multi-select combobox with selected values displayed as removable chips and a chips input."
        },
        {
          "name": "WithCustomFilter",
          "description": "Combobox with a custom client-side filter matching against both label and value fields."
        },
        {
          "name": "ControlledValue",
          "description": "Combobox with the value controlled externally via dedicated action buttons for each option."
        },
        {
          "name": "WithBadgeValue",
          "description": "Combobox that displays the selected value as a Badge component instead of inline text."
        }
      ]
    },
    {
      "name": "command",
      "title": "Command",
      "description": "A fast, searchable command palette and menu list interface driven by keyboard navigation.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/command",
      "dependencies": [
        "cmdk",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "dialog",
        "input-group",
        "ui-i18n"
      ],
      "files": [
        "components/ui/command.tsx"
      ],
      "storyTitle": "Shadcn UI/Command",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Command dialog with framework and account groups, each item displaying an icon and keyboard shortcut.",
          "code": "<CommandDialog>\n      <DefaultCommand />\n    </CommandDialog>"
        },
        {
          "name": "WithIcons",
          "description": "Command dialog with action and preference groups using descriptive icons and keyboard shortcuts.",
          "code": "<CommandDialog>\n      <CommandInput placeholder=\"Search...\" />\n      <CommandList>\n        <CommandGroup heading=\"Actions\">\n          <CommandItem>\n            <UserIcon data-icon=\"inline-start\" />\n            Add User\n            <CommandShortcut>⌘U</CommandShortcut>\n          </CommandItem>\n          <CommandItem>\n            <MailIcon data-icon=\"inline-start\" />\n            Send Email\n            <CommandShortcut>⌘E</CommandShortcut>\n          </CommandItem>\n          <CommandItem>\n            <SettingsIcon data-icon=\"inline-start\" />\n            Settings\n            <CommandShortcut>⌘,</CommandShortcut>\n          </CommandItem>\n        </CommandGroup>\n        <CommandSeparator />\n        <CommandGroup heading=\"Preferences\">\n          <CommandItem>\n            <PaletteIcon data-icon=\"inline-start\" />\n            Theme\n            <CommandShortcut>⌘T</CommandShortcut>\n          </CommandItem>\n          <CommandItem>\n            <BellIcon data-icon=\"inline-start\" />\n            Notifications\n            <CommandShortcut>⌘N</CommandShortcut>\n          </CommandItem>\n        </CommandGroup>\n      </CommandList>\n    </CommandDialog>"
        },
        {
          "name": "Empty",
          "description": "Command dialog showing the empty state message when no results match the search input.",
          "code": "<CommandDialog>\n      <CommandInput placeholder=\"Search...\" />\n      <CommandList>\n        <CommandEmpty>No results found for your search.</CommandEmpty>\n      </CommandList>\n    </CommandDialog>"
        },
        {
          "name": "WithoutDialog",
          "description": "Inline command palette rendered directly in the page without a modal overlay, inside a bordered container.",
          "code": "<div className=\"w-full max-w-sm rounded-lg border p-2\">\n      <Command>\n        <CommandInput placeholder=\"Search commands...\" />\n        <CommandList>\n          <CommandGroup heading=\"Suggestions\">\n            <CommandItem>\n              <PlusIcon data-icon=\"inline-start\" />\n              New Project\n            </CommandItem>\n            <CommandItem>\n              <UserIcon data-icon=\"inline-start\" />\n              Add Member\n            </CommandItem>\n          </CommandGroup>\n        </CommandList>\n      </Command>\n    </div>"
        }
      ]
    },
    {
      "name": "context-menu",
      "title": "Context Menu",
      "description": "A right-click context menu with items, submenus, checkboxes, radio items, and separators.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/context-menu",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/context-menu.tsx"
      ],
      "storyTitle": "Shadcn UI/Context Menu",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Full-featured context menu with edit actions, sharing options, a submenu, and a destructive delete item.",
          "code": "<ContextMenu>\n      <ContextMenuTrigger className=\"flex h-32 w-80 items-center justify-center rounded-3xl border-2 border-dashed border-border bg-muted/30 text-sm text-muted-foreground\">\n        Right-click here\n      </ContextMenuTrigger>\n      <ContextMenuContent>\n        <ContextMenuItem>\n          Edit\n          <ContextMenuShortcut>⌘E</ContextMenuShortcut>\n        </ContextMenuItem>\n        <ContextMenuItem>\n          Duplicate\n          <ContextMenuShortcut>⌘D</ContextMenuShortcut>\n        </ContextMenuItem>\n        <ContextMenuSeparator />\n        <ContextMenuLabel>Sharing</ContextMenuLabel>\n        <ContextMenuItem inset>Share via Email</ContextMenuItem>\n        <ContextMenuItem inset>Copy Link</ContextMenuItem>\n        <ContextMenuSeparator />\n        <ContextMenuSub>\n          <ContextMenuSubTrigger inset>More Actions</ContextMenuSubTrigger>\n          <ContextMenuSubContent>\n            <ContextMenuItem>Bookmark</ContextMenuItem>\n            <ContextMenuItem>Report</ContextMenuItem>\n          </ContextMenuSubContent>\n        </ContextMenuSub>\n        <ContextMenuSeparator />\n        <ContextMenuItem variant=\"destructive\">\n          Delete\n          <ContextMenuShortcut>⌘⌫</ContextMenuShortcut>\n        </ContextMenuItem>\n      </ContextMenuContent>\n    </ContextMenu>"
        },
        {
          "name": "CheckboxItems",
          "description": "Context menu with toggleable checkbox items for showing sidebar, toolbar, and status bar.",
          "code": "<ContextMenu>\n      <ContextMenuTrigger className=\"flex h-32 w-80 items-center justify-center rounded-3xl border-2 border-dashed border-border bg-muted/30 text-sm text-muted-foreground\">\n        Right-click here\n      </ContextMenuTrigger>\n      <ContextMenuContent>\n        <ContextMenuCheckboxItem checked>Show Sidebar</ContextMenuCheckboxItem>\n        <ContextMenuCheckboxItem>Show Toolbar</ContextMenuCheckboxItem>\n        <ContextMenuCheckboxItem>Show Status Bar</ContextMenuCheckboxItem>\n      </ContextMenuContent>\n    </ContextMenu>"
        },
        {
          "name": "RadioItems",
          "description": "Context menu with a radio group for selecting a sort order (name, date, or size).",
          "code": "<ContextMenu>\n      <ContextMenuTrigger className=\"flex h-32 w-80 items-center justify-center rounded-3xl border-2 border-dashed border-border bg-muted/30 text-sm text-muted-foreground\">\n        Right-click here\n      </ContextMenuTrigger>\n      <ContextMenuContent>\n        <ContextMenuLabel>Sort By</ContextMenuLabel>\n        <ContextMenuRadioGroup value=\"name\">\n          <ContextMenuRadioItem value=\"name\">Name</ContextMenuRadioItem>\n          <ContextMenuRadioItem value=\"date\">Date</ContextMenuRadioItem>\n          <ContextMenuRadioItem value=\"size\">Size</ContextMenuRadioItem>\n        </ContextMenuRadioGroup>\n      </ContextMenuContent>\n    </ContextMenu>"
        }
      ]
    },
    {
      "name": "dialog",
      "title": "Dialog",
      "description": "A modal overlay that interrupts the user with critical information or requires direct interaction.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/dialog",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ui/dialog.tsx"
      ],
      "storyTitle": "Shadcn UI/Dialog",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Modal dialog with header, form inputs, and a footer containing cancel and save buttons.",
          "code": "<Dialog>\n      <DialogTrigger asChild>\n        <Button>Open Dialog</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Edit Profile</DialogTitle>\n          <DialogDescription>\n            Make changes to your profile here. Click save when you&apos;re done.\n          </DialogDescription>\n        </DialogHeader>\n        <div className=\"grid gap-4 py-4\">\n          <Input placeholder=\"Your name\" />\n          <Input placeholder=\"Your email\" />\n        </div>\n        <DialogFooter showCloseButton>\n          <Button variant=\"outline\">Cancel</Button>\n          <Button>Save changes</Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>"
        },
        {
          "name": "WithoutCloseButton",
          "description": "Dialog with the close button hidden via `showCloseButton={false}` for non-dismissible modals.",
          "code": "<Dialog>\n      <DialogTrigger asChild>\n        <Button>No Close Button</Button>\n      </DialogTrigger>\n      <DialogContent showCloseButton={false}>\n        <DialogHeader>\n          <DialogTitle>Modal without close</DialogTitle>\n          <DialogDescription>\n            This dialog does not show a close button.\n          </DialogDescription>\n        </DialogHeader>\n        <p>Content goes here...</p>\n      </DialogContent>\n    </Dialog>"
        },
        {
          "name": "Large",
          "description": "Wide dialog with `max-w-2xl` providing extra horizontal space for forms with multiple fields.",
          "code": "<Dialog>\n      <DialogTrigger asChild>\n        <Button>Large Dialog</Button>\n      </DialogTrigger>\n      <DialogContent className=\"max-w-2xl\">\n        <DialogHeader>\n          <DialogTitle>Large Dialog</DialogTitle>\n          <DialogDescription>\n            A wider dialog for more content.\n          </DialogDescription>\n        </DialogHeader>\n        <div className=\"grid gap-4 py-4\">\n          <Input placeholder=\"Field 1\" />\n          <Input placeholder=\"Field 2\" />\n          <Input placeholder=\"Field 3\" />\n          <Input placeholder=\"Field 4\" />\n        </div>\n        <DialogFooter showCloseButton>\n          <Button variant=\"outline\">Cancel</Button>\n          <Button>Submit</Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>"
        },
        {
          "name": "Confirmation",
          "description": "Destructive confirmation dialog for delete actions with danger-styled buttons and warning text.",
          "code": "<Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"destructive\">Delete Item</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Delete Item</DialogTitle>\n          <DialogDescription>\n            Are you sure you want to delete this item? This action cannot be\n            undone.\n          </DialogDescription>\n        </DialogHeader>\n        <DialogFooter showCloseButton>\n          <Button variant=\"outline\">Cancel</Button>\n          <Button variant=\"destructive\">Delete</Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>"
        }
      ]
    },
    {
      "name": "direction",
      "title": "Direction",
      "description": "A provider component for setting text direction (LTR/RTL) using Radix UI Direction.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/direction",
      "dependencies": [
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/direction.tsx"
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Left-to-right direction context wrapping a simple text element for LTR language layouts.",
          "args": "{\n    dir: \"ltr\",\n    children: (\n      <div className=\"text-sm text-muted-foreground\">\n        Content with left-to-right direction.\n      </div>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Left-to-right direction context wrapping a simple text element for LTR language layouts.\",\n      },\n    },\n  },"
        },
        {
          "name": "RTL",
          "description": "Right-to-left direction context with Arabic text content for RTL language support.",
          "args": "{\n    dir: \"rtl\",\n    children: (\n      <div className=\"text-sm text-muted-foreground\">\n        محتوى باتجاه من اليمين إلى اليسار.\n      </div>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Right-to-left direction context with Arabic text content for RTL language support.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "drawer",
      "title": "Drawer",
      "description": "A slide-over panel built on vaul, supporting bottom, left, right, and top directions with drag-to-dismiss gestures.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/drawer",
      "dependencies": [
        "cn",
        "vaul"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/drawer.tsx"
      ],
      "storyTitle": "Shadcn UI/Drawer",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Bottom drawer with title, description, submit button, and cancel action via DrawerClose.",
          "code": "<Drawer>\n      <DrawerTrigger asChild>\n        <Button variant=\"outline\">Open</Button>\n      </DrawerTrigger>\n      <DrawerContent>\n        <DrawerHeader>\n          <DrawerTitle>Are you absolutely sure?</DrawerTitle>\n          <DrawerDescription>This action cannot be undone.</DrawerDescription>\n        </DrawerHeader>\n        <DrawerFooter>\n          <Button>Submit</Button>\n          <DrawerClose asChild>\n            <Button variant=\"outline\">Cancel</Button>\n          </DrawerClose>\n        </DrawerFooter>\n      </DrawerContent>\n    </Drawer>"
        },
        {
          "name": "WithForm",
          "description": "Bottom drawer containing form inputs for profile editing with save and cancel actions.",
          "code": "<Drawer>\n      <DrawerTrigger asChild>\n        <Button>Edit Profile</Button>\n      </DrawerTrigger>\n      <DrawerContent>\n        <DrawerHeader>\n          <DrawerTitle>Edit Profile</DrawerTitle>\n          <DrawerDescription>\n            Make changes to your profile here. Click save when you&apos;re done.\n          </DrawerDescription>\n        </DrawerHeader>\n        <div className=\"grid gap-4 px-4\">\n          <Input placeholder=\"Your name\" />\n          <Input placeholder=\"Your email\" />\n        </div>\n        <DrawerFooter>\n          <Button>Save changes</Button>\n          <DrawerClose asChild>\n            <Button variant=\"outline\">Cancel</Button>\n          </DrawerClose>\n        </DrawerFooter>\n      </DrawerContent>\n    </Drawer>"
        },
        {
          "name": "ScrollableContent",
          "description": "Bottom drawer with scrollable long-form content limited to 60% viewport height.",
          "code": "<Drawer>\n      <DrawerTrigger asChild>\n        <Button variant=\"outline\">Scrollable Content</Button>\n      </DrawerTrigger>\n      <DrawerContent className=\"data-[vaul-drawer-direction=bottom]:max-h-[60vh]\">\n        <DrawerHeader>\n          <DrawerTitle>Terms of Service</DrawerTitle>\n          <DrawerDescription>\n            Read carefully before accepting.\n          </DrawerDescription>\n        </DrawerHeader>\n        <div className=\"no-scrollbar overflow-y-auto px-4\">\n          {Array.from({ length: 8 }).map((_, i) => (\n            <p\n              key={i}\n              className=\"mb-4 text-sm leading-relaxed text-muted-foreground\"\n            >\n              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do\n              eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut\n              enim ad minim veniam, quis nostrud exercitation ullamco laboris\n              nisi ut aliquip ex ea commodo consequat.\n            </p>\n          ))}\n        </div>\n        <DrawerFooter>\n          <Button>Accept</Button>\n          <DrawerClose asChild>\n            <Button variant=\"outline\">Decline</Button>\n          </DrawerClose>\n        </DrawerFooter>\n      </DrawerContent>\n    </Drawer>"
        },
        {
          "name": "Confirmation",
          "description": "Destructive confirmation drawer for account deletion with cancel and delete actions.",
          "code": "<Drawer>\n      <DrawerTrigger asChild>\n        <Button variant=\"destructive\">Delete Account</Button>\n      </DrawerTrigger>\n      <DrawerContent>\n        <DrawerHeader>\n          <DrawerTitle>Delete Account</DrawerTitle>\n          <DrawerDescription>\n            Are you sure? This action is permanent and cannot be undone.\n          </DrawerDescription>\n        </DrawerHeader>\n        <DrawerFooter>\n          <DrawerClose asChild>\n            <Button variant=\"outline\">Cancel</Button>\n          </DrawerClose>\n          <Button variant=\"destructive\">Delete</Button>\n        </DrawerFooter>\n      </DrawerContent>\n    </Drawer>"
        },
        {
          "name": "FromLeft",
          "description": "Drawer sliding in from the left edge with navigation items for sidebar-style panels.",
          "code": "<Drawer direction=\"left\">\n      <DrawerTrigger asChild>\n        <Button variant=\"outline\">Open Left</Button>\n      </DrawerTrigger>\n      <DrawerContent>\n        <DrawerHeader>\n          <DrawerTitle>Navigation</DrawerTitle>\n          <DrawerDescription>Browse available sections.</DrawerDescription>\n        </DrawerHeader>\n        <div className=\"flex flex-col gap-1 px-4\">\n          {[\"Dashboard\", \"Analytics\", \"Settings\", \"Help\"].map((item) => (\n            <Button key={item} variant=\"ghost\" className=\"justify-start\">\n              {item}\n            </Button>\n          ))}\n        </div>\n        <DrawerFooter>\n          <DrawerClose asChild>\n            <Button variant=\"outline\">Close</Button>\n          </DrawerClose>\n        </DrawerFooter>\n      </DrawerContent>\n    </Drawer>"
        },
        {
          "name": "FromRight",
          "description": "Drawer sliding in from the right edge with notification cards displaying recent activity.",
          "code": "<Drawer direction=\"right\">\n      <DrawerTrigger asChild>\n        <Button variant=\"outline\">Open Right</Button>\n      </DrawerTrigger>\n      <DrawerContent>\n        <DrawerHeader>\n          <DrawerTitle>Notifications</DrawerTitle>\n          <DrawerDescription>Your recent activity.</DrawerDescription>\n        </DrawerHeader>\n        <div className=\"flex flex-col gap-3 px-4\">\n          {[\n            \"New comment on your post\",\n            \"Server deployment complete\",\n            \"Payment received — $249.00\",\n          ].map((msg) => (\n            <div\n              key={msg}\n              className=\"rounded-lg border border-border bg-card p-3 text-sm\"\n            >\n              {msg}\n            </div>\n          ))}\n        </div>\n        <DrawerFooter>\n          <DrawerClose asChild>\n            <Button variant=\"outline\">Close</Button>\n          </DrawerClose>\n        </DrawerFooter>\n      </DrawerContent>\n    </Drawer>"
        },
        {
          "name": "FromTop",
          "description": "Drawer sliding from the top with a grid of quick action buttons for contextual commands.",
          "code": "<Drawer direction=\"top\">\n      <DrawerTrigger asChild>\n        <Button variant=\"outline\">Open Top</Button>\n      </DrawerTrigger>\n      <DrawerContent>\n        <DrawerHeader>\n          <DrawerTitle>Quick Actions</DrawerTitle>\n          <DrawerDescription>Select an action to perform.</DrawerDescription>\n        </DrawerHeader>\n        <div className=\"grid grid-cols-3 gap-3 px-4\">\n          {[\"New File\", \"Upload\", \"Share\"].map((action) => (\n            <Button key={action} variant=\"outline\">\n              {action}\n            </Button>\n          ))}\n        </div>\n        <DrawerFooter>\n          <DrawerClose asChild>\n            <Button variant=\"ghost\" className=\"w-full\">\n              Dismiss\n            </Button>\n          </DrawerClose>\n        </DrawerFooter>\n      </DrawerContent>\n    </Drawer>"
        },
        {
          "name": "Controlled",
          "description": "Drawer open state managed externally via buttons with visual open/close indicators, no DrawerTrigger needed."
        }
      ]
    },
    {
      "name": "dropdown-menu",
      "title": "Dropdown Menu",
      "description": "A popover style menu listing choices or operations that is triggered by a button control.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/dropdown-menu",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/dropdown-menu.tsx"
      ],
      "storyTitle": "Shadcn UI/DropdownMenu",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Dropdown menu with account-related actions (profile, billing, settings, logout), icons, and keyboard shortcuts.",
          "code": "<DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">Open Menu</Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"w-56\">\n        <DropdownMenuLabel>My Account</DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            <User className=\"mr-2 size-4\" />\n            <span>Profile</span>\n            <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <CreditCard className=\"mr-2 size-4\" />\n            <span>Billing</span>\n            <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <Settings className=\"mr-2 size-4\" />\n            <span>Settings</span>\n            <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <LogOut className=\"mr-2 size-4\" />\n          <span>Log out</span>\n          <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>"
        },
        {
          "name": "WithSubmenus",
          "description": "Dropdown menu with a nested submenu for invite methods (email or message) via DropdownMenuSub.",
          "code": "<DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">Open with Submenu</Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"w-56\">\n        <DropdownMenuLabel>Actions</DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem>\n          <Plus className=\"mr-2 size-4\" />\n          <span>New Team</span>\n          <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>\n        </DropdownMenuItem>\n        <DropdownMenuSub>\n          <DropdownMenuSubTrigger>\n            <UserPlus className=\"mr-2 size-4\" />\n            <span>Invite Users</span>\n          </DropdownMenuSubTrigger>\n          <DropdownMenuPortal>\n            <DropdownMenuSubContent>\n              <DropdownMenuItem>\n                <Mail className=\"mr-2 size-4\" />\n                <span>Email</span>\n              </DropdownMenuItem>\n              <DropdownMenuItem>\n                <MessageSquare className=\"mr-2 size-4\" />\n                <span>Message</span>\n              </DropdownMenuItem>\n            </DropdownMenuSubContent>\n          </DropdownMenuPortal>\n        </DropdownMenuSub>\n      </DropdownMenuContent>\n    </DropdownMenu>"
        }
      ]
    },
    {
      "name": "ds-about-manifesto-hero",
      "title": "About Manifesto Hero",
      "description": "Hero imersivo de manifesto institucional combinando declaração tipográfica, métricas e CTAs.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/about-manifesto-hero",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ds-manifesto-statement"
      ],
      "files": [
        "components/ds/about-manifesto-hero.tsx"
      ],
      "props": [
        {
          "name": "statement",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "eyebrow",
          "required": false,
          "type": "string"
        },
        {
          "name": "author",
          "required": false,
          "type": "string"
        },
        {
          "name": "stats",
          "required": false,
          "type": "AboutManifestoHeroStat[]"
        },
        {
          "name": "primaryAction",
          "required": false,
          "type": "AboutManifestoHeroAction"
        },
        {
          "name": "secondaryAction",
          "required": false,
          "type": "AboutManifestoHeroAction"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"subtle\"",
          "options": [
            "default",
            "subtle"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "WithoutStats",
          "description": "",
          "args": "{\n    stats: [],\n  },"
        },
        {
          "name": "SubtleSurface",
          "description": "",
          "args": "{\n    variant: \"subtle\",\n  },"
        }
      ]
    },
    {
      "name": "ds-about-milestones",
      "title": "About Milestones",
      "description": "Bloco turnkey da trajetória histórica com cabeçalho de seção e MilestoneStepper.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/about-milestones",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "badge",
        "ds-milestone-stepper"
      ],
      "files": [
        "components/ds/about-milestones.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "milestones",
          "required": true,
          "type": "MilestoneItem[]"
        },
        {
          "name": "orientation",
          "required": false,
          "type": "\"vertical\" | \"horizontal\""
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\"",
          "options": [
            "default",
            "muted"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Horizontal",
          "description": "",
          "args": "{\n    orientation: \"horizontal\",\n  },"
        },
        {
          "name": "MutedSurface",
          "description": "",
          "args": "{\n    variant: \"muted\",\n  },"
        }
      ]
    },
    {
      "name": "ds-about-section",
      "title": "AboutSection",
      "description": "Bloco composto de página 'Sobre' — história + citação do fundador + tira de estatísticas + grid de equipe — construído a partir dos átomos ds-hero-section, ds-pull-quote, ds-card-stat e ds-team-roster.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/about-section",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "ds-hero-section",
        "ds-pull-quote",
        "ds-card-stat",
        "ds-team-roster"
      ],
      "files": [
        "components/ds/about-section.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "quote",
          "required": false,
          "type": "string"
        },
        {
          "name": "quoteName",
          "required": false,
          "type": "string"
        },
        {
          "name": "quoteRole",
          "required": false,
          "type": "string"
        },
        {
          "name": "quoteAvatarSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "quoteAvatarFallback",
          "required": false,
          "type": "string"
        },
        {
          "name": "stats",
          "required": false,
          "type": "AboutSectionStat[]"
        },
        {
          "name": "team",
          "required": false,
          "type": "AboutSectionTeamMember[]"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "About/AboutSection",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "WithoutQuote",
          "description": "",
          "args": "{\n    quote: undefined,\n  },"
        },
        {
          "name": "WithoutTeam",
          "description": "",
          "args": "{\n    team: [],\n  },"
        },
        {
          "name": "StoryOnly",
          "description": "",
          "args": "{\n    quote: undefined,\n    stats: [],\n    team: [],\n  },"
        }
      ]
    },
    {
      "name": "ds-about-split-story",
      "title": "About Split Story",
      "description": "Seção turnkey de história institucional em 2 colunas com badge, fotografia e métrica flutuante.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/about-split-story",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "button"
      ],
      "files": [
        "components/ds/about-split-story.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": true,
          "type": "string"
        },
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "imageSrc",
          "required": true,
          "type": "string"
        },
        {
          "name": "imageAlt",
          "required": true,
          "type": "string"
        },
        {
          "name": "floatingBadgeText",
          "required": false,
          "type": "string"
        },
        {
          "name": "primaryAction",
          "required": false,
          "type": "AboutSplitStoryAction"
        },
        {
          "name": "secondaryAction",
          "required": false,
          "type": "AboutSplitStoryAction"
        },
        {
          "name": "reverse",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\"",
          "options": [
            "default",
            "muted"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Reversed",
          "description": "",
          "args": "{\n    reverse: true,\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{\n    locale: \"en-US\",\n    badge: \"Our Story\",\n    title: \"Applied research, statistical rigor and impactful design\",\n    description:\n      \"Born at the Federal University of Paraíba, LEMA combines advanced statistics with software engineering to deliver open, reliable digital experiences.\",\n    primaryAction: {\n      label: \"Explore projects\",\n      href: \"#\",\n    },\n    secondaryAction: {\n      label: \"Read publications\",\n      href: \"#\",\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-about-values-grid",
      "title": "About Values Grid",
      "description": "Bloco turnkey completo de apresentação de valores e pilares com grid responsivo de ValuesCard.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/about-values-grid",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "ds-values-card"
      ],
      "files": [
        "components/ds/about-values-grid.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "values",
          "required": true,
          "type": "ValuesCardProps[]"
        },
        {
          "name": "columns",
          "required": false,
          "type": "2 | 3 | 4"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\"",
          "options": [
            "default",
            "muted"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "TwoColumns",
          "description": "",
          "args": "{\n    columns: 2,\n    values: sampleValues.slice(0, 4),\n  },"
        },
        {
          "name": "FourColumns",
          "description": "",
          "args": "{\n    columns: 4,\n    values: sampleValues.slice(0, 4),\n  },"
        }
      ]
    },
    {
      "name": "ds-accordion",
      "title": "Accordion UI",
      "description": "Extended accordion with icon style variants (chevron/plus/arrow/sign), size variants, rounded/bordered CVA, discriminated single/multiple types with collapsible control, i18n aria-labels, skeleton loading, and nested accordion support.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/accordion",
      "dependencies": [
        "radix-ui",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "accordion",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/accordion.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "rounded",
          "required": false,
          "type": "\"default\" | \"none\"",
          "options": [
            "default",
            "none"
          ],
          "default": "default"
        },
        {
          "name": "bordered",
          "required": false,
          "type": "\"default\" | \"none\"",
          "options": [
            "default",
            "none"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Navigation/Accordion",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    items: SAMPLE_ITEMS,\n    type: \"single\",\n    collapsible: true,\n    iconVariant: \"chevron\",\n    size: \"md\",\n    rounded: \"default\",\n    bordered: \"default\",\n    loading: false,\n    loadingCount: 3,\n  },"
        },
        {
          "name": "Multiple",
          "description": "",
          "args": "{\n    type: \"multiple\",\n    items: SAMPLE_ITEMS,\n  },"
        },
        {
          "name": "IconVariants",
          "description": "",
          "args": "{ items: [] },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      <div>\n        <p className=\"mb-2 text-sm font-medium text-muted-foreground\">\n          Chevron\n        </p>\n        <Accordion iconVariant=\"chevron\" items={SAMPLE_ITEMS} />\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm font-medium text-muted-foreground\">Plus</p>\n        <Accordion iconVariant=\"plus\" items={SAMPLE_ITEMS} />\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm font-medium text-muted-foreground\">Sign</p>\n        <Accordion iconVariant=\"sign\" items={SAMPLE_ITEMS} />\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm font-medium text-muted-foreground\">Arrow</p>\n        <Accordion iconVariant=\"arrow\" items={SAMPLE_ITEMS} />\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      <div>\n        <p className=\"mb-2 text-sm font-medium text-muted-foreground\">\n          Chevron\n        </p>\n        <Accordion iconVariant=\"chevron\" items={SAMPLE_ITEMS} />\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm font-medium text-muted-foreground\">Plus</p>\n        <Accordion iconVariant=\"plus\" items={SAMPLE_ITEMS} />\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm font-medium text-muted-foreground\">Sign</p>\n        <Accordion iconVariant=\"sign\" items={SAMPLE_ITEMS} />\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm font-medium text-muted-foreground\">Arrow</p>\n        <Accordion iconVariant=\"arrow\" items={SAMPLE_ITEMS} />\n      </div>\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ items: [] },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      <Accordion size=\"sm\" items={SAMPLE_ITEMS} />\n      <Accordion size=\"md\" items={SAMPLE_ITEMS} />\n      <Accordion size=\"lg\" items={SAMPLE_ITEMS} />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      <Accordion size=\"sm\" items={SAMPLE_ITEMS} />\n      <Accordion size=\"md\" items={SAMPLE_ITEMS} />\n      <Accordion size=\"lg\" items={SAMPLE_ITEMS} />\n    </div>"
        },
        {
          "name": "RoundedNone",
          "description": "",
          "args": "{\n    items: SAMPLE_ITEMS,\n    rounded: \"none\",\n  },"
        },
        {
          "name": "BorderNone",
          "description": "",
          "args": "{\n    items: SAMPLE_ITEMS,\n    bordered: \"none\",\n  },"
        },
        {
          "name": "RoundedNoneBorderNone",
          "description": "",
          "args": "{\n    items: SAMPLE_ITEMS,\n    rounded: \"none\",\n    bordered: \"none\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n    items: SAMPLE_ITEMS,\n  },"
        },
        {
          "name": "Nested",
          "description": "",
          "args": "{ items: [] },\n  render: () => (\n    <Accordion\n      type=\"multiple\"\n      items={[\n        {\n          value: \"outer-1\",\n          trigger: \"Design System\",\n          children: (\n            <Accordion\n              size=\"sm\"\n              type=\"multiple\"\n              items={[\n                {\n                  value: \"inner-1\",\n                  trigger: \"Components\",\n                  children: \"Buttons, cards, tables, and more.\",\n                },\n                {\n                  value: \"inner-2\",\n                  trigger: \"Tokens\",\n                  children: \"Color, typography, and spacing tokens.\",\n                },\n              ]}\n            />\n          ),\n        },\n        {\n          value: \"outer-2\",\n          trigger: \"Getting Started\",\n          children: \"Install the CLI and start using components.\",\n        },\n      ]}\n    />\n  ),",
          "code": "<Accordion\n      type=\"multiple\"\n      items={[\n        {\n          value: \"outer-1\",\n          trigger: \"Design System\",\n          children: (\n            <Accordion\n              size=\"sm\"\n              type=\"multiple\"\n              items={[\n                {\n                  value: \"inner-1\",\n                  trigger: \"Components\",\n                  children: \"Buttons, cards, tables, and more.\",\n                },\n                {\n                  value: \"inner-2\",\n                  trigger: \"Tokens\",\n                  children: \"Color, typography, and spacing tokens.\",\n                },\n              ]}\n            />\n          ),\n        },\n        {\n          value: \"outer-2\",\n          trigger: \"Getting Started\",\n          children: \"Install the CLI and start using components.\",\n        },\n      ]}\n    />"
        },
        {
          "name": "Controlled",
          "description": "",
          "args": "{ items: [] },\n  render: () => {\n    const [value, setValue] = React.useState(\"item-1\")\n    return (\n      <div className=\"flex flex-col gap-4\">\n        <p className=\"text-sm text-muted-foreground\">\n          Current:{\" \"}\n          <code className=\"rounded bg-muted px-1.5 py-0.5\">{value}</code>\n        </p>\n        <Accordion\n          value={value}\n          onValueChange={(v) => setValue(v as string)}\n          items={SAMPLE_ITEMS}\n        />\n      </div>\n    )\n  },",
          "code": "<div className=\"flex flex-col gap-4\">\n        <p className=\"text-sm text-muted-foreground\">\n          Current:{\" \"}\n          <code className=\"rounded bg-muted px-1.5 py-0.5\">{value}</code>\n        </p>\n        <Accordion\n          value={value}\n          onValueChange={(v) => setValue(v as string)}\n          items={SAMPLE_ITEMS}\n        />\n      </div>"
        }
      ]
    },
    {
      "name": "ds-activity-feed",
      "title": "Activity Feed",
      "description": "Feed cronológico de eventos e trilha de auditoria com avatar, badge de status e timestamp relativo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/activity-feed",
      "dependencies": [
        "date-fns"
      ],
      "registryDependencies": [
        "avatar",
        "badge",
        "button",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/activity-feed.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "ActivityFeedItem[]",
          "description": "Chronological list of events."
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Loading state."
        },
        {
          "name": "emptyMessage",
          "required": false,
          "type": "string",
          "description": "Message shown when items list is empty."
        },
        {
          "name": "onViewMore",
          "required": false,
          "type": "() => void",
          "description": "Callback fired when clicking the view more button."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for date formatting and labels."
        }
      ],
      "storyTitle": "Data Display/ActivityFeed",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    items: sampleItems,\n    locale: \"pt-BR\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByText(\"Mariana Souza\")).toBeInTheDocument()\n    await expect(canvas.getByText(\"Carlos Eduardo\")).toBeInTheDocument()\n  },"
        },
        {
          "name": "WithDescriptionsAndDiffs",
          "description": "",
          "args": "{\n    items: [\n      {\n        id: \"d1\",\n        actor: { name: \"Mariana Souza\", initials: \"MS\" },\n        action: \"alterou o parâmetro beta em\",\n        target: \"Função de Utilidade CES\",\n        timestamp: subMinutes(new Date(), 42),\n        status: \"warning\",\n        statusLabel: \"Pendente de revisão\",\n        description: (\n          <div className=\"flex flex-col gap-1 font-mono text-xs\">\n            <span className=\"text-destructive\">- beta = 0.985</span>\n            <span className=\"text-success\">+ beta = 0.992</span>\n          </div>\n        ),\n      },\n    ],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    items: [],\n    loading: true,\n  },"
        },
        {
          "name": "Empty",
          "description": "",
          "args": "{\n    items: [],\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-8 md:grid-cols-2\">\n      <div>\n        <span className=\"block pb-2 text-xs font-semibold text-muted-foreground\">\n          pt-BR:\n        </span>\n        <ActivityFeed locale=\"pt-BR\" items={sampleItems.slice(0, 2)} />\n      </div>\n      <div>\n        <span className=\"block pb-2 text-xs font-semibold text-muted-foreground\">\n          en-US:\n        </span>\n        <ActivityFeed locale=\"en-US\" items={sampleItems.slice(0, 2)} />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-ai-chat",
      "title": "AI Chat",
      "description": "Chat assistente — ReUI AI Chat 12.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/ai-chat",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "card",
        "button",
        "input",
        "skeleton",
        "empty",
        "message",
        "message-scroller",
        "bubble"
      ],
      "files": [
        "components/ds/ai-chat.tsx"
      ],
      "props": [
        {
          "name": "messages",
          "required": false,
          "type": "ChatMessage[]"
        },
        {
          "name": "onSend",
          "required": false,
          "type": "(message: string) => void"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Chat/AiChat",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    messages: [\n      { id: \"1\", role: \"assistant\", content: \"Hi! How can I help you today?\" },\n      { id: \"2\", role: \"user\", content: \"Can you summarize this PR?\" },\n      {\n        id: \"3\",\n        role: \"assistant\",\n        content: \"Sure — give me a moment to look at the diff.\",\n      },\n    ],\n  },"
        },
        {
          "name": "Empty",
          "description": "",
          "args": "{ messages: [] }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true }"
        }
      ]
    },
    {
      "name": "ds-animated-number",
      "title": "AnimatedNumber",
      "description": "Contador numérico animado com formatação por locale e fallback sr-only para leitores de tela.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/animated-number",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/animated-number.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "number"
        },
        {
          "name": "duration",
          "required": false,
          "type": "number",
          "description": "Animation duration in ms."
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "prefix",
          "required": false,
          "type": "string"
        },
        {
          "name": "suffix",
          "required": false,
          "type": "string"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/AnimatedNumber",
      "stories": [
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex items-center gap-6\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <AnimatedNumber key={size} value={1024} size={size} />\n      ))}\n    </div>"
        },
        {
          "name": "WithPrefixSuffix",
          "description": "",
          "args": "{ value: 42.5, prefix: \"$\", suffix: \"K\", decimals: 1 },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-2\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <AnimatedNumber\n          key={locale}\n          value={128400.5}\n          decimals={1}\n          locale={locale}\n        />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-announcement-badge",
      "title": "AnnouncementBadge",
      "description": "Badge ou pill de anúncio para o topo de seções hero com micro-animação e suporte a ping.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/announcement-badge",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/announcement-badge.tsx"
      ],
      "props": [
        {
          "name": "ping",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showArrow",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "tag",
          "required": false,
          "type": "string"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"outline\" | \"glow\" | \"gradient\"",
          "options": [
            "default",
            "outline",
            "glow",
            "gradient"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Actions/AnnouncementBadge",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    children: \"Apresentando LEMA-DS v2.0\",\n    tag: \"Novo\",\n    ping: true,\n  },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-col items-center gap-4\">\n      <AnnouncementBadge variant=\"default\" tag=\"Novo\" ping>\n        Default: Atualizações do sistema liberadas\n      </AnnouncementBadge>\n      <AnnouncementBadge variant=\"outline\" tag=\"Changelog\">\n        Outline: Veja o que mudou na última versão\n      </AnnouncementBadge>\n      <AnnouncementBadge variant=\"glow\" tag=\"Destaque\" ping>\n        Glow: Inteligência Artificial integrada\n      </AnnouncementBadge>\n      <AnnouncementBadge variant=\"gradient\" tag=\"Beta\">\n        Gradient: Experimente a nova experiência\n      </AnnouncementBadge>\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col items-center gap-4\">\n      <AnnouncementBadge size=\"sm\" tag=\"v2.1\">\n        Tamanho Pequeno (sm)\n      </AnnouncementBadge>\n      <AnnouncementBadge size=\"md\" tag=\"v2.1\" ping>\n        Tamanho Padrão (md)\n      </AnnouncementBadge>\n      <AnnouncementBadge size=\"lg\" tag=\"v2.1\" ping>\n        Tamanho Grande (lg)\n      </AnnouncementBadge>\n    </div>"
        },
        {
          "name": "WithCustomIcon",
          "description": "",
          "args": "{\n    icon: <SparklesIcon className=\"size-3.5 text-primary\" />,\n    children: \"Turbine sua produtividade com automações\",\n    variant: \"glow\",\n  },"
        },
        {
          "name": "AsLink",
          "description": "",
          "args": "{\n    href: \"https://github.com/lema-ufpb/design-system\",\n    target: \"_blank\",\n    rel: \"noopener noreferrer\",\n    children: \"Confira o repositório oficial no GitHub\",\n    tag: \"Open Source\",\n  },"
        }
      ]
    },
    {
      "name": "ds-app-sidebar",
      "title": "App Sidebar",
      "description": "Sidebar completa com TeamSwitcher, Search, NavMain colapsável, Projects, NavUser e Rail — compõe sidebar shadcn 07 + 16.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/app-sidebar",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "sidebar",
        "collapsible",
        "dropdown-menu",
        "skeleton",
        "ds-team-switcher",
        "ds-sidebar-search",
        "ui-i18n"
      ],
      "files": [
        "components/ds/app-sidebar.tsx"
      ],
      "props": [
        {
          "name": "teams",
          "required": false,
          "type": "TeamSwitcherTeam[]"
        },
        {
          "name": "navMain",
          "required": false,
          "type": "AppSidebarNavItem[]"
        },
        {
          "name": "projects",
          "required": false,
          "type": "AppSidebarProject[]"
        },
        {
          "name": "user",
          "required": false,
          "type": "UserMenuData | null"
        },
        {
          "name": "showSearch",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "searchPlaceholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "collapsible",
          "required": false,
          "type": "\"offcanvas\" | \"icon\" | \"none\""
        },
        {
          "name": "sidebarVariant",
          "required": false,
          "type": "\"sidebar\" | \"floating\" | \"inset\""
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onNavItemClick",
          "required": false,
          "type": "(item: AppSidebarNavItem) => void"
        },
        {
          "name": "onProjectClick",
          "required": false,
          "type": "(project: AppSidebarProject) => void"
        },
        {
          "name": "onTeamChange",
          "required": false,
          "type": "(team: TeamSwitcherTeam) => void"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ teams, navMain, projects, user },"
        },
        {
          "name": "CollapsibleIcon",
          "description": "",
          "args": "{ teams, navMain, projects, user, collapsible: \"icon\" },"
        },
        {
          "name": "Floating",
          "description": "",
          "args": "{ teams, navMain, projects, user, sidebarVariant: \"floating\" },"
        },
        {
          "name": "Inset",
          "description": "",
          "args": "{ teams, navMain, projects, user, sidebarVariant: \"inset\" },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6 p-4\">\n      {([\"sidebar\", \"floating\", \"inset\"] as const).map((sidebarVariant) => (\n        <div key={sidebarVariant} className=\"rounded-xl border\">\n          <p className=\"p-2 text-xs font-medium\">{sidebarVariant}</p>\n          <TooltipProvider>\n            <SidebarProvider>\n              <div className=\"flex h-64\">\n                <AppSidebar\n                  teams={teams}\n                  navMain={navMain}\n                  projects={projects}\n                  user={user}\n                  sidebarVariant={sidebarVariant}\n                />\n                <div className=\"flex flex-1 items-center justify-center bg-muted/20 text-xs text-muted-foreground\">\n                  content\n                </div>\n              </div>\n            </SidebarProvider>\n          </TooltipProvider>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "A11y",
          "description": "",
          "args": "{ teams, navMain, projects, user },\n  parameters: { a11y: { disable: true } },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByRole(\"button\")).toBeInTheDocument()\n  },"
        }
      ]
    },
    {
      "name": "ds-app-store-badges",
      "title": "AppStoreBadges",
      "description": "Botões de download para App Store e Google Play, com ícone e texto sobrescrevíveis.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/app-store-badges",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/app-store-badges.tsx"
      ],
      "props": [
        {
          "name": "links",
          "required": true,
          "type": "AppStoreBadgeLink[]"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Actions/AppStoreBadges",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "AppleOnly",
          "description": "",
          "args": "{\n    links: [{ href: \"#\", store: \"apple\" }],\n  },"
        }
      ]
    },
    {
      "name": "ds-audio-player",
      "description": "Full-featured audio player using native HTML5 Audio API.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/audio-player",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "button",
        "slider",
        "avatar",
        "card"
      ],
      "files": [
        "components/ds/audio-player.tsx"
      ],
      "props": [
        {
          "name": "src",
          "required": true,
          "type": "string"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "artist",
          "required": false,
          "type": "string"
        },
        {
          "name": "coverUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "autoPlay",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Media/AudioPlayer",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    src: SAMPLE_AUDIO,\n    title: \"SoundHelix Song 1\",\n    artist: \"SoundHelix\",\n    coverUrl: \"https://picsum.photos/seed/music/200/200\",\n  },"
        },
        {
          "name": "NoArtist",
          "description": "",
          "args": "{\n    src: SAMPLE_AUDIO,\n    title: \"Unknown Track\",\n  },"
        },
        {
          "name": "NoCover",
          "description": "",
          "args": "{\n    src: SAMPLE_AUDIO,\n    title: \"Track Without Cover\",\n    artist: \"Various Artists\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    src: \"\",\n    title: \"Loading…\",\n    loading: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-aurora-background",
      "title": "Aurora Background",
      "description": "Fundo aurora com gradientes animados, grid sutil e máscara radial — inspirado em Aceternity Aurora + Sparkles + Wavy.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/aurora-background",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/aurora-background.tsx"
      ],
      "props": [
        {
          "name": "showRadial",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\" | \"dark\"",
          "options": [
            "default",
            "muted",
            "dark"
          ],
          "default": "default"
        },
        {
          "name": "intensity",
          "required": false,
          "type": "\"subtle\" | \"medium\" | \"strong\"",
          "options": [
            "subtle",
            "medium",
            "strong"
          ],
          "default": "medium"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ variant: \"default\", intensity: \"medium\" },"
        },
        {
          "name": "Dark",
          "description": "",
          "code": "<AuroraBackground\n      variant=\"dark\"\n      intensity=\"strong\"\n      className=\"h-[420px] items-center justify-center p-8 text-center\"\n    >\n      <h2 className=\"text-3xl font-bold\">Dark aurora</h2>\n      <p className=\"mt-2 text-sm text-white/70\">\n        Para heroes escuros com contraste alto\n      </p>\n    </AuroraBackground>"
        },
        {
          "name": "Subtle",
          "description": "",
          "args": "{ intensity: \"subtle\" },\n  render: (args) => (\n    <AuroraBackground\n      {...args}\n      className=\"h-[320px] items-center justify-center\"\n    >\n      <p className=\"text-sm text-muted-foreground\">\n        Intensidade sutil para fundos de seção\n      </p>\n    </AuroraBackground>\n  ),"
        }
      ]
    },
    {
      "name": "ds-auth-card",
      "title": "Auth Card",
      "description": "Shell de autenticação unificado com variantes centered/muted/split/cover — consolida shadcn login-01..05 e signup-01..05.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/auth-card",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/auth-card.tsx"
      ],
      "props": [
        {
          "name": "mode",
          "required": false,
          "type": "\"login\" | \"signup\""
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "imageSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "imageAlt",
          "required": false,
          "type": "string"
        },
        {
          "name": "logo",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "appName",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\" | \"centered\"",
          "options": [
            "default",
            "muted",
            "centered"
          ],
          "default": "default"
        },
        {
          "name": "layout",
          "required": false,
          "type": "\"default\" | \"split\" | \"cover\"",
          "options": [
            "default",
            "split",
            "cover"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<AuthCard>\n      <DemoForm />\n    </AuthCard>"
        },
        {
          "name": "Muted",
          "description": "",
          "code": "<AuthCard variant=\"muted\">\n      <DemoForm />\n    </AuthCard>"
        },
        {
          "name": "Split",
          "description": "",
          "code": "<AuthCard layout=\"split\" imageSrc=\"https://picsum.photos/seed/acme/800/900\">\n      <DemoForm />\n    </AuthCard>"
        },
        {
          "name": "Cover",
          "description": "",
          "code": "<AuthCard\n      layout=\"cover\"\n      imageSrc=\"https://picsum.photos/seed/acme-cover/600/600\"\n    >\n      <DemoForm />\n    </AuthCard>"
        },
        {
          "name": "Signup",
          "description": "",
          "code": "<AuthCard mode=\"signup\">\n      <DemoForm />\n    </AuthCard>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"pt-BR\", \"en-US\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <div key={locale} className=\"border\">\n          <AuthCard locale={locale}>\n            <DemoForm />\n          </AuthCard>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "A11y",
          "description": "",
          "code": "<AuthCard>\n      <DemoForm />\n    </AuthCard>"
        }
      ]
    },
    {
      "name": "ds-auth-separator",
      "title": "AuthSeparator",
      "description": "Divisor estilizado com rótulo centralizado para transição entre autenticação social e credenciais tradicionais.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/auth-separator",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/auth-separator.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"badge\" | \"gradient\"",
          "options": [
            "default",
            "badge",
            "gradient"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Data Display/AuthSeparator",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    children: \"ou continue com e-mail\",\n    variant: \"default\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <AuthSeparator {...args} />\n    </div>\n  ),"
        },
        {
          "name": "BadgeVariant",
          "description": "",
          "args": "{\n    children: \"ou entre com SSO\",\n    variant: \"badge\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <AuthSeparator {...args} />\n    </div>\n  ),"
        },
        {
          "name": "GradientVariant",
          "description": "",
          "args": "{\n    children: \"ou\",\n    variant: \"gradient\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <AuthSeparator {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-auth-split-screen",
      "title": "AuthSplitScreen",
      "description": "Shell de layout de tela dividida (split-screen) completo com vitrine da marca, depoimento e estatísticas.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/auth-split-screen",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-background-glow",
        "avatar",
        "ui-i18n"
      ],
      "files": [
        "components/ds/auth-split-screen.tsx"
      ],
      "props": [
        {
          "name": "logo",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "appName",
          "required": false,
          "type": "string"
        },
        {
          "name": "testimonial",
          "required": false,
          "type": "AuthTestimonial"
        },
        {
          "name": "stats",
          "required": false,
          "type": "AuthStat[]"
        },
        {
          "name": "brandHeadline",
          "required": false,
          "type": "string"
        },
        {
          "name": "brandDescription",
          "required": false,
          "type": "string"
        },
        {
          "name": "reverse",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "storyTitle": "Auth/AuthSplitScreen",
      "stories": [
        {
          "name": "LoginSplitScreen",
          "description": "",
          "code": "<AuthSplitScreen\n      appName=\"LEMA ID\"\n      testimonial={{\n        quote:\n          \"O ecossistema unificado da UFPB reduziu a complexidade de acesso a laboratórios e pesquisas acadêmicas.\",\n        author: \"Dra. Beatriz Fernandes\",\n        role: \"Pesquisadora Principal · CCEN UFPB\",\n      }}\n      stats={[\n        { label: \"Usuários Ativos\", value: \"32.000+\" },\n        { label: \"Sistemas Integrados\", value: \"48\" },\n      ]}\n    >\n      <LoginForm\n        variant=\"flat\"\n        socialProviders={[\"google\", \"govbr\", \"cafe\"]}\n        showPasskey\n      />\n    </AuthSplitScreen>"
        },
        {
          "name": "SignUpSplitScreen",
          "description": "",
          "code": "<AuthSplitScreen\n      appName=\"LEMA ID\"\n      brandHeadline=\"Junte-se à maior comunidade de inovação acadêmica da Paraíba\"\n      brandDescription=\"Acesso centralizado a laboratórios, bolsas de pesquisa, editais e ferramentas institucionais de alta produtividade.\"\n      stats={[\n        { label: \"Laboratórios Conectados\", value: \"24\" },\n        { label: \"Artigos e Patentes\", value: \"1.200+\" },\n      ]}\n    >\n      <SignUpForm variant=\"flat\" socialProviders={[\"google\", \"govbr\"]} />\n    </AuthSplitScreen>"
        },
        {
          "name": "ReversedTestimonialLeft",
          "description": "",
          "code": "<AuthSplitScreen\n      reverse\n      appName=\"LEMA Cloud\"\n      testimonial={{\n        quote:\n          \"A facilidade do login unificado acelerou em dias a integração dos novos bolsistas de iniciação científica.\",\n        author: \"Prof. Marcos Andrade\",\n        role: \"Coordenador de TI · CI UFPB\",\n      }}\n    >\n      <LoginForm variant=\"flat\" socialProviders={[\"govbr\", \"google\"]} />\n    </AuthSplitScreen>"
        }
      ]
    },
    {
      "name": "ds-autocomplete",
      "title": "Autocomplete",
      "description": "Busca autocomplete async — ReUI Autocomplete.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/autocomplete",
      "dependencies": [],
      "registryDependencies": [
        "popover",
        "input",
        "skeleton"
      ],
      "files": [
        "components/ds/autocomplete.tsx"
      ],
      "props": [
        {
          "name": "options",
          "required": true,
          "type": "AutocompleteOption[]"
        },
        {
          "name": "value",
          "required": false,
          "type": "string"
        },
        {
          "name": "onValueChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Form/Autocomplete",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    options: [\n      { label: \"Apple\", value: \"apple\" },\n      { label: \"Banana\", value: \"banana\" },\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-avatar",
      "title": "Avatar UI",
      "description": "Extended avatar with size scale (sm through 2xl), status indicator dots, initials color generator, image loading status callback, delay fallback, avatar group with overflow count, tooltip, and skeleton loading.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/avatar",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "avatar",
        "skeleton",
        "tooltip",
        "ui-i18n"
      ],
      "files": [
        "components/ds/avatar.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\"",
          "options": [
            "sm",
            "md",
            "lg",
            "xl",
            "2xl"
          ],
          "default": "md"
        },
        {
          "name": "status",
          "required": false,
          "type": "\"online\" | \"busy\" | \"away\" | \"offline\"",
          "options": [
            "online",
            "busy",
            "away",
            "offline"
          ],
          "default": "online"
        }
      ],
      "storyTitle": "Data Display/Avatar",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    src: \"https://i.pravatar.cc/150?u=default\",\n    alt: \"John Doe\",\n    size: \"md\",\n    loading: false,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "WithInitials",
          "description": "",
          "args": "{\n    alt: \"Maria Silva\",\n    fallback: \"MS\",\n  },"
        },
        {
          "name": "WithSingleInitial",
          "description": "",
          "args": "{\n    alt: \"Ana\",\n    fallback: \"AN\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ alt: \"\" },\n  render: () => (\n    <div className=\"flex items-end gap-4\">\n      <Avatar size=\"sm\" alt=\"Small\" fallback=\"SM\" />\n      <Avatar size=\"md\" alt=\"Medium\" fallback=\"MD\" />\n      <Avatar size=\"lg\" alt=\"Large\" fallback=\"LG\" />\n      <Avatar size=\"xl\" alt=\"X Large\" fallback=\"XL\" />\n      <Avatar size=\"2xl\" alt=\"2X Large\" fallback=\"2X\" />\n    </div>\n  ),",
          "code": "<div className=\"flex items-end gap-4\">\n      <Avatar size=\"sm\" alt=\"Small\" fallback=\"SM\" />\n      <Avatar size=\"md\" alt=\"Medium\" fallback=\"MD\" />\n      <Avatar size=\"lg\" alt=\"Large\" fallback=\"LG\" />\n      <Avatar size=\"xl\" alt=\"X Large\" fallback=\"XL\" />\n      <Avatar size=\"2xl\" alt=\"2X Large\" fallback=\"2X\" />\n    </div>"
        },
        {
          "name": "StatusIndicators",
          "description": "",
          "args": "{ alt: \"\" },\n  render: () => (\n    <div className=\"flex items-center gap-4\">\n      <Avatar size=\"lg\" alt=\"Alice\" status=\"online\" fallback=\"AL\" />\n      <Avatar size=\"lg\" alt=\"Bob\" status=\"busy\" fallback=\"BO\" />\n      <Avatar size=\"lg\" alt=\"Carol\" status=\"away\" fallback=\"CA\" />\n      <Avatar size=\"lg\" alt=\"Dave\" status=\"offline\" fallback=\"DA\" />\n    </div>\n  ),",
          "code": "<div className=\"flex items-center gap-4\">\n      <Avatar size=\"lg\" alt=\"Alice\" status=\"online\" fallback=\"AL\" />\n      <Avatar size=\"lg\" alt=\"Bob\" status=\"busy\" fallback=\"BO\" />\n      <Avatar size=\"lg\" alt=\"Carol\" status=\"away\" fallback=\"CA\" />\n      <Avatar size=\"lg\" alt=\"Dave\" status=\"offline\" fallback=\"DA\" />\n    </div>"
        },
        {
          "name": "AvatarGroupStory",
          "description": "",
          "args": "{ alt: \"\" },\n  render: () => (\n    <AvatarGroup>\n      <Avatar size=\"md\" alt=\"Alice\" src=\"https://i.pravatar.cc/150?u=alice\" />\n      <Avatar size=\"md\" alt=\"Bob\" src=\"https://i.pravatar.cc/150?u=bob\" />\n      <Avatar size=\"md\" alt=\"Carol\" src=\"https://i.pravatar.cc/150?u=carol\" />\n    </AvatarGroup>\n  ),",
          "code": "<AvatarGroup>\n      <Avatar size=\"md\" alt=\"Alice\" src=\"https://i.pravatar.cc/150?u=alice\" />\n      <Avatar size=\"md\" alt=\"Bob\" src=\"https://i.pravatar.cc/150?u=bob\" />\n      <Avatar size=\"md\" alt=\"Carol\" src=\"https://i.pravatar.cc/150?u=carol\" />\n    </AvatarGroup>"
        },
        {
          "name": "AvatarGroupMax",
          "description": "",
          "args": "{ alt: \"\" },\n  render: () => (\n    <AvatarGroup max={3}>\n      <Avatar size=\"md\" alt=\"Alice\" fallback=\"AL\" />\n      <Avatar size=\"md\" alt=\"Bob\" fallback=\"BO\" />\n      <Avatar size=\"md\" alt=\"Carol\" fallback=\"CA\" />\n      <Avatar size=\"md\" alt=\"Dave\" fallback=\"DA\" />\n      <Avatar size=\"md\" alt=\"Eve\" fallback=\"EV\" />\n    </AvatarGroup>\n  ),",
          "code": "<AvatarGroup max={3}>\n      <Avatar size=\"md\" alt=\"Alice\" fallback=\"AL\" />\n      <Avatar size=\"md\" alt=\"Bob\" fallback=\"BO\" />\n      <Avatar size=\"md\" alt=\"Carol\" fallback=\"CA\" />\n      <Avatar size=\"md\" alt=\"Dave\" fallback=\"DA\" />\n      <Avatar size=\"md\" alt=\"Eve\" fallback=\"EV\" />\n    </AvatarGroup>"
        },
        {
          "name": "WithTooltip",
          "description": "",
          "args": "{\n    alt: \"John Developer\",\n    fallback: \"JD\",\n    size: \"lg\",\n    tooltip: \"John Developer (john@example.com)\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ alt: \"\" },\n  render: () => (\n    <div className=\"flex items-end gap-4\">\n      <Avatar loading size=\"sm\" alt=\"Loading\" />\n      <Avatar loading size=\"md\" alt=\"Loading\" />\n      <Avatar loading size=\"lg\" alt=\"Loading\" />\n      <Avatar loading size=\"xl\" alt=\"Loading\" />\n      <Avatar loading size=\"2xl\" alt=\"Loading\" />\n    </div>\n  ),",
          "code": "<div className=\"flex items-end gap-4\">\n      <Avatar loading size=\"sm\" alt=\"Loading\" />\n      <Avatar loading size=\"md\" alt=\"Loading\" />\n      <Avatar loading size=\"lg\" alt=\"Loading\" />\n      <Avatar loading size=\"xl\" alt=\"Loading\" />\n      <Avatar loading size=\"2xl\" alt=\"Loading\" />\n    </div>"
        },
        {
          "name": "WithImageAndStatus",
          "description": "",
          "args": "{\n    src: \"https://i.pravatar.cc/150?u=admin\",\n    alt: \"Admin User\",\n    size: \"xl\",\n    status: \"online\",\n    tooltip: \"Admin User (Online)\",\n  },"
        }
      ]
    },
    {
      "name": "ds-avatar-presence",
      "title": "Avatar Presence",
      "description": "Indicador de presença em tempo real para avatar com anel de isolamento temático e animação de pulso.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/avatar-presence",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "avatar",
        "ui-i18n"
      ],
      "files": [
        "components/ds/avatar-presence.tsx"
      ],
      "props": [
        {
          "name": "src",
          "required": false,
          "type": "string",
          "description": "Avatar image source URL."
        },
        {
          "name": "alt",
          "required": false,
          "type": "string",
          "description": "Accessible alt description."
        },
        {
          "name": "fallback",
          "required": false,
          "type": "string",
          "description": "Fallback text/initials if image fails or is omitted."
        },
        {
          "name": "status",
          "required": false,
          "type": "\"online\" | \"offline\" | \"busy\" | \"away\"",
          "description": "User presence state."
        },
        {
          "name": "pulse",
          "required": false,
          "type": "boolean",
          "description": "Subtle live pulse animation for online status."
        },
        {
          "name": "position",
          "required": false,
          "type": "\"bottom-right\" | \"top-right\"",
          "description": "Placement corner of indicator dot."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for accessible tooltip/title."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\" | \"xl\"",
          "options": [
            "sm",
            "md",
            "lg",
            "xl"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/AvatarPresence",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    src: \"https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150&auto=format&fit=crop&q=80\",\n    fallback: \"MS\",\n    alt: \"Mariana Souza\",\n    status: \"online\",\n    pulse: true,\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByText(\"MS\")).toBeInTheDocument()\n  },"
        },
        {
          "name": "AllStatuses",
          "description": "",
          "code": "<div className=\"flex items-center gap-6\">\n      <div className=\"flex flex-col items-center gap-2\">\n        <AvatarPresence status=\"online\" pulse fallback=\"ON\" />\n        <span className=\"text-xs text-muted-foreground\">Online</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <AvatarPresence status=\"away\" fallback=\"AW\" />\n        <span className=\"text-xs text-muted-foreground\">Away</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <AvatarPresence status=\"busy\" fallback=\"BU\" />\n        <span className=\"text-xs text-muted-foreground\">Busy</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <AvatarPresence status=\"offline\" fallback=\"OF\" />\n        <span className=\"text-xs text-muted-foreground\">Offline</span>\n      </div>\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex items-end gap-6\">\n      <AvatarPresence size=\"sm\" fallback=\"SM\" status=\"online\" />\n      <AvatarPresence size=\"md\" fallback=\"MD\" status=\"online\" />\n      <AvatarPresence size=\"lg\" fallback=\"LG\" status=\"online\" />\n      <AvatarPresence size=\"xl\" fallback=\"XL\" status=\"online\" />\n    </div>"
        },
        {
          "name": "TopRightPosition",
          "description": "",
          "args": "{\n    position: \"top-right\",\n    status: \"busy\",\n    fallback: \"TR\",\n  },"
        }
      ]
    },
    {
      "name": "ds-background-glow",
      "title": "BackgroundGlow",
      "description": "Ambientação luminosa e texturas de fundo em CSS puro (Aurora, Spotlight, Beam e Grid-dots) para seções Hero.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/background-glow",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/background-glow.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"aurora\" | \"spotlight\" | \"beam\" | \"grid-dots\"",
          "options": [
            "aurora",
            "spotlight",
            "beam",
            "grid-dots"
          ],
          "default": "aurora"
        },
        {
          "name": "tone",
          "required": false,
          "type": "\"primary\" | \"violet\" | \"sky\" | \"neutral\"",
          "options": [
            "primary",
            "violet",
            "sky",
            "neutral"
          ],
          "default": "primary"
        }
      ],
      "storyTitle": "Data Display/BackgroundGlow",
      "stories": [
        {
          "name": "Spotlight",
          "description": "",
          "code": "<div className=\"relative flex min-h-[400px] w-full flex-col items-center justify-center overflow-hidden bg-background p-8\">\n      <BackgroundGlow variant=\"spotlight\" tone=\"violet\" />\n      <div className=\"relative z-10 max-w-xl text-center\">\n        <h2 className=\"text-3xl font-bold tracking-tight\">\n          Feixe de Spotlight\n        </h2>\n        <p className=\"mt-3 text-sm text-muted-foreground\">\n          Foco direcional cônico trazendo sensação de profundidade e elegância\n          para o produto.\n        </p>\n      </div>\n    </div>"
        },
        {
          "name": "GridDots",
          "description": "",
          "code": "<div className=\"relative flex min-h-[400px] w-full flex-col items-center justify-center overflow-hidden bg-background p-8\">\n      <BackgroundGlow variant=\"grid-dots\" />\n      <div className=\"relative z-10 max-w-xl text-center\">\n        <h2 className=\"text-3xl font-bold tracking-tight\">\n          Grid Reticulado Tecnológico\n        </h2>\n        <p className=\"mt-3 text-sm text-muted-foreground\">\n          Textura de precisão matemática atenuada radialmente nas bordas.\n        </p>\n      </div>\n    </div>"
        },
        {
          "name": "Beam",
          "description": "",
          "code": "<div className=\"relative flex min-h-[400px] w-full flex-col items-center justify-center overflow-hidden bg-background p-8\">\n      <BackgroundGlow variant=\"beam\" tone=\"sky\" />\n      <div className=\"relative z-10 max-w-xl text-center\">\n        <h2 className=\"text-3xl font-bold tracking-tight\">\n          Eixo de Luz Linear\n        </h2>\n        <p className=\"mt-3 text-sm text-muted-foreground\">\n          Linha central etérea para guiar o olhar pelo fluxo visual.\n        </p>\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-badge",
      "title": "Badge UI",
      "description": "Extended badge with dot indicator, removable close icon, icon support, counter/overflow display, and semantic color variants (success/warning).",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/badge",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/badge.tsx"
      ],
      "props": [
        {
          "name": "dot",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "removable",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "maxCount",
          "required": false,
          "type": "number"
        },
        {
          "name": "onRemove",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "count",
          "required": false,
          "type": "number"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "background",
          "required": false,
          "type": "string",
          "description": "Override background via CSS token `--badge-background`.\nAccepts any CSS color value or `var(--my-token)`.\n@example background=\"var(--color-success)\""
        },
        {
          "name": "color",
          "required": false,
          "type": "string",
          "description": "Override text color via CSS token `--badge-color`.\nAccepts any CSS color value or `var(--my-token)`."
        },
        {
          "name": "borderColor",
          "required": false,
          "type": "string",
          "description": "Override border color via CSS token `--badge-border-color`.\nAccepts any CSS color value or `var(--my-token)`."
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"secondary\" | \"destructive\" | \"outline\" | \"success\" | \"warning\"",
          "options": [
            "default",
            "secondary",
            "destructive",
            "outline",
            "success",
            "warning"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/Badge",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    children: \"Badge\",\n    variant: \"default\",\n    size: \"md\",\n    dot: false,\n    removable: false,\n    loading: false,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-wrap items-center gap-3\">\n      <Badge variant=\"default\">Default</Badge>\n      <Badge variant=\"secondary\">Secondary</Badge>\n      <Badge variant=\"destructive\">Destructive</Badge>\n      <Badge variant=\"outline\">Outline</Badge>\n      <Badge variant=\"success\">Success</Badge>\n      <Badge variant=\"warning\">Warning</Badge>\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex items-center gap-3\">\n      <Badge size=\"sm\">Small</Badge>\n      <Badge size=\"md\">Medium</Badge>\n      <Badge size=\"lg\">Large</Badge>\n    </div>"
        },
        {
          "name": "WithDot",
          "description": "",
          "code": "<div className=\"flex flex-wrap items-center gap-3\">\n      <Badge variant=\"default\" dot>\n        Default\n      </Badge>\n      <Badge variant=\"success\" dot>\n        Online\n      </Badge>\n      <Badge variant=\"warning\" dot>\n        Pending\n      </Badge>\n      <Badge variant=\"destructive\" dot>\n        Error\n      </Badge>\n    </div>"
        },
        {
          "name": "Removable",
          "description": "",
          "args": "{\n    children: \"Dismiss me\",\n    removable: true,\n    variant: \"secondary\",\n  },\n  argTypes: {\n    onRemove: { action: \"removed\" },\n  },"
        },
        {
          "name": "WithIcon",
          "description": "",
          "code": "<div className=\"flex flex-wrap items-center gap-3\">\n      <Badge variant=\"default\" icon={<MailIcon />}>\n        Inbox\n      </Badge>\n      <Badge variant=\"success\" icon={<MailIcon />}>\n        12 new\n      </Badge>\n      <Badge variant=\"secondary\" icon={<MailIcon />}>\n        Sent\n      </Badge>\n    </div>"
        },
        {
          "name": "Counter",
          "description": "",
          "code": "<div className=\"flex flex-wrap items-center gap-3\">\n      <Badge maxCount={999} count={5}>\n        Items\n      </Badge>\n      <Badge maxCount={999} count={150}>\n        Over limit\n      </Badge>\n      <Badge maxCount={99} count={100}>\n        Overflow\n      </Badge>\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<div className=\"flex items-center gap-3\">\n      <Badge loading size=\"sm\" />\n      <Badge loading size=\"md\" />\n      <Badge loading size=\"lg\" />\n    </div>"
        },
        {
          "name": "ColorTokens",
          "description": "The `background`, `color`, and `borderColor` props accept any CSS color value or `var(--my-token)`. They set CSS custom properties (`--badge-background`, `--badge-color`, `--badge-border-color`) and apply the matching utility classes — escaping the built-in variant enum for per-instance customization.",
          "code": "<div className=\"flex flex-wrap gap-2\">\n      <Badge background=\"oklch(0.5 0.2 270)\" color=\"white\">\n        Custom Purple\n      </Badge>\n      <Badge\n        background=\"var(--color-success)\"\n        color=\"var(--color-success-foreground)\"\n      >\n        Success Token\n      </Badge>\n      <Badge\n        background=\"var(--color-warning)\"\n        color=\"var(--color-warning-foreground)\"\n        borderColor=\"var(--color-warning)\"\n      >\n        Warning Token\n      </Badge>\n      <Badge\n        background=\"oklch(0.3 0.15 30)\"\n        color=\"white\"\n        borderColor=\"oklch(0.5 0.15 30)\"\n      >\n        Custom Dark\n      </Badge>\n      <Badge background=\"var(--color-brand, oklch(0.4 0.2 240))\" color=\"white\">\n        External Token\n      </Badge>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-banner",
      "title": "Banner",
      "description": "Faixa full-width dismissível com intent, variante, posição e CTAs. Base blockus banners.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/banner",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/banner.tsx"
      ],
      "props": [
        {
          "name": "dismissible",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onDismiss",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "title",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "action",
          "required": false,
          "type": "BannerAction"
        },
        {
          "name": "secondaryAction",
          "required": false,
          "type": "BannerAction"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"info\" | \"success\" | \"warning\" | \"destructive\" | \"promo\"",
          "options": [
            "default",
            "info",
            "success",
            "warning",
            "destructive",
            "promo"
          ],
          "default": "default"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"outline\" | \"ghost\" | \"filled\"",
          "options": [
            "default",
            "outline",
            "ghost",
            "filled"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "position",
          "required": false,
          "type": "\"inline\" | \"top\" | \"bottom\" | \"floating\"",
          "options": [
            "inline",
            "top",
            "bottom",
            "floating"
          ],
          "default": "inline"
        }
      ],
      "storyTitle": "Navigation/Banner",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"New feature\",\n    description: \"Explore the new dashboard with real-time insights.\",\n    action: { label: \"Explore\" },\n    intent: \"default\",\n  },"
        },
        {
          "name": "AllIntents",
          "description": "",
          "args": "{ title: \"Title\", description: \"Description\" },\n  render: () => (\n    <div className=\"flex flex-col gap-3\">\n      {(\n        [\n          \"default\",\n          \"info\",\n          \"success\",\n          \"warning\",\n          \"destructive\",\n          \"promo\",\n        ] as const\n      ).map((intent) => (\n        <Banner\n          key={intent}\n          intent={intent}\n          title={intent}\n          description=\"This is a banner description.\"\n          action={{ label: \"Action\" }}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-3\">\n      {(\n        [\n          \"default\",\n          \"info\",\n          \"success\",\n          \"warning\",\n          \"destructive\",\n          \"promo\",\n        ] as const\n      ).map((intent) => (\n        <Banner\n          key={intent}\n          intent={intent}\n          title={intent}\n          description=\"This is a banner description.\"\n          action={{ label: \"Action\" }}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ title: \"Banner\", description: \"Description\" },\n  render: () => (\n    <div className=\"flex flex-col gap-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <Banner\n          key={size}\n          size={size}\n          title={`Size ${size}`}\n          description=\"Adjustable banner height and typography.\"\n          action={{ label: \"CTA\" }}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <Banner\n          key={size}\n          size={size}\n          title={`Size ${size}`}\n          description=\"Adjustable banner height and typography.\"\n          action={{ label: \"CTA\" }}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "WithActions",
          "description": "",
          "args": "{\n    title: \"Update available\",\n    description: \"A new version is ready to install.\",\n    intent: \"info\",\n    action: { label: \"Update\" },\n    secondaryAction: { label: \"Later\" },\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true, title: \"x\", description: \"x\" },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{\n    title: \"We use cookies\",\n    description: \"We use cookies to improve your experience.\",\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-3\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <Banner\n          key={locale}\n          locale={locale}\n          title=\"Announcement\"\n          description=\"Dismiss label is localized.\"\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-3\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <Banner\n          key={locale}\n          locale={locale}\n          title=\"Announcement\"\n          description=\"Dismiss label is localized.\"\n        />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-banner-app",
      "title": "Banner App",
      "description": "Download de app com ícone, rating e store badges — blockus #14-17.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/banner-app",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/banner-app.tsx"
      ],
      "props": [
        {
          "name": "appName",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "iconSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "iconAlt",
          "required": false,
          "type": "string"
        },
        {
          "name": "rating",
          "required": false,
          "type": "number"
        },
        {
          "name": "ratingCount",
          "required": false,
          "type": "string"
        },
        {
          "name": "appStoreUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "googlePlayUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "onDismiss",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "position",
          "required": false,
          "type": "\"inline\" | \"floating\"",
          "options": [
            "inline",
            "floating"
          ],
          "default": "inline"
        }
      ],
      "storyTitle": "Navigation/BannerApp",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    appName: \"LEMA App\",\n    description: \"Get the mobile experience\",\n    iconSrc: \"https://picsum.photos/100/100\",\n    rating: 4.8,\n    ratingCount: \"2.4k\",\n    appStoreUrl: \"#\",\n    googlePlayUrl: \"#\",\n  },"
        },
        {
          "name": "WithoutRating",
          "description": "",
          "args": "{\n    appName: \"LEMA\",\n    description: \"Available on iOS and Android\",\n    appStoreUrl: \"#\",\n    googlePlayUrl: \"#\",\n  },"
        },
        {
          "name": "Floating",
          "description": "",
          "args": "{\n    appName: \"LEMA App\",\n    description: \"Download now\",\n    rating: 4.9,\n    appStoreUrl: \"#\",\n    position: \"floating\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ appName: \"App\", loading: true }"
        }
      ]
    },
    {
      "name": "ds-banner-cookie",
      "title": "Banner Cookie",
      "description": "Barra de consentimento cookies fixed bottom/floating — blockus #09-12.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/banner-cookie",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/banner-cookie.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "learnMoreHref",
          "required": false,
          "type": "string"
        },
        {
          "name": "onAcceptAll",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onDecline",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onManage",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "position",
          "required": false,
          "type": "\"bottom\" | \"floating\"",
          "options": [
            "bottom",
            "floating"
          ],
          "default": "floating"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Navigation/BannerCookie",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    onAcceptAll: () => {},\n    onDecline: () => {},\n    onManage: () => {},\n    learnMoreHref: \"#\",\n  },"
        },
        {
          "name": "Floating",
          "description": "",
          "args": "{ position: \"floating\", onAcceptAll: () => {}, onDecline: () => {} },"
        },
        {
          "name": "Bottom",
          "description": "",
          "args": "{ position: \"bottom\", onAcceptAll: () => {}, onDecline: () => {} },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{ onAcceptAll: () => {}, onDecline: () => {} },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <BannerCookie\n          key={locale}\n          locale={locale}\n          onAcceptAll={() => {}}\n          onDecline={() => {}}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <BannerCookie\n          key={locale}\n          locale={locale}\n          onAcceptAll={() => {}}\n          onDecline={() => {}}\n        />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-banner-marquee",
      "title": "Banner Marquee",
      "description": "Faixa com rolagem infinita horizontal para highlights — blockus banner #13.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/banner-marquee",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/banner-marquee.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "string[]"
        },
        {
          "name": "separator",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "speed",
          "required": false,
          "type": "\"slow\" | \"normal\" | \"fast\""
        },
        {
          "name": "direction",
          "required": false,
          "type": "\"left\" | \"right\""
        },
        {
          "name": "pauseOnHover",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"promo\" | \"contrast\"",
          "options": [
            "default",
            "promo",
            "contrast"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Navigation/BannerMarquee",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items: [\"Deploy fast\", \"Zero config\", \"Edge CDN\", \"Global scale\"] },"
        },
        {
          "name": "Promo",
          "description": "",
          "args": "{\n    items: [\"Black Friday 30% OFF\", \"Limited time\", \"Upgrade now\"],\n    intent: \"promo\",\n  },"
        },
        {
          "name": "Speeds",
          "description": "",
          "args": "{ items: [\"Deploy fast\", \"Zero config\", \"Edge CDN\"] },\n  render: () => (\n    <div className=\"flex flex-col gap-3\">\n      <BannerMarquee items={[\"Slow — 30s\"]} speed=\"slow\" />\n      <BannerMarquee items={[\"Normal — 20s\"]} speed=\"normal\" />\n      <BannerMarquee items={[\"Fast — 10s\"]} speed=\"fast\" />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-3\">\n      <BannerMarquee items={[\"Slow — 30s\"]} speed=\"slow\" />\n      <BannerMarquee items={[\"Normal — 20s\"]} speed=\"normal\" />\n      <BannerMarquee items={[\"Fast — 10s\"]} speed=\"fast\" />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-banner-promo",
      "title": "Banner Promo",
      "description": "Card promo centrado com gradiente/imagem e 1-2 CTAs — blockus #05-08.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/banner-promo",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "button",
        "skeleton"
      ],
      "files": [
        "components/ds/banner-promo.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "imageSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "imageAlt",
          "required": false,
          "type": "string"
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"promo\" | \"info\" | \"success\" | \"warning\""
        },
        {
          "name": "primaryAction",
          "required": false,
          "type": "{ label: string; href?: string; onClick?: () => void }"
        },
        {
          "name": "secondaryAction",
          "required": false,
          "type": "{ label: string; href?: string; onClick?: () => void }"
        },
        {
          "name": "dismissible",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onDismiss",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Navigation/BannerPromo",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Ship faster with LEMA DS\",\n    description:\n      \"Drop in headers, banners and more — ship in hours, not weeks.\",\n    primaryAction: { label: \"Get access\" },\n    secondaryAction: { label: \"Learn more\" },\n  },"
        },
        {
          "name": "WithImage",
          "description": "",
          "args": "{\n    title: \"Design without limits\",\n    description: \"A new way to build landing pages with blockus.\",\n    imageSrc: \"https://picsum.photos/600/400\",\n    primaryAction: { label: \"Explore\" },\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ title: \"Loading\", loading: true }"
        }
      ]
    },
    {
      "name": "ds-banner-top",
      "title": "Banner Top",
      "description": "Bloco topo sticky com badge, título e CTA — blockus banners #01-04.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/banner-top",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-banner"
      ],
      "files": [
        "components/ds/banner-top.tsx"
      ],
      "props": [
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "position",
          "required": false,
          "type": "\"inline\" | \"top\""
        }
      ],
      "storyTitle": "Navigation/BannerTop",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    badge: \"New\",\n    title: \"v1.2 shipped\",\n    description: \"Explore headers and banners.\",\n    action: { label: \"Read more\", href: \"#\" },\n  },"
        },
        {
          "name": "Promo",
          "description": "",
          "args": "{\n    title: \"Summer sale\",\n    description: \"30% off all plans\",\n    intent: \"promo\",\n    action: { label: \"Upgrade\" },\n  },"
        },
        {
          "name": "Dismissible",
          "description": "",
          "args": "{\n    title: \"Maintenance\",\n    description: \"Scheduled down-time 02:00 UTC\",\n    intent: \"warning\",\n    dismissible: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-bar-chart",
      "title": "Bar Chart",
      "description": "A fully featured bar chart with tooltips, legend, stacking, rounded corners, and brush zoom.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/bar-chart",
      "dependencies": [
        "recharts",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils",
        "chart-axis-width"
      ],
      "files": [
        "components/ds/bar-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "Record<string, string | number>[]"
        },
        {
          "name": "dataKeys",
          "required": true,
          "type": "BarChartKey[] | string[]",
          "description": "Keys to render as bars — accepts plain strings or { key, label, color }"
        },
        {
          "name": "categoryKey",
          "required": true,
          "type": "string",
          "description": "Object key mapped to the category axis (X on vertical, Y on horizontal)"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "orientation",
          "required": false,
          "type": "BarOrientation",
          "description": "\"vertical\" = bars point up (default); \"horizontal\" = bars point right"
        },
        {
          "name": "height",
          "required": false,
          "type": "number",
          "description": "Chart canvas height in px — container width is always 100%"
        },
        {
          "name": "showGrid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showLegend",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "legendPosition",
          "required": false,
          "type": "LegendPosition",
          "description": "@default \"bottom\""
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "stacked",
          "required": false,
          "type": "boolean",
          "description": "Stack all bars into a single column/row"
        },
        {
          "name": "barSize",
          "required": false,
          "type": "number",
          "description": "Fixed bar thickness in px; recharts auto-sizes when omitted"
        },
        {
          "name": "rounded",
          "required": false,
          "type": "boolean",
          "description": "Round the leading edge of each bar"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Format the value axis tick labels and tooltip values"
        },
        {
          "name": "showBrush",
          "required": false,
          "type": "boolean",
          "description": "Show a range brush below the chart to scroll and zoom the category axis.\nWorks with vertical orientation only. The brush occupies ~30 px of the\nchart height, so increase `height` accordingly when enabling."
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "xAxisLabel",
          "required": false,
          "type": "string",
          "description": "Label centred on the horizontal (category/value) axis"
        },
        {
          "name": "yAxisLabel",
          "required": false,
          "type": "string",
          "description": "Label centred on the vertical (value/category) axis"
        }
      ],
      "storyTitle": "Data Display/BarChart",
      "stories": [
        {
          "name": "Default",
          "description": "Default vertical bar chart showing monthly revenue from January to June 2025 with tooltips and rounded corners.",
          "args": "{\n    title: \"Monthly Revenue\",\n    subtitle: \"January – June 2025\",\n    data: monthlyRevenue,\n    dataKeys: [\"revenue\"],\n    categoryKey: \"month\",\n    height: 280,\n    showGrid: true,\n    showTooltip: true,\n    rounded: true,\n    orientation: \"vertical\",\n    showLegend: false,\n    stacked: false,\n    legendPosition: \"bottom\",\n    showBrush: false,\n    decimals: 0,\n    abbreviate: false,\n    loading: false,\n    locale: \"en-US\",\n    format: \"currency\",\n    valueFormatter: formatUSD,\n  },"
        },
        {
          "name": "Horizontal",
          "description": "Horizontal bar chart showing absences per course with custom per-series color labels, ideal for reading long category names.",
          "args": "{\n    title: \"Absences by Course\",\n    subtitle: \"Semester 2025.1\",\n    data: absencesByCourse,\n    dataKeys: [{ key: \"absences\", label: \"Absences\" }],\n    categoryKey: \"course\",\n    orientation: \"horizontal\",\n    showGrid: true,\n    rounded: true,\n    height: 300,\n  },"
        },
        {
          "name": "MultiSeries",
          "description": "Multi-series vertical bar chart comparing enrolled versus active students per department with a legend and tooltip.",
          "args": "{\n    title: \"Enrollment by Department\",\n    subtitle: \"Enrolled vs. active students\",\n    data: enrollmentByDept,\n    dataKeys: [\n      { key: \"enrolled\", label: \"Enrolled\" },\n      { key: \"active\", label: \"Active\" },\n    ],\n    categoryKey: \"dept\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    rounded: true,\n    height: 300,\n  },"
        },
        {
          "name": "MultiSeriesHorizontal",
          "description": "Multi-series horizontal bar chart comparing enrolled versus active students, combining legend support with horizontal orientation.",
          "args": "{\n    title: \"Enrollment by Department\",\n    subtitle: \"Enrolled vs. active students — horizontal orientation\",\n    data: enrollmentByDept,\n    dataKeys: [\n      { key: \"enrolled\", label: \"Enrolled\" },\n      { key: \"active\", label: \"Active\" },\n    ],\n    categoryKey: \"dept\",\n    orientation: \"horizontal\",\n    showGrid: true,\n    showLegend: true,\n    rounded: true,\n    height: 320,\n  },"
        },
        {
          "name": "Stacked",
          "description": "Stacked vertical bars comparing planned, actual, and projected budget across four quarters with a USD value formatter.",
          "args": "{\n    title: \"Quarterly Budget\",\n    subtitle: \"Planned · Actual · Projected\",\n    data: quarterlyBudget,\n    dataKeys: [\n      { key: \"planned\", label: \"Planned\" },\n      { key: \"actual\", label: \"Actual\" },\n      { key: \"projected\", label: \"Projected\" },\n    ],\n    categoryKey: \"quarter\",\n    stacked: true,\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    rounded: true,\n    valueFormatter: formatUSD,\n    height: 300,\n  },"
        },
        {
          "name": "StackedHorizontal",
          "description": "Stacked horizontal bars showing cumulative quarterly budget across planned, actual, and projected categories.",
          "args": "{\n    title: \"Quarterly Budget\",\n    subtitle: \"Cumulative by quarter — horizontal\",\n    data: quarterlyBudget,\n    dataKeys: [\n      { key: \"planned\", label: \"Planned\" },\n      { key: \"actual\", label: \"Actual\" },\n      { key: \"projected\", label: \"Projected\" },\n    ],\n    categoryKey: \"quarter\",\n    orientation: \"horizontal\",\n    stacked: true,\n    showGrid: true,\n    showLegend: true,\n    rounded: true,\n    valueFormatter: formatUSD,\n    height: 260,\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Monthly revenue bar chart with a custom footer slot containing a trend indicator and update timestamp.",
          "args": "{\n    title: \"Monthly Revenue\",\n    subtitle: \"Year-to-date 2025\",\n    data: monthlyRevenue,\n    dataKeys: [{ key: \"revenue\", label: \"Revenue\", color: \"var(--chart-2)\" }],\n    categoryKey: \"month\",\n    showGrid: true,\n    showTooltip: true,\n    rounded: true,\n    valueFormatter: formatUSD,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-success\" />\n          <span>Up 18% over the last 3 months</span>\n        </span>\n        <span className=\"flex items-center gap-1 text-muted-foreground/70\">\n          <Info className=\"size-3\" />\n          Updated today\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "CustomColors",
          "description": "Bar chart using `var(--primary)` and `var(--chart-3)` as per-series color overrides instead of the default chart tokens.",
          "args": "{\n    title: \"Enrollment by Department\",\n    subtitle: \"Using var(--primary) and var(--chart-3) as series colors\",\n    data: enrollmentByDept,\n    dataKeys: [\n      { key: \"enrolled\", label: \"Enrolled\", color: \"var(--primary)\" },\n      { key: \"active\", label: \"Active\", color: \"var(--chart-3)\" },\n    ],\n    categoryKey: \"dept\",\n    showGrid: true,\n    showLegend: true,\n    rounded: true,\n    height: 300,\n  },"
        },
        {
          "name": "NoDecoration",
          "description": "Minimal bar chart with grid, tooltips, and rounded corners disabled — a compact chart with a fixed bar size.",
          "args": "{\n    data: monthlyRevenue,\n    dataKeys: [\"revenue\"],\n    categoryKey: \"month\",\n    showGrid: false,\n    showTooltip: false,\n    rounded: false,\n    barSize: 24,\n    height: 200,\n  },"
        },
        {
          "name": "WithAxisLabels",
          "description": "Pass `xAxisLabel` and `yAxisLabel` to render centred axis titles. The chart bottom and left margins are automatically expanded to prevent clipping. Works in both `vertical` and `horizontal` orientations.",
          "args": "{\n    data: monthlyRevenue,\n    dataKeys: [\"revenue\"],\n    categoryKey: \"month\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Pass `xAxisLabel` and `yAxisLabel` to render centred axis titles. The chart bottom and left margins are automatically expanded to prevent clipping. Works in both `vertical` and `horizontal` orientations.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      <BarChart\n        title=\"Vertical — with axis labels\"\n        subtitle=\"xAxisLabel + yAxisLabel\"\n        data={monthlyRevenue}\n        dataKeys={[{ key: \"revenue\", label: \"Revenue\" }]}\n        categoryKey=\"month\"\n        showGrid\n        showTooltip\n        rounded\n        valueFormatter={formatUSD}\n        xAxisLabel=\"Month\"\n        yAxisLabel=\"Revenue (USD)\"\n        height={300}\n      />\n      <BarChart\n        title=\"Horizontal — with axis labels\"\n        subtitle=\"xAxisLabel + yAxisLabel in horizontal orientation\"\n        data={absencesByCourse}\n        dataKeys={[{ key: \"absences\", label: \"Absences\" }]}\n        categoryKey=\"course\"\n        orientation=\"horizontal\"\n        showGrid\n        rounded\n        xAxisLabel=\"Number of Absences\"\n        yAxisLabel=\"Course\"\n        height={300}\n      />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      <BarChart\n        title=\"Vertical — with axis labels\"\n        subtitle=\"xAxisLabel + yAxisLabel\"\n        data={monthlyRevenue}\n        dataKeys={[{ key: \"revenue\", label: \"Revenue\" }]}\n        categoryKey=\"month\"\n        showGrid\n        showTooltip\n        rounded\n        valueFormatter={formatUSD}\n        xAxisLabel=\"Month\"\n        yAxisLabel=\"Revenue (USD)\"\n        height={300}\n      />\n      <BarChart\n        title=\"Horizontal — with axis labels\"\n        subtitle=\"xAxisLabel + yAxisLabel in horizontal orientation\"\n        data={absencesByCourse}\n        dataKeys={[{ key: \"absences\", label: \"Absences\" }]}\n        categoryKey=\"course\"\n        orientation=\"horizontal\"\n        showGrid\n        rounded\n        xAxisLabel=\"Number of Absences\"\n        yAxisLabel=\"Course\"\n        height={300}\n      />\n    </div>"
        },
        {
          "name": "WithBrush",
          "description": "Multi-series bar chart with a brush slider for interactive range selection across 24 months of enrollment and graduation data.",
          "args": "{\n    title: \"Enrollment & Graduations — 2024–2025\",\n    subtitle: \"Drag the handles at the bottom to zoom in on a time range\",\n    data: enrollmentTwoYears,\n    dataKeys: [\n      { key: \"enrolled\", label: \"Enrolled\" },\n      { key: \"graduated\", label: \"Graduated\", color: \"var(--chart-3)\" },\n    ],\n    categoryKey: \"month\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    showBrush: true,\n    rounded: true,\n    height: 340,\n  },"
        },
        {
          "name": "WithBrushStacked",
          "description": "Stacked bar chart with a brush slider combining stacked series and interactive range zoom for semester comparison.",
          "args": "{\n    title: \"Enrollment & Graduations — stacked view\",\n    subtitle: \"showBrush + stacked — scroll to compare semester peaks\",\n    data: enrollmentTwoYears,\n    dataKeys: [\n      { key: \"enrolled\", label: \"Enrolled\" },\n      { key: \"graduated\", label: \"Graduated\", color: \"var(--chart-3)\" },\n    ],\n    categoryKey: \"month\",\n    stacked: true,\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    showBrush: true,\n    rounded: true,\n    height: 340,\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Monthly revenue chart with Portuguese locale and BRL currency formatting demonstrating internationalization support.",
          "args": "{\n    title: \"Receita Mensal\",\n    subtitle: \"Janeiro – Junho 2025\",\n    data: monthlyRevenue,\n    dataKeys: [\"revenue\"],\n    categoryKey: \"month\",\n    showGrid: true,\n    showTooltip: true,\n    rounded: true,\n    valueFormatter: (v) =>\n      formatValue(v, \"currency\", {\n        currency: \"BRL\",\n        abbreviate: true,\n        decimals: 0,\n        locale: \"pt-BR\",\n      }),\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the chart with an animated skeleton. Each bar pulses in a wave cascade (left → right) with staggered delays. The skeleton mirrors the presence of `title`, `subtitle`, and `footer` props — only the sections you pass are included in the skeleton layout.\\n\\nClick **Simulate reload** to replay the transition.",
          "args": "{\n    title: \"Monthly Revenue\",\n    subtitle: \"January – June 2025\",\n    data: monthlyRevenue,\n    dataKeys: [{ key: \"revenue\", label: \"Revenue\" }],\n    categoryKey: \"month\",\n    showGrid: true,\n    showTooltip: true,\n    rounded: true,\n    valueFormatter: formatUSD,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-success\" />\n          <span>Up 18% over the last 3 months</span>\n        </span>\n        <span className=\"flex items-center gap-1 text-muted-foreground/70\">\n          <Info className=\"size-3\" />\n          Updated today\n        </span>\n      </div>\n    ),\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the chart renders a placeholder with a dashed border instead of an empty axes grid. The `title`, `subtitle`, and `footer` slots remain visible so the card context is preserved.",
          "args": "{\n    title: \"Monthly Revenue\",\n    subtitle: \"January – June 2025\",\n    data: [],\n    dataKeys: [\"revenue\"],\n    categoryKey: \"month\",\n    height: 280,\n  },"
        },
        {
          "name": "LegendPositions",
          "description": "Grid of four bar charts demonstrating all four legend positions (top, right, bottom, left) for side-by-side comparison.",
          "args": "{\n    data: enrollmentByDept,\n    dataKeys: [\"enrolled\", \"active\"],\n    categoryKey: \"dept\",\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <BarChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={enrollmentByDept}\n          dataKeys={[\n            { key: \"enrolled\", label: \"Enrolled\" },\n            { key: \"active\", label: \"Active\" },\n          ]}\n          categoryKey=\"dept\"\n          showLegend\n          legendPosition={pos}\n          showGrid\n          showTooltip\n          rounded\n          height={240}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <BarChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={enrollmentByDept}\n          dataKeys={[\n            { key: \"enrolled\", label: \"Enrolled\" },\n            { key: \"active\", label: \"Active\" },\n          ]}\n          categoryKey=\"dept\"\n          showLegend\n          legendPosition={pos}\n          showGrid\n          showTooltip\n          rounded\n          height={240}\n        />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-bento-features",
      "title": "BentoFeatures",
      "description": "Grid bento misturando tiles de feature com ícone e tiles de estatística — composto de ds-bento-grid e ds-card-stat.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/bento-features",
      "dependencies": [],
      "registryDependencies": [
        "ds-bento-grid",
        "ds-card-stat"
      ],
      "files": [
        "components/ds/bento-features.tsx"
      ],
      "props": [
        {
          "name": "features",
          "required": true,
          "type": "BentoFeaturesItem[]"
        },
        {
          "name": "stats",
          "required": false,
          "type": "BentoFeaturesStat[]"
        }
      ],
      "storyTitle": "Bento/BentoFeatures",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "WithoutStats",
          "description": "",
          "args": "{ stats: [] },"
        }
      ]
    },
    {
      "name": "ds-bento-grid",
      "title": "BentoGrid",
      "description": "Grid assimétrico com spans configuráveis para tiles de feature/mídia.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/bento-grid",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton"
      ],
      "files": [
        "components/ds/bento-grid.tsx"
      ],
      "props": [
        {
          "name": "colSpan",
          "required": false,
          "type": "\"1\" | \"2\" | \"3\" | \"4\"",
          "options": [
            "1",
            "2",
            "3",
            "4"
          ]
        },
        {
          "name": "rowSpan",
          "required": false,
          "type": "\"1\" | \"2\" | \"3\" | \"4\"",
          "options": [
            "1",
            "2",
            "3",
            "4"
          ]
        }
      ],
      "storyTitle": "Bento/BentoGrid",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<BentoGrid>\n      <BentoGridItem\n        colSpan={2}\n        rowSpan={2}\n        icon={Sparkles}\n        title=\"AI-assisted workflows\"\n        description=\"Let the assistant draft, summarize, and triage for you.\"\n      />\n      <BentoGridItem\n        icon={BarChart3}\n        title=\"Real-time insights\"\n        description=\"See how your team ships, live.\"\n      />\n      <BentoGridItem\n        icon={Zap}\n        title=\"Automation\"\n        description=\"Route work automatically.\"\n      />\n      <BentoGridItem\n        colSpan={2}\n        icon={ShieldCheck}\n        title=\"Enterprise-grade security\"\n        description=\"SSO, audit logs, and granular permissions out of the box.\"\n      />\n    </BentoGrid>"
        },
        {
          "name": "AllSpans",
          "description": "",
          "code": "<BentoGrid>\n      <BentoGridItem colSpan={1} title=\"Span 1\" description=\"col-span-1\" />\n      <BentoGridItem colSpan={2} title=\"Span 2\" description=\"col-span-2\" />\n      <BentoGridItem colSpan={3} title=\"Span 3\" description=\"col-span-3\" />\n      <BentoGridItem colSpan={4} title=\"Span 4\" description=\"col-span-4\" />\n    </BentoGrid>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<BentoGrid>\n      <BentoGridItem colSpan={2} rowSpan={2} loading />\n      <BentoGridItem loading />\n      <BentoGridItem loading />\n    </BentoGrid>"
        }
      ]
    },
    {
      "name": "ds-bento-metrics",
      "title": "BentoMetrics",
      "description": "Grid bento combinando um gráfico de barras com uma tira de estatísticas — composto de ds-bento-grid, ds-bar-chart e ds-card-stat.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/bento-metrics",
      "dependencies": [],
      "registryDependencies": [
        "ds-bento-grid",
        "ds-bar-chart",
        "ds-card-stat"
      ],
      "files": [
        "components/ds/bento-metrics.tsx"
      ],
      "props": [
        {
          "name": "stats",
          "required": true,
          "type": "BentoMetricsStat[]"
        },
        {
          "name": "chartTitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "chartData",
          "required": true,
          "type": "Record<string, string | number>[]"
        },
        {
          "name": "chartDataKeys",
          "required": true,
          "type": "BarChartKey[] | string[]"
        },
        {
          "name": "chartCategoryKey",
          "required": true,
          "type": "string"
        }
      ],
      "storyTitle": "Bento/BentoMetrics",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        }
      ]
    },
    {
      "name": "ds-bento-showcase",
      "title": "BentoShowcase",
      "description": "Grid bento exibindo screenshot de produto, preview de terminal e snippet de instalação — composto de ds-bento-grid, ds-floating-card, ds-browser-mockup e ds-copy-block.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/bento-showcase",
      "dependencies": [],
      "registryDependencies": [
        "ds-bento-grid",
        "ds-floating-card",
        "ds-browser-mockup",
        "ds-copy-block"
      ],
      "files": [
        "components/ds/bento-showcase.tsx"
      ],
      "props": [
        {
          "name": "screenshot",
          "required": true,
          "type": "React.ReactNode",
          "description": "Rendered inside the large FloatingCard tile (e.g. an <img>)."
        },
        {
          "name": "browserUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "browserVariant",
          "required": false,
          "type": "BrowserMockupProps[\"variant\"]"
        },
        {
          "name": "browserContent",
          "required": false,
          "type": "React.ReactNode",
          "description": "Rendered inside the terminal/browser tile."
        },
        {
          "name": "codeSnippet",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Bento/BentoShowcase",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "WithoutSnippet",
          "description": "",
          "args": "{ codeSnippet: undefined },"
        }
      ]
    },
    {
      "name": "ds-bento-social-proof",
      "title": "BentoSocialProof",
      "description": "Grid bento misturando tiles de depoimento com um mural de logos — composto de ds-bento-grid, ds-pull-quote e ds-press-wall.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/bento-social-proof",
      "dependencies": [],
      "registryDependencies": [
        "ds-bento-grid",
        "ds-pull-quote",
        "ds-press-wall"
      ],
      "files": [
        "components/ds/bento-social-proof.tsx"
      ],
      "props": [
        {
          "name": "quotes",
          "required": true,
          "type": "BentoSocialProofQuote[]"
        },
        {
          "name": "logos",
          "required": false,
          "type": "BentoSocialProofLogo[]"
        },
        {
          "name": "logosLabel",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Bento/BentoSocialProof",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "WithoutLogos",
          "description": "",
          "args": "{ logos: [] },"
        }
      ]
    },
    {
      "name": "ds-billing",
      "title": "Billing",
      "description": "Card de plano e fatura — ReUI Billing.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/billing",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "badge",
        "button",
        "skeleton"
      ],
      "files": [
        "components/ds/billing.tsx"
      ],
      "props": [
        {
          "name": "plan",
          "required": true,
          "type": "string"
        },
        {
          "name": "price",
          "required": true,
          "type": "string"
        },
        {
          "name": "nextBilling",
          "required": false,
          "type": "string"
        },
        {
          "name": "status",
          "required": false,
          "type": "\"active\" | \"past_due\" | \"canceled\""
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Dashboard/Billing",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    plan: \"Pro\",\n    price: \"$49/mo\",\n    nextBilling: \"Oct 10\",\n    status: \"active\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ plan: \"x\", price: \"x\", loading: true }"
        }
      ]
    },
    {
      "name": "ds-blog-author",
      "title": "Blog Author",
      "description": "Avatar + nome + role do autor para blog.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/blog-author",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "avatar",
        "skeleton"
      ],
      "files": [
        "components/ds/blog-author.tsx"
      ],
      "props": [
        {
          "name": "name",
          "required": true,
          "type": "string"
        },
        {
          "name": "avatarUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "role",
          "required": false,
          "type": "string"
        },
        {
          "name": "href",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Blog/BlogAuthor",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ name: \"Ana Silva\", avatarUrl: \"https://picsum.photos/100/100\" },"
        },
        {
          "name": "WithRole",
          "description": "",
          "args": "{\n    name: \"Carlos Mendes\",\n    avatarUrl: \"https://picsum.photos/100/100\",\n    role: \"Editor\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ name: \"Name\", loading: true, role: \"Role\" },"
        }
      ]
    },
    {
      "name": "ds-blog-card",
      "title": "Blog Card",
      "description": "Card de post com imagem, categoria, título, excerpt, tags e autor — átomo base blog.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/blog-card",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "card",
        "badge",
        "avatar",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/blog-card.tsx"
      ],
      "props": [
        {
          "name": "post",
          "required": true,
          "type": "BlogPost"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "featured",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "storyTitle": "Blog/BlogCard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ post }"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ post },\n  render: () => (\n    <div className=\"grid gap-6 md:grid-cols-3\">\n      <BlogCard post={post} size=\"sm\" />\n      <BlogCard post={post} size=\"md\" />\n      <BlogCard post={post} size=\"lg\" />\n    </div>\n  ),",
          "code": "<div className=\"grid gap-6 md:grid-cols-3\">\n      <BlogCard post={post} size=\"sm\" />\n      <BlogCard post={post} size=\"md\" />\n      <BlogCard post={post} size=\"lg\" />\n    </div>"
        },
        {
          "name": "Featured",
          "description": "",
          "args": "{ post: { ...post, featured: true } }"
        },
        {
          "name": "WithoutImage",
          "description": "",
          "args": "{ post: { ...post, imageSrc: undefined } },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ post, loading: true }"
        }
      ]
    },
    {
      "name": "ds-blog-featured",
      "title": "Blog Featured",
      "description": "Hero featured grande + 2 cards laterais — blockus #15-22.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/blog-featured",
      "dependencies": [],
      "registryDependencies": [
        "ds-blog-card",
        "skeleton"
      ],
      "files": [
        "components/ds/blog-featured.tsx"
      ],
      "props": [
        {
          "name": "featured",
          "required": true,
          "type": "BlogPost"
        },
        {
          "name": "posts",
          "required": false,
          "type": "BlogPost[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Blog/BlogFeatured",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ featured, posts: side }"
        },
        {
          "name": "OnlyFeatured",
          "description": "",
          "args": "{ featured }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ featured, loading: true }"
        }
      ]
    },
    {
      "name": "ds-blog-grid",
      "title": "Blog Grid",
      "description": "Grid responsivo 3 cols com filtros categoria + busca — blockus blog #01-07.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/blog-grid",
      "dependencies": [],
      "registryDependencies": [
        "ds-blog-card",
        "input",
        "empty",
        "ui-i18n"
      ],
      "files": [
        "components/ds/blog-grid.tsx"
      ],
      "props": [
        {
          "name": "posts",
          "required": true,
          "type": "BlogPost[]"
        },
        {
          "name": "categories",
          "required": false,
          "type": "string[]"
        },
        {
          "name": "activeCategory",
          "required": false,
          "type": "string"
        },
        {
          "name": "onCategoryChange",
          "required": false,
          "type": "(category: string | null) => void"
        },
        {
          "name": "search",
          "required": false,
          "type": "string"
        },
        {
          "name": "onSearchChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Blog/BlogGrid",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ posts, categories: [\"Design\", \"Engineering\", \"Product\"] },"
        },
        {
          "name": "Filtered",
          "description": "",
          "args": "{\n    posts: posts.filter((p) => p.category === \"Design\"),\n    categories: [\"Design\", \"Engineering\"],\n    activeCategory: \"Design\",\n  },"
        },
        {
          "name": "Empty",
          "description": "",
          "args": "{ posts: [], categories: [\"Design\"] }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ posts, loading: true }"
        }
      ]
    },
    {
      "name": "ds-blog-list",
      "title": "Blog List",
      "description": "Lista horizontal imagem à esquerda — blockus #08-12.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/blog-list",
      "dependencies": [],
      "registryDependencies": [
        "ds-blog-meta",
        "ds-blog-author",
        "separator",
        "skeleton"
      ],
      "files": [
        "components/ds/blog-list.tsx"
      ],
      "props": [
        {
          "name": "posts",
          "required": true,
          "type": "BlogPost[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Blog/BlogList",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ posts }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ posts, loading: true }"
        }
      ]
    },
    {
      "name": "ds-blog-meta",
      "title": "Blog Meta",
      "description": "Linha de metadados: data, reading time e categoria.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/blog-meta",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "badge",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/blog-meta.tsx"
      ],
      "props": [
        {
          "name": "publishedAt",
          "required": false,
          "type": "string | Date"
        },
        {
          "name": "readingTime",
          "required": false,
          "type": "number"
        },
        {
          "name": "category",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Blog/BlogMeta",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ publishedAt: \"2026-03-10\", readingTime: 5, category: \"Design\" },"
        },
        {
          "name": "WithoutCategory",
          "description": "",
          "args": "{ publishedAt: \"2026-03-10\", readingTime: 3 },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true }"
        }
      ]
    },
    {
      "name": "ds-border-beam",
      "title": "BorderBeam",
      "description": "Brilho que percorre a borda do container pai via offset-path (correto em qualquer proporção), em CSS puro — oculto em prefers-reduced-motion.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/border-beam",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/border-beam.tsx"
      ],
      "props": [
        {
          "name": "tone",
          "required": false,
          "type": "\"primary\" | \"violet\" | \"sky\"",
          "options": [
            "primary",
            "violet",
            "sky"
          ],
          "default": "primary"
        },
        {
          "name": "speed",
          "required": false,
          "type": "\"slow\" | \"normal\" | \"fast\"",
          "options": [
            "slow",
            "normal",
            "fast"
          ],
          "default": "normal"
        }
      ],
      "storyTitle": "Data Display/BorderBeam",
      "stories": [
        {
          "name": "AllTones",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      {([\"primary\", \"violet\", \"sky\"] as const).map((tone) => (\n        <div\n          key={tone}\n          className=\"relative isolate overflow-hidden rounded-2xl border border-border bg-card p-4\"\n        >\n          <BorderBeam tone={tone} />\n          <p className=\"text-xs text-muted-foreground\">{tone}</p>\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-boxplot-chart",
      "title": "Boxplot Chart",
      "description": "A fully custom SVG box-and-whisker chart with ResizeObserver for responsive layout, notch support, and outlier plotting.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/boxplot-chart",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/boxplot-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "BoxPlotItem[]"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "orientation",
          "required": false,
          "type": "BoxPlotOrientation",
          "description": "\"vertical\" = boxes grow upward (default); \"horizontal\" = boxes grow rightward"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "showGrid",
          "required": false,
          "type": "boolean",
          "description": "Draw background grid lines on the value axis"
        },
        {
          "name": "showMean",
          "required": false,
          "type": "boolean",
          "description": "Draw a diamond at the mean value"
        },
        {
          "name": "showOutliers",
          "required": false,
          "type": "boolean",
          "description": "Draw dots for outlier values"
        },
        {
          "name": "notched",
          "required": false,
          "type": "boolean",
          "description": "Notch the box at the median — visually encodes median confidence"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Format value-axis tick labels and tooltip values"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/BoxPlotChart",
      "stories": [
        {
          "name": "Default",
          "description": "Default vertical box plot showing grade distribution across four class groups with mean diamonds and outlier dots.",
          "args": "{\n    title: \"Final Exam Grades — by Class Group\",\n    subtitle: \"Hover a box for the five-number summary\",\n    data: gradesByClass,\n    orientation: \"vertical\",\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    notched: false,\n    decimals: 0,\n    abbreviate: false,\n    loading: false,\n    locale: \"en-US\",\n    height: 320,\n  },"
        },
        {
          "name": "Horizontal",
          "description": "Horizontal box plots comparing grade distribution by subject, ideal for long category labels that benefit from horizontal layout.",
          "args": "{\n    title: \"Grade Distribution by Subject\",\n    subtitle: \"Horizontal orientation — easier to read long category labels\",\n    data: gradesBySubject,\n    orientation: \"horizontal\",\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    height: 340,\n  },"
        },
        {
          "name": "Notched",
          "description": "Notched box plots where the waist width represents a 95% confidence interval around the median for significance comparison.",
          "args": "{\n    title: \"Final Exam Grades — Notched Boxes\",\n    subtitle:\n      \"Notch width ≈ 95% CI around the median — non-overlapping notches → significant difference\",\n    data: gradesByClass,\n    notched: true,\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    height: 340,\n  },"
        },
        {
          "name": "SemesterComparison",
          "description": "Box plots tracking weekly study hours distribution across three semesters with a custom hours value formatter.",
          "args": "{\n    title: \"Weekly Study Hours — Semester Trend\",\n    subtitle:\n      \"Distribution shifts rightward — students studying more over time\",\n    data: studyHoursBySemester,\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    height: 320,\n    valueFormatter: (v) => formatValue(v, \"integer\") + \"h\",\n  },"
        },
        {
          "name": "ApiResponseTime",
          "description": "API response time box plot showing latency distribution across endpoints with outliers flagged and a footer warning about SLA violations.",
          "args": "{\n    title: \"API Response Time Distribution\",\n    subtitle: \"P50 box · whiskers = min/max · circles = outliers\",\n    data: responseTimes,\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    height: 340,\n    valueFormatter: (v) => formatValue(v, \"integer\") + \"ms\",\n    footer: (\n      <span className=\"flex items-center gap-1.5\">\n        <AlertCircle className=\"size-3.5 text-warning\" />\n        /reports and /export endpoints exceed SLA — investigate caching\n      </span>\n    ),\n  },"
        },
        {
          "name": "NoMeanNoOutliers",
          "description": "Minimal horizontal box plot with mean diamonds and outlier dots disabled, showing only the clean five-number summary.",
          "args": "{\n    title: \"Grade Distribution — Minimal View\",\n    subtitle:\n      \"showMean=false · showOutliers=false · clean five-number summary only\",\n    data: gradesBySubject,\n    orientation: \"horizontal\",\n    showGrid: true,\n    showMean: false,\n    showOutliers: false,\n    height: 320,\n  },"
        },
        {
          "name": "NotchedHorizontal",
          "description": "Notched box plots in horizontal orientation combining confidence-interval visualization with publication-style layout.",
          "args": "{\n    title: \"Grade Distribution by Subject — Notched Horizontal\",\n    subtitle:\n      \"Combining notched and horizontal for publication-style comparison\",\n    data: gradesBySubject,\n    orientation: \"horizontal\",\n    notched: true,\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    height: 360,\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Box plot chart with Portuguese locale displaying exam grades by class group with localized number formatting.",
          "args": "{\n    title: \"Final Exam Grades — by Class Group\",\n    subtitle: \"Hover over a box to see the summary\",\n    data: gradesByClass,\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    height: 320,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the box plot with an animated skeleton layout that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Final Exam Grades — by Class Group\",\n    subtitle: \"Hover a box for the five-number summary\",\n    data: gradesByClass,\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    height: 320,\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the chart renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Final Exam Grades — by Class Group\",\n    subtitle: \"Hover a box for the five-number summary\",\n    data: [],\n    height: 320,\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Box plot chart with a custom footer highlighting Class D's low median and prompting intervention analysis.",
          "args": "{\n    title: \"Final Exam Grades — by Class Group\",\n    subtitle: \"Semester 2025.1 · 4 class groups\",\n    data: gradesByClass,\n    showGrid: true,\n    showMean: true,\n    showOutliers: true,\n    height: 320,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingDown className=\"size-3.5 text-destructive\" />\n          Class D median (63) significantly below others — intervention needed\n        </span>\n        <span className=\"text-muted-foreground/70\">n = 120 students</span>\n      </div>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-breadcrumbs",
      "title": "Breadcrumbs",
      "description": "A data-driven breadcrumbs component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/breadcrumbs",
      "dependencies": [],
      "registryDependencies": [
        "breadcrumb"
      ],
      "files": [
        "components/ds/breadcrumbs.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "BreadcrumbItemData[]"
        },
        {
          "name": "separator",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "itemsBeforeEllipsis",
          "required": false,
          "type": "number"
        },
        {
          "name": "itemsAfterEllipsis",
          "required": false,
          "type": "number"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Navigation/Breadcrumbs",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    items: defaultItems,\n  },"
        },
        {
          "name": "WithEllipsis",
          "description": "Automatically collapses items when the list is long.",
          "args": "{\n    items: longItems,\n    itemsBeforeEllipsis: 1,\n    itemsAfterEllipsis: 2,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Automatically collapses items when the list is long.\",\n      },\n    },\n  },"
        },
        {
          "name": "CustomSeparator",
          "description": "Use a custom separator.",
          "args": "{\n    items: defaultItems,\n    separator: <span className=\"text-muted-foreground\">/</span>,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Use a custom separator.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-browser-mockup",
      "title": "BrowserMockup",
      "description": "Moldura simulando janela de navegador ou terminal de sistema operacional para screenshots e previews.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/browser-mockup",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/browser-mockup.tsx"
      ],
      "props": [
        {
          "name": "url",
          "required": false,
          "type": "string"
        },
        {
          "name": "controls",
          "required": false,
          "type": "\"mac\" | \"windows\" | \"none\""
        },
        {
          "name": "showAddressBar",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "glow",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"minimal\" | \"glass\" | \"terminal\"",
          "options": [
            "default",
            "minimal",
            "glass",
            "terminal"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Media/BrowserMockup",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    url: \"https://lema.ufpb.br/dashboard\",\n    glow: true,\n    children: (\n      <div className=\"flex h-64 flex-col items-center justify-center bg-muted/10 p-8 text-center\">\n        <h3 className=\"text-lg font-semibold\">Dashboard de Exemplo</h3>\n        <p className=\"mt-2 max-w-sm text-xs text-muted-foreground\">\n          Insira aqui seus gráficos, capturas de tela ou componentes interativos\n          para a demonstração do produto.\n        </p>\n      </div>\n    ),\n  },"
        },
        {
          "name": "GlassVariant",
          "description": "",
          "code": "<div className=\"rounded-xl bg-gradient-to-br from-primary/10 via-background to-muted/40 p-8\">\n      <BrowserMockup variant=\"glass\" url=\"https://design.lema.ufpb.br\" glow>\n        <div className=\"grid grid-cols-3 gap-4 p-6\">\n          <div className=\"flex h-28 flex-col justify-between rounded-lg border bg-card/80 p-3\">\n            <span className=\"text-xs text-muted-foreground\">\n              Usuários Ativos\n            </span>\n            <span className=\"text-2xl font-bold\">14.820</span>\n          </div>\n          <div className=\"flex h-28 flex-col justify-between rounded-lg border bg-card/80 p-3\">\n            <span className=\"text-xs text-muted-foreground\">Uptime Médio</span>\n            <span className=\"text-2xl font-bold text-success\">99.98%</span>\n          </div>\n          <div className=\"flex h-28 flex-col justify-between rounded-lg border bg-card/80 p-3\">\n            <span className=\"text-xs text-muted-foreground\">\n              Requests / seg\n            </span>\n            <span className=\"text-2xl font-bold\">4.2k</span>\n          </div>\n        </div>\n      </BrowserMockup>\n    </div>"
        },
        {
          "name": "TerminalVariant",
          "description": "",
          "code": "<BrowserMockup variant=\"terminal\" url=\"zsh — lema-ds-cli\">\n      <div className=\"min-h-[160px] space-y-1.5 bg-zinc-950 p-4 font-mono text-xs text-zinc-300\">\n        <p className=\"text-zinc-500\"># Instalando o design system da UFPB...</p>\n        <p>\n          <span className=\"text-emerald-400\">➜</span>{\" \"}\n          <span className=\"text-cyan-400\">~</span> npx shadcn@latest add\n          https://design.lema.ufpb.br/r/ds-hero-section.json\n        </p>\n        <p className=\"text-zinc-400\">✔ Resolvendo dependências...</p>\n        <p className=\"text-zinc-400\">\n          ✔ Componente adicionado com sucesso em\n          components/ui/ds-hero-section.tsx\n        </p>\n        <p className=\"font-semibold text-emerald-400\">\n          Pronto para criar interfaces incríveis! ✨\n        </p>\n      </div>\n    </BrowserMockup>"
        },
        {
          "name": "WindowsControls",
          "description": "",
          "args": "{\n    controls: \"windows\",\n    variant: \"minimal\",\n    url: \"https://intranet.ufpb.br\",\n    children: (\n      <div className=\"p-8 text-center text-xs text-muted-foreground\">\n        Visual minimalista com controles clássicos de janela estilo Windows.\n      </div>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-bullet-chart",
      "description": "Compact bullet chart with qualitative range bands, value bar, and target marker.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/bullet-chart",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "tooltip",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/bullet-chart.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string",
          "description": "Metric label"
        },
        {
          "name": "value",
          "required": true,
          "type": "number",
          "description": "The current measured value"
        },
        {
          "name": "target",
          "required": false,
          "type": "number",
          "description": "The target/goal value — rendered as a vertical tick"
        },
        {
          "name": "ranges",
          "required": false,
          "type": "[number, number, number]",
          "description": "Qualitative range thresholds [poor, ok, good].\nRendered as background bands from low to high risk.\nIf omitted, no range bands are shown."
        },
        {
          "name": "max",
          "required": false,
          "type": "number",
          "description": "Axis maximum — defaults to max(value, target, ranges[-1]) * 1.1"
        },
        {
          "name": "size",
          "required": false,
          "type": "BulletChartSize"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(v: number) => string"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Charts/BulletChart",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    label: \"Revenue\",\n    value: 72000,\n    target: 85000,\n    ranges: [40000, 65000, 85000],\n    max: 100000,\n    format: \"currency\",\n    currency: \"USD\",\n    abbreviate: true,\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{\n    label: \"Metric\",\n    value: 50,\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <BulletChart\n          key={size}\n          label={`Size ${size}`}\n          value={68}\n          target={80}\n          ranges={[30, 60, 80]}\n          max={100}\n          size={size}\n          format=\"percent\"\n          valueFormatter={(v) => `${v}%`}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <BulletChart\n          key={size}\n          label={`Size ${size}`}\n          value={68}\n          target={80}\n          ranges={[30, 60, 80]}\n          max={100}\n          size={size}\n          format=\"percent\"\n          valueFormatter={(v) => `${v}%`}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    label: \"Loading…\",\n    value: 0,\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-3\">\n      {[\"sm\", \"md\", \"lg\"].map((size) => (\n        <BulletChart\n          key={size}\n          label=\"Loading…\"\n          value={0}\n          size={size as \"sm\" | \"md\" | \"lg\"}\n          loading\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-3\">\n      {[\"sm\", \"md\", \"lg\"].map((size) => (\n        <BulletChart\n          key={size}\n          label=\"Loading…\"\n          value={0}\n          size={size as \"sm\" | \"md\" | \"lg\"}\n          loading\n        />\n      ))}\n    </div>"
        },
        {
          "name": "NoRanges",
          "description": "",
          "args": "{\n    label: \"Conversion\",\n    value: 3.2,\n    target: 5,\n    max: 8,\n    valueFormatter: (v) => `${v.toFixed(1)}%`,\n  },"
        },
        {
          "name": "Group",
          "description": "Use `BulletChartGroup` to stack multiple metrics efficiently.",
          "args": "{\n    label: \"Revenue\",\n    value: 72000,\n  },\n  render: () => (\n    <BulletChartGroup\n      items={[\n        {\n          label: \"Revenue\",\n          value: 72000,\n          target: 85000,\n          ranges: [40000, 60000, 80000],\n          max: 100000,\n          format: \"currency\",\n          currency: \"USD\",\n          abbreviate: true,\n        },\n        {\n          label: \"Deals Closed\",\n          value: 42,\n          target: 50,\n          ranges: [20, 35, 50],\n          max: 60,\n          format: \"integer\",\n        },\n        {\n          label: \"NPS Score\",\n          value: 67,\n          target: 75,\n          ranges: [30, 55, 75],\n          max: 100,\n          format: \"integer\",\n        },\n        {\n          label: \"Churn Rate\",\n          value: 3.1,\n          target: 2.5,\n          max: 10,\n          valueFormatter: (v) => `${v.toFixed(1)}%`,\n        },\n      ]}\n    />\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story: \"Use `BulletChartGroup` to stack multiple metrics efficiently.\",\n      },\n    },\n  },",
          "code": "<BulletChartGroup\n      items={[\n        {\n          label: \"Revenue\",\n          value: 72000,\n          target: 85000,\n          ranges: [40000, 60000, 80000],\n          max: 100000,\n          format: \"currency\",\n          currency: \"USD\",\n          abbreviate: true,\n        },\n        {\n          label: \"Deals Closed\",\n          value: 42,\n          target: 50,\n          ranges: [20, 35, 50],\n          max: 60,\n          format: \"integer\",\n        },\n        {\n          label: \"NPS Score\",\n          value: 67,\n          target: 75,\n          ranges: [30, 55, 75],\n          max: 100,\n          format: \"integer\",\n        },\n        {\n          label: \"Churn Rate\",\n          value: 3.1,\n          target: 2.5,\n          max: 10,\n          valueFormatter: (v) => `${v.toFixed(1)}%`,\n        },\n      ]}\n    />"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{\n    label: \"Locales\",\n    value: 72000,\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <BulletChart\n          key={locale}\n          label={locale}\n          value={72000}\n          target={85000}\n          ranges={[40000, 60000, 80000]}\n          max={100000}\n          format=\"currency\"\n          currency=\"USD\"\n          abbreviate\n          locale={locale}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <BulletChart\n          key={locale}\n          label={locale}\n          value={72000}\n          target={85000}\n          ranges={[40000, 60000, 80000]}\n          max={100000}\n          format=\"currency\"\n          currency=\"USD\"\n          abbreviate\n          locale={locale}\n        />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-button",
      "title": "Button UI",
      "description": "Feature-rich button with loading state, start/end icons, rounded variant (full/lg/md/none), fullWidth, double-click debounce, two-step destructive confirmation, and built-in tooltip via Radix. Wraps the shadcn Button primitive.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/button",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "tooltip"
      ],
      "files": [
        "components/ds/button.tsx"
      ],
      "props": [
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Shows a spinner and disables the button."
        },
        {
          "name": "loadingText",
          "required": false,
          "type": "string",
          "description": "Text shown next to the spinner during loading. Defaults to children."
        },
        {
          "name": "startIcon",
          "required": false,
          "type": "React.ReactNode",
          "description": "Icon rendered before the button text."
        },
        {
          "name": "endIcon",
          "required": false,
          "type": "React.ReactNode",
          "description": "Icon rendered after the button text."
        },
        {
          "name": "rounded",
          "required": false,
          "type": "\"full\" | \"lg\" | \"md\" | \"none\"",
          "description": "Border radius. @default \"md\""
        },
        {
          "name": "fullWidth",
          "required": false,
          "type": "boolean",
          "description": "Makes the button span the full width of its container."
        },
        {
          "name": "debounceMs",
          "required": false,
          "type": "number",
          "description": "Minimum interval (ms) between clicks — prevents accidental double-submits."
        },
        {
          "name": "confirm",
          "required": false,
          "type": "{ text: string; duration?: number }",
          "description": "Two-step confirmation. First click shows `text`, second click fires `onClick`."
        },
        {
          "name": "tooltip",
          "required": false,
          "type": "string | { text: string; side?: \"top\" | \"right\" | \"bottom\" | \"left\" }",
          "description": "Shows a tooltip on hover. Pass a string or `{ text, side }`."
        }
      ],
      "storyTitle": "Actions/Button",
      "stories": [
        {
          "name": "Default",
          "description": "Default button with the primary variant.",
          "args": "{\n    children: \"Button\",\n    variant: \"default\",\n    loading: false,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Default button with the primary variant.\",\n      },\n    },\n  },"
        },
        {
          "name": "Variants",
          "description": "All six inherited variants rendered side by side.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Button variant=\"default\">Default</Button>\n      <Button variant=\"secondary\">Secondary</Button>\n      <Button variant=\"outline\">Outline</Button>\n      <Button variant=\"ghost\">Ghost</Button>\n      <Button variant=\"destructive\">Destructive</Button>\n      <Button variant=\"link\">Link</Button>\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "All size presets from xs to lg.",
          "code": "<div className=\"flex flex-wrap items-end gap-4\">\n      <Button size=\"xs\">XS</Button>\n      <Button size=\"sm\">SM</Button>\n      <Button size=\"default\">Default</Button>\n      <Button size=\"lg\">LG</Button>\n    </div>"
        },
        {
          "name": "Loading",
          "description": "`loading=true` replaces the content with a `Loader2` spinner. \nThe button is disabled and `aria-busy` is set.\n\nPass `loadingText` to show custom text alongside the spinner.",
          "code": "<div className=\"flex flex-wrap items-center gap-4\">\n      <Button loading>Default</Button>\n      <Button loading variant=\"secondary\">\n        Secondary\n      </Button>\n      <Button loading variant=\"destructive\">\n        Delete\n      </Button>\n      <Button loading variant=\"outline\" loadingText=\"Saving…\">\n        Save\n      </Button>\n      <Button loading variant=\"ghost\" loadingText=\"Please wait…\">\n        Connect\n      </Button>\n    </div>"
        },
        {
          "name": "WithIcons",
          "description": "Use `startIcon` and `endIcon` to add icons before or after the label.",
          "code": "<div className=\"flex flex-wrap items-center gap-4\">\n      <Button startIcon={<Mail />}>Email</Button>\n      <Button endIcon={<ChevronRight />}>Next</Button>\n      <Button startIcon={<Download />} variant=\"secondary\">\n        Download\n      </Button>\n      <Button startIcon={<UserPlus />} endIcon={<ChevronRight />}>\n        Invite\n      </Button>\n      <Button\n        startIcon={<Send />}\n        variant=\"outline\"\n        loading\n        loadingText=\"Sending…\"\n      >\n        Send\n      </Button>\n    </div>"
        },
        {
          "name": "Rounded",
          "description": "Four border-radius presets: `full` (pill, default), `lg`, `md`, and `none`.\n\nThis is especially useful when embedding buttons inside cards or dialogs that already have their own border radius.",
          "code": "<div className=\"flex flex-wrap items-center gap-4\">\n      <Button rounded=\"full\">Full</Button>\n      <Button rounded=\"lg\">LG</Button>\n      <Button rounded=\"md\">MD</Button>\n      <Button rounded=\"none\">None</Button>\n    </div>"
        },
        {
          "name": "FullWidth",
          "description": "`fullWidth` makes the button span 100% of its container.\nUseful for mobile layouts, sidebars, and call-to-action sections.",
          "code": "<div className=\"flex max-w-sm flex-col gap-3\">\n      <Button fullWidth>Full-width button</Button>\n      <Button fullWidth variant=\"secondary\">\n        Secondary action\n      </Button>\n      <Button fullWidth variant=\"outline\" rounded=\"md\">\n        Outline with rounded=&quot;md&quot;\n      </Button>\n    </div>"
        },
        {
          "name": "ConfirmMode",
          "description": "Two-step confirmation for destructive actions.\n\n**1st click** — the label changes to the `confirm.text`.\n**2nd click** — within the duration window, fires `onClick`.\n\nIf the user does not click again within the duration (default 3s), the button resets. \nDuring confirming state, the button is not disabled — the user can still click to confirm.",
          "args": "{ children: \"Delete item\", variant: \"destructive\" },\n  render: (args) => {\n    const [deleted, setDeleted] = React.useState(false)\n\n    if (deleted) {\n      return (\n        <div className=\"flex flex-col gap-3\">\n          <p className=\"text-sm text-muted-foreground\">Item deleted.</p>\n          <Button variant=\"outline\" size=\"sm\" onClick={() => setDeleted(false)}>\n            Reset\n          </Button>\n        </div>\n      )\n    }\n\n    return (\n      <Button\n        {...args}\n        confirm={{ text: \"Click again to confirm\", duration: 4000 }}\n        startIcon={<Trash2 />}\n        onClick={() => {\n          setDeleted(true)\n        }}\n        onMouseEnter={() => setDeleted(false)}\n      />\n    )\n  },"
        },
        {
          "name": "ConfirmModeControlled",
          "description": "A controlled variant: if the user hovers away from the button while in confirming state, \nthe confirmation resets. This prevents accidental confirmations when the user moves the mouse away.\n\nThe internal `confirm` mechanism fires `onClick` on the second click; \nyou can attach `onMouseLeave` or `onPointerLeave` to call `onCancel` yourself.",
          "args": "{\n    children: \"Delete record\",\n    variant: \"destructive\",\n    startIcon: <Trash2 />,\n    confirm: { text: \"Sure?\", duration: 5000 },\n  },"
        },
        {
          "name": "Debounced",
          "description": "`debounceMs={1000}` prevents the `onClick` from firing more than once per second. \nClick rapidly — only every other second the counter increments.\n\nUseful for payment forms, API submissions, and any action that should never double-fire.",
          "code": "<div className=\"flex items-center gap-4\">\n        <Button\n          debounceMs={1000}\n          variant=\"destructive\"\n          onClick={() => setCount((c) => c + 1)}\n        >\n          Click me fast\n        </Button>\n        <span className=\"text-sm text-muted-foreground\">\n          Clicks: <strong className=\"text-foreground\">{count}</strong> (max 1/s)\n        </span>\n      </div>"
        },
        {
          "name": "Tooltip",
          "description": "Add a `tooltip` prop to show a tooltip on hover. \nAccepts a plain string or `{ text, side }` to control placement.",
          "code": "<div className=\"flex flex-wrap items-center gap-6\">\n      <Button tooltip=\"Simple tooltip\" startIcon={<Download />}>\n        Download\n      </Button>\n      <Button\n        tooltip={{ text: \"This might take a moment\", side: \"top\" }}\n        variant=\"secondary\"\n        loading\n      >\n        Processing\n      </Button>\n      <Button\n        tooltip={{ text: \"Destructive action\", side: \"right\" }}\n        variant=\"destructive\"\n        aria-label=\"Delete\"\n      >\n        <Trash2 className=\"size-4\" />\n      </Button>\n      <Button\n        tooltip={{ text: \"Send email\", side: \"left\" }}\n        startIcon={<Mail />}\n        variant=\"outline\"\n      >\n        Email\n      </Button>\n    </div>"
        },
        {
          "name": "KitchenSink",
          "description": "All features combined: loading, icons, custom rounded, tooltip, and fullWidth in a single button.",
          "args": "{\n    children: \"Publish changes\",\n    variant: \"default\",\n    size: \"lg\",\n    fullWidth: false,\n    rounded: \"md\",\n    startIcon: <Send />,\n    tooltip: \"Deploy to production\",\n    loading: false,\n  },\n  render: (args) => {\n    const [loading, setLoading] = React.useState(false)\n    return (\n      <div className=\"flex max-w-xs flex-col gap-3\">\n        <Button\n          {...args}\n          loading={loading}\n          onClick={() => {\n            setLoading(true)\n            setTimeout(() => setLoading(false), 2500)\n          }}\n        />\n        <p className=\"text-xs text-muted-foreground\">\n          Click to simulate a 2.5s async operation.\n        </p>\n      </div>\n    )\n  },"
        }
      ]
    },
    {
      "name": "ds-callout",
      "title": "Callout",
      "description": "A highlighted alert component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/callout",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "alert"
      ],
      "files": [
        "components/ds/callout.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"info\" | \"success\" | \"warning\" | \"destructive\"",
          "options": [
            "default",
            "info",
            "success",
            "warning",
            "destructive"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Data Display/Callout",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Info",
          "description": "",
          "args": "{\n    variant: \"info\",\n    title: \"Did you know?\",\n    children: \"You can use keyboard shortcuts to navigate faster.\",\n  },"
        },
        {
          "name": "Success",
          "description": "",
          "args": "{\n    variant: \"success\",\n    title: \"Payment successful\",\n    children: \"Your subscription has been renewed for another year.\",\n  },"
        },
        {
          "name": "Warning",
          "description": "",
          "args": "{\n    variant: \"warning\",\n    title: \"Storage almost full\",\n    children: \"You have used 90% of your allocated storage space.\",\n  },"
        },
        {
          "name": "Destructive",
          "description": "",
          "args": "{\n    variant: \"destructive\",\n    title: \"Error connecting to server\",\n    children: \"Please check your internet connection and try again.\",\n  },"
        },
        {
          "name": "CustomIcon",
          "description": "",
          "args": "{\n    variant: \"info\",\n    title: \"New Feature\",\n    icon: <RocketIcon className=\"size-4\" />,\n    children: \"We just launched our new API dashboard.\",\n  },"
        }
      ]
    },
    {
      "name": "ds-candlestick-chart",
      "title": "Candlestick Chart",
      "description": "A financial candlestick chart with volume bars, moving averages, reference lines, and brush zoom.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/candlestick-chart",
      "dependencies": [
        "recharts",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils",
        "chart-axis-width"
      ],
      "files": [
        "components/ds/candlestick-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "CandleDataPoint[]"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "positiveColor",
          "required": false,
          "type": "string",
          "description": "Color for bullish candles (close ≥ open). Default: green."
        },
        {
          "name": "negativeColor",
          "required": false,
          "type": "string",
          "description": "Color for bearish candles (close < open). Default: red."
        },
        {
          "name": "movingAverages",
          "required": false,
          "type": "MovingAverageConfig[]",
          "description": "Compute and overlay simple moving average lines"
        },
        {
          "name": "referenceLines",
          "required": false,
          "type": "CandlestickReferenceLine[]",
          "description": "Horizontal price reference lines — targets, support/resistance levels"
        },
        {
          "name": "showVolume",
          "required": false,
          "type": "boolean",
          "description": "Render volume bars in the lower section of the chart"
        },
        {
          "name": "showGrid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showLegend",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "legendPosition",
          "required": false,
          "type": "LegendPosition",
          "description": "@default \"bottom\""
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showBrush",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Format price values (Y axis ticks + tooltip)"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "dateFormatter",
          "required": false,
          "type": "(date: string) => string",
          "description": "Format date strings (X axis ticks + tooltip header)"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/CandlestickChart",
      "stories": [
        {
          "name": "Default",
          "description": "Default OHLC candlestick chart showing equity price action with hollow bullish and filled bearish candles.",
          "args": "{\n    title: \"Equity Price — OHLC\",\n    subtitle: \"January 2025 · hollow = bullish · filled = bearish\",\n    data: equityData,\n    positiveColor: \"#22c55e\",\n    negativeColor: \"#ef4444\",\n    showVolume: false,\n    showGrid: true,\n    showLegend: false,\n    legendPosition: \"bottom\",\n    showTooltip: true,\n    showBrush: false,\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n    height: 340,\n  },"
        },
        {
          "name": "WithVolume",
          "description": "Candlestick chart with color-coded volume bars in the lower section — green for bullish sessions, red for bearish.",
          "args": "{\n    title: \"Equity Price with Volume\",\n    subtitle:\n      \"Volume bars in the lower section — green = bullish session · red = bearish\",\n    data: equityData,\n    showVolume: true,\n    showGrid: true,\n    showTooltip: true,\n    height: 360,\n  },"
        },
        {
          "name": "WithMovingAverages",
          "description": "Candlestick chart overlaying MA 7 and MA 14 lines with a dashed style for the longer period and a legend.",
          "args": "{\n    title: \"Equity Price — MA 7 & MA 14\",\n    subtitle: \"Hover a candle to see MA values at that date\",\n    data: equityData,\n    movingAverages: [\n      { period: 7, label: \"MA 7\", color: \"var(--chart-1)\" },\n      { period: 14, label: \"MA 14\", color: \"var(--chart-3)\", dashed: true },\n    ],\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 360,\n  },"
        },
        {
          "name": "FullFeatured",
          "description": "Full-featured candlestick view combining volume bars, MA 7 and MA 20 lines, and support and resistance reference lines.",
          "args": "{\n    title: \"Equity Price — Full Feature View\",\n    subtitle: \"Volume · MA 7 · MA 20 · support and resistance reference lines\",\n    data: equityData,\n    showVolume: true,\n    movingAverages: [\n      { period: 7, label: \"MA 7\", color: \"var(--chart-1)\" },\n      { period: 20, label: \"MA 20\", color: \"var(--chart-3)\", dashed: true },\n    ],\n    referenceLines: [\n      { value: 155, label: \"Support\", color: \"var(--chart-2)\", dashed: true },\n      {\n        value: 170,\n        label: \"Target\",\n        color: \"var(--destructive)\",\n        dashed: false,\n      },\n    ],\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 400,\n  },"
        },
        {
          "name": "CryptoVolatility",
          "description": "BTC/USD candlestick chart showing high-volatility sessions with large wicks, volume confirmation, and a USD value formatter.",
          "args": "{\n    title: \"BTC/USD — High-Volatility Session\",\n    subtitle: \"Large wicks signal indecision — volume confirms breakout\",\n    data: cryptoData,\n    showVolume: true,\n    movingAverages: [{ period: 5, label: \"MA 5\", color: \"var(--chart-1)\" }],\n    showGrid: true,\n    showTooltip: true,\n    height: 360,\n    valueFormatter: (v) =>\n      formatValue(v, \"currency\", {\n        currency: \"USD\",\n        abbreviate: true,\n        decimals: 0,\n      }),\n  },"
        },
        {
          "name": "BearishTrend",
          "description": "Bearish breakdown candlestick chart with increasing volume confirmation, a support reference line, and a footer analyzing the price action.",
          "args": "{\n    title: \"Equity Price — Bearish Breakdown\",\n    subtitle: \"Downtrend confirmed by increasing volume on down days\",\n    data: bearishData,\n    showVolume: true,\n    movingAverages: [{ period: 5, label: \"MA 5\", color: \"var(--chart-1)\" }],\n    referenceLines: [\n      { value: 250, label: \"Support\", color: \"var(--chart-2)\", dashed: true },\n    ],\n    showGrid: true,\n    showTooltip: true,\n    height: 360,\n    footer: (\n      <span className=\"flex items-center gap-1.5\">\n        <TrendingDown className=\"size-3.5 text-destructive\" />\n        Price broke 250 support on Mar 11 — high volume confirms distribution\n      </span>\n    ),\n  },"
        },
        {
          "name": "WithReferenceLines",
          "description": "Candlestick chart with three reference lines marking support, mid target, and resistance levels at key price points.",
          "args": "{\n    title: \"Equity Price — Support & Resistance\",\n    subtitle: \"Reference lines highlight key price levels to watch\",\n    data: equityData,\n    referenceLines: [\n      { value: 150, label: \"Support\", color: \"var(--chart-2)\", dashed: true },\n      {\n        value: 165,\n        label: \"Mid target\",\n        color: \"var(--chart-3)\",\n        dashed: true,\n      },\n      {\n        value: 175,\n        label: \"Resistance\",\n        color: \"var(--destructive)\",\n        dashed: false,\n      },\n    ],\n    showGrid: true,\n    showTooltip: true,\n    height: 360,\n  },"
        },
        {
          "name": "WithBrush",
          "description": "60-day candlestick chart with a brush slider for interactive zoom and pan across a long price series with moving averages.",
          "args": "{\n    title: \"60-Day Chart — Drag to Zoom\",\n    subtitle:\n      \"Drag the handles below to focus on any window · drag the bar to pan\",\n    data: longSeries,\n    showVolume: true,\n    movingAverages: [\n      { period: 10, label: \"MA 10\", color: \"var(--chart-1)\" },\n      { period: 20, label: \"MA 20\", color: \"var(--chart-3)\", dashed: true },\n    ],\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    showBrush: true,\n    height: 420,\n  },"
        },
        {
          "name": "LegendPositions",
          "description": "Grid of four candlestick charts demonstrating all four legend positions with MA 5 lines and the first ten trading sessions.",
          "args": "{ data: equityData },",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <CandlestickChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={equityData.slice(0, 10)}\n          movingAverages={[\n            { period: 5, label: \"MA 5\", color: \"var(--chart-1)\" },\n          ]}\n          showLegend\n          legendPosition={pos}\n          showGrid\n          showTooltip\n          height={260}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "LocalePTBR",
          "description": "Candlestick chart with Portuguese locale displaying equity OHLC data with localized date and number formatting.",
          "args": "{\n    title: \"Equity Price — OHLC\",\n    subtitle: \"January 2025 · hollow = bullish · filled = bearish\",\n    data: equityData,\n    showGrid: true,\n    showTooltip: true,\n    height: 340,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the candlestick chart with an animated skeleton that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Equity Price — OHLC\",\n    subtitle: \"January 2025 · hollow = bullish · filled = bearish\",\n    data: equityData,\n    showGrid: true,\n    showTooltip: true,\n    height: 340,\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the chart renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Equity Price — OHLC\",\n    subtitle: \"January 2025\",\n    data: [],\n    height: 340,\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Candlestick chart with volume, moving averages, and a footer summarizing the period return and key pullback events.",
          "args": "{\n    title: \"Equity Price — January 2025\",\n    subtitle: \"20 trading sessions · OHLC + volume\",\n    data: equityData,\n    showVolume: true,\n    movingAverages: [\n      { period: 7, label: \"MA 7\", color: \"var(--chart-1)\" },\n      { period: 14, label: \"MA 14\", color: \"var(--chart-3)\", dashed: true },\n    ],\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 380,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-success\" />\n          +16.3% from open (148.20) to close (173.10)\n        </span>\n        <span className=\"flex items-center gap-1.5 text-muted-foreground/70\">\n          <AlertCircle className=\"size-3\" />\n          Jan 6–7: pullback after initial rally\n        </span>\n      </div>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-card-icon",
      "title": "Card Icon",
      "description": "Feature / navigation card with a tinted icon medallion, title and description. Icon colour and background derive from a single semantic tone token. Supports soft/solid/outline media styles, three sizes, centred or left alignment, badge, link mode with hover lift, and a loading skeleton.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-icon",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card",
        "badge",
        "skeleton"
      ],
      "files": [
        "components/ds/card-icon.tsx"
      ],
      "props": [
        {
          "name": "icon",
          "required": true,
          "type": "React.ElementType",
          "description": "Icon component (e.g. a lucide icon). Rendered inside the media circle."
        },
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "tone",
          "required": false,
          "type": "CardIconTone",
          "description": "Semantic colour applied to both the icon and its background."
        },
        {
          "name": "mediaStyle",
          "required": false,
          "type": "CardIconMediaStyle",
          "description": "How the media circle is painted from the tone token."
        },
        {
          "name": "size",
          "required": false,
          "type": "CardIconSize"
        },
        {
          "name": "titleUpper",
          "required": false,
          "type": "boolean",
          "description": "Uppercase + tracked title, matching the dashboard hero style."
        },
        {
          "name": "badge",
          "required": false,
          "type": "string",
          "description": "Optional badge shown above the title."
        },
        {
          "name": "href",
          "required": false,
          "type": "string",
          "description": "Renders the whole card as a link with a hover lift."
        },
        {
          "name": "rel",
          "required": false,
          "type": "string"
        },
        {
          "name": "target",
          "required": false,
          "type": "string"
        },
        {
          "name": "actionLabel",
          "required": false,
          "type": "string",
          "description": "Optional call-to-action row shown at the bottom (interactive cards)."
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Data Display/CardIcon",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    tone: \"primary\",\n    mediaStyle: \"soft\",\n    size: \"sm\",\n    align: \"center\",\n    titleUpper: false,\n  },\n  render: (args) => (\n    <div className=\"max-w-sm\">\n      <CardIcon {...args} />\n    </div>\n  ),"
        },
        {
          "name": "Tones",
          "description": "",
          "code": "<div className=\"grid max-w-4xl grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n      <CardIcon\n        icon={LeafIcon}\n        tone=\"success\"\n        title=\"Sustainability\"\n        description=\"Environmental indicators and impact reduction targets.\"\n      />\n      <CardIcon\n        icon={TargetIcon}\n        tone=\"warning\"\n        title=\"Goals at risk\"\n        description=\"Targets requiring attention in the current cycle.\"\n      />\n      <CardIcon\n        icon={ShieldCheckIcon}\n        tone=\"destructive\"\n        title=\"Compliance\"\n        description=\"Critical requirements pending verification.\"\n      />\n      <CardIcon\n        icon={BarChart3Icon}\n        tone=\"primary\"\n        title=\"Performance\"\n        description=\"Consolidated evolution of key indicators.\"\n      />\n      <CardIcon\n        icon={GlobeIcon}\n        tone=\"sky\"\n        title=\"Territorial coverage\"\n        description=\"Data distribution by municipality and region.\"\n      />\n      <CardIcon\n        icon={HeartHandshakeIcon}\n        tone=\"violet\"\n        title=\"Partnerships\"\n        description=\"Active institutional liaisons within the program.\"\n      />\n    </div>"
        },
        {
          "name": "MediaStyles",
          "description": "",
          "code": "<div className=\"grid max-w-3xl grid-cols-1 gap-4 sm:grid-cols-3\">\n      <CardIcon\n        icon={ZapIcon}\n        tone=\"primary\"\n        mediaStyle=\"soft\"\n        title=\"Soft\"\n        description=\"Tinted token at 10%.\"\n      />\n      <CardIcon\n        icon={ZapIcon}\n        tone=\"primary\"\n        mediaStyle=\"solid\"\n        title=\"Solid\"\n        description=\"Solid fill with foreground.\"\n      />\n      <CardIcon\n        icon={ZapIcon}\n        tone=\"primary\"\n        mediaStyle=\"outline\"\n        title=\"Outline\"\n        description=\"Outline in the token colour.\"\n      />\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "",
          "code": "<div className=\"grid max-w-4xl grid-cols-1 items-start gap-4 sm:grid-cols-3\">\n      <CardIcon\n        icon={CompassIcon}\n        tone=\"sky\"\n        size=\"sm\"\n        title=\"Small\"\n        description=\"Compact scale for dense grids.\"\n      />\n      <CardIcon\n        icon={CompassIcon}\n        tone=\"sky\"\n        size=\"md\"\n        title=\"Medium\"\n        description=\"Standard size for most use cases.\"\n      />\n      <CardIcon\n        icon={CompassIcon}\n        tone=\"sky\"\n        size=\"lg\"\n        title=\"Large\"\n        description=\"Highlight in opening sections.\"\n      />\n    </div>"
        },
        {
          "name": "AlignStart",
          "description": "",
          "args": "{\n    align: \"start\",\n    titleUpper: false,\n    tone: \"primary\",\n    icon: BarChart3Icon,\n    title: \"Analytical reports\",\n    description: \"Export and share dashboards with the team.\",\n  },\n  render: (args) => (\n    <div className=\"max-w-sm\">\n      <CardIcon {...args} />\n    </div>\n  ),"
        },
        {
          "name": "AsLink",
          "description": "",
          "args": "{\n    href: \"#indicadores\",\n    tone: \"violet\",\n    titleUpper: false,\n    icon: TargetIcon,\n    title: \"Explore indicators\",\n    description: \"Browse the 17 goals and their targets.\",\n    actionLabel: \"Access\",\n  },\n  render: (args) => (\n    <div className=\"max-w-sm\">\n      <CardIcon {...args} />\n    </div>\n  ),"
        },
        {
          "name": "WithBadge",
          "description": "",
          "args": "{\n    badge: \"New\",\n    tone: \"success\",\n    titleUpper: false,\n    icon: LeafIcon,\n    title: \"Impact dashboard\",\n    description: \"Track environmental results in real time.\",\n  },\n  render: (args) => (\n    <div className=\"max-w-sm\">\n      <CardIcon {...args} />\n    </div>\n  ),"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },\n  render: (args) => (\n    <div className=\"max-w-sm\">\n      <CardIcon {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-card-stat",
      "title": "Card Stat",
      "description": "A statistical display card with label, value, trend indicator, optional icon, and loading skeleton.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/card-stat.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "string | number"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "locale",
          "required": false,
          "type": "string"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "trend",
          "required": false,
          "type": "CardStatTrend | boolean"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\" | \"flat\""
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number | string) => string"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "valueClassName",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Data Display/CardStat",
      "stories": [
        {
          "name": "Default",
          "description": "Standard configuration showing the CardStat component with revenue data, currency formatting, up trend, and a description.",
          "args": "{\n    label: \"Revenue\",\n    value: 45231.89,\n    format: \"currency\",\n    decimals: 2,\n    locale: \"en-US\",\n    currency: \"USD\",\n    abbreviate: false,\n    description: \"+20.1% from last month\",\n    trend: \"up\",\n    icon: DollarSignIcon,\n    size: \"sm\",\n    variant: \"default\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard configuration showing the CardStat component with revenue data, currency formatting, up trend, and a description.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying four placeholder CardStat cards while data is being fetched.",
          "args": "{\n    label: \"Revenue\",\n    value: 0,\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying four placeholder CardStat cards while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat label=\"Revenue\" value={0} loading />\n      <CardStat label=\"Active Users\" value={0} loading />\n      <CardStat label=\"Bounce Rate\" value={0} loading />\n      <CardStat label=\"Avg. Response\" value={0} loading />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat label=\"Revenue\" value={0} loading />\n      <CardStat label=\"Active Users\" value={0} loading />\n      <CardStat label=\"Bounce Rate\" value={0} loading />\n      <CardStat label=\"Avg. Response\" value={0} loading />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing four CardStat cards with dash placeholders when no data is available.",
          "args": "{\n    label: \"Revenue\",\n    value: 0,\n    empty: true,\n    icon: DollarSignIcon,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing four CardStat cards with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat label=\"Revenue\" value={0} empty icon={DollarSignIcon} />\n      <CardStat label=\"Active Users\" value={0} empty icon={UsersIcon} />\n      <CardStat label=\"Bounce Rate\" value={0} empty />\n      <CardStat label=\"Avg. Response\" value={0} empty />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat label=\"Revenue\" value={0} empty icon={DollarSignIcon} />\n      <CardStat label=\"Active Users\" value={0} empty icon={UsersIcon} />\n      <CardStat label=\"Bounce Rate\" value={0} empty />\n      <CardStat label=\"Avg. Response\" value={0} empty />\n    </div>"
        },
        {
          "name": "Locales",
          "description": "Demonstrates locale-aware formatting with Brazilian Portuguese (pt-BR), German (de-DE), and English (en-US) locales.",
          "args": "{\n    label: \"Revenue\",\n    value: 0,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates locale-aware formatting with Brazilian Portuguese (pt-BR), German (de-DE), and English (en-US) locales.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      <CardStat\n        label=\"Total Revenue\"\n        value={98400}\n        format=\"currency\"\n        locale=\"pt-BR\"\n        currency=\"BRL\"\n        description=\"+12.3% vs last month\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        label=\"Umsatz\"\n        value={34290}\n        format=\"currency\"\n        locale=\"de-DE\"\n        currency=\"EUR\"\n        description=\"+8,7% gegenüber Vormonat\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        label=\"Avg. Ticket\"\n        value={89.4}\n        format=\"float\"\n        decimals={2}\n        description=\"+$3.20 vs last month\"\n        trend=\"up\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      <CardStat\n        label=\"Total Revenue\"\n        value={98400}\n        format=\"currency\"\n        locale=\"pt-BR\"\n        currency=\"BRL\"\n        description=\"+12.3% vs last month\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        label=\"Umsatz\"\n        value={34290}\n        format=\"currency\"\n        locale=\"de-DE\"\n        currency=\"EUR\"\n        description=\"+8,7% gegenüber Vormonat\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        label=\"Avg. Ticket\"\n        value={89.4}\n        format=\"float\"\n        decimals={2}\n        description=\"+$3.20 vs last month\"\n        trend=\"up\"\n      />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStat component.",
          "args": "{ label: \"Revenue\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStat component.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <CardStat\n            label=\"Total Revenue\"\n            value={45231.89}\n            format=\"currency\"\n            description=\"+20.1% from last month\"\n            trend=\"up\"\n            icon={DollarSignIcon}\n            size={size}\n          />\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <CardStat\n            label=\"Total Revenue\"\n            value={45231.89}\n            format=\"currency\"\n            description=\"+20.1% from last month\"\n            trend=\"up\"\n            icon={DollarSignIcon}\n            size={size}\n          />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "ValueClassName",
          "description": "Use `valueClassName` to apply semantic color tokens directly to the value.\nCommon use case: highlight a KPI in `text-destructive` (red) or `text-success` (green) when it represents a negative or positive threshold.\n\n```tsx\nDelayed Orders\ntext-destructive\nRecovered\ntext-success\n```",
          "args": "{\n    label: \"Delayed Orders\",\n    value: 748,\n    format: \"integer\",\n    description: \"15.02% delay rate\",\n    icon: TrendingUpIcon,\n    valueClassName: \"text-destructive\",\n    size: \"sm\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          \"Use `valueClassName` to apply semantic color tokens directly to the value.\",\n          \"Common use case: highlight a KPI in `text-destructive` (red) or `text-success` (green) when it represents a negative or positive threshold.\",\n          \"\",\n          \"```tsx\",\n          '<CardStat label=\"Delayed Orders\" value={748} valueClassName=\"text-destructive\" />',\n          '<CardStat label=\"Recovered\" value={1204} valueClassName=\"text-success\" />',\n          \"```\",\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      <CardStat\n        label=\"Delayed Orders\"\n        value={748}\n        format=\"integer\"\n        description=\"15.02% delay rate\"\n        icon={TrendingUpIcon}\n        size=\"sm\"\n        valueClassName=\"text-destructive\"\n      />\n      <CardStat\n        label=\"Recovered Revenue\"\n        value={204941}\n        format=\"integer\"\n        description=\"above monthly target\"\n        icon={DollarSignIcon}\n        size=\"sm\"\n        valueClassName=\"text-success\"\n      />\n      <CardStat\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"no change this week\"\n        icon={UsersIcon}\n        size=\"sm\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      <CardStat\n        label=\"Delayed Orders\"\n        value={748}\n        format=\"integer\"\n        description=\"15.02% delay rate\"\n        icon={TrendingUpIcon}\n        size=\"sm\"\n        valueClassName=\"text-destructive\"\n      />\n      <CardStat\n        label=\"Recovered Revenue\"\n        value={204941}\n        format=\"integer\"\n        description=\"above monthly target\"\n        icon={DollarSignIcon}\n        size=\"sm\"\n        valueClassName=\"text-success\"\n      />\n      <CardStat\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"no change this week\"\n        icon={UsersIcon}\n        size=\"sm\"\n      />\n    </div>"
        },
        {
          "name": "Abbreviated",
          "description": "Set `abbreviate` to shorten large numbers with locale-aware suffixes.\nEnglish uses T/B/M/K; Portuguese uses tri/bi/mi/mil.\n\n```tsx\nMarket Cap\ncurrency\nen-US\nUSD\nValor de Mercado\ncurrency\npt-BR\nBRL\n```",
          "args": "{ label: \"Revenue\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          \"Set `abbreviate` to shorten large numbers with locale-aware suffixes.\",\n          \"English uses T/B/M/K; Portuguese uses tri/bi/mi/mil.\",\n          \"\",\n          \"```tsx\",\n          '<CardStat label=\"Market Cap\" value={1570000000} format=\"currency\" abbreviate locale=\"en-US\" currency=\"USD\" />',\n          '<CardStat label=\"Valor de Mercado\" value={1570000000} format=\"currency\" abbreviate locale=\"pt-BR\" currency=\"BRL\" />',\n          \"```\",\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        label=\"Market Cap\"\n        value={1570000000}\n        format=\"currency\"\n        abbreviate\n        locale=\"en-US\"\n        currency=\"USD\"\n        icon={DollarSignIcon}\n        description=\"+12.4% this quarter\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Market Cap\"\n        value={1570000000}\n        format=\"currency\"\n        abbreviate\n        locale=\"pt-BR\"\n        currency=\"BRL\"\n        icon={DollarSignIcon}\n        description=\"+12.4% this quarter\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Total Users\"\n        value={2847500}\n        format=\"integer\"\n        abbreviate\n        locale=\"en-US\"\n        icon={UsersIcon}\n        description=\"+843K new this month\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Total Users\"\n        value={2847500}\n        format=\"integer\"\n        abbreviate\n        locale=\"pt-BR\"\n        icon={UsersIcon}\n        description=\"+843K new this month\"\n        trend=\"up\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        label=\"Market Cap\"\n        value={1570000000}\n        format=\"currency\"\n        abbreviate\n        locale=\"en-US\"\n        currency=\"USD\"\n        icon={DollarSignIcon}\n        description=\"+12.4% this quarter\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Market Cap\"\n        value={1570000000}\n        format=\"currency\"\n        abbreviate\n        locale=\"pt-BR\"\n        currency=\"BRL\"\n        icon={DollarSignIcon}\n        description=\"+12.4% this quarter\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Total Users\"\n        value={2847500}\n        format=\"integer\"\n        abbreviate\n        locale=\"en-US\"\n        icon={UsersIcon}\n        description=\"+843K new this month\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Total Users\"\n        value={2847500}\n        format=\"integer\"\n        abbreviate\n        locale=\"pt-BR\"\n        icon={UsersIcon}\n        description=\"+843K new this month\"\n        trend=\"up\"\n      />\n    </div>"
        },
        {
          "name": "AbbreviatedCompact",
          "description": "Dense grid demonstrating abbreviation across different orders of magnitude — thousands, millions, billions, trillions.\nen-US",
          "args": "{ label: \"Label\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          \"Dense grid demonstrating abbreviation across different orders of magnitude — thousands, millions, billions, trillions.\",\n          'All cards use `locale=\"en-US\"` with `abbreviate` and format-specific formatting.',\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        label=\"Total Revenue\"\n        value={45231890}\n        format=\"currency\"\n        abbreviate\n        description=\"+12.3% vs last year\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Quarterly Profit\"\n        value={2100000000}\n        format=\"currency\"\n        abbreviate\n        description=\"+8.7% vs last quarter\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Page Views\"\n        value={8750000000}\n        format=\"float\"\n        decimals={2}\n        abbreviate\n        description=\"7.2B organic\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"National Debt\"\n        value={35700000000000}\n        format=\"currency\"\n        abbreviate\n        description=\"+2.1% this year\"\n        trend=\"up\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        label=\"Total Revenue\"\n        value={45231890}\n        format=\"currency\"\n        abbreviate\n        description=\"+12.3% vs last year\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Quarterly Profit\"\n        value={2100000000}\n        format=\"currency\"\n        abbreviate\n        description=\"+8.7% vs last quarter\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"Page Views\"\n        value={8750000000}\n        format=\"float\"\n        decimals={2}\n        abbreviate\n        description=\"7.2B organic\"\n        trend=\"up\"\n      />\n      <CardStat\n        label=\"National Debt\"\n        value={35700000000000}\n        format=\"currency\"\n        abbreviate\n        description=\"+2.1% this year\"\n        trend=\"up\"\n      />\n    </div>"
        },
        {
          "name": "MutedVariant",
          "description": "muted\nIdeal for embedding KPIs inside panels or cards where the outer container already provides elevation.\n\n```tsx\nmuted\nRevenue\ncurrency\n```",
          "args": "{ label: \"Revenue\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          'Use `variant=\"muted\"` for a flat card — no border, no shadow, `bg-muted` background.',\n          \"Ideal for embedding KPIs inside panels or cards where the outer container already provides elevation.\",\n          \"\",\n          \"```tsx\",\n          '<CardStat variant=\"muted\" label=\"Revenue\" value={45231.89} format=\"currency\" />',\n          \"```\",\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        variant=\"muted\"\n        label=\"Revenue\"\n        value={45231.89}\n        format=\"currency\"\n        description=\"+20.1% from last month\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        variant=\"muted\"\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"No change this week\"\n        trend=\"neutral\"\n        icon={UsersIcon}\n      />\n      <CardStat\n        variant=\"muted\"\n        label=\"Bounce Rate\"\n        value={0.084}\n        format=\"percent\"\n        description=\"−1.3% this week\"\n        trend=\"down\"\n      />\n      <CardStat\n        variant=\"muted\"\n        label=\"Avg. Response\"\n        value={127}\n        valueFormatter={(v) => `${v} ms`}\n        description=\"−12 ms vs yesterday\"\n        trend=\"up\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        variant=\"muted\"\n        label=\"Revenue\"\n        value={45231.89}\n        format=\"currency\"\n        description=\"+20.1% from last month\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        variant=\"muted\"\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"No change this week\"\n        trend=\"neutral\"\n        icon={UsersIcon}\n      />\n      <CardStat\n        variant=\"muted\"\n        label=\"Bounce Rate\"\n        value={0.084}\n        format=\"percent\"\n        description=\"−1.3% this week\"\n        trend=\"down\"\n      />\n      <CardStat\n        variant=\"muted\"\n        label=\"Avg. Response\"\n        value={127}\n        valueFormatter={(v) => `${v} ms`}\n        description=\"−12 ms vs yesterday\"\n        trend=\"up\"\n      />\n    </div>"
        },
        {
          "name": "FlatVariant",
          "description": "flat\nIdeal for areas where the container already has a colored background and the card needs to stand out in white.\n\n```tsx\nflat\nRevenue\ncurrency\n```",
          "args": "{ label: \"Revenue\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          'Use `variant=\"flat\"` for a borderless, shadowless card with a white background (`bg-background`).',\n          \"Ideal for areas where the container already has a colored background and the card needs to stand out in white.\",\n          \"\",\n          \"```tsx\",\n          '<CardStat variant=\"flat\" label=\"Revenue\" value={45231.89} format=\"currency\" />',\n          \"```\",\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        variant=\"flat\"\n        label=\"Revenue\"\n        value={45231.89}\n        format=\"currency\"\n        description=\"+20.1% from last month\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        variant=\"flat\"\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"No change this week\"\n        trend=\"neutral\"\n        icon={UsersIcon}\n      />\n      <CardStat\n        variant=\"flat\"\n        label=\"Bounce Rate\"\n        value={0.084}\n        format=\"percent\"\n        description=\"−1.3% this week\"\n        trend=\"down\"\n      />\n      <CardStat\n        variant=\"flat\"\n        label=\"Avg. Response\"\n        value={127}\n        valueFormatter={(v) => `${v} ms`}\n        description=\"−12 ms vs yesterday\"\n        trend=\"up\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        variant=\"flat\"\n        label=\"Revenue\"\n        value={45231.89}\n        format=\"currency\"\n        description=\"+20.1% from last month\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        variant=\"flat\"\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"No change this week\"\n        trend=\"neutral\"\n        icon={UsersIcon}\n      />\n      <CardStat\n        variant=\"flat\"\n        label=\"Bounce Rate\"\n        value={0.084}\n        format=\"percent\"\n        description=\"−1.3% this week\"\n        trend=\"down\"\n      />\n      <CardStat\n        variant=\"flat\"\n        label=\"Avg. Response\"\n        value={127}\n        valueFormatter={(v) => `${v} ms`}\n        description=\"−12 ms vs yesterday\"\n        trend=\"up\"\n      />\n    </div>"
        },
        {
          "name": "AllTrends",
          "description": "Demonstrates all trend directions — up, down, and neutral — side by side with different metrics.",
          "args": "{\n    label: \"Metric\",\n    value: 0,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates all trend directions — up, down, and neutral — side by side with different metrics.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        label=\"Revenue\"\n        value={45231.89}\n        format=\"currency\"\n        description=\"+20.1% from last month\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        label=\"Bounce Rate\"\n        value={0.084}\n        format=\"percent\"\n        description=\"−1.3% this week\"\n        trend=\"down\"\n      />\n      <CardStat\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"No change this week\"\n        trend=\"neutral\"\n        icon={UsersIcon}\n      />\n      <CardStat\n        label=\"Avg. Response Time\"\n        value={127}\n        valueFormatter={(v) => `${v} ms`}\n        description=\"−12 ms vs yesterday\"\n        trend=\"up\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n      <CardStat\n        label=\"Revenue\"\n        value={45231.89}\n        format=\"currency\"\n        description=\"+20.1% from last month\"\n        trend=\"up\"\n        icon={DollarSignIcon}\n      />\n      <CardStat\n        label=\"Bounce Rate\"\n        value={0.084}\n        format=\"percent\"\n        description=\"−1.3% this week\"\n        trend=\"down\"\n      />\n      <CardStat\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"No change this week\"\n        trend=\"neutral\"\n        icon={UsersIcon}\n      />\n      <CardStat\n        label=\"Avg. Response Time\"\n        value={127}\n        valueFormatter={(v) => `${v} ms`}\n        description=\"−12 ms vs yesterday\"\n        trend=\"up\"\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-card-stat-compact",
      "title": "Card Stat Compact",
      "description": "A compact statistical card with trend badge, description, icon, and loading skeleton.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat-compact",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/card-stat-compact.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "string | number"
        },
        {
          "name": "trend",
          "required": false,
          "type": "CardStatTrend | boolean"
        },
        {
          "name": "trendValue",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\" | \"flat\""
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Data Display/CardStatCompact",
      "stories": [
        {
          "name": "Default",
          "description": "Standard horizontal compact card showing total revenue with currency value and trend badge.",
          "args": "{\n    label: \"Total Revenue\",\n    value: 124500,\n    format: \"currency\",\n    decimals: 2,\n    locale: \"en-US\",\n    currency: \"USD\",\n    abbreviate: false,\n    trend: \"up\",\n    trendValue: \"+26.8%\",\n    icon: DollarSignIcon,\n    size: \"sm\",\n    variant: \"default\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard horizontal compact card showing total revenue with currency value and trend badge.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying four CardStatCompact placeholders while data is being fetched.",
          "args": "{\n    label: \"Total Revenue\",\n    value: 0,\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying four CardStatCompact placeholders while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact label=\"Total Revenue\" value={0} loading />\n      <CardStatCompact label=\"Active Users\" value={0} loading />\n      <CardStatCompact label=\"Orders\" value={0} loading />\n      <CardStatCompact label=\"Churn Rate\" value={0} loading />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact label=\"Total Revenue\" value={0} loading />\n      <CardStatCompact label=\"Active Users\" value={0} loading />\n      <CardStatCompact label=\"Orders\" value={0} loading />\n      <CardStatCompact label=\"Churn Rate\" value={0} loading />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing four compact cards with dash placeholders when no data is available.",
          "args": "{\n    label: \"Total Revenue\",\n    value: 0,\n    empty: true,\n    icon: DollarSignIcon,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing four compact cards with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact\n        label=\"Total Revenue\"\n        value={0}\n        empty\n        icon={DollarSignIcon}\n      />\n      <CardStatCompact label=\"Active Users\" value={0} empty icon={UsersIcon} />\n      <CardStatCompact label=\"Orders\" value={0} empty icon={ShoppingCartIcon} />\n      <CardStatCompact label=\"Churn Rate\" value={0} empty icon={ActivityIcon} />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact\n        label=\"Total Revenue\"\n        value={0}\n        empty\n        icon={DollarSignIcon}\n      />\n      <CardStatCompact label=\"Active Users\" value={0} empty icon={UsersIcon} />\n      <CardStatCompact label=\"Orders\" value={0} empty icon={ShoppingCartIcon} />\n      <CardStatCompact label=\"Churn Rate\" value={0} empty icon={ActivityIcon} />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStatCompact component with multiple metrics.",
          "args": "{ label: \"Metric\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStatCompact component with multiple metrics.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n            <CardStatCompact\n              label=\"Total Revenue\"\n              value={124500}\n              format=\"currency\"\n              trend=\"up\"\n              trendValue=\"+26.8%\"\n              icon={DollarSignIcon}\n              size={size}\n            />\n            <CardStatCompact\n              label=\"Active Users\"\n              value={57891}\n              format=\"integer\"\n              trend=\"up\"\n              trendValue=\"+12.4%\"\n              icon={UsersIcon}\n              size={size}\n            />\n            <CardStatCompact\n              label=\"Orders\"\n              value={1847}\n              format=\"integer\"\n              trend=\"neutral\"\n              trendValue=\"0.0%\"\n              icon={ShoppingCartIcon}\n              size={size}\n            />\n            <CardStatCompact\n              label=\"Churn Rate\"\n              value={0.024}\n              format=\"percent\"\n              decimals={1}\n              trend=\"down\"\n              trendValue=\"-0.8%\"\n              icon={ActivityIcon}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n            <CardStatCompact\n              label=\"Total Revenue\"\n              value={124500}\n              format=\"currency\"\n              trend=\"up\"\n              trendValue=\"+26.8%\"\n              icon={DollarSignIcon}\n              size={size}\n            />\n            <CardStatCompact\n              label=\"Active Users\"\n              value={57891}\n              format=\"integer\"\n              trend=\"up\"\n              trendValue=\"+12.4%\"\n              icon={UsersIcon}\n              size={size}\n            />\n            <CardStatCompact\n              label=\"Orders\"\n              value={1847}\n              format=\"integer\"\n              trend=\"neutral\"\n              trendValue=\"0.0%\"\n              icon={ShoppingCartIcon}\n              size={size}\n            />\n            <CardStatCompact\n              label=\"Churn Rate\"\n              value={0.024}\n              format=\"percent\"\n              decimals={1}\n              trend=\"down\"\n              trendValue=\"-0.8%\"\n              icon={ActivityIcon}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "MutedVariant",
          "description": "muted\n\n```tsx\nmuted\nRevenue\ncurrency\n```",
          "args": "{ label: \"Metric\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          'Use `variant=\"muted\"` para card sem borda, sem sombra e fundo `bg-muted`.',\n          \"\",\n          \"```tsx\",\n          '<CardStatCompact variant=\"muted\" label=\"Revenue\" value={124500} format=\"currency\" />',\n          \"```\",\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact\n        variant=\"muted\"\n        label=\"Total Revenue\"\n        value={124500}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+26.8%\"\n        icon={DollarSignIcon}\n      />\n      <CardStatCompact\n        variant=\"muted\"\n        label=\"Active Users\"\n        value={57891}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+12.4%\"\n        icon={UsersIcon}\n      />\n      <CardStatCompact\n        variant=\"muted\"\n        label=\"Orders\"\n        value={1847}\n        format=\"integer\"\n        trend=\"neutral\"\n        trendValue=\"0.0%\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatCompact\n        variant=\"muted\"\n        label=\"Churn Rate\"\n        value={0.024}\n        format=\"percent\"\n        decimals={1}\n        trend=\"down\"\n        trendValue=\"-0.8%\"\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact\n        variant=\"muted\"\n        label=\"Total Revenue\"\n        value={124500}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+26.8%\"\n        icon={DollarSignIcon}\n      />\n      <CardStatCompact\n        variant=\"muted\"\n        label=\"Active Users\"\n        value={57891}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+12.4%\"\n        icon={UsersIcon}\n      />\n      <CardStatCompact\n        variant=\"muted\"\n        label=\"Orders\"\n        value={1847}\n        format=\"integer\"\n        trend=\"neutral\"\n        trendValue=\"0.0%\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatCompact\n        variant=\"muted\"\n        label=\"Churn Rate\"\n        value={0.024}\n        format=\"percent\"\n        decimals={1}\n        trend=\"down\"\n        trendValue=\"-0.8%\"\n        icon={ActivityIcon}\n      />\n    </div>"
        },
        {
          "name": "FlatVariant",
          "description": "flat\n\n```tsx\nflat\nRevenue\ncurrency\n```",
          "args": "{ label: \"Metric\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          'Use `variant=\"flat\"` para card sem borda, sem sombra e fundo branco (`bg-background`).',\n          \"\",\n          \"```tsx\",\n          '<CardStatCompact variant=\"flat\" label=\"Revenue\" value={124500} format=\"currency\" />',\n          \"```\",\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact\n        variant=\"flat\"\n        label=\"Total Revenue\"\n        value={124500}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+26.8%\"\n        icon={DollarSignIcon}\n      />\n      <CardStatCompact\n        variant=\"flat\"\n        label=\"Active Users\"\n        value={57891}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+12.4%\"\n        icon={UsersIcon}\n      />\n      <CardStatCompact\n        variant=\"flat\"\n        label=\"Orders\"\n        value={1847}\n        format=\"integer\"\n        trend=\"neutral\"\n        trendValue=\"0.0%\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatCompact\n        variant=\"flat\"\n        label=\"Churn Rate\"\n        value={0.024}\n        format=\"percent\"\n        decimals={1}\n        trend=\"down\"\n        trendValue=\"-0.8%\"\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact\n        variant=\"flat\"\n        label=\"Total Revenue\"\n        value={124500}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+26.8%\"\n        icon={DollarSignIcon}\n      />\n      <CardStatCompact\n        variant=\"flat\"\n        label=\"Active Users\"\n        value={57891}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+12.4%\"\n        icon={UsersIcon}\n      />\n      <CardStatCompact\n        variant=\"flat\"\n        label=\"Orders\"\n        value={1847}\n        format=\"integer\"\n        trend=\"neutral\"\n        trendValue=\"0.0%\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatCompact\n        variant=\"flat\"\n        label=\"Churn Rate\"\n        value={0.024}\n        format=\"percent\"\n        decimals={1}\n        trend=\"down\"\n        trendValue=\"-0.8%\"\n        icon={ActivityIcon}\n      />\n    </div>"
        },
        {
          "name": "AllVariants",
          "description": "Demonstrates all available variant configurations side by side — revenue, users, orders, and churn rate.",
          "args": "{\n    label: \"Metric\",\n    value: 0,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates all available variant configurations side by side — revenue, users, orders, and churn rate.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact\n        label=\"Total Revenue\"\n        value={124500}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+26.8%\"\n        icon={DollarSignIcon}\n      />\n      <CardStatCompact\n        label=\"Active Users\"\n        value={57891}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+12.4%\"\n        icon={UsersIcon}\n      />\n      <CardStatCompact\n        label=\"Orders\"\n        value={1847}\n        format=\"integer\"\n        trend=\"neutral\"\n        trendValue=\"0.0%\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatCompact\n        label=\"Churn Rate\"\n        value={0.024}\n        format=\"percent\"\n        decimals={1}\n        trend=\"down\"\n        trendValue=\"-0.8%\"\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatCompact\n        label=\"Total Revenue\"\n        value={124500}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+26.8%\"\n        icon={DollarSignIcon}\n      />\n      <CardStatCompact\n        label=\"Active Users\"\n        value={57891}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+12.4%\"\n        icon={UsersIcon}\n      />\n      <CardStatCompact\n        label=\"Orders\"\n        value={1847}\n        format=\"integer\"\n        trend=\"neutral\"\n        trendValue=\"0.0%\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatCompact\n        label=\"Churn Rate\"\n        value={0.024}\n        format=\"percent\"\n        decimals={1}\n        trend=\"down\"\n        trendValue=\"-0.8%\"\n        icon={ActivityIcon}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-card-stat-comparison",
      "title": "Card Stat Comparison",
      "description": "A side-by-side comparison card for current vs. previous period values with trend indicators.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat-comparison",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/card-stat-comparison.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "current",
          "required": true,
          "type": "number"
        },
        {
          "name": "previous",
          "required": true,
          "type": "number"
        },
        {
          "name": "currentLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "previousLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Data Display/CardStatComparison",
      "stories": [
        {
          "name": "Default",
          "description": "Standard configuration comparing current month revenue against the previous month with automatic delta calculation.",
          "args": "{\n    label: \"Monthly Revenue\",\n    current: 124500,\n    previous: 98200,\n    format: \"currency\",\n    decimals: 2,\n    locale: \"en-US\",\n    currency: \"USD\",\n    abbreviate: false,\n    currentLabel: \"This month\",\n    previousLabel: \"Last month\",\n    icon: DollarSignIcon,\n    size: \"sm\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard configuration comparing current month revenue against the previous month with automatic delta calculation.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying two CardStatComparison placeholders while data is being fetched.",
          "args": "{\n    label: \"Monthly Revenue\",\n    current: 0,\n    previous: 0,\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying two CardStatComparison placeholders while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatComparison\n        label=\"Monthly Revenue\"\n        current={0}\n        previous={0}\n        loading\n        icon={DollarSignIcon}\n      />\n      <CardStatComparison\n        label=\"Session Duration\"\n        current={0}\n        previous={0}\n        loading\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatComparison\n        label=\"Monthly Revenue\"\n        current={0}\n        previous={0}\n        loading\n        icon={DollarSignIcon}\n      />\n      <CardStatComparison\n        label=\"Session Duration\"\n        current={0}\n        previous={0}\n        loading\n        icon={ActivityIcon}\n      />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing two comparison cards with dash placeholders when no data is available.",
          "args": "{\n    label: \"Monthly Revenue\",\n    current: 0,\n    previous: 0,\n    empty: true,\n    icon: DollarSignIcon,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing two comparison cards with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatComparison\n        label=\"Monthly Revenue\"\n        current={0}\n        previous={0}\n        empty\n        currentLabel=\"This month\"\n        previousLabel=\"Last month\"\n        icon={DollarSignIcon}\n      />\n      <CardStatComparison\n        label=\"Session Duration\"\n        current={0}\n        previous={0}\n        empty\n        currentLabel=\"This week\"\n        previousLabel=\"Last week\"\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatComparison\n        label=\"Monthly Revenue\"\n        current={0}\n        previous={0}\n        empty\n        currentLabel=\"This month\"\n        previousLabel=\"Last month\"\n        icon={DollarSignIcon}\n      />\n      <CardStatComparison\n        label=\"Session Duration\"\n        current={0}\n        previous={0}\n        empty\n        currentLabel=\"This week\"\n        previousLabel=\"Last week\"\n        icon={ActivityIcon}\n      />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStatComparison component.",
          "args": "{ label: \"Comparison\", current: 0, previous: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStatComparison component.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n            <CardStatComparison\n              label=\"Monthly Revenue\"\n              current={124500}\n              previous={98200}\n              format=\"currency\"\n              currentLabel=\"This month\"\n              previousLabel=\"Last month\"\n              icon={DollarSignIcon}\n              size={size}\n            />\n            <CardStatComparison\n              label=\"Session Duration\"\n              current={3.7}\n              previous={4.1}\n              format=\"float\"\n              decimals={1}\n              valueFormatter={(v) => `${v} min`}\n              currentLabel=\"This week\"\n              previousLabel=\"Last week\"\n              icon={ActivityIcon}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n            <CardStatComparison\n              label=\"Monthly Revenue\"\n              current={124500}\n              previous={98200}\n              format=\"currency\"\n              currentLabel=\"This month\"\n              previousLabel=\"Last month\"\n              icon={DollarSignIcon}\n              size={size}\n            />\n            <CardStatComparison\n              label=\"Session Duration\"\n              current={3.7}\n              previous={4.1}\n              format=\"float\"\n              decimals={1}\n              valueFormatter={(v) => `${v} min`}\n              currentLabel=\"This week\"\n              previousLabel=\"Last week\"\n              icon={ActivityIcon}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllComparisons",
          "description": "Side-by-side comparison of monthly revenue and session duration with auto-computed deltas.",
          "args": "{\n    label: \"Comparison\",\n    current: 0,\n    previous: 0,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Side-by-side comparison of monthly revenue and session duration with auto-computed deltas.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatComparison\n        label=\"Monthly Revenue\"\n        current={124500}\n        previous={98200}\n        format=\"currency\"\n        currentLabel=\"This month\"\n        previousLabel=\"Last month\"\n        icon={DollarSignIcon}\n      />\n      <CardStatComparison\n        label=\"Session Duration\"\n        current={3.7}\n        previous={4.1}\n        format=\"float\"\n        decimals={1}\n        valueFormatter={(v) => `${v} min`}\n        currentLabel=\"This week\"\n        previousLabel=\"Last week\"\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatComparison\n        label=\"Monthly Revenue\"\n        current={124500}\n        previous={98200}\n        format=\"currency\"\n        currentLabel=\"This month\"\n        previousLabel=\"Last month\"\n        icon={DollarSignIcon}\n      />\n      <CardStatComparison\n        label=\"Session Duration\"\n        current={3.7}\n        previous={4.1}\n        format=\"float\"\n        decimals={1}\n        valueFormatter={(v) => `${v} min`}\n        currentLabel=\"This week\"\n        previousLabel=\"Last week\"\n        icon={ActivityIcon}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-card-stat-gauge",
      "title": "Card Stat Gauge",
      "description": "A statistical card with a gauge visualization for showing metrics within a target range.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat-gauge",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/card-stat-gauge.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "number"
        },
        {
          "name": "min",
          "required": false,
          "type": "number"
        },
        {
          "name": "max",
          "required": false,
          "type": "number"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "zones",
          "required": false,
          "type": "CardStatGaugeZone[]"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/CardStatGauge",
      "stories": [
        {
          "name": "Default",
          "description": "Standard semi-circular SVG gauge showing an NPS score of 78 out of 100 with default color zones.",
          "args": "{\n    label: \"NPS Score\",\n    value: 78,\n    format: \"integer\",\n    decimals: 0,\n    locale: \"en-US\",\n    currency: \"USD\",\n    abbreviate: false,\n    min: 0,\n    max: 100,\n    description: \"Promoters vs detractors\",\n    size: \"sm\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard semi-circular SVG gauge showing an NPS score of 78 out of 100 with default color zones.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying four CardStatGauge placeholders while data is being fetched.",
          "args": "{\n    label: \"NPS Score\",\n    value: 0,\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying four CardStatGauge placeholders while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n      <CardStatGauge label=\"NPS Score\" value={0} loading />\n      <CardStatGauge label=\"CPU Usage\" value={0} loading icon={CpuIcon} />\n      <CardStatGauge\n        label=\"Quality Score\"\n        value={0}\n        loading\n        icon={ShieldCheckIcon}\n      />\n      <CardStatGauge label=\"Team Velocity\" value={0} loading />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n      <CardStatGauge label=\"NPS Score\" value={0} loading />\n      <CardStatGauge label=\"CPU Usage\" value={0} loading icon={CpuIcon} />\n      <CardStatGauge\n        label=\"Quality Score\"\n        value={0}\n        loading\n        icon={ShieldCheckIcon}\n      />\n      <CardStatGauge label=\"Team Velocity\" value={0} loading />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing four gauge cards with dash placeholders when no data is available.",
          "args": "{\n    label: \"NPS Score\",\n    value: 0,\n    empty: true,\n    description: \"Awaiting survey responses\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing four gauge cards with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n      <CardStatGauge\n        label=\"NPS Score\"\n        value={0}\n        empty\n        description=\"Awaiting survey responses\"\n      />\n      <CardStatGauge\n        label=\"CPU Usage\"\n        value={0}\n        empty\n        description=\"No metrics collected\"\n        icon={CpuIcon}\n      />\n      <CardStatGauge\n        label=\"Quality Score\"\n        value={0}\n        empty\n        description=\"Pipeline not configured\"\n        icon={ShieldCheckIcon}\n      />\n      <CardStatGauge\n        label=\"Team Velocity\"\n        value={0}\n        empty\n        description=\"No sprints completed\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n      <CardStatGauge\n        label=\"NPS Score\"\n        value={0}\n        empty\n        description=\"Awaiting survey responses\"\n      />\n      <CardStatGauge\n        label=\"CPU Usage\"\n        value={0}\n        empty\n        description=\"No metrics collected\"\n        icon={CpuIcon}\n      />\n      <CardStatGauge\n        label=\"Quality Score\"\n        value={0}\n        empty\n        description=\"Pipeline not configured\"\n        icon={ShieldCheckIcon}\n      />\n      <CardStatGauge\n        label=\"Team Velocity\"\n        value={0}\n        empty\n        description=\"No sprints completed\"\n      />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStatGauge component with various metrics.",
          "args": "{ label: \"Gauge\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStatGauge component with various metrics.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n            <CardStatGauge\n              label=\"NPS Score\"\n              value={78}\n              min={0}\n              max={100}\n              description=\"Promoters vs detractors\"\n              size={size}\n            />\n            <CardStatGauge\n              label=\"CPU Usage\"\n              value={42}\n              min={0}\n              max={100}\n              valueFormatter={(v) => `${v}%`}\n              description=\"Production cluster avg\"\n              icon={CpuIcon}\n              size={size}\n            />\n            <CardStatGauge\n              label=\"Quality Score\"\n              value={91}\n              min={0}\n              max={100}\n              description=\"Code review pipeline\"\n              icon={ShieldCheckIcon}\n              size={size}\n            />\n            <CardStatGauge\n              label=\"Team Velocity\"\n              value={34}\n              min={0}\n              max={60}\n              valueFormatter={(v) => `${v} pts`}\n              description=\"Story points per sprint\"\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n            <CardStatGauge\n              label=\"NPS Score\"\n              value={78}\n              min={0}\n              max={100}\n              description=\"Promoters vs detractors\"\n              size={size}\n            />\n            <CardStatGauge\n              label=\"CPU Usage\"\n              value={42}\n              min={0}\n              max={100}\n              valueFormatter={(v) => `${v}%`}\n              description=\"Production cluster avg\"\n              icon={CpuIcon}\n              size={size}\n            />\n            <CardStatGauge\n              label=\"Quality Score\"\n              value={91}\n              min={0}\n              max={100}\n              description=\"Code review pipeline\"\n              icon={ShieldCheckIcon}\n              size={size}\n            />\n            <CardStatGauge\n              label=\"Team Velocity\"\n              value={34}\n              min={0}\n              max={60}\n              valueFormatter={(v) => `${v} pts`}\n              description=\"Story points per sprint\"\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllGauges",
          "description": "Demonstrates four gauge configurations — NPS score, CPU usage with custom zones, quality score, and team velocity.",
          "args": "{\n    label: \"Gauge\",\n    value: 0,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates four gauge configurations — NPS score, CPU usage with custom zones, quality score, and team velocity.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n      <CardStatGauge\n        label=\"NPS Score\"\n        value={78}\n        min={0}\n        max={100}\n        description=\"Promoters vs detractors\"\n      />\n      <CardStatGauge\n        label=\"CPU Usage\"\n        value={42}\n        min={0}\n        max={100}\n        valueFormatter={(v) => `${v}%`}\n        description=\"Production cluster avg\"\n        icon={CpuIcon}\n        zones={[\n          { label: \"Low\", color: \"#10b981\", max: 50 },\n          { label: \"Medium\", color: \"#f59e0b\", max: 80 },\n          { label: \"High\", color: \"#f97316\", max: 95 },\n          { label: \"Critical\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n      <CardStatGauge\n        label=\"Quality Score\"\n        value={91}\n        min={0}\n        max={100}\n        description=\"Code review pipeline\"\n        icon={ShieldCheckIcon}\n      />\n      <CardStatGauge\n        label=\"Team Velocity\"\n        value={34}\n        min={0}\n        max={60}\n        valueFormatter={(v) => `${v} pts`}\n        description=\"Story points per sprint\"\n        zones={[\n          { label: \"Behind\", color: \"#ef4444\", max: 25 },\n          { label: \"On track\", color: \"#f59e0b\", max: 50 },\n          { label: \"Ahead\", color: \"#10b981\", max: 100 },\n        ]}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n      <CardStatGauge\n        label=\"NPS Score\"\n        value={78}\n        min={0}\n        max={100}\n        description=\"Promoters vs detractors\"\n      />\n      <CardStatGauge\n        label=\"CPU Usage\"\n        value={42}\n        min={0}\n        max={100}\n        valueFormatter={(v) => `${v}%`}\n        description=\"Production cluster avg\"\n        icon={CpuIcon}\n        zones={[\n          { label: \"Low\", color: \"#10b981\", max: 50 },\n          { label: \"Medium\", color: \"#f59e0b\", max: 80 },\n          { label: \"High\", color: \"#f97316\", max: 95 },\n          { label: \"Critical\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n      <CardStatGauge\n        label=\"Quality Score\"\n        value={91}\n        min={0}\n        max={100}\n        description=\"Code review pipeline\"\n        icon={ShieldCheckIcon}\n      />\n      <CardStatGauge\n        label=\"Team Velocity\"\n        value={34}\n        min={0}\n        max={60}\n        valueFormatter={(v) => `${v} pts`}\n        description=\"Story points per sprint\"\n        zones={[\n          { label: \"Behind\", color: \"#ef4444\", max: 25 },\n          { label: \"On track\", color: \"#f59e0b\", max: 50 },\n          { label: \"Ahead\", color: \"#10b981\", max: 100 },\n        ]}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-card-stat-heatbar",
      "title": "Card Stat Heatbar",
      "description": "A statistical card with a segmented heatbar visualization for multi-zone metric display.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat-heatbar",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "progress",
        "skeleton"
      ],
      "files": [
        "components/ds/card-stat-heatbar.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "number"
        },
        {
          "name": "min",
          "required": false,
          "type": "number"
        },
        {
          "name": "max",
          "required": false,
          "type": "number"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "zones",
          "required": false,
          "type": "CardStatHeatbarZone[]"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/CardStatHeatbar",
      "stories": [
        {
          "name": "Default",
          "description": "Standard segmented color bar showing customer satisfaction at 87 with a triangle pointer and tooltip on hover.",
          "args": "{\n    label: \"Customer Satisfaction\",\n    value: 87,\n    format: \"integer\",\n    decimals: 0,\n    locale: \"en-US\",\n    currency: \"USD\",\n    abbreviate: false,\n    description: \"Based on 2,847 responses this month\",\n    icon: HeartIcon,\n    size: \"sm\",\n    min: 0,\n    max: 100,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard segmented color bar showing customer satisfaction at 87 with a triangle pointer and tooltip on hover.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying four CardStatHeatbar placeholders while data is being fetched.",
          "args": "{\n    label: \"Customer Satisfaction\",\n    value: 0,\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying four CardStatHeatbar placeholders while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatHeatbar\n        label=\"Customer Satisfaction\"\n        value={0}\n        loading\n        icon={HeartIcon}\n      />\n      <CardStatHeatbar\n        label=\"Page Load Speed\"\n        value={0}\n        loading\n        icon={ZapIcon}\n      />\n      <CardStatHeatbar\n        label=\"Security Score\"\n        value={0}\n        loading\n        icon={ShieldCheckIcon}\n      />\n      <CardStatHeatbar label=\"SLA Compliance\" value={0} loading />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatHeatbar\n        label=\"Customer Satisfaction\"\n        value={0}\n        loading\n        icon={HeartIcon}\n      />\n      <CardStatHeatbar\n        label=\"Page Load Speed\"\n        value={0}\n        loading\n        icon={ZapIcon}\n      />\n      <CardStatHeatbar\n        label=\"Security Score\"\n        value={0}\n        loading\n        icon={ShieldCheckIcon}\n      />\n      <CardStatHeatbar label=\"SLA Compliance\" value={0} loading />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing four heatbar cards with dash placeholders when no data is available.",
          "args": "{\n    label: \"Customer Satisfaction\",\n    value: 0,\n    empty: true,\n    icon: HeartIcon,\n    description: \"Based on survey responses\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing four heatbar cards with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatHeatbar\n        label=\"Customer Satisfaction\"\n        value={0}\n        empty\n        description=\"Based on survey responses\"\n        icon={HeartIcon}\n      />\n      <CardStatHeatbar\n        label=\"Page Load Speed\"\n        value={0}\n        empty\n        description=\"Core Web Vitals average\"\n        icon={ZapIcon}\n        zones={[\n          { label: \"Fast\", color: \"#10b981\", max: 25 },\n          { label: \"OK\", color: \"#3b82f6\", max: 50 },\n          { label: \"Slow\", color: \"#f59e0b\", max: 75 },\n          { label: \"Poor\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n      <CardStatHeatbar\n        label=\"Security Score\"\n        value={0}\n        empty\n        description=\"Last audit pending\"\n        icon={ShieldCheckIcon}\n      />\n      <CardStatHeatbar\n        label=\"SLA Compliance\"\n        value={0}\n        empty\n        description=\"Uptime target: 99.5%\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatHeatbar\n        label=\"Customer Satisfaction\"\n        value={0}\n        empty\n        description=\"Based on survey responses\"\n        icon={HeartIcon}\n      />\n      <CardStatHeatbar\n        label=\"Page Load Speed\"\n        value={0}\n        empty\n        description=\"Core Web Vitals average\"\n        icon={ZapIcon}\n        zones={[\n          { label: \"Fast\", color: \"#10b981\", max: 25 },\n          { label: \"OK\", color: \"#3b82f6\", max: 50 },\n          { label: \"Slow\", color: \"#f59e0b\", max: 75 },\n          { label: \"Poor\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n      <CardStatHeatbar\n        label=\"Security Score\"\n        value={0}\n        empty\n        description=\"Last audit pending\"\n        icon={ShieldCheckIcon}\n      />\n      <CardStatHeatbar\n        label=\"SLA Compliance\"\n        value={0}\n        empty\n        description=\"Uptime target: 99.5%\"\n      />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStatHeatbar component with custom zone configurations.",
          "args": "{ label: \"Heatbar\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStatHeatbar component with custom zone configurations.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n            <CardStatHeatbar\n              label=\"Customer Satisfaction\"\n              value={87}\n              description=\"Based on 2,847 responses this month\"\n              icon={HeartIcon}\n              size={size}\n            />\n            <CardStatHeatbar\n              label=\"Security Score\"\n              value={64}\n              description=\"Last audit: 3 medium issues open\"\n              icon={ShieldCheckIcon}\n              zones={[\n                { label: \"Critical\", color: \"#ef4444\", max: 25 },\n                { label: \"At risk\", color: \"#f97316\", max: 50 },\n                { label: \"Fair\", color: \"#f59e0b\", max: 75 },\n                { label: \"Secure\", color: \"#10b981\", max: 100 },\n              ]}\n              size={size}\n            />\n            <CardStatHeatbar\n              label=\"Page Load Speed\"\n              value={1.4}\n              min={0}\n              max={5}\n              valueFormatter={(v) => `${v}s`}\n              description=\"Core Web Vitals average\"\n              icon={ZapIcon}\n              zones={[\n                { label: \"Fast\", color: \"#10b981\", max: 25 },\n                { label: \"OK\", color: \"#3b82f6\", max: 50 },\n                { label: \"Slow\", color: \"#f59e0b\", max: 75 },\n                { label: \"Poor\", color: \"#ef4444\", max: 100 },\n              ]}\n              size={size}\n            />\n            <CardStatHeatbar\n              label=\"SLA Compliance\"\n              value={0.987}\n              min={0}\n              max={1}\n              format=\"percent\"\n              decimals={1}\n              description=\"Uptime target: 99.5%\"\n              zones={[\n                { label: \"Breach\", color: \"#ef4444\", max: 95 },\n                { label: \"Warning\", color: \"#f59e0b\", max: 99 },\n                { label: \"On target\", color: \"#10b981\", max: 100 },\n              ]}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n            <CardStatHeatbar\n              label=\"Customer Satisfaction\"\n              value={87}\n              description=\"Based on 2,847 responses this month\"\n              icon={HeartIcon}\n              size={size}\n            />\n            <CardStatHeatbar\n              label=\"Security Score\"\n              value={64}\n              description=\"Last audit: 3 medium issues open\"\n              icon={ShieldCheckIcon}\n              zones={[\n                { label: \"Critical\", color: \"#ef4444\", max: 25 },\n                { label: \"At risk\", color: \"#f97316\", max: 50 },\n                { label: \"Fair\", color: \"#f59e0b\", max: 75 },\n                { label: \"Secure\", color: \"#10b981\", max: 100 },\n              ]}\n              size={size}\n            />\n            <CardStatHeatbar\n              label=\"Page Load Speed\"\n              value={1.4}\n              min={0}\n              max={5}\n              valueFormatter={(v) => `${v}s`}\n              description=\"Core Web Vitals average\"\n              icon={ZapIcon}\n              zones={[\n                { label: \"Fast\", color: \"#10b981\", max: 25 },\n                { label: \"OK\", color: \"#3b82f6\", max: 50 },\n                { label: \"Slow\", color: \"#f59e0b\", max: 75 },\n                { label: \"Poor\", color: \"#ef4444\", max: 100 },\n              ]}\n              size={size}\n            />\n            <CardStatHeatbar\n              label=\"SLA Compliance\"\n              value={0.987}\n              min={0}\n              max={1}\n              format=\"percent\"\n              decimals={1}\n              description=\"Uptime target: 99.5%\"\n              zones={[\n                { label: \"Breach\", color: \"#ef4444\", max: 95 },\n                { label: \"Warning\", color: \"#f59e0b\", max: 99 },\n                { label: \"On target\", color: \"#10b981\", max: 100 },\n              ]}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "PercentLocale",
          "description": "Regression check: `value` is a 0-1 fraction rendered with `format=\"percent\"`. The two cards use the same value with different `locale` — the headline must respect the decimal separator (\"99,2%\" for pt-BR vs \"99.2%\" for en-US), matching the sibling CardStatProgress component. Before the fix, `locale` was dropped when formatting the headline and both always rendered with a period regardless of the `locale` prop.",
          "args": "{\n    label: \"Escore de Risco\",\n    value: 0.992,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'Regression check: `value` is a 0-1 fraction rendered with `format=\"percent\"`. The two cards use the same value with different `locale` — the headline must respect the decimal separator (\"99,2%\" for pt-BR vs \"99.2%\" for en-US), matching the sibling CardStatProgress component. Before the fix, `locale` was dropped when formatting the headline and both always rendered with a period regardless of the `locale` prop.',\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatHeatbar\n        label=\"Escore de Risco\"\n        value={0.992}\n        min={0}\n        max={1}\n        format=\"percent\"\n        decimals={1}\n        locale=\"pt-BR\"\n        description=\"Média do segmento: 59,7%\"\n        icon={ShieldCheckIcon}\n        zones={[\n          { label: \"Baixo\", color: \"#10b981\", max: 25 },\n          { label: \"Moderado\", color: \"#f59e0b\", max: 50 },\n          { label: \"Alto\", color: \"#f97316\", max: 75 },\n          { label: \"Crítico\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n      <CardStatHeatbar\n        label=\"Risk Score\"\n        value={0.992}\n        min={0}\n        max={1}\n        format=\"percent\"\n        decimals={1}\n        locale=\"en-US\"\n        description=\"Segment average: 59.7%\"\n        icon={ShieldCheckIcon}\n        zones={[\n          { label: \"Low\", color: \"#10b981\", max: 25 },\n          { label: \"Moderate\", color: \"#f59e0b\", max: 50 },\n          { label: \"High\", color: \"#f97316\", max: 75 },\n          { label: \"Critical\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatHeatbar\n        label=\"Escore de Risco\"\n        value={0.992}\n        min={0}\n        max={1}\n        format=\"percent\"\n        decimals={1}\n        locale=\"pt-BR\"\n        description=\"Média do segmento: 59,7%\"\n        icon={ShieldCheckIcon}\n        zones={[\n          { label: \"Baixo\", color: \"#10b981\", max: 25 },\n          { label: \"Moderado\", color: \"#f59e0b\", max: 50 },\n          { label: \"Alto\", color: \"#f97316\", max: 75 },\n          { label: \"Crítico\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n      <CardStatHeatbar\n        label=\"Risk Score\"\n        value={0.992}\n        min={0}\n        max={1}\n        format=\"percent\"\n        decimals={1}\n        locale=\"en-US\"\n        description=\"Segment average: 59.7%\"\n        icon={ShieldCheckIcon}\n        zones={[\n          { label: \"Low\", color: \"#10b981\", max: 25 },\n          { label: \"Moderate\", color: \"#f59e0b\", max: 50 },\n          { label: \"High\", color: \"#f97316\", max: 75 },\n          { label: \"Critical\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n    </div>"
        },
        {
          "name": "AllHeatbars",
          "description": "Demonstrates four heatbar configurations — customer satisfaction, page load speed, security score, and SLA compliance.",
          "args": "{\n    label: \"Heatbar\",\n    value: 0,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates four heatbar configurations — customer satisfaction, page load speed, security score, and SLA compliance.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatHeatbar\n        label=\"Customer Satisfaction\"\n        value={87}\n        description=\"Based on 2,847 responses this month\"\n        icon={HeartIcon}\n      />\n      <CardStatHeatbar\n        label=\"Page Load Speed\"\n        value={1.4}\n        min={0}\n        max={5}\n        valueFormatter={(v) => `${v}s`}\n        description=\"Core Web Vitals average\"\n        icon={ZapIcon}\n        zones={[\n          { label: \"Fast\", color: \"#10b981\", max: 25 },\n          { label: \"OK\", color: \"#3b82f6\", max: 50 },\n          { label: \"Slow\", color: \"#f59e0b\", max: 75 },\n          { label: \"Poor\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n      <CardStatHeatbar\n        label=\"Security Score\"\n        value={64}\n        description=\"Last audit: 3 medium issues open\"\n        icon={ShieldCheckIcon}\n        zones={[\n          { label: \"Critical\", color: \"#ef4444\", max: 25 },\n          { label: \"At risk\", color: \"#f97316\", max: 50 },\n          { label: \"Fair\", color: \"#f59e0b\", max: 75 },\n          { label: \"Secure\", color: \"#10b981\", max: 100 },\n        ]}\n      />\n      <CardStatHeatbar\n        label=\"SLA Compliance\"\n        value={0.987}\n        min={0}\n        max={1}\n        format=\"percent\"\n        decimals={1}\n        description=\"Uptime target: 99.5%\"\n        zones={[\n          { label: \"Breach\", color: \"#ef4444\", max: 95 },\n          { label: \"Warning\", color: \"#f59e0b\", max: 99 },\n          { label: \"On target\", color: \"#10b981\", max: 100 },\n        ]}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatHeatbar\n        label=\"Customer Satisfaction\"\n        value={87}\n        description=\"Based on 2,847 responses this month\"\n        icon={HeartIcon}\n      />\n      <CardStatHeatbar\n        label=\"Page Load Speed\"\n        value={1.4}\n        min={0}\n        max={5}\n        valueFormatter={(v) => `${v}s`}\n        description=\"Core Web Vitals average\"\n        icon={ZapIcon}\n        zones={[\n          { label: \"Fast\", color: \"#10b981\", max: 25 },\n          { label: \"OK\", color: \"#3b82f6\", max: 50 },\n          { label: \"Slow\", color: \"#f59e0b\", max: 75 },\n          { label: \"Poor\", color: \"#ef4444\", max: 100 },\n        ]}\n      />\n      <CardStatHeatbar\n        label=\"Security Score\"\n        value={64}\n        description=\"Last audit: 3 medium issues open\"\n        icon={ShieldCheckIcon}\n        zones={[\n          { label: \"Critical\", color: \"#ef4444\", max: 25 },\n          { label: \"At risk\", color: \"#f97316\", max: 50 },\n          { label: \"Fair\", color: \"#f59e0b\", max: 75 },\n          { label: \"Secure\", color: \"#10b981\", max: 100 },\n        ]}\n      />\n      <CardStatHeatbar\n        label=\"SLA Compliance\"\n        value={0.987}\n        min={0}\n        max={1}\n        format=\"percent\"\n        decimals={1}\n        description=\"Uptime target: 99.5%\"\n        zones={[\n          { label: \"Breach\", color: \"#ef4444\", max: 95 },\n          { label: \"Warning\", color: \"#f59e0b\", max: 99 },\n          { label: \"On target\", color: \"#10b981\", max: 100 },\n        ]}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-card-stat-highlight",
      "title": "Card Stat Highlight",
      "description": "A high-emphasis statistical card with a colored background for key metric prominence.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat-highlight",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/card-stat-highlight.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "string | number"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "trend",
          "required": false,
          "type": "CardStatTrend | boolean"
        },
        {
          "name": "trendValue",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "background",
          "required": false,
          "type": "string",
          "description": "Override card background via CSS token `--card-highlight-background`.\nAccepts any CSS color or `var(--my-token)`."
        },
        {
          "name": "color",
          "required": false,
          "type": "string",
          "description": "Override card text color via CSS token `--card-highlight-color`."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"primary\" | \"emerald\" | \"amber\" | \"rose\" | \"violet\" | \"sky\" | \"white\"",
          "options": [
            "primary",
            "emerald",
            "amber",
            "rose",
            "violet",
            "sky",
            "white"
          ],
          "default": "primary"
        }
      ],
      "storyTitle": "Data Display/CardStatHighlight",
      "stories": [
        {
          "name": "Default",
          "description": "Standard hero KPI card with primary variant showing total revenue, up trend, and quarterly comparison.",
          "args": "{\n    label: \"Total Revenue\",\n    value: 2400000,\n    format: \"currency\",\n    decimals: 2,\n    locale: \"en-US\",\n    currency: \"USD\",\n    abbreviate: false,\n    trend: \"up\",\n    trendValue: \"+18%\",\n    description: \"vs last quarter\",\n    icon: DollarSignIcon,\n    variant: \"primary\",\n    size: \"sm\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard hero KPI card with primary variant showing total revenue, up trend, and quarterly comparison.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying six CardStatHighlight placeholders across all color variants while data is being fetched.",
          "args": "{\n    label: \"Total Revenue\",\n    value: 0,\n    loading: true,\n    variant: \"primary\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying six CardStatHighlight placeholders across all color variants while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatHighlight\n        label=\"Total Revenue\"\n        value={0}\n        loading\n        variant=\"primary\"\n        icon={DollarSignIcon}\n      />\n      <CardStatHighlight\n        label=\"Satisfaction\"\n        value={0}\n        loading\n        variant=\"emerald\"\n        icon={HeartIcon}\n      />\n      <CardStatHighlight\n        label=\"Subscriptions\"\n        value={0}\n        loading\n        variant=\"violet\"\n        icon={StarIcon}\n      />\n      <CardStatHighlight\n        label=\"Avg. Order\"\n        value={0}\n        loading\n        variant=\"sky\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatHighlight\n        label=\"Shipments\"\n        value={0}\n        loading\n        variant=\"amber\"\n        icon={PackageIcon}\n      />\n      <CardStatHighlight\n        label=\"Refund Rate\"\n        value={0}\n        loading\n        variant=\"rose\"\n        icon={ActivityIcon}\n      />\n      <CardStatHighlight\n        label=\"Net Profit\"\n        value={0}\n        loading\n        variant=\"white\"\n        icon={TrendingUpIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatHighlight\n        label=\"Total Revenue\"\n        value={0}\n        loading\n        variant=\"primary\"\n        icon={DollarSignIcon}\n      />\n      <CardStatHighlight\n        label=\"Satisfaction\"\n        value={0}\n        loading\n        variant=\"emerald\"\n        icon={HeartIcon}\n      />\n      <CardStatHighlight\n        label=\"Subscriptions\"\n        value={0}\n        loading\n        variant=\"violet\"\n        icon={StarIcon}\n      />\n      <CardStatHighlight\n        label=\"Avg. Order\"\n        value={0}\n        loading\n        variant=\"sky\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatHighlight\n        label=\"Shipments\"\n        value={0}\n        loading\n        variant=\"amber\"\n        icon={PackageIcon}\n      />\n      <CardStatHighlight\n        label=\"Refund Rate\"\n        value={0}\n        loading\n        variant=\"rose\"\n        icon={ActivityIcon}\n      />\n      <CardStatHighlight\n        label=\"Net Profit\"\n        value={0}\n        loading\n        variant=\"white\"\n        icon={TrendingUpIcon}\n      />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing six hero cards across all color variants with dash placeholders when no data is available.",
          "args": "{\n    label: \"Total Revenue\",\n    value: 0,\n    empty: true,\n    variant: \"primary\",\n    icon: DollarSignIcon,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing six hero cards across all color variants with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n      <CardStatHighlight\n        label=\"Total Revenue\"\n        value={0}\n        empty\n        variant=\"primary\"\n        icon={DollarSignIcon}\n      />\n      <CardStatHighlight\n        label=\"Satisfaction\"\n        value={0}\n        empty\n        variant=\"emerald\"\n        icon={HeartIcon}\n      />\n      <CardStatHighlight\n        label=\"Subscriptions\"\n        value={0}\n        empty\n        variant=\"violet\"\n        icon={StarIcon}\n      />\n      <CardStatHighlight\n        label=\"Avg. Order\"\n        value={0}\n        empty\n        variant=\"sky\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatHighlight\n        label=\"Shipments\"\n        value={0}\n        empty\n        variant=\"amber\"\n        icon={PackageIcon}\n      />\n      <CardStatHighlight\n        label=\"Refund Rate\"\n        value={0}\n        empty\n        variant=\"rose\"\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n      <CardStatHighlight\n        label=\"Total Revenue\"\n        value={0}\n        empty\n        variant=\"primary\"\n        icon={DollarSignIcon}\n      />\n      <CardStatHighlight\n        label=\"Satisfaction\"\n        value={0}\n        empty\n        variant=\"emerald\"\n        icon={HeartIcon}\n      />\n      <CardStatHighlight\n        label=\"Subscriptions\"\n        value={0}\n        empty\n        variant=\"violet\"\n        icon={StarIcon}\n      />\n      <CardStatHighlight\n        label=\"Avg. Order\"\n        value={0}\n        empty\n        variant=\"sky\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatHighlight\n        label=\"Shipments\"\n        value={0}\n        empty\n        variant=\"amber\"\n        icon={PackageIcon}\n      />\n      <CardStatHighlight\n        label=\"Refund Rate\"\n        value={0}\n        empty\n        variant=\"rose\"\n        icon={ActivityIcon}\n      />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStatHighlight component with primary, emerald, and violet variants.",
          "args": "{ label: \"Metric\", value: 0 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStatHighlight component with primary, emerald, and violet variants.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n            <CardStatHighlight\n              label=\"Total Revenue\"\n              value={2400000}\n              format=\"currency\"\n              trend=\"up\"\n              trendValue=\"+18%\"\n              description=\"vs last quarter\"\n              icon={DollarSignIcon}\n              variant=\"primary\"\n              size={size}\n            />\n            <CardStatHighlight\n              label=\"Customer Satisfaction\"\n              value={0.964}\n              format=\"percent\"\n              decimals={1}\n              trend=\"up\"\n              trendValue=\"+2.1pts\"\n              description=\"NPS this month\"\n              icon={HeartIcon}\n              variant=\"emerald\"\n              size={size}\n            />\n            <CardStatHighlight\n              label=\"Active Subscriptions\"\n              value={12847}\n              format=\"integer\"\n              trend=\"up\"\n              trendValue=\"+847\"\n              description=\"new this month\"\n              icon={StarIcon}\n              variant=\"violet\"\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n            <CardStatHighlight\n              label=\"Total Revenue\"\n              value={2400000}\n              format=\"currency\"\n              trend=\"up\"\n              trendValue=\"+18%\"\n              description=\"vs last quarter\"\n              icon={DollarSignIcon}\n              variant=\"primary\"\n              size={size}\n            />\n            <CardStatHighlight\n              label=\"Customer Satisfaction\"\n              value={0.964}\n              format=\"percent\"\n              decimals={1}\n              trend=\"up\"\n              trendValue=\"+2.1pts\"\n              description=\"NPS this month\"\n              icon={HeartIcon}\n              variant=\"emerald\"\n              size={size}\n            />\n            <CardStatHighlight\n              label=\"Active Subscriptions\"\n              value={12847}\n              format=\"integer\"\n              trend=\"up\"\n              trendValue=\"+847\"\n              description=\"new this month\"\n              icon={StarIcon}\n              variant=\"violet\"\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllVariants",
          "description": "Demonstrates all seven built-in variants — primary, emerald, violet, sky, amber, rose, and white — side by side.",
          "args": "{\n    label: \"Metric\",\n    value: 0,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates all seven built-in variants — primary, emerald, violet, sky, amber, rose, and white — side by side.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatHighlight\n        label=\"Total Revenue\"\n        value={2400000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+18%\"\n        description=\"vs last quarter\"\n        icon={DollarSignIcon}\n        variant=\"primary\"\n      />\n      <CardStatHighlight\n        label=\"Customer Satisfaction\"\n        value={0.964}\n        format=\"percent\"\n        decimals={1}\n        trend=\"up\"\n        trendValue=\"+2.1pts\"\n        description=\"NPS this month\"\n        icon={HeartIcon}\n        variant=\"emerald\"\n      />\n      <CardStatHighlight\n        label=\"Active Subscriptions\"\n        value={12847}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+847\"\n        description=\"new this month\"\n        icon={StarIcon}\n        variant=\"violet\"\n      />\n      <CardStatHighlight\n        label=\"Avg. Order Value\"\n        value={67.4}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+$4.20\"\n        description=\"vs last month\"\n        icon={ShoppingCartIcon}\n        variant=\"sky\"\n      />\n      <CardStatHighlight\n        label=\"Pending Shipments\"\n        value={248}\n        format=\"integer\"\n        trend=\"down\"\n        trendValue=\"−12%\"\n        description=\"processing backlog\"\n        icon={PackageIcon}\n        variant=\"amber\"\n      />\n      <CardStatHighlight\n        label=\"Refund Rate\"\n        value={0.018}\n        format=\"percent\"\n        decimals={1}\n        trend=\"up\"\n        trendValue=\"+0.3%\"\n        description=\"needs attention\"\n        icon={ActivityIcon}\n        variant=\"rose\"\n      />\n      <CardStatHighlight\n        label=\"Net Profit\"\n        value={420000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+12%\"\n        description=\"YTD performance\"\n        icon={TrendingUpIcon}\n        variant=\"white\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatHighlight\n        label=\"Total Revenue\"\n        value={2400000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+18%\"\n        description=\"vs last quarter\"\n        icon={DollarSignIcon}\n        variant=\"primary\"\n      />\n      <CardStatHighlight\n        label=\"Customer Satisfaction\"\n        value={0.964}\n        format=\"percent\"\n        decimals={1}\n        trend=\"up\"\n        trendValue=\"+2.1pts\"\n        description=\"NPS this month\"\n        icon={HeartIcon}\n        variant=\"emerald\"\n      />\n      <CardStatHighlight\n        label=\"Active Subscriptions\"\n        value={12847}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+847\"\n        description=\"new this month\"\n        icon={StarIcon}\n        variant=\"violet\"\n      />\n      <CardStatHighlight\n        label=\"Avg. Order Value\"\n        value={67.4}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+$4.20\"\n        description=\"vs last month\"\n        icon={ShoppingCartIcon}\n        variant=\"sky\"\n      />\n      <CardStatHighlight\n        label=\"Pending Shipments\"\n        value={248}\n        format=\"integer\"\n        trend=\"down\"\n        trendValue=\"−12%\"\n        description=\"processing backlog\"\n        icon={PackageIcon}\n        variant=\"amber\"\n      />\n      <CardStatHighlight\n        label=\"Refund Rate\"\n        value={0.018}\n        format=\"percent\"\n        decimals={1}\n        trend=\"up\"\n        trendValue=\"+0.3%\"\n        description=\"needs attention\"\n        icon={ActivityIcon}\n        variant=\"rose\"\n      />\n      <CardStatHighlight\n        label=\"Net Profit\"\n        value={420000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+12%\"\n        description=\"YTD performance\"\n        icon={TrendingUpIcon}\n        variant=\"white\"\n      />\n    </div>"
        },
        {
          "name": "BannerKPI",
          "description": "Full-width hero KPI in emerald variant showing Q4 total revenue with 18% year-over-year growth and a trend description.",
          "args": "{\n    label: \"Total Revenue — Q4 2024\",\n    value: 2400000,\n    format: \"currency\",\n    trend: \"up\",\n    trendValue: \"+18% YoY\",\n    description: \"ahead of forecast\",\n    icon: TrendingUpIcon,\n    variant: \"emerald\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Full-width hero KPI in emerald variant showing Q4 total revenue with 18% year-over-year growth and a trend description.\",\n      },\n    },\n  },"
        },
        {
          "name": "ColorTokens",
          "description": "The `background` and `color` props accept any CSS color or `var(--my-token)`. They set `--card-highlight-background` and `--card-highlight-color` as CSS custom properties and apply via `bg-(--card-highlight-background)` and `text-(--card-highlight-color)` — escaping the 7-variant enum for per-instance customization.",
          "args": "{ label: \"Custom KPI\", value: 12847 },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n      <CardStatHighlight\n        label=\"Custom Purple\"\n        value={12847}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+847\"\n        description=\"new this month\"\n        icon={StarIcon}\n        background=\"oklch(0.5 0.2 270)\"\n        color=\"white\"\n      />\n      <CardStatHighlight\n        label=\"Success Token\"\n        value={0.964}\n        format=\"percent\"\n        decimals={1}\n        trend=\"up\"\n        trendValue=\"+2.1pts\"\n        description=\"NPS this month\"\n        icon={HeartIcon}\n        background=\"var(--color-success)\"\n        color=\"var(--color-success-foreground)\"\n      />\n      <CardStatHighlight\n        label=\"Warning Token\"\n        value={248}\n        format=\"integer\"\n        trend=\"down\"\n        trendValue=\"−12%\"\n        description=\"processing backlog\"\n        icon={ShoppingCartIcon}\n        background=\"var(--color-warning)\"\n        color=\"var(--color-warning-foreground)\"\n      />\n      <CardStatHighlight\n        label=\"Custom Amber\"\n        value={2400000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+18%\"\n        description=\"vs last quarter\"\n        icon={DollarSignIcon}\n        background=\"oklch(0.75 0.18 75)\"\n        color=\"oklch(0.2 0.05 75)\"\n      />\n      <CardStatHighlight\n        label=\"External Token\"\n        value={420000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+12%\"\n        description=\"YTD performance\"\n        icon={TrendingUpIcon}\n        background=\"var(--color-brand, oklch(0.4 0.2 240))\"\n        color=\"white\"\n      />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"The `background` and `color` props accept any CSS color or `var(--my-token)`. They set `--card-highlight-background` and `--card-highlight-color` as CSS custom properties and apply via `bg-(--card-highlight-background)` and `text-(--card-highlight-color)` — escaping the 7-variant enum for per-instance customization.\",\n      },\n    },\n  },",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n      <CardStatHighlight\n        label=\"Custom Purple\"\n        value={12847}\n        format=\"integer\"\n        trend=\"up\"\n        trendValue=\"+847\"\n        description=\"new this month\"\n        icon={StarIcon}\n        background=\"oklch(0.5 0.2 270)\"\n        color=\"white\"\n      />\n      <CardStatHighlight\n        label=\"Success Token\"\n        value={0.964}\n        format=\"percent\"\n        decimals={1}\n        trend=\"up\"\n        trendValue=\"+2.1pts\"\n        description=\"NPS this month\"\n        icon={HeartIcon}\n        background=\"var(--color-success)\"\n        color=\"var(--color-success-foreground)\"\n      />\n      <CardStatHighlight\n        label=\"Warning Token\"\n        value={248}\n        format=\"integer\"\n        trend=\"down\"\n        trendValue=\"−12%\"\n        description=\"processing backlog\"\n        icon={ShoppingCartIcon}\n        background=\"var(--color-warning)\"\n        color=\"var(--color-warning-foreground)\"\n      />\n      <CardStatHighlight\n        label=\"Custom Amber\"\n        value={2400000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+18%\"\n        description=\"vs last quarter\"\n        icon={DollarSignIcon}\n        background=\"oklch(0.75 0.18 75)\"\n        color=\"oklch(0.2 0.05 75)\"\n      />\n      <CardStatHighlight\n        label=\"External Token\"\n        value={420000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+12%\"\n        description=\"YTD performance\"\n        icon={TrendingUpIcon}\n        background=\"var(--color-brand, oklch(0.4 0.2 240))\"\n        color=\"white\"\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-card-stat-list",
      "title": "Card Stat List",
      "description": "A statistical card containing a list of labeled items with icons and trend indicators.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat-list",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/card-stat-list.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "items",
          "required": true,
          "type": "CardStatListItem[]"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/CardStatList",
      "stories": [
        {
          "name": "Default",
          "description": "Standard stacked metrics card displaying five performance indicators with trend icons and color-coded values.",
          "args": "{\n    label: \"Performance Overview\",\n    icon: BarChart2Icon,\n    size: \"sm\",\n    items: [\n      {\n        label: \"Sessions\",\n        value: 57891,\n        format: \"integer\",\n        trend: \"up\",\n        trendValue: \"+12%\",\n      },\n      {\n        label: \"Bounce Rate\",\n        value: 0.342,\n        format: \"percent\",\n        decimals: 1,\n        trend: \"down\",\n        trendValue: \"−3pts\",\n      },\n      {\n        label: \"Avg. Duration\",\n        value: \"3m 42s\",\n        trend: \"up\",\n        trendValue: \"+8%\",\n      },\n      {\n        label: \"Conversions\",\n        value: 1284,\n        format: \"integer\",\n        trend: \"up\",\n        trendValue: \"+8%\",\n      },\n      {\n        label: \"Revenue / Session\",\n        value: 2.15,\n        format: \"currency\",\n        trend: \"neutral\",\n        trendValue: \"0%\",\n      },\n    ],\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard stacked metrics card displaying five performance indicators with trend icons and color-coded values.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying two CardStatList placeholders while data is being fetched.",
          "args": "{\n    label: \"Performance Overview\",\n    items: [],\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying two CardStatList placeholders while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatList\n        label=\"Performance Overview\"\n        items={[]}\n        loading\n        icon={BarChart2Icon}\n      />\n      <CardStatList label=\"Top Channels\" items={[]} loading icon={ZapIcon} />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatList\n        label=\"Performance Overview\"\n        items={[]}\n        loading\n        icon={BarChart2Icon}\n      />\n      <CardStatList label=\"Top Channels\" items={[]} loading icon={ZapIcon} />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing two list cards with dash placeholders when no data is available.",
          "args": "{\n    label: \"Performance Overview\",\n    items: [],\n    empty: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing two list cards with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatList\n        label=\"Performance Overview\"\n        items={[]}\n        empty\n        icon={BarChart2Icon}\n      />\n      <CardStatList label=\"Top Channels\" items={[]} empty icon={ZapIcon} />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatList\n        label=\"Performance Overview\"\n        items={[]}\n        empty\n        icon={BarChart2Icon}\n      />\n      <CardStatList label=\"Top Channels\" items={[]} empty icon={ZapIcon} />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStatList component with five performance metrics.",
          "args": "{ label: \"Metric\", items: [] },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStatList component with five performance metrics.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <CardStatList\n            label=\"Performance Overview\"\n            icon={BarChart2Icon}\n            size={size}\n            items={[\n              {\n                label: \"Sessions\",\n                value: 57891,\n                format: \"integer\",\n                trend: \"up\",\n                trendValue: \"+12%\",\n              },\n              {\n                label: \"Bounce Rate\",\n                value: 0.342,\n                format: \"percent\",\n                decimals: 1,\n                trend: \"down\",\n                trendValue: \"−3pts\",\n              },\n              {\n                label: \"Avg. Duration\",\n                value: \"3m 42s\",\n                trend: \"up\",\n                trendValue: \"+8%\",\n              },\n              {\n                label: \"Conversions\",\n                value: 1284,\n                format: \"integer\",\n                trend: \"up\",\n                trendValue: \"+8%\",\n              },\n              {\n                label: \"Revenue / Session\",\n                value: 2.15,\n                format: \"currency\",\n                trend: \"neutral\",\n                trendValue: \"0%\",\n              },\n            ]}\n          />\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <CardStatList\n            label=\"Performance Overview\"\n            icon={BarChart2Icon}\n            size={size}\n            items={[\n              {\n                label: \"Sessions\",\n                value: 57891,\n                format: \"integer\",\n                trend: \"up\",\n                trendValue: \"+12%\",\n              },\n              {\n                label: \"Bounce Rate\",\n                value: 0.342,\n                format: \"percent\",\n                decimals: 1,\n                trend: \"down\",\n                trendValue: \"−3pts\",\n              },\n              {\n                label: \"Avg. Duration\",\n                value: \"3m 42s\",\n                trend: \"up\",\n                trendValue: \"+8%\",\n              },\n              {\n                label: \"Conversions\",\n                value: 1284,\n                format: \"integer\",\n                trend: \"up\",\n                trendValue: \"+8%\",\n              },\n              {\n                label: \"Revenue / Session\",\n                value: 2.15,\n                format: \"currency\",\n                trend: \"neutral\",\n                trendValue: \"0%\",\n              },\n            ]}\n          />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "TopChannels",
          "description": "Demonstrates a marketing channels use case with organic search, direct, social media, email, and paid ads breakdown.",
          "args": "{\n    label: \"Top Channels\",\n    icon: ZapIcon,\n    items: [\n      {\n        label: \"Organic Search\",\n        value: 0.412,\n        format: \"percent\",\n        decimals: 1,\n        trend: \"up\",\n        trendValue: \"+4%\",\n      },\n      {\n        label: \"Direct\",\n        value: 0.227,\n        format: \"percent\",\n        decimals: 1,\n        trend: \"neutral\",\n        trendValue: \"0%\",\n      },\n      {\n        label: \"Social Media\",\n        value: 0.184,\n        format: \"percent\",\n        decimals: 1,\n        trend: \"up\",\n        trendValue: \"+6%\",\n      },\n      {\n        label: \"Email\",\n        value: 0.113,\n        format: \"percent\",\n        decimals: 1,\n        trend: \"down\",\n        trendValue: \"−2%\",\n      },\n      {\n        label: \"Paid Ads\",\n        value: 0.064,\n        format: \"percent\",\n        decimals: 1,\n        trend: \"down\",\n        trendValue: \"−8%\",\n      },\n    ],\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates a marketing channels use case with organic search, direct, social media, email, and paid ads breakdown.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-card-stat-progress",
      "title": "Card Stat Progress",
      "description": "A statistical card with an embedded progress bar for showing completion or attainment levels.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat-progress",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "progress",
        "skeleton"
      ],
      "files": [
        "components/ds/card-stat-progress.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "number"
        },
        {
          "name": "goal",
          "required": true,
          "type": "number"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "showPercent",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Data Display/CardStatProgress",
      "stories": [
        {
          "name": "Default",
          "description": "Standard progress card showing monthly orders at 1,284 out of a 2,000 goal with a color-coded progress bar.",
          "args": "{\n    label: \"Monthly Orders\",\n    value: 1284,\n    goal: 2000,\n    format: \"integer\",\n    decimals: 0,\n    locale: \"en-US\",\n    currency: \"USD\",\n    abbreviate: false,\n    description: \"Target by end of month\",\n    icon: ShoppingCartIcon,\n    size: \"sm\",\n    showPercent: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard progress card showing monthly orders at 1,284 out of a 2,000 goal with a color-coded progress bar.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying three CardStatProgress placeholders while data is being fetched.",
          "args": "{\n    label: \"Monthly Orders\",\n    value: 0,\n    goal: 100,\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying three CardStatProgress placeholders while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n      <CardStatProgress\n        label=\"Monthly Orders\"\n        value={0}\n        goal={100}\n        loading\n        icon={ShoppingCartIcon}\n      />\n      <CardStatProgress\n        label=\"Revenue Goal\"\n        value={0}\n        goal={100}\n        loading\n        icon={DollarSignIcon}\n      />\n      <CardStatProgress\n        label=\"New Customers\"\n        value={0}\n        goal={100}\n        loading\n        icon={UsersIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n      <CardStatProgress\n        label=\"Monthly Orders\"\n        value={0}\n        goal={100}\n        loading\n        icon={ShoppingCartIcon}\n      />\n      <CardStatProgress\n        label=\"Revenue Goal\"\n        value={0}\n        goal={100}\n        loading\n        icon={DollarSignIcon}\n      />\n      <CardStatProgress\n        label=\"New Customers\"\n        value={0}\n        goal={100}\n        loading\n        icon={UsersIcon}\n      />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing three progress cards with dash placeholders when no data is available.",
          "args": "{\n    label: \"Monthly Orders\",\n    value: 0,\n    goal: 100,\n    empty: true,\n    icon: ShoppingCartIcon,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing three progress cards with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n      <CardStatProgress\n        label=\"Monthly Orders\"\n        value={0}\n        goal={100}\n        empty\n        icon={ShoppingCartIcon}\n      />\n      <CardStatProgress\n        label=\"Revenue Goal\"\n        value={0}\n        goal={100}\n        empty\n        icon={DollarSignIcon}\n      />\n      <CardStatProgress\n        label=\"New Customers\"\n        value={0}\n        goal={100}\n        empty\n        icon={UsersIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n      <CardStatProgress\n        label=\"Monthly Orders\"\n        value={0}\n        goal={100}\n        empty\n        icon={ShoppingCartIcon}\n      />\n      <CardStatProgress\n        label=\"Revenue Goal\"\n        value={0}\n        goal={100}\n        empty\n        icon={DollarSignIcon}\n      />\n      <CardStatProgress\n        label=\"New Customers\"\n        value={0}\n        goal={100}\n        empty\n        icon={UsersIcon}\n      />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStatProgress component with orders, revenue, and customer goals.",
          "args": "{ label: \"Goal\", value: 0, goal: 100 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStatProgress component with orders, revenue, and customer goals.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n            <CardStatProgress\n              label=\"Monthly Orders\"\n              value={1284}\n              goal={2000}\n              format=\"integer\"\n              description=\"Target by end of month\"\n              icon={ShoppingCartIcon}\n              size={size}\n            />\n            <CardStatProgress\n              label=\"Revenue Goal\"\n              value={87500}\n              goal={100000}\n              format=\"currency\"\n              description=\"Q4 quarterly target\"\n              icon={DollarSignIcon}\n              size={size}\n            />\n            <CardStatProgress\n              label=\"New Customers\"\n              value={314}\n              goal={500}\n              format=\"integer\"\n              description=\"Acquisition campaign\"\n              icon={UsersIcon}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n            <CardStatProgress\n              label=\"Monthly Orders\"\n              value={1284}\n              goal={2000}\n              format=\"integer\"\n              description=\"Target by end of month\"\n              icon={ShoppingCartIcon}\n              size={size}\n            />\n            <CardStatProgress\n              label=\"Revenue Goal\"\n              value={87500}\n              goal={100000}\n              format=\"currency\"\n              description=\"Q4 quarterly target\"\n              icon={DollarSignIcon}\n              size={size}\n            />\n            <CardStatProgress\n              label=\"New Customers\"\n              value={314}\n              goal={500}\n              format=\"integer\"\n              description=\"Acquisition campaign\"\n              icon={UsersIcon}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllGoals",
          "description": "Demonstrates three goal progress scenarios — monthly orders at 64%, revenue at 87%, and new customers at 63%.",
          "args": "{\n    label: \"Goal\",\n    value: 0,\n    goal: 100,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates three goal progress scenarios — monthly orders at 64%, revenue at 87%, and new customers at 63%.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n      <CardStatProgress\n        label=\"Monthly Orders\"\n        value={1284}\n        goal={2000}\n        format=\"integer\"\n        description=\"Target by end of month\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatProgress\n        label=\"Revenue Goal\"\n        value={87500}\n        goal={100000}\n        format=\"currency\"\n        description=\"Q4 quarterly target\"\n        icon={DollarSignIcon}\n      />\n      <CardStatProgress\n        label=\"New Customers\"\n        value={314}\n        goal={500}\n        format=\"integer\"\n        description=\"Acquisition campaign\"\n        icon={UsersIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n      <CardStatProgress\n        label=\"Monthly Orders\"\n        value={1284}\n        goal={2000}\n        format=\"integer\"\n        description=\"Target by end of month\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatProgress\n        label=\"Revenue Goal\"\n        value={87500}\n        goal={100000}\n        format=\"currency\"\n        description=\"Q4 quarterly target\"\n        icon={DollarSignIcon}\n      />\n      <CardStatProgress\n        label=\"New Customers\"\n        value={314}\n        goal={500}\n        format=\"integer\"\n        description=\"Acquisition campaign\"\n        icon={UsersIcon}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-card-stat-sparkline",
      "title": "Card Stat Sparkline",
      "description": "A statistical card with an inline sparkline chart for visual trend representation.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stat-sparkline",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "card-stat-shared",
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/card-stat-sparkline.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "string | number"
        },
        {
          "name": "data",
          "required": false,
          "type": "number[]"
        },
        {
          "name": "trend",
          "required": false,
          "type": "CardStatTrend | boolean"
        },
        {
          "name": "trendValue",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType"
        },
        {
          "name": "size",
          "required": false,
          "type": "CardStatSize"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "empty",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/CardStatSparkline",
      "stories": [
        {
          "name": "Default",
          "description": "Standard sparkline card showing weekly sessions with an upward Catmull-Rom SVG line chart and trend badge.",
          "args": "{\n    label: \"Weekly Sessions\",\n    value: 57891,\n    format: \"integer\",\n    decimals: 0,\n    locale: \"en-US\",\n    currency: \"USD\",\n    abbreviate: false,\n    data: WEEKLY_SESSIONS,\n    trend: \"up\",\n    trendValue: \"+5.2% vs last week\",\n    icon: EyeIcon,\n    size: \"sm\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Standard sparkline card showing weekly sessions with an upward Catmull-Rom SVG line chart and trend badge.\",\n      },\n    },\n  },"
        },
        {
          "name": "PercentLocale",
          "description": "Regression check: `value` is a 0-1 fraction rendered with `format=\"percent\"`. The two cards use the same value with different `locale` — the headline must respect the decimal separator (\"32,4%\" for pt-BR vs \"32.4%\" for en-US).",
          "args": "{\n    label: \"Bounce Rate\",\n    value: 0.324,\n    data: WEEKLY_BOUNCE,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'Regression check: `value` is a 0-1 fraction rendered with `format=\"percent\"`. The two cards use the same value with different `locale` — the headline must respect the decimal separator (\"32,4%\" for pt-BR vs \"32.4%\" for en-US).',\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatSparkline\n        label=\"Taxa de Rejeição\"\n        value={0.324}\n        format=\"percent\"\n        decimals={1}\n        locale=\"pt-BR\"\n        data={WEEKLY_BOUNCE}\n        trend=\"down\"\n        trendValue=\"−5,9% vs. semana anterior\"\n        icon={ActivityIcon}\n      />\n      <CardStatSparkline\n        label=\"Bounce Rate\"\n        value={0.324}\n        format=\"percent\"\n        decimals={1}\n        locale=\"en-US\"\n        data={WEEKLY_BOUNCE}\n        trend=\"down\"\n        trendValue=\"−5.9% vs last week\"\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n      <CardStatSparkline\n        label=\"Taxa de Rejeição\"\n        value={0.324}\n        format=\"percent\"\n        decimals={1}\n        locale=\"pt-BR\"\n        data={WEEKLY_BOUNCE}\n        trend=\"down\"\n        trendValue=\"−5,9% vs. semana anterior\"\n        icon={ActivityIcon}\n      />\n      <CardStatSparkline\n        label=\"Bounce Rate\"\n        value={0.324}\n        format=\"percent\"\n        decimals={1}\n        locale=\"en-US\"\n        data={WEEKLY_BOUNCE}\n        trend=\"down\"\n        trendValue=\"−5.9% vs last week\"\n        icon={ActivityIcon}\n      />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "Loading skeleton state displaying four CardStatSparkline placeholders while data is being fetched.",
          "args": "{\n    label: \"Weekly Sessions\",\n    value: 0,\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading skeleton state displaying four CardStatSparkline placeholders while data is being fetched.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatSparkline\n        label=\"Weekly Sessions\"\n        value={0}\n        loading\n        icon={EyeIcon}\n      />\n      <CardStatSparkline\n        label=\"Revenue\"\n        value={0}\n        loading\n        icon={DollarSignIcon}\n      />\n      <CardStatSparkline\n        label=\"Orders\"\n        value={0}\n        loading\n        icon={ShoppingCartIcon}\n      />\n      <CardStatSparkline\n        label=\"Bounce Rate\"\n        value={0}\n        loading\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatSparkline\n        label=\"Weekly Sessions\"\n        value={0}\n        loading\n        icon={EyeIcon}\n      />\n      <CardStatSparkline\n        label=\"Revenue\"\n        value={0}\n        loading\n        icon={DollarSignIcon}\n      />\n      <CardStatSparkline\n        label=\"Orders\"\n        value={0}\n        loading\n        icon={ShoppingCartIcon}\n      />\n      <CardStatSparkline\n        label=\"Bounce Rate\"\n        value={0}\n        loading\n        icon={ActivityIcon}\n      />\n    </div>"
        },
        {
          "name": "EmptyState",
          "description": "Empty state showing four sparkline cards with dash placeholders when no data is available.",
          "args": "{\n    label: \"Weekly Sessions\",\n    value: 0,\n    empty: true,\n    icon: EyeIcon,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state showing four sparkline cards with dash placeholders when no data is available.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatSparkline\n        label=\"Weekly Sessions\"\n        value={0}\n        empty\n        icon={EyeIcon}\n      />\n      <CardStatSparkline\n        label=\"Revenue\"\n        value={0}\n        empty\n        icon={DollarSignIcon}\n      />\n      <CardStatSparkline\n        label=\"Orders\"\n        value={0}\n        empty\n        icon={ShoppingCartIcon}\n      />\n      <CardStatSparkline\n        label=\"Bounce Rate\"\n        value={0}\n        empty\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatSparkline\n        label=\"Weekly Sessions\"\n        value={0}\n        empty\n        icon={EyeIcon}\n      />\n      <CardStatSparkline\n        label=\"Revenue\"\n        value={0}\n        empty\n        icon={DollarSignIcon}\n      />\n      <CardStatSparkline\n        label=\"Orders\"\n        value={0}\n        empty\n        icon={ShoppingCartIcon}\n      />\n      <CardStatSparkline\n        label=\"Bounce Rate\"\n        value={0}\n        empty\n        icon={ActivityIcon}\n      />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison across sm, md, and lg size presets for the CardStatSparkline component with sessions, revenue, orders, and bounce rate.",
          "args": "{ label: \"Metric\", value: 0, data: [] },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison across sm, md, and lg size presets for the CardStatSparkline component with sessions, revenue, orders, and bounce rate.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n            <CardStatSparkline\n              label=\"Weekly Sessions\"\n              value={57891}\n              format=\"integer\"\n              data={WEEKLY_SESSIONS}\n              trend=\"up\"\n              trendValue=\"+5.2% vs last week\"\n              icon={EyeIcon}\n              size={size}\n            />\n            <CardStatSparkline\n              label=\"Revenue\"\n              value={31750}\n              format=\"currency\"\n              data={WEEKLY_REVENUE}\n              trend=\"up\"\n              trendValue=\"+11.8% vs last week\"\n              icon={DollarSignIcon}\n              size={size}\n            />\n            <CardStatSparkline\n              label=\"Orders\"\n              value={521}\n              format=\"integer\"\n              data={WEEKLY_ORDERS}\n              trend=\"up\"\n              trendValue=\"+15.2% vs last week\"\n              icon={ShoppingCartIcon}\n              size={size}\n            />\n            <CardStatSparkline\n              label=\"Bounce Rate\"\n              value={0.324}\n              format=\"percent\"\n              decimals={1}\n              data={WEEKLY_BOUNCE}\n              trend=\"down\"\n              trendValue=\"−5.9% vs last week\"\n              icon={ActivityIcon}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <p className=\"font-mono text-xs text-muted-foreground\">\n            {`size=\"${size}\"`}\n          </p>\n          <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n            <CardStatSparkline\n              label=\"Weekly Sessions\"\n              value={57891}\n              format=\"integer\"\n              data={WEEKLY_SESSIONS}\n              trend=\"up\"\n              trendValue=\"+5.2% vs last week\"\n              icon={EyeIcon}\n              size={size}\n            />\n            <CardStatSparkline\n              label=\"Revenue\"\n              value={31750}\n              format=\"currency\"\n              data={WEEKLY_REVENUE}\n              trend=\"up\"\n              trendValue=\"+11.8% vs last week\"\n              icon={DollarSignIcon}\n              size={size}\n            />\n            <CardStatSparkline\n              label=\"Orders\"\n              value={521}\n              format=\"integer\"\n              data={WEEKLY_ORDERS}\n              trend=\"up\"\n              trendValue=\"+15.2% vs last week\"\n              icon={ShoppingCartIcon}\n              size={size}\n            />\n            <CardStatSparkline\n              label=\"Bounce Rate\"\n              value={0.324}\n              format=\"percent\"\n              decimals={1}\n              data={WEEKLY_BOUNCE}\n              trend=\"down\"\n              trendValue=\"−5.9% vs last week\"\n              icon={ActivityIcon}\n              size={size}\n            />\n          </div>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllMetrics",
          "description": "Demonstrates four sparkline metrics — weekly sessions, revenue, orders, and bounce rate — with up and down trends.",
          "args": "{\n    label: \"Metric\",\n    value: 0,\n    data: [],\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Demonstrates four sparkline metrics — weekly sessions, revenue, orders, and bounce rate — with up and down trends.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatSparkline\n        label=\"Weekly Sessions\"\n        value={57891}\n        format=\"integer\"\n        data={WEEKLY_SESSIONS}\n        trend=\"up\"\n        trendValue=\"+5.2% vs last week\"\n        icon={EyeIcon}\n      />\n      <CardStatSparkline\n        label=\"Revenue\"\n        value={31750}\n        format=\"currency\"\n        data={WEEKLY_REVENUE}\n        trend=\"up\"\n        trendValue=\"+11.8% vs last week\"\n        icon={DollarSignIcon}\n      />\n      <CardStatSparkline\n        label=\"Orders\"\n        value={521}\n        format=\"integer\"\n        data={WEEKLY_ORDERS}\n        trend=\"up\"\n        trendValue=\"+15.2% vs last week\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatSparkline\n        label=\"Bounce Rate\"\n        value={0.324}\n        format=\"percent\"\n        decimals={1}\n        data={WEEKLY_BOUNCE}\n        trend=\"down\"\n        trendValue=\"−5.9% vs last week\"\n        icon={ActivityIcon}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n      <CardStatSparkline\n        label=\"Weekly Sessions\"\n        value={57891}\n        format=\"integer\"\n        data={WEEKLY_SESSIONS}\n        trend=\"up\"\n        trendValue=\"+5.2% vs last week\"\n        icon={EyeIcon}\n      />\n      <CardStatSparkline\n        label=\"Revenue\"\n        value={31750}\n        format=\"currency\"\n        data={WEEKLY_REVENUE}\n        trend=\"up\"\n        trendValue=\"+11.8% vs last week\"\n        icon={DollarSignIcon}\n      />\n      <CardStatSparkline\n        label=\"Orders\"\n        value={521}\n        format=\"integer\"\n        data={WEEKLY_ORDERS}\n        trend=\"up\"\n        trendValue=\"+15.2% vs last week\"\n        icon={ShoppingCartIcon}\n      />\n      <CardStatSparkline\n        label=\"Bounce Rate\"\n        value={0.324}\n        format=\"percent\"\n        decimals={1}\n        data={WEEKLY_BOUNCE}\n        trend=\"down\"\n        trendValue=\"−5.9% vs last week\"\n        icon={ActivityIcon}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-card-stats",
      "title": "Card Stats (All)",
      "description": "A portfolio of all statistical display cards: CardStat, CardStatCompact, CardStatProgress, CardStatComparison, CardStatSparkline, CardStatHighlight, CardStatList, CardStatGauge, and CardStatHeatbar.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/card-stats",
      "dependencies": [],
      "registryDependencies": [
        "ds-card-stat",
        "ds-card-stat-compact",
        "ds-card-stat-progress",
        "ds-card-stat-comparison",
        "ds-card-stat-sparkline",
        "ds-card-stat-highlight",
        "ds-card-stat-list",
        "ds-card-stat-gauge",
        "ds-card-stat-heatbar"
      ],
      "files": [
        "components/ds/card-stats.tsx"
      ],
      "storyTitle": "Data Display/CardStatsDashboard",
      "props": [],
      "stories": [
        {
          "name": "Dashboard",
          "description": "Full dashboard layout combining all CardStat variants — compact counters, sparklines, comparison, progress, gauge, heatbar, and list components in a realistic grid.",
          "code": "<div className=\"flex min-h-screen flex-col gap-4 rounded-2xl bg-muted/30 p-6\">\n      <CardStat\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"No change this week\"\n        trend=\"neutral\"\n        icon={UsersIcon}\n      />\n      {/* Banner KPI */}\n      <CardStatHighlight\n        label=\"Total Revenue — Q4 2024\"\n        value={2400000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+18% YoY\"\n        description=\"ahead of forecast\"\n        icon={TrendingUpIcon}\n        variant=\"emerald\"\n      />\n\n      {/* Row 1 — compact counters */}\n      <div className=\"grid grid-cols-2 gap-3 lg:grid-cols-4\">\n        <CardStatCompact\n          label=\"Sessions\"\n          value={57891}\n          format=\"integer\"\n          trend=\"up\"\n          trendValue=\"+12.4%\"\n          icon={EyeIcon}\n        />\n        <CardStatCompact\n          label=\"Orders\"\n          value={1847}\n          format=\"integer\"\n          trend=\"up\"\n          trendValue=\"+8.1%\"\n          icon={ShoppingCartIcon}\n        />\n        <CardStatCompact\n          label=\"Avg. Order Value\"\n          value={67.4}\n          format=\"currency\"\n          trend=\"up\"\n          trendValue=\"+$4.20\"\n          icon={DollarSignIcon}\n        />\n        <CardStatCompact\n          label=\"Churn Rate\"\n          value={0.024}\n          format=\"percent\"\n          decimals={1}\n          trend=\"down\"\n          trendValue=\"−0.8%\"\n          icon={ActivityIcon}\n        />\n      </div>\n\n      {/* Row 2 — sparklines */}\n      <div className=\"grid grid-cols-2 gap-3 lg:grid-cols-4\">\n        <CardStatSparkline\n          label=\"Weekly Sessions\"\n          value={57891}\n          format=\"integer\"\n          data={WEEKLY_SESSIONS}\n          trend=\"up\"\n          trendValue=\"+5.2%\"\n          icon={EyeIcon}\n        />\n        <CardStatSparkline\n          label=\"Weekly Revenue\"\n          value={31750}\n          format=\"currency\"\n          data={WEEKLY_REVENUE}\n          trend=\"up\"\n          trendValue=\"+11.8%\"\n          icon={DollarSignIcon}\n        />\n        <CardStatSparkline\n          label=\"Weekly Orders\"\n          value={521}\n          format=\"integer\"\n          data={WEEKLY_ORDERS}\n          trend=\"up\"\n          trendValue=\"+15.2%\"\n          icon={ShoppingCartIcon}\n        />\n        <CardStatSparkline\n          label=\"Bounce Rate\"\n          value={0.324}\n          format=\"percent\"\n          decimals={1}\n          data={WEEKLY_BOUNCE}\n          trend=\"down\"\n          trendValue=\"−5.9%\"\n          icon={ActivityIcon}\n        />\n      </div>\n\n      {/* Row 3 — comparison + progress */}\n      <div className=\"grid grid-cols-1 gap-3 lg:grid-cols-3\">\n        <CardStatComparison\n          label=\"Monthly Revenue\"\n          current={124500}\n          previous={98200}\n          format=\"currency\"\n          currentLabel=\"This month\"\n          previousLabel=\"Last month\"\n          icon={DollarSignIcon}\n        />\n        <CardStatProgress\n          label=\"Monthly Orders Goal\"\n          value={1284}\n          goal={2000}\n          format=\"integer\"\n          description=\"Target by end of month\"\n          icon={ShoppingCartIcon}\n        />\n        <CardStatProgress\n          label=\"Revenue Goal\"\n          value={87500}\n          goal={100000}\n          format=\"currency\"\n          description=\"Q4 quarterly target\"\n          icon={DollarSignIcon}\n        />\n      </div>\n\n      {/* Row 4 — gauge + heatbar + list */}\n      <div className=\"grid grid-cols-1 gap-3 lg:grid-cols-3\">\n        <div className=\"grid grid-cols-2 gap-3\">\n          <CardStatGauge\n            label=\"NPS Score\"\n            value={78}\n            min={0}\n            max={100}\n            description=\"Customer loyalty\"\n          />\n          <CardStatGauge\n            label=\"Quality\"\n            value={91}\n            min={0}\n            max={100}\n            description=\"Code pipeline\"\n            icon={ShieldCheckIcon}\n          />\n        </div>\n        <CardStatHeatbar\n          label=\"Customer Satisfaction\"\n          value={87}\n          description=\"Based on 2,847 responses this month\"\n          icon={HeartIcon}\n        />\n        <CardStatList\n          label=\"Performance Overview\"\n          icon={BarChart2Icon}\n          items={[\n            {\n              label: \"Sessions\",\n              value: 57891,\n              format: \"integer\",\n              trend: \"up\",\n              trendValue: \"+12%\",\n            },\n            {\n              label: \"Bounce Rate\",\n              value: 0.342,\n              format: \"percent\",\n              decimals: 1,\n              trend: \"down\",\n              trendValue: \"−3pts\",\n            },\n            {\n              label: \"Avg. Duration\",\n              value: \"3m 42s\",\n              trend: \"up\",\n              trendValue: \"+8%\",\n            },\n            {\n              label: \"Conversions\",\n              value: 1284,\n              format: \"integer\",\n              trend: \"up\",\n              trendValue: \"+8%\",\n            },\n          ]}\n        />\n      </div>\n    </div>"
        },
        {
          "name": "DashboardWithIconMiniCards",
          "description": "Adds an extra row of mini icon cards at the bottom — ultra-compact `CardStatCompact` with `size='sm'` showing only icons and minimal data.",
          "code": "<div className=\"flex min-h-screen flex-col gap-4 rounded-2xl bg-muted/30 p-6\">\n      <CardStat\n        label=\"Active Users\"\n        value={15309}\n        format=\"integer\"\n        description=\"No change this week\"\n        trend=\"neutral\"\n        icon={UsersIcon}\n      />\n      <CardStatHighlight\n        label=\"Total Revenue — Q4 2024\"\n        value={2400000}\n        format=\"currency\"\n        trend=\"up\"\n        trendValue=\"+18% YoY\"\n        description=\"ahead of forecast\"\n        icon={TrendingUpIcon}\n        variant=\"emerald\"\n      />\n      <div className=\"grid grid-cols-2 gap-3 lg:grid-cols-4\">\n        <CardStatCompact\n          label=\"Sessions\"\n          value={57891}\n          format=\"integer\"\n          trend=\"up\"\n          trendValue=\"+12.4%\"\n          icon={EyeIcon}\n        />\n        <CardStatCompact\n          label=\"Orders\"\n          value={1847}\n          format=\"integer\"\n          trend=\"up\"\n          trendValue=\"+8.1%\"\n          icon={ShoppingCartIcon}\n        />\n        <CardStatCompact\n          label=\"Avg. Order Value\"\n          value={67.4}\n          format=\"currency\"\n          trend=\"up\"\n          trendValue=\"+$4.20\"\n          icon={DollarSignIcon}\n        />\n        <CardStatCompact\n          label=\"Churn Rate\"\n          value={0.024}\n          format=\"percent\"\n          decimals={1}\n          trend=\"down\"\n          trendValue=\"−0.8%\"\n          icon={ActivityIcon}\n        />\n      </div>\n      <div className=\"grid grid-cols-2 gap-3 lg:grid-cols-4\">\n        <CardStatSparkline\n          label=\"Weekly Sessions\"\n          value={57891}\n          format=\"integer\"\n          data={WEEKLY_SESSIONS}\n          trend=\"up\"\n          trendValue=\"+5.2%\"\n          icon={EyeIcon}\n        />\n        <CardStatSparkline\n          label=\"Weekly Revenue\"\n          value={31750}\n          format=\"currency\"\n          data={WEEKLY_REVENUE}\n          trend=\"up\"\n          trendValue=\"+11.8%\"\n          icon={DollarSignIcon}\n        />\n        <CardStatSparkline\n          label=\"Weekly Orders\"\n          value={521}\n          format=\"integer\"\n          data={WEEKLY_ORDERS}\n          trend=\"up\"\n          trendValue=\"+15.2%\"\n          icon={ShoppingCartIcon}\n        />\n        <CardStatSparkline\n          label=\"Bounce Rate\"\n          value={0.324}\n          format=\"percent\"\n          decimals={1}\n          data={WEEKLY_BOUNCE}\n          trend=\"down\"\n          trendValue=\"−5.9%\"\n          icon={ActivityIcon}\n        />\n      </div>\n      <div className=\"grid grid-cols-1 gap-3 lg:grid-cols-3\">\n        <CardStatComparison\n          label=\"Monthly Revenue\"\n          current={124500}\n          previous={98200}\n          format=\"currency\"\n          currentLabel=\"This month\"\n          previousLabel=\"Last month\"\n          icon={DollarSignIcon}\n        />\n        <CardStatProgress\n          label=\"Monthly Orders Goal\"\n          value={1284}\n          goal={2000}\n          format=\"integer\"\n          description=\"Target by end of month\"\n          icon={ShoppingCartIcon}\n        />\n        <CardStatProgress\n          label=\"Revenue Goal\"\n          value={87500}\n          goal={100000}\n          format=\"currency\"\n          description=\"Q4 quarterly target\"\n          icon={DollarSignIcon}\n        />\n      </div>\n      <div className=\"grid grid-cols-1 gap-3 lg:grid-cols-3\">\n        <div className=\"grid grid-cols-2 gap-3\">\n          <CardStatGauge\n            label=\"NPS Score\"\n            value={78}\n            min={0}\n            max={100}\n            description=\"Customer loyalty\"\n          />\n          <CardStatGauge\n            label=\"Quality\"\n            value={91}\n            min={0}\n            max={100}\n            description=\"Code pipeline\"\n            icon={ShieldCheckIcon}\n          />\n        </div>\n        <CardStatHeatbar\n          label=\"Customer Satisfaction\"\n          value={87}\n          description=\"Based on 2,847 responses this month\"\n          icon={HeartIcon}\n        />\n        <CardStatList\n          label=\"Performance Overview\"\n          icon={BarChart2Icon}\n          items={[\n            {\n              label: \"Sessions\",\n              value: 57891,\n              format: \"integer\",\n              trend: \"up\",\n              trendValue: \"+12%\",\n            },\n            {\n              label: \"Bounce Rate\",\n              value: 0.342,\n              format: \"percent\",\n              decimals: 1,\n              trend: \"down\",\n              trendValue: \"−3pts\",\n            },\n            {\n              label: \"Avg. Duration\",\n              value: \"3m 42s\",\n              trend: \"up\",\n              trendValue: \"+8%\",\n            },\n            {\n              label: \"Conversions\",\n              value: 1284,\n              format: \"integer\",\n              trend: \"up\",\n              trendValue: \"+8%\",\n            },\n          ]}\n        />\n      </div>\n\n      {/* ── Row 5 — Mini Icon Cards ── */}\n      <h3 className=\"mt-2 text-sm font-semibold text-muted-foreground\">\n        Mini Icon Cards\n      </h3>\n      <div className=\"grid grid-cols-3 gap-2 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8\">\n        <CardStatCompact\n          label=\"Users\"\n          value={15309}\n          format=\"integer\"\n          icon={UsersIcon}\n          size=\"sm\"\n          variant=\"muted\"\n        />\n        <CardStatCompact\n          label=\"Revenue\"\n          value={31750}\n          format=\"currency\"\n          icon={DollarSignIcon}\n          size=\"sm\"\n          variant=\"muted\"\n        />\n        <CardStatCompact\n          label=\"Orders\"\n          value={521}\n          format=\"integer\"\n          icon={ShoppingCartIcon}\n          size=\"sm\"\n          variant=\"muted\"\n        />\n        <CardStatCompact\n          label=\"Sessions\"\n          value={57891}\n          format=\"integer\"\n          icon={EyeIcon}\n          size=\"sm\"\n          variant=\"muted\"\n        />\n        <CardStatCompact\n          label=\"Churn\"\n          value={0.024}\n          format=\"percent\"\n          decimals={1}\n          trend=\"down\"\n          trendValue=\"−0.8%\"\n          icon={ActivityIcon}\n          size=\"sm\"\n          variant=\"muted\"\n        />\n        <CardStatCompact\n          label=\"NPS\"\n          value={78}\n          format=\"integer\"\n          icon={ShieldCheckIcon}\n          size=\"sm\"\n          variant=\"muted\"\n        />\n        <CardStatCompact\n          label=\"Satisfaction\"\n          value={0.87}\n          format=\"percent\"\n          decimals={0}\n          icon={HeartIcon}\n          size=\"sm\"\n          variant=\"muted\"\n        />\n        <CardStatCompact\n          label=\"Conversions\"\n          value={1284}\n          format=\"integer\"\n          icon={BarChart2Icon}\n          size=\"sm\"\n          variant=\"muted\"\n        />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-carousel",
      "title": "Carousel UI",
      "description": "Extended carousel with autoplay support via embla-carousel-autoplay, multiple nav variants (side/overlay/bottom/none), card/showcase/minimal display modes, dot indicators, responsive slides-per-view, external API control via setApi, i18n aria-labels, and skeleton loading. Wraps the shadcn Carousel primitive.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/carousel",
      "dependencies": [
        "embla-carousel-autoplay",
        "embla-carousel-react",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "carousel",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/carousel.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "CarouselVariant"
        },
        {
          "name": "orientation",
          "required": false,
          "type": "\"horizontal\" | \"vertical\""
        },
        {
          "name": "setApi",
          "required": false,
          "type": "(api: CarouselApi) => void"
        },
        {
          "name": "slidesPerView",
          "required": false,
          "type": "number | CarouselSlidesPerView"
        },
        {
          "name": "autoplayInterval",
          "required": false,
          "type": "number"
        },
        {
          "name": "pauseOnHover",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showDots",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showProgress",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loadingSlideCount",
          "required": false,
          "type": "number"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "navVariant",
          "required": false,
          "type": "CarouselNavVariant"
        },
        {
          "name": "navSize",
          "required": false,
          "type": "CarouselNavSize"
        },
        {
          "name": "navPosition",
          "required": false,
          "type": "CarouselNavPosition"
        },
        {
          "name": "dotVariant",
          "required": false,
          "type": "CarouselDotVariant"
        },
        {
          "name": "dotPosition",
          "required": false,
          "type": "CarouselDotPosition"
        },
        {
          "name": "loop",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "align",
          "required": false,
          "type": "\"start\" | \"center\" | \"end\""
        },
        {
          "name": "skipSnaps",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "children",
          "required": false,
          "type": "React.ReactNode"
        }
      ],
      "storyTitle": "Navigation/Carousel",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    variant: \"default\",\n    orientation: \"horizontal\",\n    pauseOnHover: true,\n    showDots: true,\n    showProgress: false,\n    loading: false,\n    loadingSlideCount: 4,\n    locale: \"pt-BR\",\n    navVariant: \"outline\",\n    navSize: \"icon-sm\",\n    dotVariant: \"filled\",\n    dotPosition: \"bottom\",\n    loop: false,\n    align: \"start\",\n    skipSnaps: false,\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        },
        {
          "name": "Cards",
          "description": "",
          "args": "{\n    variant: \"cards\",\n    slidesPerView: { sm: 1, md: 2, lg: 3 },\n    showDots: true,\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => (\n        <div\n          key={i}\n          className=\"flex h-64 flex-col items-center justify-center gap-2 p-6\"\n        >\n          <span className=\"text-4xl font-bold text-foreground\">{i + 1}</span>\n          <span className=\"text-sm text-muted-foreground\">\n            Card item {i + 1}\n          </span>\n        </div>\n      ))}\n    </Carousel>\n  ),"
        },
        {
          "name": "Showcase",
          "description": "",
          "args": "{\n    variant: \"showcase\",\n    navPosition: \"overlay\",\n    showDots: true,\n    dotPosition: \"overlay\",\n    navVariant: \"primary\",\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 5 }).map((_, i) => (\n        <div\n          key={i}\n          className={`flex h-80 items-center justify-center text-3xl font-bold ${i % 2 === 0 ? \"bg-primary text-primary-foreground\" : \"bg-secondary text-secondary-foreground\"}`}\n        >\n          Showcase {i + 1}\n        </div>\n      ))}\n    </Carousel>\n  ),"
        },
        {
          "name": "Minimal",
          "description": "",
          "args": "{ variant: \"minimal\", showDots: true },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        },
        {
          "name": "Autoplay",
          "description": "",
          "args": "{\n    variant: \"default\",\n    autoplayInterval: 3000,\n    loop: true,\n    showDots: true,\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        },
        {
          "name": "WithProgress",
          "description": "",
          "args": "{\n    variant: \"default\",\n    showProgress: true,\n    showDots: true,\n    loop: true,\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        },
        {
          "name": "PrimaryNav",
          "description": "",
          "args": "{\n    variant: \"default\",\n    navVariant: \"primary\",\n    showDots: true,\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        },
        {
          "name": "SecondaryNav",
          "description": "",
          "args": "{\n    variant: \"default\",\n    navVariant: \"secondary\",\n    showDots: true,\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        },
        {
          "name": "Vertical",
          "description": "",
          "args": "{\n    variant: \"default\",\n    orientation: \"vertical\",\n    showDots: true,\n  },\n  render: (args) => (\n    <div className=\"flex justify-center\">\n      <Carousel className=\"h-80 w-64\" {...args}>\n        {Array.from({ length: 6 }).map((_, i) => (\n          <div\n            key={i}\n            className=\"flex h-32 items-center justify-center rounded-xl bg-muted text-2xl font-medium text-muted-foreground\"\n          >\n            {i + 1}\n          </div>\n        ))}\n      </Carousel>\n    </div>\n  ),"
        },
        {
          "name": "MultipleSlides",
          "description": "",
          "args": "{\n    variant: \"default\",\n    slidesPerView: { sm: 1, md: 2, lg: 3 },\n    showDots: true,\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 9 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true, loadingSlideCount: 4 },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        },
        {
          "name": "OverlayDots",
          "description": "",
          "args": "{\n    variant: \"default\",\n    dotPosition: \"overlay\",\n    showDots: true,\n  },\n  render: (args) => (\n    <Carousel className=\"mx-16\" {...args}>\n      {Array.from({ length: 6 }).map((_, i) => slide(i))}\n    </Carousel>\n  ),"
        }
      ]
    },
    {
      "name": "ds-cascader",
      "title": "Cascader",
      "description": "Seleção em cascata níveis — ReUI Cascader.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/cascader",
      "dependencies": [],
      "registryDependencies": [
        "popover",
        "button"
      ],
      "files": [
        "components/ds/cascader.tsx"
      ],
      "props": [
        {
          "name": "options",
          "required": true,
          "type": "CascaderOption[]"
        },
        {
          "name": "value",
          "required": false,
          "type": "string[]"
        },
        {
          "name": "onValueChange",
          "required": false,
          "type": "(value: string[]) => void"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/Cascader",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    options: [\n      {\n        label: \"Brazil\",\n        value: \"br\",\n        children: [\n          { label: \"SP\", value: \"sp\" },\n          { label: \"RJ\", value: \"rj\" },\n        ],\n      },\n      { label: \"USA\", value: \"us\", children: [{ label: \"NY\", value: \"ny\" }] },\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-changelog",
      "title": "Changelog",
      "description": "Visualização estruturada de release notes com categorização semântica e timeline de versões.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/changelog",
      "dependencies": [
        "date-fns",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/changelog.tsx"
      ],
      "props": [
        {
          "name": "releases",
          "required": true,
          "type": "ChangelogRelease[]",
          "description": "Release list in descending chronological order."
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Loading state."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Localization setting."
        }
      ],
      "storyTitle": "Data Display/Changelog",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    locale: \"pt-BR\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByText(\"v1.11.0\")).toBeInTheDocument()\n    await expect(canvas.getByText(\"v1.10.0\")).toBeInTheDocument()\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex max-w-xl flex-col gap-8\">\n      <div>\n        <span className=\"block pb-2 text-xs font-semibold text-muted-foreground\">\n          pt-BR:\n        </span>\n        <Changelog locale=\"pt-BR\" releases={sampleReleases.slice(0, 1)} />\n      </div>\n      <div>\n        <span className=\"block pb-2 text-xs font-semibold text-muted-foreground\">\n          en-US:\n        </span>\n        <Changelog locale=\"en-US\" releases={sampleReleases.slice(0, 1)} />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-checkout",
      "title": "Checkout",
      "description": "Resumo de pedido — ReUI Checkout.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/checkout",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "button",
        "separator",
        "skeleton"
      ],
      "files": [
        "components/ds/checkout.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "CheckoutItem[]"
        },
        {
          "name": "total",
          "required": true,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Commerce/Checkout",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items: [{ name: \"Shoes\", price: \"$99\", quantity: 1 }], total: \"$99\" },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ items: [], total: \"x\", loading: true }"
        }
      ]
    },
    {
      "name": "ds-color-picker",
      "title": "Color Picker",
      "description": "A color picker input.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/color-picker",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "input"
      ],
      "files": [
        "components/ds/color-picker.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "string"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "invalid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/ColorPicker",
      "stories": [
        {
          "name": "Sizes",
          "description": "The component supports `sm`, `md`, and `lg` sizes."
        },
        {
          "name": "Invalid",
          "description": "Set `invalid` to true to apply error styling.",
          "args": "{\n    invalid: true,\n    value: \"#ff0000\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Set `invalid` to true to apply error styling.\",\n      },\n    },\n  },"
        },
        {
          "name": "Disabled",
          "description": "Set `disabled` to true to disable interactions.",
          "args": "{\n    disabled: true,\n    value: \"#cccccc\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Set `disabled` to true to disable interactions.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-combobox",
      "title": "Combobox UI",
      "description": "A batteries-included combobox with virtual scrolling, search, single/multi-select, groups, custom option rendering, and configurable popover positioning (side/align/offset).",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/combobox",
      "dependencies": [
        "@tanstack/react-virtual",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "popover",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/combobox.tsx"
      ],
      "storyTitle": "Form/Combobox",
      "props": [
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "rounded",
          "control": "inline-radio",
          "options": [
            "full",
            "md",
            "none"
          ],
          "default": "md"
        },
        {
          "name": "disabled",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "loading",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "clearable",
          "control": "boolean",
          "default": "true"
        },
        {
          "name": "searchable",
          "control": "boolean",
          "default": "true"
        },
        {
          "name": "multiple",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "placeholder",
          "control": "text",
          "default": ""
        },
        {
          "name": "searchPlaceholder",
          "control": "text",
          "default": ""
        },
        {
          "name": "emptyText",
          "control": "text",
          "default": ""
        },
        {
          "name": "noOptionsText",
          "control": "text",
          "default": ""
        },
        {
          "name": "maxWidth",
          "control": "text",
          "default": ""
        },
        {
          "name": "locale",
          "control": "inline-radio",
          "options": [
            "en-US",
            "pt-BR",
            "es-ES",
            "fr-FR"
          ],
          "default": "en-US"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Default single-select combobox with search bar and a list of framework options.",
          "args": "{\n    options: FRAMEWORKS,\n    placeholder: \"Select a framework…\",\n    \"aria-label\": \"Select a framework\",\n    maxWidth: \"320px\",\n    size: \"md\",\n    rounded: \"md\",\n    loading: false,\n    disabled: false,\n    clearable: true,\n    searchable: true,\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default single-select combobox with search bar and a list of framework options.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithGroups",
          "description": "Options with a `group` field are automatically sorted into labeled sections inside the dropdown.",
          "args": "{\n    options: GROUPED,\n    placeholder: \"Select a technology…\",\n    maxWidth: \"320px\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Options with a `group` field are automatically sorted into labeled sections inside the dropdown.\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization applied to the combobox.",
          "args": "{\n    options: FRAMEWORKS,\n    placeholder: \"Selecione um framework…\",\n    maxWidth: \"320px\",\n    locale: \"pt-BR\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Portuguese (pt-BR) localization applied to the combobox.\",\n      },\n    },\n  },"
        },
        {
          "name": "Disabled",
          "description": "Disabled state preventing the user from opening the combobox or changing the value.",
          "args": "{\n    options: FRAMEWORKS,\n    defaultValue: \"next\",\n    disabled: true,\n    maxWidth: \"320px\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Disabled state preventing the user from opening the combobox or changing the value.\",\n      },\n    },\n  },"
        },
        {
          "name": "DisabledOptions",
          "description": "Individual options can be disabled via `option.disabled`.",
          "args": "{\n    options: FRAMEWORKS.map((o) =>\n      [\"remix\", \"nuxt\"].includes(o.value as string)\n        ? { ...o, disabled: true }\n        : o\n    ),\n    placeholder: \"Select a framework…\",\n    maxWidth: \"320px\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Individual options can be disabled via `option.disabled`.\",\n      },\n    },\n  },"
        },
        {
          "name": "NoSearchBar",
          "description": "Set `searchable={false}` to hide the search bar. Keyboard nav (↑↓ Enter Esc) still works via the focused list.",
          "args": "{\n    options: FRAMEWORKS,\n    searchable: false,\n    placeholder: \"Select a framework…\",\n    maxWidth: \"320px\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Set `searchable={false}` to hide the search bar. Keyboard nav (↑↓ Enter Esc) still works via the focused list.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-command-palette",
      "title": "Command Palette",
      "description": "A high-level command palette modal triggered by keyboard shortcuts.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/command-palette",
      "dependencies": [],
      "registryDependencies": [
        "command",
        "dialog"
      ],
      "files": [
        "components/ds/command-palette.tsx"
      ],
      "props": [
        {
          "name": "groups",
          "required": true,
          "type": "CommandPaletteGroup[]"
        },
        {
          "name": "open",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onOpenChange",
          "required": false,
          "type": "(open: boolean) => void"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "shortcut",
          "required": false,
          "type": "string // Define which key combined with meta/ctrl opens it, default is \"k\""
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Navigation/CommandPalette",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    groups: sampleGroups,\n  },"
        }
      ]
    },
    {
      "name": "ds-compare-slider",
      "title": "CompareSlider",
      "description": "Slider de comparação antes/depois com clip-path, arrastável ou via teclado (range input nativo).",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/compare-slider",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/compare-slider.tsx"
      ],
      "props": [
        {
          "name": "beforeSrc",
          "required": true,
          "type": "string"
        },
        {
          "name": "beforeAlt",
          "required": true,
          "type": "string"
        },
        {
          "name": "afterSrc",
          "required": true,
          "type": "string"
        },
        {
          "name": "afterAlt",
          "required": true,
          "type": "string"
        },
        {
          "name": "defaultValue",
          "required": false,
          "type": "number",
          "description": "Initial handle position, 0-100."
        },
        {
          "name": "label",
          "required": false,
          "type": "string",
          "description": "Accessible label for the drag handle."
        }
      ],
      "storyTitle": "Data Display/CompareSlider",
      "stories": [
        {
          "name": "StartAt25",
          "description": "",
          "args": "{ defaultValue: 25 },\n  render: (args) => (\n    <div className=\"mx-auto max-w-2xl\">\n      <CompareSlider {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-comparison",
      "title": "Comparison",
      "description": "Before/after slider — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/comparison",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/comparison.tsx"
      ],
      "props": [
        {
          "name": "before",
          "required": true,
          "type": "string"
        },
        {
          "name": "after",
          "required": true,
          "type": "string"
        },
        {
          "name": "beforeLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "afterLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "altBefore",
          "required": false,
          "type": "string"
        },
        {
          "name": "altAfter",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Data Display/Comparison",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    before: \"https://picsum.photos/600/400?1\",\n    after: \"https://picsum.photos/600/400?2\",\n  },"
        }
      ]
    },
    {
      "name": "ds-confetti",
      "description": "Confetti animation with 4 presets. Also exports useConfetti hook.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/confetti",
      "dependencies": [
        "canvas-confetti"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/confetti.tsx"
      ],
      "storyTitle": "Feedback/Confetti",
      "props": [
        {
          "name": "variant",
          "control": "inline-radio",
          "options": [
            "burst",
            "fireworks",
            "rain",
            "sides"
          ]
        }
      ],
      "stories": [
        {
          "name": "WithHook",
          "description": "Use the `useConfetti()` hook for programmatic control.",
          "code": "<div className=\"flex flex-col items-center gap-3\">\n        <p className=\"text-sm text-muted-foreground\">Click a button to fire</p>\n        <div className=\"flex flex-wrap justify-center gap-2\">\n          {([\"burst\", \"fireworks\", \"rain\", \"sides\"] as ConfettiVariant[]).map(\n            (v) => (\n              <Button key={v} onClick={() => fire(v)} variant=\"outline\">\n                🎉 {v}\n              </Button>\n            )\n          )}\n        </div>\n      </div>"
        },
        {
          "name": "Declarative",
          "description": "Wrap a child element with `<Confetti trigger={bool}>` — fires when `trigger` flips to `true`.",
          "code": "<Confetti\n        trigger={trigger}\n        variant=\"burst\"\n        onAnimationEnd={() => setTrigger(false)}\n      >\n        <Button\n          onClick={() => {\n            setTrigger(false)\n            requestAnimationFrame(() => setTrigger(true))\n          }}\n        >\n          🎊 Celebrate!\n        </Button>\n      </Confetti>"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"grid grid-cols-2 gap-3\">\n        <Button variant=\"outline\" onClick={() => fire(\"burst\")}>\n          🎉 Burst\n        </Button>\n        <Button variant=\"outline\" onClick={() => fire(\"fireworks\")}>\n          🎆 Fireworks (2s)\n        </Button>\n        <Button variant=\"outline\" onClick={() => fire(\"rain\")}>\n          🌧️ Rain\n        </Button>\n        <Button variant=\"outline\" onClick={() => fire(\"sides\")}>\n          🎊 Sides\n        </Button>\n      </div>"
        },
        {
          "name": "CustomColors",
          "description": "",
          "code": "<Button\n        onClick={() =>\n          fire(\"burst\", {\n            colors: [\"#6366f1\", \"#8b5cf6\", \"#a78bfa\"],\n            particleCount: 120,\n            spread: 90,\n          })\n        }\n      >\n        💜 LEMA Colors\n      </Button>"
        }
      ]
    },
    {
      "name": "ds-confirm-dialog",
      "title": "Confirm Dialog",
      "description": "Diálogo de confirmação com typed confirmation para ações irreversíveis de alto risco.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/confirm-dialog",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "dialog",
        "button",
        "input",
        "spinner",
        "ui-i18n"
      ],
      "files": [
        "components/ds/confirm-dialog.tsx"
      ],
      "props": [
        {
          "name": "open",
          "required": false,
          "type": "boolean",
          "description": "Controlled open state."
        },
        {
          "name": "onOpenChange",
          "required": false,
          "type": "(open: boolean) => void",
          "description": "Callback fired on open change."
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode",
          "description": "Dialog title heading."
        },
        {
          "name": "description",
          "required": true,
          "type": "React.ReactNode",
          "description": "Detailed explanation of what will be affected."
        },
        {
          "name": "confirmWord",
          "required": false,
          "type": "string",
          "description": "Target word user must type to unlock confirmation."
        },
        {
          "name": "requireTyping",
          "required": false,
          "type": "boolean",
          "description": "Whether typed confirmation is enforced."
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"destructive\" | \"warning\"",
          "description": "Visual risk intent."
        },
        {
          "name": "onConfirm",
          "required": true,
          "type": "() => void | Promise<void>",
          "description": "Action executed upon confirmation."
        },
        {
          "name": "onCancel",
          "required": false,
          "type": "() => void",
          "description": "Action executed upon cancellation."
        },
        {
          "name": "confirmLabel",
          "required": false,
          "type": "string",
          "description": "Custom label for confirm button."
        },
        {
          "name": "cancelLabel",
          "required": false,
          "type": "string",
          "description": "Custom label for cancel button."
        },
        {
          "name": "trigger",
          "required": false,
          "type": "React.ReactNode",
          "description": "Optional custom trigger element."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Localization locale."
        },
        {
          "name": "className",
          "required": false,
          "type": "string",
          "description": "Extra styling on modal content."
        }
      ],
      "storyTitle": "Feedback/ConfirmDialog",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Excluir Dados da Simulação\",\n    description: \"Esta ação não pode ser desfeita.\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    const trigger = canvas.getByRole(\"button\")\n    await expect(trigger).toBeInTheDocument()\n    await userEvent.click(trigger)\n    // Dialog opens in document.body\n    const dialogHeading = await within(document.body).findByText(\n      \"Excluir Dados da Simulação\"\n    )\n    await expect(dialogHeading).toBeInTheDocument()\n  },"
        },
        {
          "name": "SpecificResourceName",
          "description": "",
          "args": "{\n    title: \"Revogar Chave de API de Produção\",\n    description:\n      \"Todas as requisições ativas usando este token serão interrompidas imediatamente.\",\n    confirmWord: \"api_live_lema_prod\",\n  },"
        },
        {
          "name": "WarningIntent",
          "description": "",
          "args": "{\n    intent: \"warning\",\n    title: \"Interromper Conexão com o Cluster\",\n    description:\n      \"O cluster entrará em modo offline durante a janela de manutenção.\",\n    confirmWord: \"OFFLINE\",\n  },"
        },
        {
          "name": "WithoutTypingRequirement",
          "description": "",
          "args": "{\n    requireTyping: false,\n    title: \"Redefinir Configuração Padrão\",\n    description:\n      \"Deseja retornar as opções de visualização aos valores originais de fábrica?\",\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-wrap gap-3\">\n      <ConfirmDialog\n        locale=\"pt-BR\"\n        trigger={<Button size=\"sm\">pt-BR</Button>}\n        title=\"Excluir\"\n        description=\"Confirmação em Português\"\n        onConfirm={() => {}}\n      />\n      <ConfirmDialog\n        locale=\"en-US\"\n        trigger={<Button size=\"sm\">en-US</Button>}\n        title=\"Delete\"\n        description=\"Confirmation in English\"\n        onConfirm={() => {}}\n      />\n      <ConfirmDialog\n        locale=\"es-ES\"\n        trigger={<Button size=\"sm\">es-ES</Button>}\n        title=\"Eliminar\"\n        description=\"Confirmación en Español\"\n        onConfirm={() => {}}\n      />\n      <ConfirmDialog\n        locale=\"fr-FR\"\n        trigger={<Button size=\"sm\">fr-FR</Button>}\n        title=\"Supprimer\"\n        description=\"Confirmation en Français\"\n        onConfirm={() => {}}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-contact-bento",
      "title": "ContactBento",
      "description": "Grid bento com o formulário de contato como tile principal e tiles satélite — composto de ds-bento-grid e ds-contact-form.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/contact-bento",
      "dependencies": [],
      "registryDependencies": [
        "ds-bento-grid",
        "ds-contact-form"
      ],
      "files": [
        "components/ds/contact-bento.tsx"
      ],
      "props": [
        {
          "name": "formProps",
          "required": false,
          "type": "ContactFormProps"
        },
        {
          "name": "children",
          "required": false,
          "type": "React.ReactNode",
          "description": "Additional `BentoGridItem` tiles rendered beside the form (office locations, stats...)."
        }
      ],
      "storyTitle": "Contact/ContactBento",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<ContactBento>\n      <BentoGridItem\n        colSpan={2}\n        className=\"items-stretch justify-center border-0 bg-transparent p-0 hover:translate-y-0 hover:shadow-none\"\n      >\n        <OfficeLocations className=\"w-full rounded-2xl border border-border bg-card p-6\">\n          <OfficeLocationItem\n            city=\"São Paulo\"\n            country=\"Brazil\"\n            timeZone=\"America/Sao_Paulo\"\n          />\n        </OfficeLocations>\n      </BentoGridItem>\n      <BentoGridItem\n        title=\"Response time\"\n        description=\"Under 24 hours, every day.\"\n      />\n      <BentoGridItem title=\"Support\" description=\"Real humans, no bots.\" />\n    </ContactBento>"
        }
      ]
    },
    {
      "name": "ds-contact-channels",
      "title": "ContactChannels",
      "description": "Linha de cartões de canal de contato (e-mail, telefone, chat) — composto de ds-card-icon.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/contact-channels",
      "dependencies": [],
      "registryDependencies": [
        "ds-card-icon"
      ],
      "files": [
        "components/ds/contact-channels.tsx"
      ],
      "props": [
        {
          "name": "channels",
          "required": true,
          "type": "ContactChannel[]"
        }
      ],
      "storyTitle": "Contact/ContactChannels",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        }
      ]
    },
    {
      "name": "ds-contact-form",
      "title": "ContactForm",
      "description": "Formulário de contato (nome, e-mail, assunto, tópico e mensagem) com estados idle/submitting/success/error.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/contact-form",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "field",
        "input",
        "textarea",
        "button",
        "ds-pill-group",
        "ui-i18n"
      ],
      "files": [
        "components/ds/contact-form.tsx"
      ],
      "props": [
        {
          "name": "topics",
          "required": false,
          "type": "ContactFormTopic[]",
          "description": "Optional topic/department chips rendered above the message field."
        },
        {
          "name": "showSubject",
          "required": false,
          "type": "boolean",
          "description": "Shows the subject field. Defaults to true when `topics` is omitted."
        },
        {
          "name": "onSubmit",
          "required": false,
          "type": "(values: ContactFormValues) => Promise<boolean | void> | void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Contact/ContactForm",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "WithTopics",
          "description": "",
          "args": "{ topics },"
        },
        {
          "name": "WithoutSubject",
          "description": "",
          "args": "{ showSubject: false },"
        },
        {
          "name": "SubmitError",
          "description": "",
          "args": "{\n    onSubmit: async () => false,\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-10\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as UILocale[]).map((locale) => (\n        <ContactForm key={locale} locale={locale} topics={topics} />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-contact-split",
      "title": "ContactSplit",
      "description": "Seção de contato split com formulário de um lado e um slot flexível do outro — composto de ds-hero-section e ds-contact-form.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/contact-split",
      "dependencies": [],
      "registryDependencies": [
        "ds-hero-section",
        "ds-contact-form",
        "badge"
      ],
      "files": [
        "components/ds/contact-split.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "formProps",
          "required": false,
          "type": "ContactFormProps"
        },
        {
          "name": "aside",
          "required": true,
          "type": "React.ReactNode",
          "description": "Content shown beside the form — plug in `OfficeLocations`, `TeamRoster`,\na `CardIcon` list, or plain copy, depending on the variant you need."
        }
      ],
      "storyTitle": "Contact/ContactSplit",
      "stories": [
        {
          "name": "WithOfficeLocations",
          "description": "",
          "args": "{\n    aside: (\n      <OfficeLocations>\n        {offices.map((office) => (\n          <OfficeLocationItem key={office.city} {...office} />\n        ))}\n      </OfficeLocations>\n    ),\n  },"
        },
        {
          "name": "WithTeam",
          "description": "",
          "args": "{\n    aside: (\n      <TeamRoster columns={2}>\n        {team.map((member) => (\n          <TeamRosterCard key={member.name} {...member} />\n        ))}\n      </TeamRoster>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-contribution-graph",
      "title": "Contribution Graph",
      "description": "Graph estilo GitHub 7x20 — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/contribution-graph",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/contribution-graph.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": false,
          "type": "number[][] // 7 x weeks"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/ContributionGraph",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{}"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true }"
        }
      ]
    },
    {
      "name": "ds-copy-block",
      "title": "CopyBlock",
      "description": "Exibe um trecho de texto ou código com um botão acoplado para cópia rápida.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/copy-block",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "tooltip",
        "ui-i18n"
      ],
      "files": [
        "components/ds/copy-block.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "string",
          "description": "The text to display and copy."
        },
        {
          "name": "size",
          "required": false,
          "type": "CopyBlockSize",
          "description": "Defines the size of the block."
        },
        {
          "name": "truncate",
          "required": false,
          "type": "boolean",
          "description": "Whether the text should truncate if it exceeds the container width.\nIf false, it will wrap to the next line."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Localization for the tooltip texts."
        }
      ],
      "storyTitle": "Data Display/CopyBlock",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    value: \"npm install @lema-ufpb/design-system\",\n    size: \"md\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "The component supports 3 sizes: sm, md and lg.",
          "args": "{\n    value: \"\",\n  },\n  render: (args) => (\n    <div className=\"flex w-full max-w-md flex-col gap-4\">\n      <CopyBlock {...args} size=\"sm\" value=\"token_abc123_sm\" />\n      <CopyBlock {...args} size=\"md\" value=\"token_abc123_md\" />\n      <CopyBlock {...args} size=\"lg\" value=\"token_abc123_lg\" />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story: \"The component supports 3 sizes: sm, md and lg.\",\n      },\n    },\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{\n    value: \"\",\n  },\n  render: () => (\n    <div className=\"flex w-full max-w-md flex-col gap-4\">\n      <CopyBlock locale=\"pt-BR\" value=\"npm install pacote\" />\n      <CopyBlock locale=\"en-US\" value=\"npm install package\" />\n      <CopyBlock locale=\"es-ES\" value=\"npm install paquete\" />\n      <CopyBlock locale=\"fr-FR\" value=\"npm install paquet\" />\n    </div>\n  ),",
          "code": "<div className=\"flex w-full max-w-md flex-col gap-4\">\n      <CopyBlock locale=\"pt-BR\" value=\"npm install pacote\" />\n      <CopyBlock locale=\"en-US\" value=\"npm install package\" />\n      <CopyBlock locale=\"es-ES\" value=\"npm install paquete\" />\n      <CopyBlock locale=\"fr-FR\" value=\"npm install paquet\" />\n    </div>"
        },
        {
          "name": "Truncated",
          "description": "Use `truncate={true}` when the block may be in a container smaller than the content and you want to force a single line. When `false`, the text wraps to multiple lines.",
          "args": "{\n    value:\n      \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ\",\n    truncate: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Use `truncate={true}` when the block may be in a container smaller than the content and you want to force a single line. When `false`, the text wraps to multiple lines.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-counter",
      "title": "Counter",
      "description": "A precision numeric input with button controls, direct keyboard entry support, and inputProps passthrough for native HTML attributes.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/counter",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/counter.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "number"
        },
        {
          "name": "defaultValue",
          "required": false,
          "type": "number"
        },
        {
          "name": "min",
          "required": false,
          "type": "number"
        },
        {
          "name": "max",
          "required": false,
          "type": "number"
        },
        {
          "name": "step",
          "required": false,
          "type": "number"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "label",
          "required": false,
          "type": "string"
        },
        {
          "name": "maxWidth",
          "required": false,
          "type": "string | number"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: number) => void"
        },
        {
          "name": "onBlur",
          "required": false,
          "type": "(e: React.FocusEvent<HTMLInputElement>) => void"
        },
        {
          "name": "onKeyDown",
          "required": false,
          "type": "(e: React.KeyboardEvent<HTMLInputElement>) => void"
        },
        {
          "name": "id",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "inputProps",
          "required": false,
          "type": "Omit< React.ComponentProps<\"input\">, | \"type\" | \"value\" | \"defaultValue\" | \"onChange\" | \"min\" | \"max\" | \"step\" | \"onBlur\" | \"onKeyDown\" | \"id\" | \"disabled\" | \"ref\" | \"className\" >"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"ghost\" | \"outline\"",
          "options": [
            "default",
            "ghost",
            "outline"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Form/Counter",
      "stories": [
        {
          "name": "Default",
          "description": "Default counter with min=0, max=10, and step=1 constraints.",
          "args": "{\n    defaultValue: 0,\n    min: 0,\n    max: 10,\n    step: 1,\n    size: \"md\",\n    variant: \"default\",\n    loading: false,\n    disabled: false,\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Default counter with min=0, max=10, and step=1 constraints.\",\n      },\n    },\n  },"
        },
        {
          "name": "MaxWidth",
          "description": "Use `maxWidth` to cap how wide the counter grows. Accepts any valid CSS value (`px`, `%`, `rem`, etc.).",
          "args": "{\n    defaultValue: 5,\n    min: 0,\n    max: 100,\n    maxWidth: \"320px\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Use `maxWidth` to cap how wide the counter grows. Accepts any valid CSS value (`px`, `%`, `rem`, etc.).\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) locale applied to the counter.",
          "args": "{\n    defaultValue: 0,\n    min: 0,\n    max: 10,\n    step: 1,\n    locale: \"pt-BR\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Portuguese (pt-BR) locale applied to the counter.\",\n      },\n    },\n  },"
        },
        {
          "name": "FluidWidth",
          "description": "The counter fills its container by default. `maxWidth` constrains the growth.",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          Full width (default)\n        </p>\n        <Counter defaultValue={5} min={0} max={100} />\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">maxWidth: 400px</p>\n        <Counter defaultValue={5} min={0} max={100} maxWidth=\"400px\" />\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">maxWidth: 50%</p>\n        <Counter defaultValue={5} min={0} max={100} maxWidth=\"50%\" />\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">maxWidth: 200px</p>\n        <Counter defaultValue={5} min={0} max={100} maxWidth=\"200px\" />\n      </div>\n    </div>"
        },
        {
          "name": "Controlled",
          "description": "Controlled counter — value managed externally with an onChange handler.",
          "code": "<div className=\"flex flex-col gap-4\">\n        <p className=\"text-sm text-muted-foreground\">\n          Controlled value: <strong>{count}</strong>\n        </p>\n        <Counter\n          value={count}\n          onChange={setCount}\n          min={0}\n          max={20}\n          maxWidth=\"320px\"\n        />\n      </div>"
        },
        {
          "name": "Variants",
          "description": "Comparison of all three border variants — default, ghost, and outline.",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"default\", \"ghost\", \"outline\"] as const).map((variant) => (\n        <div key={variant} className=\"flex items-center gap-4\">\n          <span className=\"w-16 shrink-0 text-sm font-medium capitalize\">\n            {variant}\n          </span>\n          <Counter variant={variant} defaultValue={10} />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "Comparison of all three size presets — sm, md, and lg.",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex items-center gap-4\">\n          <span className=\"w-16 shrink-0 text-sm font-medium capitalize\">\n            {size}\n          </span>\n          <Counter size={size} defaultValue={5} />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "Disabled state preventing user interaction with the increment and decrement buttons.",
          "args": "{\n    disabled: true,\n    defaultValue: 5,\n    maxWidth: \"320px\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Disabled state preventing user interaction with the increment and decrement buttons.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` while the initial value is being fetched. The control is replaced by a `Skeleton` that matches the size variant — no layout shift when the value arrives.",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex items-center gap-4\">\n          <span className=\"w-8 shrink-0 text-sm font-medium\">{size}</span>\n          <Counter loading size={size} maxWidth=\"320px\" />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "SimulatedLoading",
          "description": "Simulates a 2-second async fetch. The skeleton holds space, then the counter appears pre-filled with the loaded value.",
          "code": "<div className=\"flex flex-col gap-3\">\n        <Counter\n          loading={loading}\n          value={value}\n          onChange={setValue}\n          min={0}\n          max={100}\n          maxWidth=\"320px\"\n        />\n        <p className=\"text-xs text-muted-foreground\">\n          {loading ? \"Fetching value…\" : `Loaded with value ${value}`}\n        </p>\n      </div>"
        }
      ]
    },
    {
      "name": "ds-credit-card",
      "title": "Credit Card",
      "description": "Card visual com gradient e brand — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/credit-card",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/credit-card.tsx"
      ],
      "props": [
        {
          "name": "number",
          "required": false,
          "type": "string"
        },
        {
          "name": "holder",
          "required": false,
          "type": "string"
        },
        {
          "name": "expiry",
          "required": false,
          "type": "string"
        },
        {
          "name": "cvc",
          "required": false,
          "type": "string"
        },
        {
          "name": "brand",
          "required": false,
          "type": "\"visa\" | \"mastercard\" | \"amex\""
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"dark\" | \"light\"",
          "options": [
            "default",
            "dark",
            "light"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Commerce/CreditCard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    number: \"4242 4242 4242 4242\",\n    holder: \"Alex Silva\",\n    expiry: \"12/28\",\n  },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "args": "{ holder: \"Alex\" },\n  render: () => (\n    <div className=\"flex flex-wrap gap-4\">\n      <CreditCard\n        variant=\"default\"\n        number=\"4242 4242 4242 4242\"\n        holder=\"Ana\"\n        expiry=\"12/28\"\n      />\n      <CreditCard\n        variant=\"dark\"\n        number=\"4242 4242 4242 4242\"\n        holder=\"Ana\"\n        expiry=\"12/28\"\n      />\n      <CreditCard\n        variant=\"light\"\n        number=\"4242 4242 4242 4242\"\n        holder=\"Ana\"\n        expiry=\"12/28\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <CreditCard\n        variant=\"default\"\n        number=\"4242 4242 4242 4242\"\n        holder=\"Ana\"\n        expiry=\"12/28\"\n      />\n      <CreditCard\n        variant=\"dark\"\n        number=\"4242 4242 4242 4242\"\n        holder=\"Ana\"\n        expiry=\"12/28\"\n      />\n      <CreditCard\n        variant=\"light\"\n        number=\"4242 4242 4242 4242\"\n        holder=\"Ana\"\n        expiry=\"12/28\"\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-cron-builder",
      "description": "Visual cron expression builder with simple and advanced modes.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/cron-builder",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "button",
        "label",
        "input",
        "badge",
        "select",
        "toggle-group",
        "tabs",
        "ui-i18n"
      ],
      "files": [
        "components/ds/cron-builder.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "string"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "mode",
          "required": false,
          "type": "CronBuilderMode"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Form/CronBuilder",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    value: \"0 9 * * 1-5\",\n    mode: \"simple\",\n  },"
        },
        {
          "name": "Advanced",
          "description": "",
          "args": "{\n    value: \"30 14 * * 3\",\n    mode: \"advanced\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    value: \"* * * * *\",\n    loading: true,\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    value: \"0 0 1 * *\",\n    disabled: true,\n  },"
        },
        {
          "name": "Controlled",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n        <CronBuilder value={cron} onChange={setCron} />\n        <div className=\"rounded-lg border border-border bg-muted p-3 font-mono text-sm\">\n          Current value: <strong>{cron}</strong>\n        </div>\n      </div>"
        }
      ]
    },
    {
      "name": "ds-cta",
      "title": "Cta",
      "description": "Container CTA core com badge, título, descrição e ações — átomo base CTA.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/cta",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "skeleton"
      ],
      "files": [
        "components/ds/cta.tsx"
      ],
      "props": [
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "primaryAction",
          "required": false,
          "type": "CtaAction"
        },
        {
          "name": "secondaryAction",
          "required": false,
          "type": "CtaAction"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "tone",
          "required": false,
          "type": "\"default\" | \"primary\" | \"muted\" | \"glow\"",
          "options": [
            "default",
            "primary",
            "muted",
            "glow"
          ],
          "default": "default"
        },
        {
          "name": "align",
          "required": false,
          "type": "\"left\" | \"center\"",
          "options": [
            "left",
            "center"
          ],
          "default": "center"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "CTA/Cta",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    badge: \"New\",\n    title: \"Ready to get started?\",\n    description:\n      \"Join researchers and developers building modern web apps with LEMA DS.\",\n    primaryAction: { label: \"Get started\" },\n    secondaryAction: { label: \"Learn more\" },\n  },"
        },
        {
          "name": "AllTones",
          "description": "",
          "args": "{ title: \"Title\", description: \"Description\" },\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      {([\"default\", \"primary\", \"muted\", \"glow\"] as const).map((tone) => (\n        <Cta\n          key={tone}\n          tone={tone}\n          title={`Tone ${tone}`}\n          description=\"Description for CTA tone variant.\"\n          primaryAction={{ label: \"Primary\" }}\n          secondaryAction={{ label: \"Secondary\" }}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-6\">\n      {([\"default\", \"primary\", \"muted\", \"glow\"] as const).map((tone) => (\n        <Cta\n          key={tone}\n          tone={tone}\n          title={`Tone ${tone}`}\n          description=\"Description for CTA tone variant.\"\n          primaryAction={{ label: \"Primary\" }}\n          secondaryAction={{ label: \"Secondary\" }}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "AlignLeft",
          "description": "",
          "args": "{\n    title: \"Left aligned CTA\",\n    description: \"Content aligns to the left for editorial layouts.\",\n    align: \"left\",\n    primaryAction: { label: \"Get started\" },\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ title: \"Loading\", loading: true }"
        }
      ]
    },
    {
      "name": "ds-cta-centered",
      "title": "Cta Centered",
      "description": "CTA centrado editorial — blockus CTA #01-08.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/cta-centered",
      "dependencies": [],
      "registryDependencies": [
        "ds-cta"
      ],
      "files": [
        "components/ds/cta-centered.tsx"
      ],
      "storyTitle": "CTA/CtaCentered",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Build faster\",\n    description: \"Drop in blocks and ship.\",\n    primaryAction: { label: \"Get access\" },\n    secondaryAction: { label: \"Learn more\" },\n    tone: \"glow\",\n    badge: \"New\",\n  },"
        },
        {
          "name": "Primary",
          "description": "",
          "args": "{\n    title: \"Start today\",\n    description: \"Trusted by 1k+ teams.\",\n    primaryAction: { label: \"Try free\" },\n    tone: \"primary\",\n  },"
        }
      ]
    },
    {
      "name": "ds-cta-newsletter",
      "title": "Cta Newsletter",
      "description": "CTA com captura email inline — blockus #17-24.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/cta-newsletter",
      "dependencies": [],
      "registryDependencies": [
        "ds-cta",
        "input",
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/cta-newsletter.tsx"
      ],
      "props": [
        {
          "name": "onSubscribe",
          "required": false,
          "type": "(email: string) => Promise<boolean | void> | void"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "disclaimer",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "CTA/CtaNewsletter",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Stay updated\",\n    description: \"Subscribe for latest releases.\",\n    badge: \"Newsletter\",\n  },"
        },
        {
          "name": "WithHandler",
          "description": "",
          "args": "{\n    title: \"Join waitlist\",\n    description: \"Be first to access.\",\n    onSubscribe: async () => {\n      await new Promise((r) => setTimeout(r, 500))\n      return true\n    },\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{ title: \"Stay updated\", description: \"Description\" },\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <CtaNewsletter\n          key={locale}\n          locale={locale}\n          title=\"Stay updated\"\n          description=\"Subscribe\"\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-6\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <CtaNewsletter\n          key={locale}\n          locale={locale}\n          title=\"Stay updated\"\n          description=\"Subscribe\"\n        />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-cta-split",
      "title": "Cta Split",
      "description": "CTA split imagem + conteúdo — blockus #09-16.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/cta-split",
      "dependencies": [],
      "registryDependencies": [
        "ds-cta"
      ],
      "files": [
        "components/ds/cta-split.tsx"
      ],
      "props": [
        {
          "name": "imageSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "imageAlt",
          "required": false,
          "type": "string"
        },
        {
          "name": "reverse",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "CTA/CtaSplit",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Ship in hours\",\n    description: \"A new way to build pages.\",\n    imageSrc: \"https://picsum.photos/600/600\",\n    primaryAction: { label: \"Get started\" },\n    secondaryAction: { label: \"Learn more\" },\n  },"
        },
        {
          "name": "Reverse",
          "description": "",
          "args": "{\n    title: \"Reverse layout\",\n    description: \"Image on the right.\",\n    imageSrc: \"https://picsum.photos/600/600\",\n    reverse: true,\n    primaryAction: { label: \"Explore\" },\n  },"
        },
        {
          "name": "WithoutImage",
          "description": "",
          "args": "{\n    title: \"No image CTA\",\n    description: \"Falls back to single column.\",\n    primaryAction: { label: \"Contact\" },\n  },"
        }
      ]
    },
    {
      "name": "ds-culture-gallery",
      "title": "Culture Gallery",
      "description": "Mosaico e grade fotográfica da cultura institucional e equipe em ação.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/culture-gallery",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/culture-gallery.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "CultureGalleryItem[]"
        },
        {
          "name": "layout",
          "required": false,
          "type": "\"mosaic\" | \"grid\"",
          "options": [
            "mosaic",
            "grid"
          ],
          "default": "mosaic"
        }
      ],
      "stories": [
        {
          "name": "GridLayout",
          "description": "",
          "args": "{\n    layout: \"grid\",\n  },"
        }
      ]
    },
    {
      "name": "ds-cursor",
      "title": "Cursor",
      "description": "Cursor remoto com label para collab — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/cursor",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/cursor.tsx"
      ],
      "props": [
        {
          "name": "name",
          "required": false,
          "type": "string"
        },
        {
          "name": "color",
          "required": false,
          "type": "string"
        },
        {
          "name": "x",
          "required": false,
          "type": "number"
        },
        {
          "name": "y",
          "required": false,
          "type": "number"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Effects/Cursor",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ name: \"Ana\", x: 40, y: 40 },\n  render: (args) => (\n    <div className=\"relative h-48 w-full rounded-2xl border bg-card\">\n      <Cursor {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-cursor-spotlight",
      "title": "CursorSpotlight",
      "description": "Glow radial que segue o cursor do ponteiro, com fallback estático em prefers-reduced-motion.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/cursor-spotlight",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/cursor-spotlight.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "number",
          "description": "Diameter of the glow, in pixels."
        },
        {
          "name": "tone",
          "required": false,
          "type": "\"primary\" | \"violet\" | \"sky\"",
          "options": [
            "primary",
            "violet",
            "sky"
          ],
          "default": "primary"
        }
      ],
      "storyTitle": "Data Display/CursorSpotlight",
      "stories": [
        {
          "name": "AllTones",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      {([\"primary\", \"violet\", \"sky\"] as const).map((tone) => (\n        <CursorSpotlight\n          key={tone}\n          tone={tone}\n          className=\"flex h-40 items-center justify-center rounded-2xl border border-border bg-card\"\n        >\n          <p className=\"text-xs text-muted-foreground\">{tone}</p>\n        </CursorSpotlight>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-dashboard",
      "title": "Dashboard",
      "description": "Shell de dashboard com AppSidebar, Header, SectionCards, Chart e DataTable — replica shadcn dashboard-01.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/dashboard",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-app-sidebar",
        "ds-section-cards",
        "sidebar",
        "separator",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/dashboard.tsx"
      ],
      "props": [
        {
          "name": "sidebar",
          "required": false,
          "type": "{ teams?: TeamSwitcherTeam[] navMain?: AppSidebarNavItem[] projects?: AppSidebarProject[] user?: UserMenuData | null }"
        },
        {
          "name": "header",
          "required": false,
          "type": "{ title?: string actions?: React.ReactNode }"
        },
        {
          "name": "stats",
          "required": false,
          "type": "SectionCardItem[]"
        },
        {
          "name": "chart",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "table",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"inset\"",
          "options": [
            "default",
            "inset"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    sidebar: { teams, navMain, projects, user },\n    header: {\n      title: \"Documents\",\n      actions: (\n        <Button size=\"sm\" variant=\"outline\">\n          GitHub\n        </Button>\n      ),\n    },\n    stats,\n    chart: (\n      <div className=\"h-64 rounded-xl border bg-muted/50 p-6 text-sm text-muted-foreground\">\n        Chart placeholder\n      </div>\n    ),\n    table: (\n      <div className=\"h-64 rounded-xl border bg-muted/50 p-6 text-sm text-muted-foreground\">\n        DataTable placeholder\n      </div>\n    ),\n  },"
        },
        {
          "name": "Inset",
          "description": "",
          "args": "{\n    variant: \"inset\",\n    sidebar: { teams, navMain, user },\n    header: { title: \"Dashboard\" },\n    stats,\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        },
        {
          "name": "WithoutSidebar",
          "description": "",
          "args": "{\n    header: { title: \"Documents\" },\n    stats,\n  },"
        },
        {
          "name": "A11y",
          "description": "",
          "args": "{\n    sidebar: { teams, navMain, user },\n    header: { title: \"Documents\" },\n    stats,\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByText(\"Documents\")).toBeInTheDocument()\n  },"
        }
      ]
    },
    {
      "name": "ds-dashboard-layout",
      "title": "Dashboard Layout",
      "description": "A base layout for complex dashboards with sidebar and header.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/dashboard-layout",
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "registryDependencies": [
        "sidebar"
      ],
      "files": [
        "components/ds/dashboard-layout.tsx"
      ],
      "props": [
        {
          "name": "sidebar",
          "required": true,
          "type": "React.ReactNode",
          "description": "The sidebar component to render"
        },
        {
          "name": "header",
          "required": false,
          "type": "React.ReactNode",
          "description": "The global header/topbar"
        },
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode",
          "description": "The main content"
        },
        {
          "name": "defaultOpen",
          "required": false,
          "type": "boolean",
          "description": "Default state of the sidebar"
        }
      ],
      "storyTitle": "Layout/DashboardLayout",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    sidebar: undefined,\n    header: undefined,\n    children: undefined,\n  },\n  render: (args) => (\n    <DashboardLayout\n      {...args}\n      sidebar={<MockSidebar />}\n      header={<div className=\"font-medium\">Dashboard Overview</div>}\n    >\n      <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n        <Skeleton className=\"h-32 rounded-xl\" />\n        <Skeleton className=\"h-32 rounded-xl\" />\n        <Skeleton className=\"h-32 rounded-xl\" />\n        <Skeleton className=\"h-32 rounded-xl\" />\n      </div>\n      <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-7\">\n        <Skeleton className=\"col-span-4 h-[400px] rounded-xl\" />\n        <Skeleton className=\"col-span-3 h-[400px] rounded-xl\" />\n      </div>\n    </DashboardLayout>\n  ),"
        }
      ]
    },
    {
      "name": "ds-dashbox",
      "title": "Dashbox",
      "description": "A structured dashboard card with collapse/expand, fullscreen, refresh, loading skeleton, status badge, and configurable body padding.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/dashbox",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "tooltip",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/dashbox.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Layout/Dashbox",
      "stories": [
        {
          "name": "Default",
          "description": "Default Dashbox with title, description, and placeholder content.",
          "args": "{\n    title: \"My Dashbox\",\n    description: \"An example panel with simple content.\",\n    size: \"md\",\n    bodyPadding: \"md\",\n    loading: false,\n    locale: \"en-US\",\n    showToolbar: true,\n    showHeader: true,\n    showMaximize: true,\n    showMinimize: true,\n    children: (\n      <p className=\"text-muted-foreground\">\n        Place any content here — charts, tables, metrics.\n      </p>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default Dashbox with title, description, and placeholder content.\",\n      },\n    },\n  },"
        },
        {
          "name": "NoHeader",
          "description": "Dashbox with showHeader={false} — header, toolbar, and status badge are hidden.",
          "args": "{\n    showHeader: false,\n    title: \"My Dashbox\",\n    children: (\n      <p className=\"text-muted-foreground\">\n        Content without header or toolbar.\n      </p>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dashbox with showHeader={false} — header, toolbar, and status badge are hidden.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithStatus",
          "description": "Dashbox with a live status badge in the header.",
          "args": "{\n    title: \"API Status\",\n    status: \"live\",\n    children: (\n      <p className=\"text-sm text-muted-foreground\">\n        Service is responding normally.\n      </p>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Dashbox with a live status badge in the header.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllStatuses",
          "description": "Comparison of all four status badges — live, warning, error, and idle.",
          "code": "<div className=\"flex w-full max-w-lg flex-col gap-4\">\n      <Dashbox title=\"Live\" status=\"live\">\n        <p className=\"text-sm text-muted-foreground\">\n          Real-time data stream active.\n        </p>\n      </Dashbox>\n      <Dashbox title=\"Warning\" status=\"warning\">\n        <p className=\"text-sm text-muted-foreground\">\n          High latency detected in region us-east-1.\n        </p>\n      </Dashbox>\n      <Dashbox title=\"Error\" status=\"error\">\n        <p className=\"text-sm text-muted-foreground\">\n          Service currently unavailable.\n        </p>\n      </Dashbox>\n      <Dashbox title=\"Idle\" status=\"idle\">\n        <p className=\"text-sm text-muted-foreground\">\n          Maintenance mode active.\n        </p>\n      </Dashbox>\n    </div>"
        },
        {
          "name": "WithToolbar",
          "description": "Dashbox with custom toolbar actions (download, settings) in the header.",
          "args": "{\n    title: \"Monthly Revenue\",\n    description: \"January — May 2025\",\n    toolbar: (\n      <>\n        <button\n          className=\"flex size-7 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\"\n          aria-label=\"Download CSV\"\n        >\n          <DownloadIcon className=\"size-3.5\" />\n        </button>\n        <button\n          className=\"flex size-7 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\"\n          aria-label=\"Settings\"\n        >\n          <SettingsIcon className=\"size-3.5\" />\n        </button>\n      </>\n    ),\n    children: (\n      <div className=\"grid grid-cols-3 gap-3\">\n        {[\"Jan\", \"Feb\", \"Mar\"].map((m) => (\n          <div key={m} className=\"rounded-lg bg-muted p-4 text-center\">\n            <p className=\"text-xs text-muted-foreground\">{m}</p>\n            <p className=\"mt-1 text-lg font-semibold text-foreground\">\n              ${Math.floor(Math.random() * 500 + 100)}k\n            </p>\n          </div>\n        ))}\n      </div>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dashbox with custom toolbar actions (download, settings) in the header.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithRefresh",
          "description": "Dashbox with a refresh button that triggers an async onRefresh callback.",
          "args": "{\n    title: \"Real-time Data\",\n    status: \"live\",\n    onRefresh: async () => {\n      await new Promise((r) => setTimeout(r, 1200))\n    },\n    children: (\n      <p className=\"text-sm text-muted-foreground\">\n        Click the refresh button to see the spin animation.\n      </p>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dashbox with a refresh button that triggers an async onRefresh callback.\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalizedToolbar",
          "description": "Toolbar labels and status badge translated to Portuguese (pt-BR).",
          "args": "{\n    title: \"Overview\",\n    description: \"Example with locale pt-PR\",\n    status: \"live\",\n    locale: \"pt-BR\",\n    onRefresh: async () => {\n      await new Promise((r) => setTimeout(r, 800))\n    },\n    children: (\n      <p className=\"text-sm text-muted-foreground\">\n        Hover over the buttons in the top right corner to see the translated\n        tooltips and status badge.\n      </p>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Toolbar labels and status badge translated to Portuguese (pt-BR).\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading state — the entire Dashbox body is replaced by animated skeleton placeholders.",
          "args": "{\n    title: \"Loading...\",\n    loading: true,\n    children: null,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading state — the entire Dashbox body is replaced by animated skeleton placeholders.\",\n      },\n    },\n  },"
        },
        {
          "name": "NoPadding",
          "description": "Dashbox with bodyPadding='none' — content stretches edge-to-edge.",
          "args": "{\n    title: \"No Padding\",\n    bodyPadding: \"none\",\n    children: (\n      <div className=\"flex h-32 w-full items-center justify-center bg-linear-to-r from-primary/20 to-primary/5\">\n        <span className=\"text-sm text-muted-foreground\">\n          Edge-to-edge content area\n        </span>\n      </div>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dashbox with bodyPadding='none' — content stretches edge-to-edge.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithProgressBars",
          "description": "Two Dashbox panels side-by-side containing ProgressBar components with different intents.",
          "code": "<div className=\"flex w-full gap-4\">\n      <Dashbox\n        title=\"Performance\"\n        description=\"Semester indicators summary\"\n        status=\"live\"\n        onRefresh={async () => {\n          await new Promise((r) => setTimeout(r, 800))\n        }}\n      >\n        <div className=\"flex flex-col gap-3\">\n          <ProgressBar\n            value={0.88}\n            name=\"Approval Rate\"\n            intent=\"success\"\n            precision={1}\n          />\n          <ProgressBar\n            value={0.62}\n            name=\"Attendance\"\n            intent=\"primary\"\n            precision={1}\n          />\n          <ProgressBar\n            value={0.35}\n            name=\"Dropout Rate\"\n            intent=\"destructive\"\n            precision={1}\n          />\n        </div>\n      </Dashbox>\n\n      <Dashbox\n        title=\"Goals\"\n        description=\"Q1 target achievement\"\n        status=\"warning\"\n      >\n        <div className=\"flex flex-col gap-3\">\n          <ProgressBar value={100} name=\"Enrolled\" intent=\"success\" />\n          <ProgressBar value={72} name=\"Active\" intent=\"primary\" />\n          <ProgressBar value={18} name=\"Completed\" intent=\"destructive\" />\n        </div>\n      </Dashbox>\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "Comparison of all three size presets — sm, md, and lg.",
          "code": "<div className=\"flex w-full max-w-md flex-col gap-4\">\n      <Dashbox title=\"Small\" size=\"sm\">\n        <p className=\"text-muted-foreground\">Content in small size variant.</p>\n      </Dashbox>\n      <Dashbox title=\"Medium\" size=\"md\">\n        <p className=\"text-muted-foreground\">Content in medium size variant.</p>\n      </Dashbox>\n      <Dashbox title=\"Large\" size=\"lg\">\n        <p className=\"text-muted-foreground\">Content in large size variant.</p>\n      </Dashbox>\n    </div>"
        },
        {
          "name": "MaximizeAwareContent",
          "description": "`children` can be a function receiving `{ maximized, minimized }`, so content (e.g. a chart) can grow to fill the fullscreen viewport and shrink back to its standard size when restored.",
          "args": "{\n    title: \"Revenue Over Time\",\n    description: \"Click the fullscreen toggle to see the content react.\",\n    children: ({ maximized }) => (\n      <div\n        className=\"flex w-full items-center justify-center rounded-lg border border-dashed border-border text-muted-foreground transition-all duration-300\"\n        style={{ height: maximized ? \"70vh\" : 220 }}\n      >\n        {maximized\n          ? \"Chart at full height — fills the fullscreen viewport\"\n          : \"Chart at standard height (220px)\"}\n      </div>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"`children` can be a function receiving `{ maximized, minimized }`, so content (e.g. a chart) can grow to fill the fullscreen viewport and shrink back to its standard size when restored.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-dashrow",
      "title": "Dashrow",
      "description": "Responsive layout container for dashboard panels with resizable split ratios and N-child support.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/dashrow",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/dashrow.tsx"
      ],
      "props": [
        {
          "name": "alignment",
          "required": false,
          "type": "DashrowAlignment",
          "description": "Width ratio between children on desktop (lg+).\n- `left`  — first child gets 60%, rest share 40%\n- `right` — first child gets 40%, last gets 60%\n- `equal` — all children share equally\n@default \"left\""
        },
        {
          "name": "gap",
          "required": false,
          "type": "DashrowGap",
          "description": "@default \"md\""
        },
        {
          "name": "padding",
          "required": false,
          "type": "DashrowPadding",
          "description": "@default \"none\""
        },
        {
          "name": "storageKey",
          "required": false,
          "type": "string",
          "description": "A unique key used to persist panel sizes in sessionStorage.\nIf omitted, sizes are not persisted across renders."
        },
        {
          "name": "resizable",
          "required": false,
          "type": "boolean",
          "description": "@default true"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "children",
          "required": true,
          "type": "ReactNode"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "position",
          "required": false,
          "type": "\"first\" | \"last\" | \"middle\"",
          "options": [
            "first",
            "last",
            "middle"
          ],
          "default": "first"
        }
      ],
      "storyTitle": "Layout/Dashrow",
      "stories": [
        {
          "name": "Default",
          "description": "Default Dashrow with left-aligned split between main and side panels.",
          "args": "{\n    alignment: \"left\",\n    gap: \"md\",\n    padding: \"none\",\n    resizable: true,\n    locale: \"en-US\",\n    children: (\n      <>\n        <Dashbox title=\"Main Panel\">\n          <SampleContent />\n        </Dashbox>\n        <Dashbox title=\"Side Panel\">\n          <SampleContent />\n        </Dashbox>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default Dashrow with left-aligned split between main and side panels.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllAlignments",
          "description": "Comparison of all three alignment presets — left (60/40), right (40/60), and equal (50/50).",
          "args": "{ children: null },\n  render: () => (\n    <div className=\"flex w-full flex-col gap-6\">\n      {([\"left\", \"right\", \"equal\"] as const).map((align) => (\n        <div key={align}>\n          <p className=\"mb-2 font-mono text-xs text-muted-foreground\">\n            alignment=&quot;{align}&quot;\n          </p>\n          <Dashrow alignment={align}>\n            <Dashbox title=\"Panel A\">\n              <SampleContent />\n            </Dashbox>\n            <Dashbox title=\"Panel B\">\n              <SampleContent />\n            </Dashbox>\n          </Dashrow>\n        </div>\n      ))}\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison of all three alignment presets — left (60/40), right (40/60), and equal (50/50).\",\n      },\n    },\n  },",
          "code": "<div className=\"flex w-full flex-col gap-6\">\n      {([\"left\", \"right\", \"equal\"] as const).map((align) => (\n        <div key={align}>\n          <p className=\"mb-2 font-mono text-xs text-muted-foreground\">\n            alignment=&quot;{align}&quot;\n          </p>\n          <Dashrow alignment={align}>\n            <Dashbox title=\"Panel A\">\n              <SampleContent />\n            </Dashbox>\n            <Dashbox title=\"Panel B\">\n              <SampleContent />\n            </Dashbox>\n          </Dashrow>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) locale applied to the drag-resize tooltips.",
          "args": "{\n    alignment: \"left\",\n    locale: \"pt-BR\",\n    children: (\n      <>\n        <Dashbox title=\"Main Panel\">\n          <p className=\"text-sm text-muted-foreground\">\n            Main panel content. Charts, tables, or metrics.\n          </p>\n        </Dashbox>\n        <Dashbox title=\"Side Panel\">\n          <p className=\"text-sm text-muted-foreground\">\n            Secondary panel with supplementary information.\n          </p>\n        </Dashbox>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Portuguese (pt-BR) locale applied to the drag-resize tooltips.\",\n      },\n    },\n  },"
        },
        {
          "name": "EqualHeightStretch",
          "description": "Dashrow automatically stretches the shorter panel to match the taller sibling's height.",
          "args": "{\n    alignment: \"left\",\n    children: (\n      <>\n        <Dashbox title=\"Short Content\">\n          <SampleContent />\n        </Dashbox>\n        <Dashbox title=\"Tall Content\">\n          <TallContent />\n        </Dashbox>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dashrow automatically stretches the shorter panel to match the taller sibling's height.\",\n      },\n    },\n  },"
        },
        {
          "name": "ThreePanels",
          "description": "Three panels — a divider is placed between each adjacent pair.",
          "args": "{\n    alignment: \"equal\",\n    children: (\n      <>\n        <Dashbox title=\"Panel A\">\n          <SampleContent />\n        </Dashbox>\n        <Dashbox title=\"Panel B\">\n          <SampleContent />\n        </Dashbox>\n        <Dashbox title=\"Panel C\">\n          <SampleContent />\n        </Dashbox>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Three panels — a divider is placed between each adjacent pair.\",\n      },\n    },\n  },"
        },
        {
          "name": "Persistent",
          "description": "Resize the panels then refresh — the split is persisted in `sessionStorage`.",
          "args": "{\n    alignment: \"left\",\n    storageKey: \"storybook-persistent-demo\",\n    children: (\n      <>\n        <Dashbox\n          title=\"Persistent Left\"\n          description=\"Resize and refresh the page — width is remembered.\"\n        >\n          <SampleContent />\n        </Dashbox>\n        <Dashbox title=\"Persistent Right\">\n          <SampleContent />\n        </Dashbox>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Resize the panels then refresh — the split is persisted in `sessionStorage`.\",\n      },\n    },\n  },"
        },
        {
          "name": "NotResizable",
          "description": "With `resizable={false}`, the divider handle is hidden.",
          "args": "{\n    alignment: \"left\",\n    resizable: false,\n    children: (\n      <>\n        <Dashbox title=\"Fixed Left\">\n          <SampleContent />\n        </Dashbox>\n        <Dashbox title=\"Fixed Right\">\n          <SampleContent />\n        </Dashbox>\n      </>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"With `resizable={false}`, the divider handle is hidden.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithRealContent",
          "description": "Dashrow with live content — progress bars, status badges, and refresh actions inside Dashbox panels.",
          "args": "{ children: null },\n  render: () => (\n    <Dashrow alignment=\"left\" storageKey=\"demo-real-content\">\n      <Dashbox\n        title=\"Performance\"\n        description=\"Semester indicators\"\n        status=\"live\"\n        onRefresh={async () => {\n          await new Promise((r) => setTimeout(r, 800))\n        }}\n      >\n        <div className=\"flex flex-col gap-3\">\n          <ProgressBar\n            value={0.88}\n            name=\"Approval Rate\"\n            intent=\"success\"\n            precision={1}\n          />\n          <ProgressBar\n            value={0.62}\n            name=\"Attendance\"\n            intent=\"primary\"\n            precision={1}\n          />\n          <ProgressBar\n            value={0.35}\n            name=\"Dropout Rate\"\n            intent=\"destructive\"\n            precision={1}\n          />\n        </div>\n      </Dashbox>\n\n      <Dashbox title=\"Q1 Goals\" status=\"warning\">\n        <div className=\"flex flex-col gap-3\">\n          <ProgressBar value={100} name=\"Enrolled\" intent=\"success\" />\n          <ProgressBar value={72} name=\"Active\" intent=\"primary\" />\n          <ProgressBar value={18} name=\"Completed\" intent=\"destructive\" />\n        </div>\n      </Dashbox>\n    </Dashrow>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dashrow with live content — progress bars, status badges, and refresh actions inside Dashbox panels.\",\n      },\n    },\n  },",
          "code": "<Dashrow alignment=\"left\" storageKey=\"demo-real-content\">\n      <Dashbox\n        title=\"Performance\"\n        description=\"Semester indicators\"\n        status=\"live\"\n        onRefresh={async () => {\n          await new Promise((r) => setTimeout(r, 800))\n        }}\n      >\n        <div className=\"flex flex-col gap-3\">\n          <ProgressBar\n            value={0.88}\n            name=\"Approval Rate\"\n            intent=\"success\"\n            precision={1}\n          />\n          <ProgressBar\n            value={0.62}\n            name=\"Attendance\"\n            intent=\"primary\"\n            precision={1}\n          />\n          <ProgressBar\n            value={0.35}\n            name=\"Dropout Rate\"\n            intent=\"destructive\"\n            precision={1}\n          />\n        </div>\n      </Dashbox>\n\n      <Dashbox title=\"Q1 Goals\" status=\"warning\">\n        <div className=\"flex flex-col gap-3\">\n          <ProgressBar value={100} name=\"Enrolled\" intent=\"success\" />\n          <ProgressBar value={72} name=\"Active\" intent=\"primary\" />\n          <ProgressBar value={18} name=\"Completed\" intent=\"destructive\" />\n        </div>\n      </Dashbox>\n    </Dashrow>"
        },
        {
          "name": "GapVariants",
          "description": "Comparison of all four gap presets — none, sm, md, and lg.",
          "args": "{ children: null },\n  render: () => (\n    <div className=\"flex w-full flex-col gap-8\">\n      {([\"none\", \"sm\", \"md\", \"lg\"] as const).map((g) => (\n        <div key={g}>\n          <p className=\"mb-2 font-mono text-xs text-muted-foreground\">\n            gap=&quot;{g}&quot;\n          </p>\n          <Dashrow gap={g}>\n            <Dashbox title=\"Left\">\n              <SampleContent />\n            </Dashbox>\n            <Dashbox title=\"Right\">\n              <SampleContent />\n            </Dashbox>\n          </Dashrow>\n        </div>\n      ))}\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story: \"Comparison of all four gap presets — none, sm, md, and lg.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex w-full flex-col gap-8\">\n      {([\"none\", \"sm\", \"md\", \"lg\"] as const).map((g) => (\n        <div key={g}>\n          <p className=\"mb-2 font-mono text-xs text-muted-foreground\">\n            gap=&quot;{g}&quot;\n          </p>\n          <Dashrow gap={g}>\n            <Dashbox title=\"Left\">\n              <SampleContent />\n            </Dashbox>\n            <Dashbox title=\"Right\">\n              <SampleContent />\n            </Dashbox>\n          </Dashrow>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "Mobile",
          "description": "On mobile (<1024px), boxes stack vertically and the divider is hidden.",
          "args": "{\n    alignment: \"left\",\n    children: (\n      <>\n        <Dashbox title=\"Top Box\">\n          <SampleContent />\n        </Dashbox>\n        <Dashbox title=\"Bottom Box\">\n          <SampleContent />\n        </Dashbox>\n      </>\n    ),\n  },\n  globals: { viewport: { value: \"mobile1\", isRotated: false } },\n  parameters: {\n    layout: \"fullscreen\",\n    docs: {\n      description: {\n        story:\n          \"On mobile (<1024px), boxes stack vertically and the divider is hidden.\",\n      },\n    },\n  },"
        },
        {
          "name": "Desktop",
          "description": "Desktop (1024px+) — panels side-by-side with the draggable divider visible.",
          "args": "{\n    alignment: \"left\",\n    children: (\n      <>\n        <Dashbox title=\"Dashboard Panel A\">\n          <SampleContent />\n        </Dashbox>\n        <Dashbox title=\"Dashboard Panel B\">\n          <SampleContent />\n        </Dashbox>\n      </>\n    ),\n  },\n  globals: { viewport: { value: \"desktop\", isRotated: false } },\n  parameters: {\n    layout: \"fullscreen\",\n    docs: {\n      description: {\n        story:\n          \"Desktop (1024px+) — panels side-by-side with the draggable divider visible.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-data-table",
      "title": "Data Table",
      "description": "A high-performance virtualized data table with built-in toolbar, pagination, and sorting capabilities.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/data-table",
      "dependencies": [
        "@tanstack/react-table",
        "@tanstack/react-virtual",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "skeleton",
        "ds-pagination",
        "ds-search-bar",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/data-table.tsx"
      ],
      "storyTitle": "Data Display/DataTable",
      "props": [
        {
          "name": "size",
          "control": "radio",
          "options": [
            "default",
            "compact"
          ],
          "default": "default"
        },
        {
          "name": "textSize",
          "control": "select",
          "options": [
            "xs",
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "loading",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "showSearch",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "showDownload",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "pagination",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "paginationRounded",
          "control": "radio",
          "options": [
            "full",
            "light",
            "none"
          ],
          "default": "full"
        },
        {
          "name": "selectRows",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "title",
          "control": "text",
          "default": ""
        },
        {
          "name": "subtitle",
          "control": "text",
          "default": ""
        },
        {
          "name": "voiceSearch",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "rounded",
          "control": "boolean",
          "default": "true"
        },
        {
          "name": "manualPagination",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "manualSorting",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "locale",
          "control": "inline-radio",
          "options": [
            "en-US",
            "pt-BR",
            "es-ES",
            "fr-FR"
          ],
          "default": "en-US"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Default data table with simple column definitions and 20 student records.",
          "args": "{\n    ...base,\n    loading: false,\n    size: \"default\",\n    rounded: true,\n    showSearch: false,\n    pagination: false,\n    manualPagination: false,\n    defaultPageSize: 10,\n    defaultGlobalFilter: \"\",\n    selectRows: false,\n    stickyColumns: 0,\n    showDownload: false,\n    voiceSearch: false,\n    hasMore: false,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default data table with simple column definitions and 20 student records.\",\n      },\n    },\n  },"
        },
        {
          "name": "TitleAndSubtitle",
          "description": "Data table with title and subtitle text displayed above the table.",
          "args": "{\n    ...base,\n    title: \"Enrolled Students\",\n    subtitle: \"Academic term 2025.1 — Department of Computing · UFPB\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Data table with title and subtitle text displayed above the table.\",\n      },\n    },\n  },"
        },
        {
          "name": "FluidLastColumn",
          "description": "Omit `width` from a column to make it fill all remaining space via `flexGrow: 1`.\nEvery other column keeps its fixed size (`flexGrow: 0`); the fluid column absorbs\nwhatever width the container provides — with no empty gap at the right edge.\n\n```tsx\n// Fixed width — rigid, no growth\ncol({ key: 'name', label: 'Name', width: 190 })\n\n// No width — grows to fill remaining space\ncol({ key: 'city', label: 'City' })\n```\n\nHeader and body cells use the same `colStyle()` function, so they grow in perfect sync.\nThe resize handle is only rendered for fixed-width columns, so the fluid column stays\nclean. Resize any adjacent column and the fluid column adjusts automatically.",
          "args": "{\n    data: STUDENTS_20 as unknown as object[],\n    columns: FLUID_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Enrolled Students\",\n    subtitle:\n      \"Last column (City) has no width — it fills the remaining table width\",\n    height: 400,\n  },"
        },
        {
          "name": "WithSearch",
          "description": "Global filter powered by TanStack Table's `getFilteredRowModel`. Searches across all columns simultaneously and resets the page index to 0 on each keystroke.",
          "args": "{\n    ...base,\n    title: \"Real-time Search\",\n    subtitle: \"Filters across every column as you type\",\n    showSearch: true,\n  },"
        },
        {
          "name": "VoiceSearch",
          "description": "Enables the microphone button inside the search bar via `voiceSearch`. Uses the browser's Web Speech API — the button is hidden automatically in unsupported environments. Click the mic to dictate; the transcribed text is applied to the global filter in real time.",
          "args": "{\n    ...base,\n    title: \"Voice Search\",\n    subtitle: \"Click the microphone icon and speak to filter rows\",\n    showSearch: true,\n    voiceSearch: true,\n  },"
        },
        {
          "name": "Sortable",
          "description": "Set `enableSorting: true` on a column (or `sortable: true` via `col()`). Clicking the header cycles **asc → desc → none** via TanStack Table's `getSortedRowModel`.\n\n**Visual feedback uses only semantic tokens — no hardcoded colours:**\n\n- **Hover** → `hover:text-foreground` + `hover:border-b-2 hover:border-ring`\n- **Sorted (asc/desc)** → `text-primary` + `border-b-2 border-primary`\n- **Sort icon** → `opacity-100` when active, `opacity-60` when idle\n- **Body cells** → `bg-muted/30` tint on the active sorted column (non-sticky only)\n\nBecause every token is resolved from `globals.css` at runtime, the hover and sorted states\nadapt automatically to light/dark mode and any theme variant without extra CSS.",
          "args": "{\n    ...base,\n    title: \"Sortable columns\",\n    subtitle:\n      \"Click a header to sort — click again to reverse, third click to clear\",\n  },"
        },
        {
          "name": "ManualSorting",
          "description": "With `manualSorting`, the table stops sorting rows itself — it only tracks the clicked column/direction via the controlled `sorting` prop and reports changes through `onSortingChange`.\n\nThe consumer owns the actual ordering (e.g. re-fetching from a server with `?sort=` params) and passes back already-sorted `data`. Mirrors the `manualPagination` / `pageIndex` / `onPageChange` pattern.",
          "args": "{ data: [], columns: [] },\n  render: () => {\n    const [sorting, setSorting] = React.useState<SortingState>([\n      { id: \"name\", desc: false },\n    ])\n\n    const sortedData = React.useMemo(() => {\n      const [sort] = sorting\n      if (!sort) return STUDENTS_20\n      const copy = [...STUDENTS_20]\n      copy.sort((a, b) => {\n        const av = a[sort.id as keyof Student]\n        const bv = b[sort.id as keyof Student]\n        const cmp = av < bv ? -1 : av > bv ? 1 : 0\n        return sort.desc ? -cmp : cmp\n      })\n      return copy\n    }, [sorting])\n\n    return (\n      <DataTable\n        data={sortedData as unknown as object[]}\n        columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n        height={400}\n        title=\"Students — server-sorted\"\n        subtitle=\"`data` is pre-sorted by the consumer; the table only reflects the active sort\"\n        manualSorting\n        sorting={sorting}\n        onSortingChange={setSorting}\n      />\n    )\n  },",
          "code": "<DataTable\n        data={sortedData as unknown as object[]}\n        columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n        height={400}\n        title=\"Students — server-sorted\"\n        subtitle=\"`data` is pre-sorted by the consumer; the table only reflects the active sort\"\n        manualSorting\n        sorting={sorting}\n        onSortingChange={setSorting}\n      />"
        },
        {
          "name": "WithPagination",
          "description": "Uses TanStack Table's `getPaginationRowModel`. Combine with `pageSizeOptions` for a per-page selector. Works seamlessly with the global search filter.",
          "args": "{\n    ...base,\n    title: \"Students — paginated\",\n    pagination: true,\n    defaultPageSize: 5,\n    pageSizeOptions: [5, 10, 20],\n    height: 280,\n  },"
        },
        {
          "name": "PaginationPtBR",
          "description": "Paginated table with `locale=\"pt-BR\"` — button labels and the row counter are resolved automatically from `UI_I18N[\"pt-BR\"]` with no manual `labels` prop.",
          "args": "{\n    data: STUDENTS_200 as unknown as object[],\n    columns: SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Students — paginated\",\n    subtitle: 'locale=\"pt-BR\" — labels resolved automatically from UI_I18N',\n    pagination: true,\n    defaultPageSize: 10,\n    pageSizeOptions: [5, 10, 20],\n    height: 400,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "PaginationRoundedFull",
          "description": "Pagination buttons with `paginationRounded=\"full\"` — fully rounded (pill-style, default).",
          "args": "{\n    data: STUDENTS_200 as unknown as object[],\n    columns: SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Rounded Full\",\n    subtitle: 'paginationRounded=\"full\" — pill-shaped buttons',\n    pagination: true,\n    defaultPageSize: 10,\n    height: 400,\n    paginationRounded: \"full\",\n  },"
        },
        {
          "name": "PaginationRoundedLight",
          "description": "Pagination buttons with `paginationRounded=\"light\"` — slightly rounded corners.",
          "args": "{\n    data: STUDENTS_200 as unknown as object[],\n    columns: SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Rounded Light\",\n    subtitle: 'paginationRounded=\"light\" — subtle rounding',\n    pagination: true,\n    defaultPageSize: 10,\n    height: 400,\n    paginationRounded: \"light\",\n  },"
        },
        {
          "name": "PaginationRoundedNone",
          "description": "Pagination buttons with `paginationRounded=\"none\"` — square corners.",
          "args": "{\n    data: STUDENTS_200 as unknown as object[],\n    columns: SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Rounded None\",\n    subtitle: 'paginationRounded=\"none\" — square buttons',\n    pagination: true,\n    defaultPageSize: 10,\n    height: 400,\n    paginationRounded: \"none\",\n  },"
        },
        {
          "name": "SearchAndPagination",
          "description": "Combined global search and pagination — filtering resets the page index on each keystroke.",
          "args": "{\n    ...base,\n    title: \"Students\",\n    subtitle: \"Search + pagination in a single table\",\n    showSearch: true,\n    pagination: true,\n    defaultPageSize: 8,\n    pageSizeOptions: [5, 8, 15, 20],\n    height: 380,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Combined global search and pagination — filtering resets the page index on each keystroke.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithCustomCells",
          "description": "Mix `col()` helpers with native `ColumnDef` objects for full control.\n\n- **GPA** — colour-coded: green ≥ 8.5, amber < 7\n- **Absences** — red when ≥ 10\n- **Status** — `Badge` with an icon derived from a status map\n- **Scholar** — checkmark icon or em dash",
          "args": "{\n    data: STUDENTS_20 as unknown as object[],\n    columns: RICH_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Student Overview\",\n    subtitle: \"Colour-coded GPA · status badge · scholarship icon\",\n    showSearch: true,\n    height: 420,\n  },"
        },
        {
          "name": "RowSelection",
          "description": "Enable `selectRows` to inject a checkbox column managed by TanStack Table's `rowSelection` state.\nThe header checkbox selects/deselects the entire current page and shows an indeterminate state when partially selected.\n\nUse `onSelectedRowsChange` to receive the array of selected row objects whenever the selection changes.\nThe callback fires synchronously via a `useEffect` scoped to `rowSelection` state, so it reflects\nthe current page's selection after every toggle.\n\n```tsx\nconst [selected, setSelected] = React.useState<Student[]>([])\n\n<DataTable\n  data={students}\n  columns={columns}\n  selectRows\n  onSelectedRowsChange={setSelected}\n/>\n```",
          "args": "{ data: [], columns: [] },\n  render: () => {\n    const [selected, setSelected] = React.useState<Student[]>([])\n    return (\n      <div className=\"flex flex-col gap-4\">\n        <DataTable\n          data={STUDENTS_20}\n          columns={MANY_COLUMNS}\n          title=\"Row Selection\"\n          subtitle=\"Scroll horizontally to see the selection column stay fixed on the left\"\n          selectRows\n          onSelectedRowsChange={(rows) => setSelected(rows as Student[])}\n          height={400}\n        />\n        <div className=\"min-h-10 rounded-lg border border-border bg-muted/30 px-4 py-2.5 text-sm\">\n          {selected.length === 0 ? (\n            <span className=\"text-muted-foreground\">\n              No rows selected — use the checkboxes above.\n            </span>\n          ) : (\n            <span>\n              <span className=\"font-semibold\">{selected.length}</span>{\" \"}\n              {selected.length === 1 ? \"student\" : \"students\"} selected:{\" \"}\n              <span className=\"text-muted-foreground\">\n                {selected\n                  .slice(0, 4)\n                  .map((s) => s.name)\n                  .join(\", \")}\n                {selected.length > 4 && ` +${selected.length - 4} more`}\n              </span>\n            </span>\n          )}\n        </div>\n      </div>\n    )\n  },",
          "code": "<div className=\"flex flex-col gap-4\">\n        <DataTable\n          data={STUDENTS_20}\n          columns={MANY_COLUMNS}\n          title=\"Row Selection\"\n          subtitle=\"Scroll horizontally to see the selection column stay fixed on the left\"\n          selectRows\n          onSelectedRowsChange={(rows) => setSelected(rows as Student[])}\n          height={400}\n        />\n        <div className=\"min-h-10 rounded-lg border border-border bg-muted/30 px-4 py-2.5 text-sm\">\n          {selected.length === 0 ? (\n            <span className=\"text-muted-foreground\">\n              No rows selected — use the checkboxes above.\n            </span>\n          ) : (\n            <span>\n              <span className=\"font-semibold\">{selected.length}</span>{\" \"}\n              {selected.length === 1 ? \"student\" : \"students\"} selected:{\" \"}\n              <span className=\"text-muted-foreground\">\n                {selected\n                  .slice(0, 4)\n                  .map((s) => s.name)\n                  .join(\", \")}\n                {selected.length > 4 && ` +${selected.length - 4} more`}\n              </span>\n            </span>\n          )}\n        </div>\n      </div>"
        },
        {
          "name": "BulkAction",
          "description": "A common pattern: combine `onSelectedRowsChange` with a conditionally rendered toolbar button.\nThe button only appears when at least one row is selected.\n\n```tsx\nconst [selected, setSelected] = React.useState<Student[]>([])\n\n<DataTable\n  data={students}\n  columns={columns}\n  selectRows\n  onSelectedRowsChange={setSelected}\n  toolbar={\n    selected.length > 0 ? (\n      <Button size='sm' variant='destructive' onClick={handleDelete}>\n        <Trash2 className='size-4' />\n        Delete selected ({selected.length})\n      </Button>\n    ) : null\n  }\n/>\n```",
          "args": "{ data: [], columns: [] },\n  render: () => {\n    const [rows, setRows] = React.useState<Student[]>(STUDENTS_20)\n    const [selected, setSelected] = React.useState<Student[]>([])\n    const [lastDeleted, setLastDeleted] = React.useState<number | null>(null)\n\n    function handleDelete() {\n      const ids = new Set(selected.map((s) => s.id))\n      setLastDeleted(ids.size)\n      setRows((prev) => prev.filter((s) => !ids.has(s.id)))\n      setSelected([])\n    }\n\n    return (\n      <div className=\"flex flex-col gap-4\">\n        <DataTable\n          data={rows}\n          columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n          title=\"Students\"\n          subtitle=\"Select rows to reveal the bulk-delete toolbar button\"\n          selectRows\n          onSelectedRowsChange={(r) => setSelected(r as Student[])}\n          pagination\n          defaultPageSize={8}\n          height={380}\n          toolbar={\n            selected.length > 0 ? (\n              <button\n                onClick={handleDelete}\n                className=\"text-destructive-foreground inline-flex items-center gap-1.5 rounded-md bg-destructive px-3 py-1.5 text-xs font-medium transition-opacity hover:opacity-90\"\n              >\n                <Trash2 className=\"size-3.5\" />\n                Delete selected ({selected.length})\n              </button>\n            ) : null\n          }\n        />\n        {lastDeleted !== null && (\n          <p className=\"text-xs text-muted-foreground\">\n            {lastDeleted} {lastDeleted === 1 ? \"row\" : \"rows\"} removed.{\" \"}\n            {rows.length} remaining.\n          </p>\n        )}\n      </div>\n    )\n  },",
          "code": "<div className=\"flex flex-col gap-4\">\n        <DataTable\n          data={rows}\n          columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n          title=\"Students\"\n          subtitle=\"Select rows to reveal the bulk-delete toolbar button\"\n          selectRows\n          onSelectedRowsChange={(r) => setSelected(r as Student[])}\n          pagination\n          defaultPageSize={8}\n          height={380}\n          toolbar={\n            selected.length > 0 ? (\n              <button\n                onClick={handleDelete}\n                className=\"text-destructive-foreground inline-flex items-center gap-1.5 rounded-md bg-destructive px-3 py-1.5 text-xs font-medium transition-opacity hover:opacity-90\"\n              >\n                <Trash2 className=\"size-3.5\" />\n                Delete selected ({selected.length})\n              </button>\n            ) : null\n          }\n        />\n        {lastDeleted !== null && (\n          <p className=\"text-xs text-muted-foreground\">\n            {lastDeleted} {lastDeleted === 1 ? \"row\" : \"rows\"} removed.{\" \"}\n            {rows.length} remaining.\n          </p>\n        )}\n      </div>"
        },
        {
          "name": "StickyColumns",
          "description": "The `stickyColumns` prop pins the first N columns to the left during horizontal scroll. Here, the first two columns (Enrollment ID and Name) stay fixed while the remaining columns scroll. The selection column can be combined with sticky columns — it always takes precedence at the far left.",
          "args": "{ data: [], columns: [] },\n  render: () => (\n    <DataTable\n      data={STUDENTS_20}\n      columns={MANY_COLUMNS}\n      title=\"Sticky Columns\"\n      subtitle=\"First two columns stay fixed — scroll horizontally to see them pinned\"\n      stickyColumns={2}\n      height={400}\n    />\n  ),",
          "code": "<DataTable\n      data={STUDENTS_20}\n      columns={MANY_COLUMNS}\n      title=\"Sticky Columns\"\n      subtitle=\"First two columns stay fixed — scroll horizontally to see them pinned\"\n      stickyColumns={2}\n      height={400}\n    />"
        },
        {
          "name": "StickyColumnsWithSelection",
          "description": "Combines `stickyColumns={2}` with `selectRows`. The selection checkbox is always the first sticky column (leftmost), followed by the two configured sticky columns. Scroll horizontally to see all three columns pinned on the left.",
          "args": "{ data: [], columns: [] },\n  render: () => (\n    <DataTable\n      data={STUDENTS_20}\n      columns={MANY_COLUMNS}\n      title=\"Sticky Columns + Selection\"\n      subtitle=\"Selection checkbox + first two data columns stay fixed on the left\"\n      stickyColumns={2}\n      selectRows\n      height={400}\n    />\n  ),",
          "code": "<DataTable\n      data={STUDENTS_20}\n      columns={MANY_COLUMNS}\n      title=\"Sticky Columns + Selection\"\n      subtitle=\"Selection checkbox + first two data columns stay fixed on the left\"\n      stickyColumns={2}\n      selectRows\n      height={400}\n    />"
        },
        {
          "name": "SquareBorders",
          "description": "Set `rounded={false}` to render the table with straight corners instead of the default `rounded-xl`. Useful when embedding the table in a container that already provides its own border-radius or when a sharper aesthetic is desired.",
          "args": "{ data: [], columns: [] },\n  render: () => (\n    <DataTable\n      data={STUDENTS_20}\n      columns={MANY_COLUMNS}\n      title=\"Square Borders\"\n      subtitle=\"rounded={false} — no rounded corners on the table wrapper\"\n      rounded={false}\n      height={400}\n    />\n  ),",
          "code": "<DataTable\n      data={STUDENTS_20}\n      columns={MANY_COLUMNS}\n      title=\"Square Borders\"\n      subtitle=\"rounded={false} — no rounded corners on the table wrapper\"\n      rounded={false}\n      height={400}\n    />"
        },
        {
          "name": "ClickableRows",
          "description": "Row click handler — clicking a row displays the selected student's details below the table.",
          "args": "{ data: [], columns: [] },\n  render: () => {\n    const [selected, setSelected] = React.useState<Student | null>(null)\n    return (\n      <div className=\"flex flex-col gap-4\">\n        <DataTable\n          title=\"Click a Row\"\n          subtitle=\"onRowClick receives the original row object\"\n          data={STUDENTS_20}\n          columns={RICH_COLUMNS}\n          height={360}\n          onRowClick={(row) => setSelected(row as Student)}\n        />\n        {selected && (\n          <div className=\"rounded-lg border border-border bg-muted/30 px-4 py-3 text-sm\">\n            <span className=\"font-semibold\">{selected.name}</span>\n            {\" — \"}\n            <span className=\"text-muted-foreground\">\n              {selected.course}, semester {selected.semester}\n            </span>\n            <span className=\"ml-2 font-medium\">\n              GPA {selected.gpa.toFixed(1)}\n            </span>\n          </div>\n        )}\n      </div>\n    )\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Row click handler — clicking a row displays the selected student's details below the table.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-col gap-4\">\n        <DataTable\n          title=\"Click a Row\"\n          subtitle=\"onRowClick receives the original row object\"\n          data={STUDENTS_20}\n          columns={RICH_COLUMNS}\n          height={360}\n          onRowClick={(row) => setSelected(row as Student)}\n        />\n        {selected && (\n          <div className=\"rounded-lg border border-border bg-muted/30 px-4 py-3 text-sm\">\n            <span className=\"font-semibold\">{selected.name}</span>\n            {\" — \"}\n            <span className=\"text-muted-foreground\">\n              {selected.course}, semester {selected.semester}\n            </span>\n            <span className=\"ml-2 font-medium\">\n              GPA {selected.gpa.toFixed(1)}\n            </span>\n          </div>\n        )}\n      </div>"
        },
        {
          "name": "CompactSize",
          "description": "Compact table variant with tighter padding — ideal for dashboards and sidebars.",
          "args": "{\n    ...base,\n    title: \"Compact mode\",\n    subtitle: 'size=\"compact\" — useful for dashboards and sidebars',\n    size: \"compact\",\n    showSearch: true,\n    height: 380,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Compact table variant with tighter padding — ideal for dashboards and sidebars.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithDownload",
          "description": "Download button in the toolbar that triggers an onDownload callback.",
          "args": "{\n    ...base,\n    title: \"Export Data\",\n    showDownload: true,\n    showSearch: true,\n    onDownload: () => alert(\"Exporting...\"),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Download button in the toolbar that triggers an onDownload callback.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithFooter",
          "description": "The `footer` prop accepts any `ReactNode` rendered below the table wrapper in a muted text row.",
          "args": "{\n    data: STUDENTS_20 as unknown as object[],\n    columns: RICH_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Enrolled Students\",\n    subtitle: \"Source: SIGAA — 2025.1\",\n    height: 400,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <Users className=\"size-3.5\" />\n          {STUDENTS_20.length} students enrolled\n        </span>\n        <span className=\"flex items-center gap-1 opacity-60\">\n          <Info className=\"size-3\" />\n          Updated today at 08:30\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "KitchenSink",
          "description": "All features active at once: title, subtitle, search, sortable columns, row selection, pagination, download, and footer.",
          "args": "{\n    data: STUDENTS_200 as unknown as object[],\n    columns: RICH_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Faculty Portal — Student Progress\",\n    subtitle: \"UFPB · Department of Computing · 2025.1\",\n    showSearch: true,\n    showDownload: true,\n    selectRows: true,\n    pagination: true,\n    defaultPageSize: 7,\n    pageSizeOptions: [5, 7, 10, 20, 50],\n    height: 380,\n    onDownload: () => alert(\"Exporting CSV...\"),\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-success\" />\n          Average GPA: 7.9\n        </span>\n        <span className=\"flex items-center gap-1 opacity-60\">\n          <Info className=\"size-3\" />\n          Source: SIGAA\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "TenThousandRows",
          "description": "**10 000 rows** rendered without pagination.\n\nOnly the rows visible inside the scrollable viewport are mounted in the DOM.\n`@tanstack/react-virtual` measures the container, calculates a virtual window,\nand updates it on scroll — keeping frame-rate smooth even at this scale.\n\n> Data is generated lazily on first mount — not at module load — to avoid blocking Storybook on import.",
          "args": "{ data: [], columns: [] },\n  render: () => {\n    const [data] = React.useState(() => generateStudents(10_000))\n    return (\n      <DataTable\n        data={data as unknown as object[]}\n        columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n        title=\"10 000 Rows\"\n        subtitle=\"Scroll to see virtualization in action — only visible rows are in the DOM\"\n        showSearch\n        height={480}\n      />\n    )\n  },",
          "code": "<DataTable\n        data={data as unknown as object[]}\n        columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n        title=\"10 000 Rows\"\n        subtitle=\"Scroll to see virtualization in action — only visible rows are in the DOM\"\n        showSearch\n        height={480}\n      />"
        },
        {
          "name": "HundredThousandRows",
          "description": "**100 000 rows** in a single scrollable viewport.\n\nThe total virtual height of all rows is pre-calculated, so the browser's\nnative scrollbar reflects the correct proportion — but only a tiny DOM window\nof real `<tr>` elements is ever mounted at once.\n\n> Data is generated lazily on first mount — not at module load — to avoid blocking Storybook on import.",
          "args": "{ data: [], columns: [] },\n  render: () => {\n    const [data] = React.useState(() => generateStudents(100_000))\n    return (\n      <DataTable\n        data={data as unknown as object[]}\n        columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n        title=\"100 000 Rows\"\n        subtitle=\"Virtual DOM window: ~15 rows regardless of dataset size\"\n        height={480}\n      />\n    )\n  },",
          "code": "<DataTable\n        data={data as unknown as object[]}\n        columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n        title=\"100 000 Rows\"\n        subtitle=\"Virtual DOM window: ~15 rows regardless of dataset size\"\n        height={480}\n      />"
        },
        {
          "name": "VirtualizedWithPagination",
          "description": "Pagination and virtualization work together: TanStack Table slices the filtered rows into pages; the virtualizer renders only the visible rows within that page.",
          "args": "{ data: [], columns: [] },\n  render: () => {\n    const [data] = React.useState(() => generateStudents(10_000))\n    return (\n      <DataTable\n        data={data as unknown as object[]}\n        columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n        title=\"10 000 Rows with Pagination\"\n        showSearch\n        pagination\n        defaultPageSize={50}\n        pageSizeOptions={[20, 50, 100, 200]}\n        height={480}\n      />\n    )\n  },",
          "code": "<DataTable\n        data={data as unknown as object[]}\n        columns={SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[]}\n        title=\"10 000 Rows with Pagination\"\n        showSearch\n        pagination\n        defaultPageSize={50}\n        pageSizeOptions={[20, 50, 100, 200]}\n        height={480}\n      />"
        },
        {
          "name": "LoadingSkeleton",
          "description": "When `loading=true` and `data=[]`, the table renders an animated skeleton that mirrors the exact column layout. Placeholders are only shown for slots you actually pass (`title`, `subtitle`, `showSearch`, `pagination`, `footer`).",
          "args": "{\n    data: [],\n    columns: SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Enrolled Students\",\n    subtitle: \"Academic term 2025.1\",\n    showSearch: true,\n    pagination: true,\n    height: 380,\n    footer: <span>Source: SIGAA</span>,\n  },\n  render: (args) => <SimulateFirstLoad {...args} />,"
        },
        {
          "name": "LoadingRefetch",
          "description": "When `loading=true` and `data` already has rows, the existing data stays visible while a slim progress bar at the top signals an in-flight request. Rows dim to reinforce the pending state.",
          "args": "{\n    data: STUDENTS_20 as unknown as object[],\n    columns: RICH_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"Enrolled Students\",\n    subtitle: \"Background refresh in progress\",\n    showSearch: true,\n    height: 380,\n  },\n  render: (args) => <SimulateRefetch {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data=[]` and `loading=false`, the body shows a centred empty-state with a `Table2` icon. Customise the message and description via the `labels` prop.",
          "args": "{\n    data: [],\n    columns: SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"No results\",\n    subtitle: \"Try adjusting your filters or check back later\",\n    height: 340,\n  },"
        },
        {
          "name": "EmptyAfterSearch",
          "description": "The same empty state is shown when a search term matches no rows. The search field stays interactive so the user can clear the filter. `defaultGlobalFilter` pre-fills the search bar on mount.",
          "args": "{\n    data: STUDENTS_20 as unknown as object[],\n    columns: SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"No results for this search\",\n    showSearch: true,\n    defaultGlobalFilter: \"zzz_no_match\",\n    height: 340,\n    labels: {\n      noData: \"No students match your search\",\n      noDataDescription: \"Try searching by name, course, or enrollment ID.\",\n    },\n  },"
        },
        {
          "name": "EmptyStatePtBR",
          "description": "Empty state with `locale=\"pt-BR\"` — the built-in message and description resolve automatically from `UI_I18N[\"pt-BR\"]` without any `labels` override.",
          "args": "{\n    data: [],\n    columns: SIMPLE_COLUMNS as unknown as DataTableColumnDef<object>[],\n    title: \"No results\",\n    subtitle: \"Try adjusting your filters or check back later\",\n    height: 340,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "ColHelper",
          "description": "The exported `col<T>()` function converts a simple descriptor into a full `DataTableColumnDef<T>`.\n\n```tsx\nimport { col } from '@/components/ds/data-table'\n\nconst columns: DataTableColumnDef<Student>[] = [\n  // Sortable plain column\n  col({ key: 'name', label: 'Name', sortable: true }),\n\n  // Fixed-width centred column with number formatting\n  col({ key: 'gpa', label: 'GPA', width: 80, align: 'center', format: 'number' }),\n\n  // Custom cell renderer — receives (value, row)\n  col({\n    key: 'status',\n    label: 'Status',\n    cell: (_, row) => <Badge>{row.status}</Badge>,\n  }),\n]\n```",
          "args": "{ data: [], columns: [] },\n  render: () => (\n    <DataTable\n      title=\"col() Helper Demo\"\n      subtitle=\"All columns below are defined via col()\"\n      data={STUDENTS_20}\n      columns={[\n        col<Student>({\n          key: \"name\",\n          label: \"Name\",\n          width: 190,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"course\",\n          label: \"Course\",\n          width: 220,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"semester\",\n          label: \"Semester\",\n          width: 90,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"gpa\",\n          label: \"GPA\",\n          width: 80,\n          align: \"center\",\n          format: \"number\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"absences\",\n          label: \"Absences\",\n          width: 90,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"status\",\n          label: \"Status\",\n          width: 120,\n          cell: (v) => <span className=\"capitalize\">{String(v)}</span>,\n        }),\n        col<Student>({ key: \"city\", label: \"City\", width: 140 }),\n      ]}\n      showSearch\n      pagination\n      defaultPageSize={8}\n      pageSizeOptions={[5, 8, 10, 20]}\n      height={380}\n    />\n  ),",
          "code": "<DataTable\n      title=\"col() Helper Demo\"\n      subtitle=\"All columns below are defined via col()\"\n      data={STUDENTS_20}\n      columns={[\n        col<Student>({\n          key: \"name\",\n          label: \"Name\",\n          width: 190,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"course\",\n          label: \"Course\",\n          width: 220,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"semester\",\n          label: \"Semester\",\n          width: 90,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"gpa\",\n          label: \"GPA\",\n          width: 80,\n          align: \"center\",\n          format: \"number\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"absences\",\n          label: \"Absences\",\n          width: 90,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"status\",\n          label: \"Status\",\n          width: 120,\n          cell: (v) => <span className=\"capitalize\">{String(v)}</span>,\n        }),\n        col<Student>({ key: \"city\", label: \"City\", width: 140 }),\n      ]}\n      showSearch\n      pagination\n      defaultPageSize={8}\n      pageSizeOptions={[5, 8, 10, 20]}\n      height={380}\n    />"
        },
        {
          "name": "ResizableColumns",
          "description": "Hover the right edge of any column header to reveal the resize handle, then drag left or right to adjust the width.\n\n**How it works:**\n\n- `columnResizeMode: 'onChange'` updates widths in real time as you drag\n- `header.getResizeHandler()` from TanStack Table manages the drag lifecycle (mouse + touch)\n- `header.column.getIsResizing()` drives the handle colour: `bg-border` at rest → `bg-primary/50` on hover → `bg-primary` while dragging\n- Only columns with an explicit `width` in `col()` get a resize handle — flex-grow columns are excluded to avoid an initial-width jump\n- Width overrides live in TanStack's internal `columnSizing` state and are passed as `override` to `colStyle`, switching those columns from flex to fixed-width",
          "args": "{ data: [], columns: [] },\n  render: () => (\n    <DataTable\n      data={STUDENTS_20}\n      columns={[\n        col<Student>({\n          key: \"enrollmentId\",\n          label: \"Enrollment ID\",\n          width: 130,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"name\",\n          label: \"Name\",\n          width: 200,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"course\",\n          label: \"Course\",\n          width: 200,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"semester\",\n          label: \"Sem.\",\n          width: 70,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"gpa\",\n          label: \"GPA\",\n          width: 80,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"absences\",\n          label: \"Absences\",\n          width: 90,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"city\",\n          label: \"City\",\n          width: 150,\n          sortable: true,\n        }),\n      ]}\n      title=\"Resizable Columns\"\n      subtitle=\"Drag the right edge of any column header to resize it\"\n      showSearch\n      height={400}\n    />\n  ),",
          "code": "<DataTable\n      data={STUDENTS_20}\n      columns={[\n        col<Student>({\n          key: \"enrollmentId\",\n          label: \"Enrollment ID\",\n          width: 130,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"name\",\n          label: \"Name\",\n          width: 200,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"course\",\n          label: \"Course\",\n          width: 200,\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"semester\",\n          label: \"Sem.\",\n          width: 70,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"gpa\",\n          label: \"GPA\",\n          width: 80,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"absences\",\n          label: \"Absences\",\n          width: 90,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Student>({\n          key: \"city\",\n          label: \"City\",\n          width: 150,\n          sortable: true,\n        }),\n      ]}\n      title=\"Resizable Columns\"\n      subtitle=\"Drag the right edge of any column header to resize it\"\n      showSearch\n      height={400}\n    />"
        },
        {
          "name": "NumberFormats",
          "description": "Demonstrates the built-in number formatting via `format` + the new `locale` and `formatOptions` props on `col()`.\n\n| Column | `format` | `locale` | `formatOptions` override |\n| --- | --- | --- | --- |\n| Total Budget | `currency` | `pt-BR` (default) | — |\n| Disbursed | `currency` | `pt-BR` (default) | — |\n| Execution | `percent` | `pt-BR` | `minimumFractionDigits: 1` |\n| Avg Cost/Item | `number` | `pt-BR` | `minimumFractionDigits: 2, maximumFractionDigits: 2` |\n| Items | `number` | `pt-BR` | `maximumFractionDigits: 0` |\n\n**`locale` and `formatOptions` are spread into `Intl.NumberFormat`**, so any combination the browser supports works:\n\n```tsx\n// BRL — default, no extra config needed\ncol({ key: 'budget', label: 'Budget', format: 'currency' })\n\n// USD — override currency\ncol({ key: 'budget', label: 'Budget', format: 'currency', locale: 'en-US',\n      formatOptions: { currency: 'USD' } })\n\n// Percent with 1 decimal in pt-BR\ncol({ key: 'rate', label: 'Execution Rate', format: 'percent', locale: 'pt-BR',\n      formatOptions: { minimumFractionDigits: 1 } })\n\n// Fixed 2 decimals in pt-BR\ncol({ key: 'cost', label: 'Cost', format: 'number', locale: 'pt-BR',\n      formatOptions: { minimumFractionDigits: 2, maximumFractionDigits: 2 } })\n```",
          "args": "{ data: [], columns: [] },\n  render: () => (\n    <DataTable\n      data={GRANTS}\n      columns={[\n        col<Grant>({\n          key: \"id\",\n          label: \"Process #\",\n          width: 110,\n          sortable: true,\n        }),\n        col<Grant>({\n          key: \"project\",\n          label: \"Project\",\n          width: 360,\n          sortable: true,\n        }),\n        col<Grant>({\n          key: \"agency\",\n          label: \"Agency\",\n          width: 90,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Grant>({\n          key: \"totalBudget\",\n          label: \"Total Budget\",\n          width: 180,\n          align: \"right\",\n          sortable: true,\n          format: \"currency\",\n        }),\n        col<Grant>({\n          key: \"disbursed\",\n          label: \"Disbursed\",\n          width: 140,\n          align: \"right\",\n          sortable: true,\n          format: \"currency\",\n        }),\n        col<Grant>({\n          key: \"executionRate\",\n          label: \"Execution\",\n          width: 120,\n          align: \"right\",\n          sortable: true,\n          format: \"percent\",\n          locale: \"pt-BR\",\n          formatOptions: { minimumFractionDigits: 1 },\n        }),\n        col<Grant>({\n          key: \"costPerItem\",\n          label: \"Avg Cost/Item\",\n          width: 170,\n          align: \"right\",\n          sortable: true,\n          format: \"number\",\n          locale: \"pt-BR\",\n          formatOptions: { minimumFractionDigits: 2, maximumFractionDigits: 2 },\n        }),\n        col<Grant>({\n          key: \"items\",\n          label: \"Items\",\n          width: 70,\n          align: \"center\",\n          sortable: true,\n          format: \"number\",\n          locale: \"pt-BR\",\n          formatOptions: { maximumFractionDigits: 0 },\n        }),\n      ]}\n      title=\"Research & Extension Projects — UFPB\"\n      subtitle=\"Budget execution by project · fiscal year 2025\"\n      showSearch\n      height={420}\n    />\n  ),",
          "code": "<DataTable\n      data={GRANTS}\n      columns={[\n        col<Grant>({\n          key: \"id\",\n          label: \"Process #\",\n          width: 110,\n          sortable: true,\n        }),\n        col<Grant>({\n          key: \"project\",\n          label: \"Project\",\n          width: 360,\n          sortable: true,\n        }),\n        col<Grant>({\n          key: \"agency\",\n          label: \"Agency\",\n          width: 90,\n          align: \"center\",\n          sortable: true,\n        }),\n        col<Grant>({\n          key: \"totalBudget\",\n          label: \"Total Budget\",\n          width: 180,\n          align: \"right\",\n          sortable: true,\n          format: \"currency\",\n        }),\n        col<Grant>({\n          key: \"disbursed\",\n          label: \"Disbursed\",\n          width: 140,\n          align: \"right\",\n          sortable: true,\n          format: \"currency\",\n        }),\n        col<Grant>({\n          key: \"executionRate\",\n          label: \"Execution\",\n          width: 120,\n          align: \"right\",\n          sortable: true,\n          format: \"percent\",\n          locale: \"pt-BR\",\n          formatOptions: { minimumFractionDigits: 1 },\n        }),\n        col<Grant>({\n          key: \"costPerItem\",\n          label: \"Avg Cost/Item\",\n          width: 170,\n          align: \"right\",\n          sortable: true,\n          format: \"number\",\n          locale: \"pt-BR\",\n          formatOptions: { minimumFractionDigits: 2, maximumFractionDigits: 2 },\n        }),\n        col<Grant>({\n          key: \"items\",\n          label: \"Items\",\n          width: 70,\n          align: \"center\",\n          sortable: true,\n          format: \"number\",\n          locale: \"pt-BR\",\n          formatOptions: { maximumFractionDigits: 0 },\n        }),\n      ]}\n      title=\"Research & Extension Projects — UFPB\"\n      subtitle=\"Budget execution by project · fiscal year 2025\"\n      showSearch\n      height={420}\n    />"
        },
        {
          "name": "Primitives",
          "description": "The `Table`, `TableHeader`, `TableBody`, `TableRow`, `TableHead`, and `TableCell` primitives are exported for fully custom layouts — no DataTable state management or virtualization.",
          "args": "{ data: [], columns: [] },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"The `Table`, `TableHeader`, `TableBody`, `TableRow`, `TableHead`, and `TableCell` primitives are exported for fully custom layouts — no DataTable state management or virtualization.\",\n      },\n    },\n  },\n  render: () => {\n    type CourseRow = {\n      course: string\n      enrolled: number\n      avgGpa: number\n      status: \"ok\" | \"alert\"\n    }\n    const rows: CourseRow[] = [\n      { course: \"Computer Science\", enrolled: 6, avgGpa: 8.8, status: \"ok\" },\n      {\n        course: \"Electrical Engineering\",\n        enrolled: 5,\n        avgGpa: 7.1,\n        status: \"alert\",\n      },\n      { course: \"Mathematics\", enrolled: 5, avgGpa: 7.2, status: \"ok\" },\n      { course: \"Physics\", enrolled: 4, avgGpa: 8.2, status: \"ok\" },\n      { course: \"Statistics\", enrolled: 3, avgGpa: 7.7, status: \"ok\" },\n    ]\n\n    return (\n      <div className=\"overflow-hidden rounded-xl border border-border shadow-sm\">\n        <Table>\n          <TableHeader sticky>\n            <TableRow>\n              <TableHead>Course</TableHead>\n              <TableHead className=\"text-center\">Enrolled</TableHead>\n              <TableHead className=\"text-center\">Avg GPA</TableHead>\n              <TableHead className=\"text-right\">Status</TableHead>\n            </TableRow>\n          </TableHeader>\n          <TableBody>\n            {rows.map((row) => (\n              <TableRow key={row.course} clickable>\n                <TableCell className=\"font-medium\">{row.course}</TableCell>\n                <TableCell className=\"text-center\">{row.enrolled}</TableCell>\n                <TableCell className=\"text-center\">\n                  {row.avgGpa.toFixed(1)}\n                </TableCell>\n                <TableCell className=\"text-right\">\n                  <Badge\n                    variant={\n                      row.status === \"alert\" ? \"destructive\" : \"secondary\"\n                    }\n                  >\n                    {row.status === \"alert\" ? (\n                      <>\n                        <TrendingDown className=\"mr-1 size-3\" />\n                        at risk\n                      </>\n                    ) : (\n                      <>\n                        <TrendingUp className=\"mr-1 size-3\" />\n                        on track\n                      </>\n                    )}\n                  </Badge>\n                </TableCell>\n              </TableRow>\n            ))}\n          </TableBody>\n        </Table>\n      </div>\n    )\n  },",
          "code": "<div className=\"overflow-hidden rounded-xl border border-border shadow-sm\">\n        <Table>\n          <TableHeader sticky>\n            <TableRow>\n              <TableHead>Course</TableHead>\n              <TableHead className=\"text-center\">Enrolled</TableHead>\n              <TableHead className=\"text-center\">Avg GPA</TableHead>\n              <TableHead className=\"text-right\">Status</TableHead>\n            </TableRow>\n          </TableHeader>\n          <TableBody>\n            {rows.map((row) => (\n              <TableRow key={row.course} clickable>\n                <TableCell className=\"font-medium\">{row.course}</TableCell>\n                <TableCell className=\"text-center\">{row.enrolled}</TableCell>\n                <TableCell className=\"text-center\">\n                  {row.avgGpa.toFixed(1)}\n                </TableCell>\n                <TableCell className=\"text-right\">\n                  <Badge\n                    variant={\n                      row.status === \"alert\" ? \"destructive\" : \"secondary\"\n                    }\n                  >\n                    {row.status === \"alert\" ? (\n                      <>\n                        <TrendingDown className=\"mr-1 size-3\" />\n                        at risk\n                      </>\n                    ) : (\n                      <>\n                        <TrendingUp className=\"mr-1 size-3\" />\n                        on track\n                      </>\n                    )}\n                  </Badge>\n                </TableCell>\n              </TableRow>\n            ))}\n          </TableBody>\n        </Table>\n      </div>"
        }
      ]
    },
    {
      "name": "ds-date-picker",
      "title": "DatePicker",
      "description": "Seletor de data combinando um botão e um calendário (Popover).",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/date-picker",
      "dependencies": [
        "date-fns",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "popover",
        "calendar",
        "ui-i18n"
      ],
      "files": [
        "components/ds/date-picker.tsx"
      ],
      "props": [
        {
          "name": "date",
          "required": false,
          "type": "Date",
          "description": "The currently selected date."
        },
        {
          "name": "onSelect",
          "required": false,
          "type": "(date?: Date) => void",
          "description": "Callback when a date is selected."
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string",
          "description": "Placeholder text when no date is selected."
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean",
          "description": "Disables the date picker."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for date formatting and the calendar component."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "description": "Component size, applied to the trigger button."
        }
      ],
      "storyTitle": "Form/DatePicker",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    disabled: true,\n  },"
        },
        {
          "name": "WithPreset",
          "description": "",
          "args": "{\n    date: new Date(2025, 0, 1),\n  },"
        },
        {
          "name": "AllSizes",
          "description": "The component supports 3 sizes: sm, md and lg."
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <DatePicker locale=\"pt-BR\" date={new Date(2025, 0, 1)} />\n      <DatePicker locale=\"en-US\" date={new Date(2025, 0, 1)} />\n      <DatePicker locale=\"es-ES\" date={new Date(2025, 0, 1)} />\n      <DatePicker locale=\"fr-FR\" date={new Date(2025, 0, 1)} />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-date-range-picker",
      "title": "Date Range Picker",
      "description": "Seleção intuitiva de intervalos de datas com presets e suporte aos 4 locales.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/date-range-picker",
      "dependencies": [
        "date-fns",
        "react-day-picker",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "calendar",
        "popover",
        "ui-i18n"
      ],
      "files": [
        "components/ds/date-range-picker.tsx"
      ],
      "props": [
        {
          "name": "date",
          "required": false,
          "type": "DateRange",
          "description": "Selected date range { from, to }."
        },
        {
          "name": "onSelect",
          "required": false,
          "type": "(range?: DateRange) => void",
          "description": "Callback fired when a range is selected."
        },
        {
          "name": "presets",
          "required": false,
          "type": "boolean",
          "description": "Whether to display quick selection presets."
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string",
          "description": "Placeholder displayed when no date is selected."
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean",
          "description": "Disables the trigger and calendar interaction."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Localization setting."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "description": "Button trigger size."
        }
      ],
      "storyTitle": "Form/DateRangePicker",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    locale: \"pt-BR\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByRole(\"button\")).toBeInTheDocument()\n  },"
        },
        {
          "name": "WithPreselectedRange",
          "description": "",
          "args": "{\n    locale: \"pt-BR\",\n    date: {\n      from: subDays(new Date(), 14),\n      to: new Date(),\n    },\n  },"
        },
        {
          "name": "WithoutPresets",
          "description": "",
          "args": "{\n    presets: false,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    disabled: true,\n    date: {\n      from: subDays(new Date(), 7),\n      to: new Date(),\n    },\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <InteractiveRangePicker locale=\"pt-BR\" />\n      <InteractiveRangePicker locale=\"en-US\" />\n      <InteractiveRangePicker locale=\"es-ES\" />\n      <InteractiveRangePicker locale=\"fr-FR\" />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-deck",
      "title": "Deck",
      "description": "Swipe deck de cards — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/deck",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/deck.tsx"
      ],
      "props": [
        {
          "name": "cards",
          "required": true,
          "type": "React.ReactNode[]"
        }
      ],
      "storyTitle": "Navigation/Deck",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    cards: [\n      <div key=\"1\" className=\"p-4\">\n        Card 1\n      </div>,\n      <div key=\"2\" className=\"p-4\">\n        Card 2\n      </div>,\n      <div key=\"3\" className=\"p-4\">\n        Card 3\n      </div>,\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-description-list",
      "title": "Description List",
      "description": "A description list component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/description-list",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/description-list.tsx"
      ],
      "props": [
        {
          "name": "layout",
          "required": false,
          "type": "\"vertical\" | \"horizontal\" | \"grid\"",
          "options": [
            "vertical",
            "horizontal",
            "grid"
          ],
          "default": "vertical"
        }
      ],
      "storyTitle": "Data Display/DescriptionList",
      "stories": [
        {
          "name": "Vertical",
          "description": "Default vertical layout.",
          "code": "<Card className=\"w-full max-w-[400px]\">\n      <CardHeader>\n        <CardTitle>Applicant Information</CardTitle>\n      </CardHeader>\n      <CardContent>\n        <DescriptionList layout=\"vertical\">\n          <SampleData />\n        </DescriptionList>\n      </CardContent>\n    </Card>"
        },
        {
          "name": "Horizontal",
          "description": "Horizontal layout for wider screens.",
          "code": "<Card className=\"w-[600px]\">\n      <CardHeader>\n        <CardTitle>Applicant Information</CardTitle>\n      </CardHeader>\n      <CardContent>\n        <DescriptionList layout=\"horizontal\">\n          <SampleData />\n        </DescriptionList>\n      </CardContent>\n    </Card>"
        },
        {
          "name": "Grid",
          "description": "Grid layout for dense data display.",
          "code": "<Card className=\"w-full max-w-[800px]\">\n      <CardHeader>\n        <CardTitle>Applicant Information</CardTitle>\n      </CardHeader>\n      <CardContent>\n        <DescriptionList layout=\"grid\">\n          <SampleData />\n        </DescriptionList>\n      </CardContent>\n    </Card>"
        }
      ]
    },
    {
      "name": "ds-diff-viewer",
      "description": "Line-level diff viewer with unified and split modes. No external dependencies.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/diff-viewer",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "badge",
        "card",
        "toggle-group"
      ],
      "files": [
        "components/ds/diff-viewer.tsx"
      ],
      "props": [
        {
          "name": "oldValue",
          "required": true,
          "type": "string"
        },
        {
          "name": "newValue",
          "required": true,
          "type": "string"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "oldLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "newLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "mode",
          "required": false,
          "type": "DiffMode"
        },
        {
          "name": "maxLines",
          "required": false,
          "type": "number",
          "description": "Max lines to display before truncating — 0 = unlimited"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showLineNumbers",
          "required": false,
          "type": "boolean",
          "description": "Show line numbers"
        }
      ],
      "storyTitle": "Data Display/DiffViewer",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"package.json\",\n    oldValue: OLD_JSON,\n    newValue: NEW_JSON,\n    oldLabel: \"v1.2.0\",\n    newLabel: \"v1.3.0\",\n    mode: \"unified\",\n  },"
        },
        {
          "name": "SplitMode",
          "description": "",
          "args": "{\n    title: \"package.json — Split View\",\n    oldValue: OLD_JSON,\n    newValue: NEW_JSON,\n    oldLabel: \"v1.2.0\",\n    newLabel: \"v1.3.0\",\n    mode: \"split\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    title: \"Loading diff…\",\n    oldValue: \"\",\n    newValue: \"\",\n    loading: true,\n  },"
        },
        {
          "name": "NoChanges",
          "description": "",
          "args": "{\n    title: \"No Changes\",\n    oldValue: OLD_JSON,\n    newValue: OLD_JSON,\n    oldLabel: \"Before\",\n    newLabel: \"After\",\n  },"
        },
        {
          "name": "CodeDiff",
          "description": "",
          "args": "{\n    title: \"button.tsx\",\n    oldLabel: \"main\",\n    newLabel: \"feat/icon-button\",\n    oldValue: `export function Button({ children, variant = \"default\", ...props }) {\n  return (\n    <button\n      className={cn(buttonVariants({ variant }), props.className)}\n      {...props}\n    >\n      {children}\n    </button>\n  )\n}`,\n    newValue: `export function Button({ children, variant = \"default\", size = \"md\", icon, ...props }) {\n  return (\n    <button\n      className={cn(buttonVariants({ variant, size }), props.className)}\n      {...props}\n    >\n      {icon && <span className=\"mr-2\">{icon}</span>}\n      {children}\n    </button>\n  )\n}`,\n  },"
        },
        {
          "name": "LongDiff",
          "description": "",
          "args": "{\n    title: \"Large file diff (truncated at 30 lines)\",\n    maxLines: 30,\n    oldValue: Array.from(\n      { length: 50 },\n      (_, i) => `line ${i + 1}: original content here`\n    ).join(\"\\n\"),\n    newValue: Array.from({ length: 55 }, (_, i) =>\n      i % 7 === 0\n        ? `line ${i + 1}: MODIFIED content here`\n        : i >= 50\n          ? `line ${i + 1}: new line added`\n          : `line ${i + 1}: original content here`\n    ).join(\"\\n\"),\n  },"
        }
      ]
    },
    {
      "name": "ds-direction-aware-hover",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/direction-aware-hover",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/direction-aware-hover.tsx"
      ],
      "props": [
        {
          "name": "imageSrc",
          "required": true,
          "type": "string",
          "description": "URL da imagem de fundo"
        },
        {
          "name": "imageAlt",
          "required": false,
          "type": "string",
          "description": "Texto alternativo da imagem"
        },
        {
          "name": "imageClassName",
          "required": false,
          "type": "string",
          "description": "Classes extras para a imagem"
        },
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode",
          "description": "Conteúdo do overlay animado"
        }
      ],
      "storyTitle": "Data Display/DirectionAwareHover",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    imageSrc:\n      \"https://images.unsplash.com/photo-1550537687-c91072c4792d?q=80&w=600&auto=format&fit=crop\",\n    imageAlt: \"Foto de exemplo\",\n    className: \"w-80 h-96\",\n    children: (\n      <div className=\"flex h-full flex-col justify-end p-6\">\n        <p className=\"text-xl font-bold\">Arquitetura Moderna</p>\n        <p className=\"mt-2 text-sm text-muted-foreground\">\n          Descubra os detalhes incríveis desta nova construção no centro da\n          cidade.\n        </p>\n      </div>\n    ),\n  },"
        },
        {
          "name": "FocusWithin",
          "description": "Simula o estado de foco. Use a tecla TAB para focar no botão interno e o overlay permanecerá visível devido ao `focus-within`.",
          "args": "{\n    imageSrc:\n      \"https://images.unsplash.com/photo-1600585154340-be6161a56a0c?q=80&w=600&auto=format&fit=crop\",\n    className: \"max-w-[400px] w-full h-[300px]\",\n    children: (\n      <div className=\"flex h-full flex-col items-center justify-center gap-4 p-6 text-center\">\n        <h3 className=\"text-2xl font-bold\">Imóveis Premium</h3>\n        <button className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none\">\n          Focar Aqui (Tab)\n        </button>\n      </div>\n    ),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Simula o estado de foco. Use a tecla TAB para focar no botão interno e o overlay permanecerá visível devido ao `focus-within`.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-drawer",
      "title": "Drawer UI",
      "description": "A full-featured drawer wrapper with optional header, scrollable body, footer, direction-aware close button, snap points, scale background, and escape/pointer-down-outside event handlers.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/drawer",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "drawer"
      ],
      "files": [
        "components/ds/drawer.tsx"
      ],
      "props": [
        {
          "name": "direction",
          "required": false,
          "type": "DrawerDirection"
        },
        {
          "name": "title",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "trigger",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "children",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "showCloseButton",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "open",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onOpenChange",
          "required": false,
          "type": "(open: boolean) => void"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "shouldScaleBackground",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "snapPoints",
          "required": false,
          "type": "(number | string)[]"
        },
        {
          "name": "activeSnapPoint",
          "required": false,
          "type": "number | string | null"
        },
        {
          "name": "setActiveSnapPoint",
          "required": false,
          "type": "(snapPoint: number | string | null) => void"
        },
        {
          "name": "onEscapeKeyDown",
          "required": false,
          "type": "React.ComponentPropsWithoutRef< typeof DrawerContent >[\"onEscapeKeyDown\"]"
        },
        {
          "name": "onPointerDownOutside",
          "required": false,
          "type": "React.ComponentPropsWithoutRef< typeof DrawerContent >[\"onPointerDownOutside\"]"
        }
      ],
      "storyTitle": "Layout/Drawer",
      "stories": [
        {
          "name": "Default",
          "description": "Bottom drawer with form fields (name, email) and a save/cancel footer.",
          "code": "<Drawer\n      direction=\"bottom\"\n      title=\"Edit Profile\"\n      description=\"Make changes to your profile here.\"\n      trigger={<Button>Open Drawer</Button>}\n      footer={\n        <>\n          <Button variant=\"outline\">Cancel</Button>\n          <Button>Save changes</Button>\n        </>\n      }\n    >\n      <div className=\"flex flex-col gap-4\">\n        <Input placeholder=\"Your name\" />\n        <Input placeholder=\"Your email\" />\n      </div>\n    </Drawer>"
        },
        {
          "name": "FromLeft",
          "description": "Left-side drawer with a vertical navigation menu.",
          "code": "<Drawer\n      direction=\"left\"\n      title=\"Navigation\"\n      description=\"Browse available sections.\"\n      trigger={<Button>Open Menu</Button>}\n    >\n      <nav className=\"flex flex-col gap-1\">\n        {[\"Dashboard\", \"Analytics\", \"Settings\", \"Help Center\"].map(\n          (item, i) => (\n            <Button\n              key={item}\n              variant={i === 0 ? \"default\" : \"ghost\"}\n              className=\"justify-start\"\n            >\n              {item}\n            </Button>\n          )\n        )}\n      </nav>\n    </Drawer>"
        },
        {
          "name": "FromRight",
          "description": "Right-side drawer showing a list of notifications with badges and timestamps.",
          "code": "<Drawer\n      direction=\"right\"\n      title=\"Notifications\"\n      description=\"Your recent activity.\"\n      trigger={\n        <Button>\n          <BellIcon />\n          Notifications\n        </Button>\n      }\n    >\n      <div className=\"flex flex-col gap-3\">\n        {[\n          {\n            msg: \"New comment on your post\",\n            time: \"2m ago\",\n            variant: \"default\" as const,\n          },\n          {\n            msg: \"Server deployment complete\",\n            time: \"15m ago\",\n            variant: \"secondary\" as const,\n          },\n          {\n            msg: \"Payment received — $249.00\",\n            time: \"1h ago\",\n            variant: \"secondary\" as const,\n          },\n          {\n            msg: \"Security alert: new login\",\n            time: \"3h ago\",\n            variant: \"destructive\" as const,\n          },\n        ].map(({ msg, time, variant }) => (\n          <div\n            key={msg}\n            className=\"flex items-start justify-between rounded-lg border border-border bg-card p-3\"\n          >\n            <div className=\"flex flex-col gap-1\">\n              <span className=\"text-sm\">{msg}</span>\n              <span className=\"text-xs text-muted-foreground\">{time}</span>\n            </div>\n            <Badge variant={variant} className=\"shrink-0\">\n              New\n            </Badge>\n          </div>\n        ))}\n      </div>\n    </Drawer>"
        },
        {
          "name": "FromTop",
          "description": "Top drawer with grid of quick action buttons (New File, Upload, Share).",
          "code": "<Drawer\n      direction=\"top\"\n      title=\"Quick Actions\"\n      description=\"Select an action to perform.\"\n      trigger={<Button variant=\"outline\">Actions</Button>}\n    >\n      <div className=\"grid grid-cols-3 gap-3\">\n        {[\"New File\", \"Upload\", \"Share\"].map((action) => (\n          <Button\n            key={action}\n            variant=\"outline\"\n            className=\"flex-col gap-1 py-4\"\n          >\n            {action}\n          </Button>\n        ))}\n      </div>\n    </Drawer>"
        },
        {
          "name": "Confirmation",
          "description": "Bottom drawer with a destructive delete confirmation dialog.",
          "code": "<Drawer\n      direction=\"bottom\"\n      title=\"Delete Item\"\n      description=\"This action cannot be undone.\"\n      trigger={<Button variant=\"destructive\">Delete Item</Button>}\n      footer={\n        <>\n          <Button variant=\"outline\">Cancel</Button>\n          <Button variant=\"destructive\">Delete</Button>\n        </>\n      }\n    >\n      <p className=\"text-sm text-muted-foreground\">\n        Are you sure you want to delete this item? All associated data will be\n        permanently removed.\n      </p>\n    </Drawer>"
        },
        {
          "name": "ScrollableContent",
          "description": "Right drawer with scrollable body content and a submit/cancel footer.",
          "code": "<Drawer\n      direction=\"right\"\n      title=\"Activity Log\"\n      description=\"Set your daily activity goal.\"\n      trigger={<Button variant=\"outline\">Scrollable Content</Button>}\n      footer={\n        <>\n          <Button>Submit</Button>\n          <Button variant=\"outline\">Cancel</Button>\n        </>\n      }\n    >\n      <div className=\"flex flex-col gap-4\">\n        {Array.from({ length: 10 }).map((_, index) => (\n          <p key={index} className=\"leading-relaxed text-muted-foreground\">\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do\n            eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim\n            ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut\n            aliquip ex ea commodo consequat.\n          </p>\n        ))}\n      </div>\n    </Drawer>"
        },
        {
          "name": "NoHeader",
          "description": "Bottom drawer without title or description — content starts below the close button.",
          "code": "<Drawer\n      direction=\"bottom\"\n      trigger={<Button variant=\"outline\">No Header</Button>}\n      footer={\n        <Button variant=\"outline\" className=\"w-full\">\n          Done\n        </Button>\n      }\n    >\n      <p className=\"text-sm text-muted-foreground\">\n        This drawer has no title or description. Content starts right after the\n        close button.\n      </p>\n    </Drawer>"
        },
        {
          "name": "NoCloseButton",
          "description": "Left drawer without a close button — dismiss via drag gesture or backdrop tap.",
          "code": "<Drawer\n      direction=\"left\"\n      showCloseButton={false}\n      title=\"No Close Button\"\n      description=\"Swipe or tap the backdrop to close.\"\n      trigger={<Button variant=\"outline\">Open</Button>}\n    >\n      <p className=\"text-sm text-muted-foreground\">\n        This drawer hides the close button. Use drag gestures or the backdrop to\n        dismiss.\n      </p>\n    </Drawer>"
        },
        {
          "name": "ProgrammaticControl",
          "description": "Bottom drawer controlled externally via open/onOpenChange props."
        }
      ]
    },
    {
      "name": "ds-dynamic-island",
      "description": "Dynamic island notification component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/dynamic-island",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/dynamic-island.tsx"
      ],
      "props": [
        {
          "name": "state",
          "required": false,
          "type": "\"idle\" | \"compact\" | \"expanded\""
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "title",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "onClick",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"success\" | \"warning\" | \"destructive\"",
          "options": [
            "default",
            "success",
            "warning",
            "destructive"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Feedback/DynamicIsland",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    state: \"compact\",\n    title: \"Uploading 3 files\",\n    subtitle: \"24%\",\n    icon: <UploadCloudIcon className=\"size-4\" />,\n  },"
        },
        {
          "name": "Interactive",
          "description": "",
          "code": "<div className=\"flex w-full max-w-[400px] flex-col items-center gap-12\">\n        <div className=\"flex h-[200px] w-full items-start justify-center rounded-2xl border bg-muted/30 pt-8\">\n          <DynamicIsland\n            state={state}\n            title={state === \"expanded\" ? undefined : \"Incoming Call\"}\n            subtitle=\"0:24\"\n            icon={<PhoneCallIcon className=\"size-4 text-success\" />}\n            intent=\"default\"\n            onClick={() =>\n              setState(state === \"expanded\" ? \"compact\" : \"expanded\")\n            }\n          >\n            <div className=\"flex flex-col items-center gap-4\">\n              <div className=\"flex w-full items-center justify-between\">\n                <div className=\"flex items-center gap-3\">\n                  <Avatar className=\"size-10\">\n                    <AvatarImage src=\"https://i.pravatar.cc/150?u=a042581f4e29026704d\" />\n                    <AvatarFallback>JD</AvatarFallback>\n                  </Avatar>\n                  <div className=\"flex flex-col\">\n                    <span className=\"text-sm font-medium\">Jane Doe</span>\n                    <span className=\"text-xs opacity-70\">iPhone</span>\n                  </div>\n                </div>\n                <span className=\"text-xl font-light opacity-80\">0:24</span>\n              </div>\n              <div className=\"flex gap-3\">\n                <Button\n                  variant=\"secondary\"\n                  size=\"icon\"\n                  className=\"text-destructive-foreground size-12 rounded-full bg-destructive hover:bg-destructive/90\"\n                  onClick={(e) => {\n                    e.stopPropagation()\n                    setState(\"idle\")\n                  }}\n                >\n                  <PhoneCallIcon className=\"size-5 rotate-[135deg]\" />\n                </Button>\n                <Button\n                  variant=\"secondary\"\n                  size=\"icon\"\n                  className=\"size-12 rounded-full bg-success text-success-foreground hover:bg-success/90\"\n                  onClick={(e) => {\n                    e.stopPropagation()\n                    setState(\"compact\")\n                  }}\n                >\n                  <PhoneCallIcon className=\"size-5\" />\n                </Button>\n              </div>\n            </div>\n          </DynamicIsland>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button variant=\"outline\" size=\"sm\" onClick={() => setState(\"idle\")}>\n            Idle\n          </Button>\n          <Button\n            variant=\"outline\"\n            size=\"sm\"\n            onClick={() => setState(\"compact\")}\n          >\n            Compact\n          </Button>\n          <Button\n            variant=\"outline\"\n            size=\"sm\"\n            onClick={() => setState(\"expanded\")}\n          >\n            Expanded\n          </Button>\n        </div>\n      </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col items-center gap-4\">\n      <DynamicIsland\n        state=\"compact\"\n        size=\"sm\"\n        title=\"Connected\"\n        icon={<CheckCircle2Icon />}\n      />\n      <DynamicIsland\n        state=\"compact\"\n        size=\"md\"\n        title=\"Connected\"\n        icon={<CheckCircle2Icon />}\n      />\n      <DynamicIsland\n        state=\"compact\"\n        size=\"lg\"\n        title=\"Connected\"\n        icon={<CheckCircle2Icon />}\n      />\n    </div>"
        },
        {
          "name": "AllIntents",
          "description": "",
          "code": "<div className=\"flex flex-col items-center gap-4\">\n      <DynamicIsland\n        state=\"compact\"\n        intent=\"default\"\n        title=\"System update\"\n        icon={<UploadCloudIcon />}\n      />\n      <DynamicIsland\n        state=\"compact\"\n        intent=\"success\"\n        title=\"Payment sent\"\n        subtitle=\"$45.00\"\n        icon={<CheckCircle2Icon />}\n      />\n      <DynamicIsland\n        state=\"compact\"\n        intent=\"warning\"\n        title=\"Low battery\"\n        subtitle=\"10%\"\n        icon={<AlertTriangleIcon />}\n      />\n      <DynamicIsland\n        state=\"compact\"\n        intent=\"destructive\"\n        title=\"Connection lost\"\n        subtitle=\"Retry\"\n        icon={<AlertTriangleIcon />}\n      />\n    </div>"
        },
        {
          "name": "MusicPlayer",
          "description": "",
          "code": "<div className=\"flex h-[300px] w-full max-w-[400px] items-start justify-center pt-8\">\n        <DynamicIsland\n          state={state}\n          title=\"Lo-fi Beats\"\n          subtitle={\n            <div className=\"flex items-center gap-1\">\n              <span className=\"flex h-3.5 items-end gap-[2px]\">\n                <span\n                  className={cn(\n                    \"block h-2 w-1 rounded-full bg-current\",\n                    isPlaying && \"animate-[bounce_1s_ease-in-out_infinite]\"\n                  )}\n                />\n                <span\n                  className={cn(\n                    \"block h-3 w-1 rounded-full bg-current\",\n                    isPlaying && \"animate-[bounce_1s_ease-in-out_infinite]\"\n                  )}\n                  style={{ animationDelay: \"0.2s\" }}\n                />\n                <span\n                  className={cn(\n                    \"block h-1.5 w-1 rounded-full bg-current\",\n                    isPlaying && \"animate-[bounce_1s_ease-in-out_infinite]\"\n                  )}\n                  style={{ animationDelay: \"0.4s\" }}\n                />\n              </span>\n            </div>\n          }\n          icon={\n            <img\n              src=\"https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=150&h=150&fit=crop\"\n              className=\"size-full rounded-sm object-cover\"\n              alt=\"Album art\"\n              loading=\"lazy\"\n              decoding=\"async\"\n            />\n          }\n          onClick={() =>\n            setState(state === \"expanded\" ? \"compact\" : \"expanded\")\n          }\n        >\n          <div className=\"flex flex-col gap-4\">\n            <div className=\"flex items-center gap-4\">\n              <img\n                src=\"https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=300&h=300&fit=crop\"\n                className=\"size-16 rounded-lg object-cover shadow-sm\"\n                alt=\"Album art\"\n                loading=\"lazy\"\n                decoding=\"async\"\n              />\n              <div className=\"flex flex-1 flex-col\">\n                <span className=\"text-base font-semibold\">\n                  Chill Study Beats\n                </span>\n                <span className=\"text-sm opacity-70\">Lofi Girl</span>\n              </div>\n              <Button\n                variant=\"ghost\"\n                size=\"icon\"\n                className=\"text-current hover:bg-white/20\"\n                onClick={(e) => {\n                  e.stopPropagation()\n                  setIsPlaying(!isPlaying)\n                }}\n                aria-label={isPlaying ? \"Pause\" : \"Play\"}\n              >\n                {isPlaying ? (\n                  <PauseIcon className=\"size-6 fill-current\" />\n                ) : (\n                  <PlayIcon className=\"size-6 fill-current\" />\n                )}\n              </Button>\n            </div>\n\n            <div className=\"flex items-center gap-2\">\n              <span className=\"text-xs opacity-70\">1:24</span>\n              <div className=\"h-1.5 flex-1 overflow-hidden rounded-full bg-white/20\">\n                <div className=\"h-full w-1/3 rounded-full bg-white\" />\n              </div>\n              <span className=\"text-xs opacity-70\">-2:10</span>\n            </div>\n          </div>\n        </DynamicIsland>\n      </div>"
        }
      ]
    },
    {
      "name": "ds-empty",
      "title": "Empty UI",
      "description": "Contextual empty states with built-in SVG icons for no-data, search, error, and no-results scenarios, i18n titles, action button, compact mode, and skeleton loading.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/empty",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "empty",
        "button",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/empty.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "EmptyVariant"
        },
        {
          "name": "title",
          "required": false,
          "type": "string",
          "description": "Sobrescreve o título i18n"
        },
        {
          "name": "description",
          "required": false,
          "type": "string",
          "description": "Sobrescreve a descrição i18n"
        },
        {
          "name": "action",
          "required": false,
          "type": "EmptyAction"
        },
        {
          "name": "compact",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Feedback/Empty",
      "stories": [
        {
          "name": "NoData",
          "description": "",
          "args": "{\n    variant: \"no-data\",\n  },"
        },
        {
          "name": "Search",
          "description": "",
          "args": "{\n    variant: \"search\",\n  },"
        },
        {
          "name": "Error",
          "description": "",
          "args": "{\n    variant: \"error\",\n  },"
        },
        {
          "name": "NoResults",
          "description": "",
          "args": "{\n    variant: \"no-results\",\n  },"
        },
        {
          "name": "WithAction",
          "description": "",
          "args": "{\n    variant: \"no-data\",\n    action: {\n      label: \"Refresh data\",\n      onClick: () => alert(\"Refresh clicked\"),\n    },\n  },"
        },
        {
          "name": "Compact",
          "description": "",
          "args": "{\n    variant: \"no-data\",\n    compact: true,\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n  },"
        },
        {
          "name": "CustomTitle",
          "description": "",
          "args": "{\n    variant: \"no-data\",\n    title: \"Nothing here yet\",\n    description: \"Create your first project to get started.\",\n    action: {\n      label: \"Create project\",\n      onClick: () => alert(\"Create clicked\"),\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-empty-action",
      "title": "Empty Action",
      "description": "Estado vazio acionável com ação principal, atalhos e sugestões para zero-data e onboarding.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/empty-action",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/empty-action.tsx"
      ],
      "props": [
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode",
          "description": "Top illustration or icon."
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode",
          "description": "Primary title."
        },
        {
          "name": "description",
          "required": true,
          "type": "React.ReactNode",
          "description": "Explanatory description."
        },
        {
          "name": "primaryAction",
          "required": false,
          "type": "EmptyActionItem",
          "description": "Primary call to action button."
        },
        {
          "name": "secondaryAction",
          "required": false,
          "type": "EmptyActionItem",
          "description": "Secondary action button or documentation link."
        },
        {
          "name": "suggestions",
          "required": false,
          "type": "string[]",
          "description": "Optional recommended next steps list."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Localization locale."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Feedback/EmptyAction",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    icon: <Database className=\"size-full\" />,\n    primaryAction: {\n      label: \"Nova Simulação\",\n      icon: <Plus className=\"size-4\" />,\n      onClick: () => alert(\"Criando nova simulação!\"),\n    },\n    secondaryAction: {\n      label: \"Ver Documentação\",\n      onClick: () => alert(\"Abrindo docs!\"),\n    },\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(\n      canvas.getByText(\"Nenhuma Simulação Encontrada\")\n    ).toBeInTheDocument()\n    await expect(canvas.getByText(\"Nova Simulação\")).toBeInTheDocument()\n  },"
        },
        {
          "name": "FilterZeroResults",
          "description": "",
          "args": "{\n    icon: <FilterX className=\"size-full\" />,\n    title: \"Nenhum resultado para estes filtros\",\n    description:\n      \"Tente ajustar o intervalo de datas ou remover alguns termos da busca.\",\n    secondaryAction: {\n      label: \"Limpar Filtros\",\n      onClick: () => alert(\"Filtros limpos!\"),\n    },\n  },"
        },
        {
          "name": "WithSuggestions",
          "description": "",
          "args": "{\n    primaryAction: {\n      label: \"Conectar Base de Dados\",\n    },\n    suggestions: [\n      \"Configurar credenciais do S3 / RustFS\",\n      \"Definir dicionário de variáveis\",\n      \"Executar validação de esquema de colunas\",\n    ],\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex w-full max-w-xl flex-col gap-6\">\n      <EmptyAction\n        size=\"sm\"\n        title=\"Pequeno (sm)\"\n        description=\"Adequado para uso interno em cartões ou widgets compactos.\"\n        primaryAction={{ label: \"Adicionar\" }}\n      />\n      <EmptyAction\n        size=\"md\"\n        title=\"Médio (md)\"\n        description=\"Padrão do design system para seções de página inteira.\"\n        primaryAction={{ label: \"Adicionar Item\" }}\n      />\n    </div>"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex max-w-lg flex-col gap-6\">\n      <EmptyAction\n        locale=\"pt-BR\"\n        title=\"Sem dados\"\n        description=\"Nenhum registro localizado\"\n        primaryAction={{ label: \"Começar\" }}\n      />\n      <EmptyAction\n        locale=\"en-US\"\n        title=\"No data\"\n        description=\"No records found in this view\"\n        primaryAction={{ label: \"Get started\" }}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-empty-state-illustration",
      "description": "Empty state with 8 animated SVG illustrations for common UI contexts.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/empty-state-illustration",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "button"
      ],
      "files": [
        "components/ds/empty-state-illustration.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "EmptyStateVariant"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "action",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "size",
          "required": false,
          "type": "EmptyStateSize"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "illustration",
          "required": false,
          "type": "React.ReactNode",
          "description": "Override the SVG illustration with a custom node"
        }
      ],
      "storyTitle": "Feedback/EmptyStateIllustration",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    variant: \"default\",\n    size: \"md\",\n  },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"grid grid-cols-2 gap-4 md:grid-cols-4\">\n      {(\n        [\n          \"default\",\n          \"search\",\n          \"error\",\n          \"success\",\n          \"inbox\",\n          \"filter\",\n          \"upload\",\n          \"locked\",\n        ] as EmptyStateVariant[]\n      ).map((variant) => (\n        <div key={variant} className=\"rounded-xl border border-border p-4\">\n          <EmptyStateIllustration variant={variant} size=\"sm\" />\n          <p className=\"mt-2 text-center text-xs text-muted-foreground\">\n            {variant}\n          </p>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col divide-y divide-border\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <EmptyStateIllustration\n          key={size}\n          variant=\"search\"\n          size={size}\n          title={`Size: ${size}`}\n          description=\"This is the description text shown below the illustration.\"\n        />\n      ))}\n    </div>"
        },
        {
          "name": "WithAction",
          "description": "",
          "args": "{\n    variant: \"default\",\n    title: \"No projects yet\",\n    description:\n      \"Create your first project to get started with the design system.\",\n    action: <Button size=\"sm\">Create Project</Button>,\n    size: \"md\",\n  },"
        },
        {
          "name": "ErrorWithRetry",
          "description": "",
          "args": "{\n    variant: \"error\",\n    title: \"Failed to load data\",\n    description:\n      \"We couldn't fetch the data. Please check your connection and try again.\",\n    action: (\n      <div className=\"flex gap-2\">\n        <Button size=\"sm\" variant=\"outline\">\n          Contact Support\n        </Button>\n        <Button size=\"sm\">Retry</Button>\n      </div>\n    ),\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    variant: \"default\",\n    loading: true,\n    size: \"md\",\n  },"
        },
        {
          "name": "CustomIllustration",
          "description": "",
          "args": "{\n    title: \"No notifications\",\n    description: \"You're all caught up! Check back later.\",\n    illustration: (\n      <div className=\"flex size-24 items-center justify-center rounded-full bg-muted text-4xl\">\n        🔔\n      </div>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-event-calendar",
      "title": "Event Calendar",
      "description": "Calendário mensal com eventos — ReUI Event Calendar 6.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/event-calendar",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/event-calendar.tsx"
      ],
      "props": [
        {
          "name": "events",
          "required": true,
          "type": "CalendarEvent[]"
        },
        {
          "name": "month",
          "required": false,
          "type": "Date"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Dashboard/EventCalendar",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ events: [{ id: \"1\", title: \"Meeting\", date: \"2026-09-10\" }] },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ events: [], loading: true }"
        }
      ]
    },
    {
      "name": "ds-fade",
      "title": "Fade",
      "description": "Fade mask com variantes x/y/top/bottom/left/right — inspirado em Launch UI Fade.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/fade",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/fade.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"x\" | \"y\" | \"top\" | \"bottom\" | \"left\" | \"right\" | \"top-lg\" | \"bottom-lg\" | \"left-lg\" | \"right-lg\"",
          "options": [
            "x",
            "y",
            "top",
            "bottom",
            "left",
            "right",
            "top-lg",
            "bottom-lg",
            "left-lg",
            "right-lg"
          ],
          "default": "x"
        }
      ],
      "stories": [
        {
          "name": "X",
          "description": "",
          "args": "{ variant: \"x\" },"
        },
        {
          "name": "Y",
          "description": "",
          "args": "{ variant: \"y\" },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"grid gap-4 md:grid-cols-2\">\n      {([\"top\", \"bottom\", \"left\", \"right\"] as const).map((v) => (\n        <Fade\n          key={v}\n          variant={v}\n          className=\"h-24 overflow-hidden rounded-xl border bg-muted p-4 text-xs font-medium\"\n        >\n          fade-{v}\n        </Fade>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-faqs",
      "title": "Faqs",
      "description": "Seção FAQ core com heading, accordion, busca opcional.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/faqs",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-accordion",
        "input",
        "empty",
        "ui-i18n"
      ],
      "files": [
        "components/ds/faqs.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "items",
          "required": true,
          "type": "AccordionItem[]"
        },
        {
          "name": "searchable",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "search",
          "required": false,
          "type": "string"
        },
        {
          "name": "onSearchChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "iconVariant",
          "required": false,
          "type": "\"chevron\" | \"plus\" | \"arrow\" | \"sign\""
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "FAQ/Faqs",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items, title: \"FAQs\", description: \"Quick answers\" },"
        },
        {
          "name": "Searchable",
          "description": "",
          "args": "{\n    items: [\n      ...items,\n      { value: \"5\", trigger: \"Billing question\", children: \"Billing info.\" },\n      { value: \"6\", trigger: \"Support hours\", children: \"24/7.\" },\n    ],\n    searchable: true,\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ items },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      <Faqs items={items} size=\"sm\" title=\"Small\" />\n      <Faqs items={items} size=\"md\" title=\"Medium\" />\n      <Faqs items={items} size=\"lg\" title=\"Large\" />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      <Faqs items={items} size=\"sm\" title=\"Small\" />\n      <Faqs items={items} size=\"md\" title=\"Medium\" />\n      <Faqs items={items} size=\"lg\" title=\"Large\" />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ items, loading: true }"
        },
        {
          "name": "Empty",
          "description": "",
          "args": "{ items, searchable: true, search: \"xyz\" }"
        }
      ]
    },
    {
      "name": "ds-faqs-support",
      "title": "Faqs Support",
      "description": "FAQs com card suporte lateral — blockus #14 #19.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/faqs-support",
      "dependencies": [],
      "registryDependencies": [
        "ds-faqs",
        "card",
        "button"
      ],
      "files": [
        "components/ds/faqs-support.tsx"
      ],
      "props": [
        {
          "name": "supportTitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "supportDescription",
          "required": false,
          "type": "string"
        },
        {
          "name": "supportAction",
          "required": false,
          "type": "{ label: string; href?: string; onClick?: () => void }"
        }
      ],
      "storyTitle": "FAQ/FaqsSupport",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    items,\n    supportTitle: \"Still have questions?\",\n    supportDescription: \"Our team is here to help.\",\n    supportAction: { label: \"Contact us\", href: \"#\" },\n  },"
        },
        {
          "name": "WithoutSupport",
          "description": "",
          "args": "{ items }"
        }
      ]
    },
    {
      "name": "ds-faqs-tabs",
      "title": "Faqs Tabs",
      "description": "FAQs agrupadas por abas — blockus #03 #07.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/faqs-tabs",
      "dependencies": [],
      "registryDependencies": [
        "ds-faqs",
        "tabs"
      ],
      "files": [
        "components/ds/faqs-tabs.tsx"
      ],
      "props": [
        {
          "name": "groups",
          "required": true,
          "type": "FaqsTabsGroup[]"
        },
        {
          "name": "defaultGroup",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "FAQ/FaqsTabs",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ groups }"
        },
        {
          "name": "Searchable",
          "description": "",
          "args": "{ groups, searchable: true }"
        }
      ]
    },
    {
      "name": "ds-feature-spotlight",
      "title": "Feature Spotlight",
      "description": "Destaque ancorado para apresentar novas funcionalidades e guias passo a passo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/feature-spotlight",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "popover",
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/feature-spotlight.tsx"
      ],
      "props": [
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode",
          "description": "The element to anchor the spotlight to."
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode",
          "description": "Title of highlighted feature."
        },
        {
          "name": "description",
          "required": true,
          "type": "React.ReactNode",
          "description": "Description explaining the feature."
        },
        {
          "name": "open",
          "required": false,
          "type": "boolean",
          "description": "Controlled open state."
        },
        {
          "name": "onOpenChange",
          "required": false,
          "type": "(open: boolean) => void",
          "description": "Open state change callback."
        },
        {
          "name": "step",
          "required": false,
          "type": "number",
          "description": "Current step number in a tour."
        },
        {
          "name": "totalSteps",
          "required": false,
          "type": "number",
          "description": "Total steps in tour."
        },
        {
          "name": "onNext",
          "required": false,
          "type": "() => void",
          "description": "Next step callback."
        },
        {
          "name": "onPrevious",
          "required": false,
          "type": "() => void",
          "description": "Previous step callback."
        },
        {
          "name": "onDismiss",
          "required": false,
          "type": "() => void",
          "description": "Dismiss callback."
        },
        {
          "name": "side",
          "required": false,
          "type": "\"top\" | \"right\" | \"bottom\" | \"left\"",
          "description": "Popover placement side."
        },
        {
          "name": "align",
          "required": false,
          "type": "\"start\" | \"center\" | \"end\"",
          "description": "Popover alignment."
        },
        {
          "name": "showBeacon",
          "required": false,
          "type": "boolean",
          "description": "Whether to render a pulsing beacon ring on the target."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Localization locale."
        },
        {
          "name": "className",
          "required": false,
          "type": "string",
          "description": "Content box custom classes."
        }
      ],
      "storyTitle": "Feedback/FeatureSpotlight",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    locale: \"pt-BR\",\n  },\n  play: async () => {\n    const popoverHeading = await within(document.body).findByText(\n      \"Novo Formato de Exportação\"\n    )\n    await expect(popoverHeading).toBeInTheDocument()\n  },"
        },
        {
          "name": "MultiStepTour",
          "description": "",
          "args": "{\n    step: 2,\n    totalSteps: 4,\n    title: \"Ajuste de Hiperparâmetros\",\n    description:\n      \"Configure a taxa de aprendizado e o número de épocas da estimação bayesiana antes de executar a simulação.\",\n    onNext: () => alert(\"Próximo passo!\"),\n    onPrevious: () => alert(\"Passo anterior!\"),\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6\">\n      <FeatureSpotlight\n        locale=\"en-US\"\n        title=\"New Export Feature\"\n        description=\"Download files directly in Parquet format.\"\n        step={1}\n        totalSteps={3}\n      >\n        <Button size=\"sm\" variant=\"outline\">\n          Export\n        </Button>\n      </FeatureSpotlight>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-feature-sticky",
      "title": "Feature Sticky",
      "description": "Seção feature com texto e mockup sticky (left/right) — inspirado em Launch UI Feature Sticky.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/feature-sticky",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "badge",
        "skeleton"
      ],
      "files": [
        "components/ds/feature-sticky.tsx"
      ],
      "props": [
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "heading",
          "required": false,
          "type": "string"
        },
        {
          "name": "subheading",
          "required": false,
          "type": "string"
        },
        {
          "name": "items",
          "required": false,
          "type": "FeatureStickyItem[]"
        },
        {
          "name": "media",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "sticky",
          "required": false,
          "type": "\"left\" | \"right\"",
          "options": [
            "left",
            "right"
          ],
          "default": "left"
        }
      ],
      "stories": [
        {
          "name": "Left",
          "description": "",
          "args": "{ sticky: \"left\" },"
        },
        {
          "name": "Right",
          "description": "",
          "args": "{ sticky: \"right\" },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        }
      ]
    },
    {
      "name": "ds-feedback-widget",
      "description": "Floating feedback widget component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/feedback-widget",
      "dependencies": [],
      "registryDependencies": [
        "button",
        "dialog",
        "radio-group",
        "textarea"
      ],
      "files": [
        "components/ds/feedback-widget.tsx"
      ],
      "props": [
        {
          "name": "onSubmit",
          "required": false,
          "type": "(data: { rating: number; text: string }) => Promise<void> | void"
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"primary\""
        },
        {
          "name": "position",
          "required": false,
          "type": "\"br\" | \"bl\"",
          "options": [
            "br",
            "bl"
          ],
          "default": "br"
        }
      ],
      "storyTitle": "Feedback/FeedbackWidget",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    position: \"br\",\n    intent: \"primary\",\n    onSubmit: async (data) => {\n      console.log(\"Feedback submitted:\", data)\n      await new Promise((resolve) => setTimeout(resolve, 1500))\n    },\n  },"
        },
        {
          "name": "BottomLeft",
          "description": "",
          "args": "{\n    position: \"bl\",\n    intent: \"default\",\n  },"
        }
      ]
    },
    {
      "name": "ds-file-preview",
      "description": "File preview card with auto-detected type icons, size formatting and hover actions.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/file-preview",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "button",
        "badge"
      ],
      "files": [
        "components/ds/file-preview.tsx"
      ],
      "props": [
        {
          "name": "fileName",
          "required": true,
          "type": "string"
        },
        {
          "name": "fileSize",
          "required": false,
          "type": "number"
        },
        {
          "name": "fileType",
          "required": false,
          "type": "string"
        },
        {
          "name": "previewUrl",
          "required": false,
          "type": "string",
          "description": "URL for image previews"
        },
        {
          "name": "onDownload",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onPreview",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onRemove",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "size",
          "required": false,
          "type": "FilePreviewSize"
        },
        {
          "name": "variant",
          "required": false,
          "type": "FilePreviewVariant"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Media/FilePreview",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    fileName: \"design-system-v2.pdf\",\n    fileSize: 4200000,\n    onDownload: () => alert(\"Download\"),\n    onRemove: () => alert(\"Remove\"),\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{\n    fileName: \"document.pdf\",\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <FilePreview\n          key={size}\n          fileName={`document-${size}.pdf`}\n          fileSize={1024 * 1024 * 2.4}\n          size={size}\n          onDownload={() => {}}\n          onRemove={() => {}}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <FilePreview\n          key={size}\n          fileName={`document-${size}.pdf`}\n          fileSize={1024 * 1024 * 2.4}\n          size={size}\n          onDownload={() => {}}\n          onRemove={() => {}}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "AllFileTypes",
          "description": "",
          "args": "{\n    fileName: \"report.pdf\",\n  },\n  render: () => (\n    <FilePreviewList\n      files={[\n        { fileName: \"report.pdf\", fileSize: 2048000, onDownload: () => {} },\n        {\n          fileName: \"photo.jpg\",\n          fileSize: 512000,\n          previewUrl: \"https://picsum.photos/seed/file/100/100\",\n          onDownload: () => {},\n        },\n        { fileName: \"data.xlsx\", fileSize: 156000, onDownload: () => {} },\n        { fileName: \"video.mp4\", fileSize: 104857600, onDownload: () => {} },\n        { fileName: \"component.tsx\", fileSize: 8200, onDownload: () => {} },\n        { fileName: \"readme.md\", fileSize: 3400, onDownload: () => {} },\n        { fileName: \"archive.zip\", fileSize: 52428800, onDownload: () => {} },\n        { fileName: \"unknown.bin\", fileSize: 102400 },\n      ]}\n    />\n  ),",
          "code": "<FilePreviewList\n      files={[\n        { fileName: \"report.pdf\", fileSize: 2048000, onDownload: () => {} },\n        {\n          fileName: \"photo.jpg\",\n          fileSize: 512000,\n          previewUrl: \"https://picsum.photos/seed/file/100/100\",\n          onDownload: () => {},\n        },\n        { fileName: \"data.xlsx\", fileSize: 156000, onDownload: () => {} },\n        { fileName: \"video.mp4\", fileSize: 104857600, onDownload: () => {} },\n        { fileName: \"component.tsx\", fileSize: 8200, onDownload: () => {} },\n        { fileName: \"readme.md\", fileSize: 3400, onDownload: () => {} },\n        { fileName: \"archive.zip\", fileSize: 52428800, onDownload: () => {} },\n        { fileName: \"unknown.bin\", fileSize: 102400 },\n      ]}\n    />"
        },
        {
          "name": "WithImageThumbnail",
          "description": "",
          "args": "{\n    fileName: \"hero-banner.png\",\n    fileSize: 890000,\n    fileType: \"image/png\",\n    previewUrl: \"https://picsum.photos/seed/banner/300/200\",\n    onPreview: () => {},\n    onDownload: () => {},\n    onRemove: () => {},\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    fileName: \"loading.pdf\",\n  },\n  render: () => <FilePreviewList files={[]} loading loadingCount={4} />,"
        },
        {
          "name": "NoActions",
          "description": "",
          "args": "{\n    fileName: \"contract-signed.pdf\",\n    fileSize: 380000,\n  },"
        }
      ]
    },
    {
      "name": "ds-file-upload",
      "title": "FileUpload",
      "description": "Área de upload de arquivos com suporte a arrastar e soltar e barra de progresso.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/file-upload",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "button",
        "progress",
        "ui-i18n"
      ],
      "files": [
        "components/ds/file-upload.tsx"
      ],
      "props": [
        {
          "name": "onUpload",
          "required": true,
          "type": "(file: File) => void"
        },
        {
          "name": "accept",
          "required": false,
          "type": "string"
        },
        {
          "name": "maxSizeMB",
          "required": false,
          "type": "number"
        },
        {
          "name": "progress",
          "required": false,
          "type": "number"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "isDragActive",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/FileUpload",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    maxSizeMB: 10,\n    onUpload: (file) => console.log(file),\n  },"
        },
        {
          "name": "AllSizes",
          "description": "The component supports 2 sizes: sm and md.",
          "args": "{\n    maxSizeMB: 10,\n    onUpload: () => {},\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"The component supports 2 sizes: sm and md.\",\n      },\n    },\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{\n    maxSizeMB: 10,\n    onUpload: () => {},\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    maxSizeMB: 50,\n    onUpload: () => {},\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    disabled: true,\n    onUpload: () => {},\n  },"
        }
      ]
    },
    {
      "name": "ds-filter-builder",
      "title": "Filter Builder",
      "description": "A complex component for building advanced query filters.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/filter-builder",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "input",
        "select",
        "ui-i18n"
      ],
      "files": [
        "components/ds/filter-builder.tsx"
      ],
      "props": [
        {
          "name": "fields",
          "required": true,
          "type": "FilterField[]"
        },
        {
          "name": "rules",
          "required": true,
          "type": "FilterRule[]"
        },
        {
          "name": "onChange",
          "required": true,
          "type": "(rules: FilterRule[]) => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Form/FilterBuilder",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<Card className=\"w-full max-w-[800px]\">\n        <CardContent className=\"p-6\">\n          <FilterBuilder\n            fields={sampleFields}\n            rules={rules}\n            onChange={setRules}\n          />\n        </CardContent>\n      </Card>"
        },
        {
          "name": "Empty",
          "description": "",
          "code": "<Card className=\"w-full max-w-[800px]\">\n        <CardContent className=\"p-6\">\n          <FilterBuilder\n            fields={sampleFields}\n            rules={rules}\n            onChange={setRules}\n          />\n        </CardContent>\n      </Card>"
        }
      ]
    },
    {
      "name": "ds-filter-sidebar",
      "title": "Filter Sidebar",
      "description": "Filtros categoria e preço — ReUI Filter Sidebar.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/filter-sidebar",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "checkbox",
        "label",
        "slider",
        "skeleton"
      ],
      "files": [
        "components/ds/filter-sidebar.tsx"
      ],
      "props": [
        {
          "name": "categories",
          "required": false,
          "type": "string[]"
        },
        {
          "name": "priceRange",
          "required": false,
          "type": "[number, number]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Dashboard/FilterSidebar",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{}"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true }"
        }
      ]
    },
    {
      "name": "ds-floating-card",
      "title": "FloatingCard",
      "description": "Card com tilt 3D sutil ao seguir o ponteiro, para exibir screenshots/mockups em heroes.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/floating-card",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/floating-card.tsx"
      ],
      "props": [
        {
          "name": "intensity",
          "required": false,
          "type": "number",
          "description": "Maximum tilt rotation in degrees."
        }
      ],
      "storyTitle": "Effects/FloatingCard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<FloatingCard className=\"flex h-64 w-96 items-center justify-center p-6\">\n      <p className=\"text-sm text-muted-foreground\">Product screenshot</p>\n    </FloatingCard>"
        },
        {
          "name": "CustomIntensity",
          "description": "",
          "code": "<div className=\"flex gap-8\">\n      <FloatingCard\n        intensity={4}\n        className=\"flex h-48 w-64 items-center justify-center p-6\"\n      >\n        <p className=\"text-xs text-muted-foreground\">intensity=4</p>\n      </FloatingCard>\n      <FloatingCard\n        intensity={16}\n        className=\"flex h-48 w-64 items-center justify-center p-6\"\n      >\n        <p className=\"text-xs text-muted-foreground\">intensity=16</p>\n      </FloatingCard>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-floating-dock",
      "title": "Floating Dock",
      "description": "Dock flutuante com magnificação no hover e fallback grid mobile — inspirado em Aceternity Floating Dock.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/floating-dock",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "tooltip"
      ],
      "files": [
        "components/ds/floating-dock.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "FloatingDockItem[]"
        },
        {
          "name": "desktopClassName",
          "required": false,
          "type": "string"
        },
        {
          "name": "mobileClassName",
          "required": false,
          "type": "string"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\"",
          "options": [
            "default",
            "muted"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items },"
        },
        {
          "name": "Small",
          "description": "",
          "args": "{ items, size: \"sm\" },"
        },
        {
          "name": "Muted",
          "description": "",
          "args": "{ items, variant: \"muted\" },"
        }
      ]
    },
    {
      "name": "ds-footer-bottom-bar",
      "title": "Footer Bottom Bar",
      "description": "Faixa inferior atômica com copyright dinâmico, links legais e ações acessórias.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/footer-bottom-bar",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/footer-bottom-bar.tsx"
      ],
      "props": [
        {
          "name": "brandName",
          "required": false,
          "type": "string"
        },
        {
          "name": "year",
          "required": false,
          "type": "number | string"
        },
        {
          "name": "legalLinks",
          "required": false,
          "type": "LegalLinkItem[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "spacing",
          "required": false,
          "type": "\"compact\" | \"normal\" | \"relaxed\"",
          "options": [
            "compact",
            "normal",
            "relaxed"
          ],
          "default": "normal"
        }
      ],
      "stories": [
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex w-full flex-col gap-6\">\n      <FooterBottomBar locale=\"pt-BR\" brandName=\"UFPB\" />\n      <FooterBottomBar locale=\"en-US\" brandName=\"LEMA\" />\n      <FooterBottomBar locale=\"es-ES\" brandName=\"LEMA\" />\n      <FooterBottomBar locale=\"fr-FR\" brandName=\"LEMA\" />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-footer-brand-backdrop",
      "title": "Footer Brand Backdrop",
      "description": "Rodapé de vanguarda com mega letreiro tipográfico de fundo, grade compacta de links, newsletter e status.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/footer-brand-backdrop",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-footer-wordmark",
        "ds-social-links",
        "ds-system-status-badge",
        "ds-footer-bottom-bar",
        "ds-footer-menu",
        "ui-i18n"
      ],
      "files": [
        "components/ds/footer-brand-backdrop.tsx"
      ],
      "props": [
        {
          "name": "wordmarkText",
          "required": false,
          "type": "string"
        },
        {
          "name": "wordmarkVariant",
          "required": false,
          "type": "\"outline\" | \"muted\" | \"gradient\""
        },
        {
          "name": "brand",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "columns",
          "required": true,
          "type": "FooterGroupData[]"
        },
        {
          "name": "socialLinks",
          "required": false,
          "type": "SocialLinkItem[]"
        },
        {
          "name": "showStatusBadge",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "status",
          "required": false,
          "type": "SystemHealthStatus"
        },
        {
          "name": "statusUptime",
          "required": false,
          "type": "string"
        },
        {
          "name": "statusHref",
          "required": false,
          "type": "string"
        },
        {
          "name": "brandName",
          "required": false,
          "type": "string"
        },
        {
          "name": "legalLinks",
          "required": false,
          "type": "LegalLinkItem[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "spacing",
          "required": false,
          "type": "\"normal\" | \"relaxed\"",
          "options": [
            "normal",
            "relaxed"
          ],
          "default": "normal"
        }
      ],
      "stories": [
        {
          "name": "MutedVariant",
          "description": "",
          "args": "{\n    wordmarkVariant: \"muted\",\n  },"
        },
        {
          "name": "GradientVariant",
          "description": "",
          "args": "{\n    wordmarkVariant: \"gradient\",\n  },"
        },
        {
          "name": "CustomInstitution",
          "description": "",
          "args": "{\n    wordmarkText: \"UFPB\",\n    wordmarkVariant: \"outline\",\n    brandName: \"Universidade Federal da Paraíba\",\n  },"
        }
      ]
    },
    {
      "name": "ds-footer-cta",
      "title": "Footer CTA",
      "description": "Bloco de rodapé integrado com cartão de conversão de alto impacto posicionado antes dos links.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/footer-cta",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ds-social-links",
        "ds-footer-bottom-bar",
        "ds-footer-menu",
        "ui-i18n"
      ],
      "files": [
        "components/ds/footer-cta.tsx"
      ],
      "props": [
        {
          "name": "ctaTitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "ctaDescription",
          "required": false,
          "type": "string"
        },
        {
          "name": "primaryAction",
          "required": false,
          "type": "FooterCtaAction"
        },
        {
          "name": "secondaryAction",
          "required": false,
          "type": "FooterCtaAction"
        },
        {
          "name": "columns",
          "required": false,
          "type": "FooterGroupData[]"
        },
        {
          "name": "brand",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "socialLinks",
          "required": false,
          "type": "SocialLinkItem[]"
        },
        {
          "name": "brandName",
          "required": false,
          "type": "string"
        },
        {
          "name": "legalLinks",
          "required": false,
          "type": "LegalLinkItem[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "ctaTone",
          "required": false,
          "type": "\"card\" | \"primary\" | \"glow\"",
          "options": [
            "card",
            "primary",
            "glow"
          ],
          "default": "glow"
        }
      ],
      "stories": [
        {
          "name": "PrimaryTone",
          "description": "",
          "args": "{\n    ctaTone: \"primary\",\n  },"
        },
        {
          "name": "CardTone",
          "description": "",
          "args": "{\n    ctaTone: \"card\",\n  },"
        }
      ]
    },
    {
      "name": "ds-footer-mega",
      "title": "Footer Mega",
      "description": "Rodapé institucional completo com múltiplas colunas de links, apresentação de missão, newsletter e barra inferior.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/footer-mega",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-social-links",
        "ds-footer-newsletter",
        "ds-system-status-badge",
        "ds-app-store-badges",
        "ds-footer-bottom-bar",
        "ds-footer-menu",
        "ui-i18n"
      ],
      "files": [
        "components/ds/footer-mega.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "columns",
          "required": true,
          "type": "FooterGroupData[]"
        },
        {
          "name": "socialLinks",
          "required": false,
          "type": "SocialLinkItem[]"
        },
        {
          "name": "showNewsletter",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "newsletterTitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "newsletterDescription",
          "required": false,
          "type": "string"
        },
        {
          "name": "onSubscribe",
          "required": false,
          "type": "(email: string) => Promise<boolean | void> | void"
        },
        {
          "name": "showAppBadges",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "appStoreUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "googlePlayUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "showStatusBadge",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "status",
          "required": false,
          "type": "SystemHealthStatus"
        },
        {
          "name": "statusUptime",
          "required": false,
          "type": "string"
        },
        {
          "name": "statusHref",
          "required": false,
          "type": "string"
        },
        {
          "name": "brandName",
          "required": false,
          "type": "string"
        },
        {
          "name": "legalLinks",
          "required": false,
          "type": "LegalLinkItem[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "tone",
          "required": false,
          "type": "\"plain\" | \"card\"",
          "options": [
            "plain",
            "card"
          ],
          "default": "plain"
        }
      ],
      "stories": [
        {
          "name": "WithAppBadges",
          "description": "",
          "args": "{\n    showAppBadges: true,\n    appStoreUrl: \"https://apple.com\",\n    googlePlayUrl: \"https://google.com\",\n  },"
        },
        {
          "name": "CardTone",
          "description": "",
          "args": "{\n    tone: \"card\",\n  },"
        }
      ]
    },
    {
      "name": "ds-footer-menu",
      "title": "Footer Menu",
      "description": "A responsive footer navigation that displays in columns on desktop and as an accordion on mobile.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/footer-menu",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "accordion",
        "ui-i18n"
      ],
      "files": [
        "components/ds/footer-menu.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "FooterGroupData[]"
        },
        {
          "name": "upper",
          "required": false,
          "type": "boolean",
          "description": "@default false"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        }
      ],
      "storyTitle": "Footer/FooterMenu",
      "stories": [
        {
          "name": "Default",
          "description": "Default footer menu with four columns (Product, Company, Resources, Social) in uppercase mode.",
          "args": "{\n    data: footerData,\n    size: \"md\",\n    upper: true,\n    locale: \"en-US\",\n  },\n  render: (args) => (\n    <div className=\"mx-auto w-full max-w-6xl rounded-xl bg-card\">\n      <FooterMenu {...args} />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default footer menu with four columns (Product, Company, Resources, Social) in uppercase mode.\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization — two-column layout with translated headings.",
          "args": "{\n    data: [\n      {\n        title: \"Product\",\n        options: [\n          { name: \"Features\", url: \"#\" },\n          { name: \"Integrations\", url: \"#\" },\n          { name: \"Pricing\", url: \"#\" },\n        ],\n      },\n      {\n        title: \"Company\",\n        options: [\n          { name: \"About Us\", url: \"#\" },\n          { name: \"Careers\", url: \"#\" },\n          { name: \"Contact\", url: \"#\" },\n        ],\n      },\n    ],\n    size: \"md\",\n    locale: \"pt-BR\",\n  },\n  render: (args) => (\n    <div className=\"mx-auto w-full max-w-6xl rounded-xl bg-card\">\n      <FooterMenu {...args} />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) localization — two-column layout with translated headings.\",\n      },\n    },\n  },"
        },
        {
          "name": "Simple",
          "description": "Simplified footer menu with two columns and large size preset, no uppercase toggle.",
          "args": "{\n    data: footerData.slice(0, 2),\n    size: \"lg\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Simplified footer menu with two columns and large size preset, no uppercase toggle.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-footer-newsletter",
      "title": "Footer Newsletter",
      "description": "Captura atômica de e-mail para newsletter com validação, estado de envio e confirmação acessível.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/footer-newsletter",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "input",
        "label",
        "ui-i18n"
      ],
      "files": [
        "components/ds/footer-newsletter.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "onSubscribe",
          "required": false,
          "type": "(email: string) => Promise<boolean | void> | void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "showPrivacyNotice",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "layout",
          "required": false,
          "type": "\"inline\" | \"stacked\"",
          "options": [
            "inline",
            "stacked"
          ],
          "default": "inline"
        }
      ],
      "stories": [
        {
          "name": "StackedLayout",
          "description": "",
          "args": "{\n    layout: \"stacked\",\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex max-w-md flex-col gap-8\">\n      <div>\n        <span className=\"text-xs font-semibold text-muted-foreground uppercase\">\n          pt-BR:\n        </span>\n        <FooterNewsletter locale=\"pt-BR\" />\n      </div>\n      <div>\n        <span className=\"text-xs font-semibold text-muted-foreground uppercase\">\n          en-US:\n        </span>\n        <FooterNewsletter locale=\"en-US\" />\n      </div>\n      <div>\n        <span className=\"text-xs font-semibold text-muted-foreground uppercase\">\n          es-ES:\n        </span>\n        <FooterNewsletter locale=\"es-ES\" />\n      </div>\n      <div>\n        <span className=\"text-xs font-semibold text-muted-foreground uppercase\">\n          fr-FR:\n        </span>\n        <FooterNewsletter locale=\"fr-FR\" />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-footer-simple",
      "title": "Footer Simple",
      "description": "Bloco de rodapé minimalista e centralizado com logotipo, links de navegação, canais sociais e copyright.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/footer-simple",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-social-links",
        "ds-system-status-badge",
        "ds-footer-bottom-bar",
        "ui-i18n"
      ],
      "files": [
        "components/ds/footer-simple.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "links",
          "required": false,
          "type": "FooterSimpleNavLink[]"
        },
        {
          "name": "socialLinks",
          "required": false,
          "type": "SocialLinkItem[]"
        },
        {
          "name": "showStatusBadge",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "status",
          "required": false,
          "type": "SystemHealthStatus"
        },
        {
          "name": "statusUptime",
          "required": false,
          "type": "string"
        },
        {
          "name": "statusHref",
          "required": false,
          "type": "string"
        },
        {
          "name": "brandName",
          "required": false,
          "type": "string"
        },
        {
          "name": "legalLinks",
          "required": false,
          "type": "LegalLinkItem[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "align",
          "required": false,
          "type": "\"center\" | \"start\"",
          "options": [
            "center",
            "start"
          ],
          "default": "center"
        }
      ],
      "stories": [
        {
          "name": "WithStatusBadge",
          "description": "",
          "args": "{\n    showStatusBadge: true,\n    status: \"operational\",\n    statusUptime: \"99.99%\",\n    statusHref: \"https://status.ufpb.br\",\n  },"
        },
        {
          "name": "LeftAligned",
          "description": "",
          "args": "{\n    align: \"start\",\n    showStatusBadge: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-footer-wordmark",
      "title": "Footer Wordmark",
      "description": "Letreiro tipográfico de rodapé de grande porte com corte outline, preenchimento sutil ou gradiente.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/footer-wordmark",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/footer-wordmark.tsx"
      ],
      "props": [
        {
          "name": "text",
          "required": false,
          "type": "string"
        },
        {
          "name": "decorative",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "align",
          "required": false,
          "type": "\"center\" | \"left\"",
          "options": [
            "center",
            "left"
          ],
          "default": "center"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"outline\" | \"muted\" | \"gradient\"",
          "options": [
            "outline",
            "muted",
            "gradient"
          ],
          "default": "outline"
        }
      ],
      "stories": [
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex w-full flex-col gap-12\">\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-semibold text-muted-foreground uppercase\">\n          Outline:\n        </span>\n        <FooterWordmark text=\"LEMA\" variant=\"outline\" />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-semibold text-muted-foreground uppercase\">\n          Muted Fill:\n        </span>\n        <FooterWordmark text=\"LEMA\" variant=\"muted\" />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-semibold text-muted-foreground uppercase\">\n          Gradient:\n        </span>\n        <FooterWordmark text=\"LEMA\" variant=\"gradient\" />\n      </div>\n    </div>"
        },
        {
          "name": "CustomInstitution",
          "description": "",
          "args": "{\n    text: \"UFPB\",\n    variant: \"outline\",\n  },"
        }
      ]
    },
    {
      "name": "ds-forgot-password-form",
      "title": "ForgotPasswordForm",
      "description": "Bloco completo de recuperação de conta e redefinição de senha com instruções e confirmação.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/forgot-password-form",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "input",
        "button",
        "label",
        "ui-i18n"
      ],
      "files": [
        "components/ds/forgot-password-form.tsx"
      ],
      "props": [
        {
          "name": "onSubmit",
          "required": false,
          "type": "(email: string) => Promise<boolean | void> | void"
        },
        {
          "name": "onBackToLogin",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "resendCooldown",
          "required": false,
          "type": "number"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"flat\"",
          "options": [
            "default",
            "flat"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Auth/ForgotPasswordForm",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    variant: \"default\",\n    resendCooldown: 60,\n  },"
        },
        {
          "name": "FlatVariant",
          "description": "",
          "args": "{\n    variant: \"flat\",\n  },"
        }
      ]
    },
    {
      "name": "ds-form-builder",
      "title": "Form Builder",
      "description": "Gera um formulário validado a partir de um schema zod (validação) e uma lista de campos (rótulo, tipo de widget, opções) — react-hook-form + Field/FieldGroup.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/form-builder",
      "dependencies": [
        "react-hook-form",
        "zod",
        "@hookform/resolvers"
      ],
      "registryDependencies": [
        "field",
        "button",
        "input",
        "textarea",
        "select",
        "switch",
        "checkbox",
        "spinner"
      ],
      "files": [
        "components/ds/form-builder.tsx"
      ],
      "props": [
        {
          "name": "schema",
          "required": true,
          "type": "z.ZodType<FieldValues, FieldValues>",
          "description": "Validation only — field rendering comes from `fields`, not schema introspection."
        },
        {
          "name": "fields",
          "required": true,
          "type": "FormFieldConfig[]"
        },
        {
          "name": "defaultValues",
          "required": false,
          "type": "FieldValues"
        },
        {
          "name": "onSubmit",
          "required": true,
          "type": "(values: FieldValues) => void | Promise<void>"
        },
        {
          "name": "submitLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Form/FormBuilder",
      "stories": [
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        }
      ]
    },
    {
      "name": "ds-founder-letter",
      "title": "Founder Letter",
      "description": "Carta aberta ou mensagem do coordenador/diretor com retrato, prosa editorial, drop cap e assinatura.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/founder-letter",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/founder-letter.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "paragraphs",
          "required": true,
          "type": "string[]"
        },
        {
          "name": "authorName",
          "required": true,
          "type": "string"
        },
        {
          "name": "authorRole",
          "required": true,
          "type": "string"
        },
        {
          "name": "authorAvatar",
          "required": false,
          "type": "string"
        },
        {
          "name": "authorSignature",
          "required": false,
          "type": "string"
        },
        {
          "name": "withDropCap",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"elevated\" | \"muted\"",
          "options": [
            "default",
            "elevated",
            "muted"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "WithoutDropCap",
          "description": "",
          "args": "{\n    withDropCap: false,\n  },"
        },
        {
          "name": "Elevated",
          "description": "",
          "args": "{\n    variant: \"elevated\",\n  },"
        }
      ]
    },
    {
      "name": "ds-funnel-chart",
      "description": "Funnel chart for visualizing conversion rates between sequential stages.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/funnel-chart",
      "dependencies": [],
      "registryDependencies": [
        "chart",
        "skeleton",
        "card",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/funnel-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "FunnelStage[]"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "height",
          "required": false,
          "type": "number",
          "description": "Chart canvas height in px"
        },
        {
          "name": "showLabels",
          "required": false,
          "type": "boolean",
          "description": "Show value labels inside/beside each bar"
        },
        {
          "name": "showPercentage",
          "required": false,
          "type": "boolean",
          "description": "Show conversion rate between consecutive stages"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Custom value formatter — overrides format/decimals/locale/currency"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Charts/FunnelChart",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    data: MARKETING_DATA,\n    title: \"Marketing Funnel\",\n    subtitle: \"Q3 2026 conversion pipeline\",\n    showLabels: true,\n    showPercentage: true,\n    height: 320,\n  },"
        },
        {
          "name": "WithCurrency",
          "description": "",
          "args": "{\n    data: [\n      { name: \"Pipeline\", value: 2500000 },\n      { name: \"Qualified\", value: 1800000 },\n      { name: \"Proposal\", value: 900000 },\n      { name: \"Negotiation\", value: 400000 },\n      { name: \"Won\", value: 180000 },\n    ],\n    title: \"Revenue Funnel\",\n    subtitle: \"Quarterly revenue pipeline\",\n    format: \"currency\",\n    currency: \"USD\",\n    abbreviate: true,\n    height: 320,\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    data: [],\n    title: \"Marketing Funnel\",\n    subtitle: \"Loading conversion data…\",\n    loading: true,\n    height: 320,\n  },"
        },
        {
          "name": "EmptyData",
          "description": "",
          "args": "{\n    data: [],\n    title: \"Marketing Funnel\",\n    height: 320,\n  },"
        },
        {
          "name": "NoLabels",
          "description": "",
          "args": "{\n    data: MARKETING_DATA,\n    title: \"Clean Funnel\",\n    showLabels: false,\n    showPercentage: false,\n    height: 320,\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{\n    data: MARKETING_DATA,\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <FunnelChart\n          key={locale}\n          data={MARKETING_DATA}\n          title={locale}\n          locale={locale}\n          height={240}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <FunnelChart\n          key={locale}\n          data={MARKETING_DATA}\n          title={locale}\n          locale={locale}\n          height={240}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "ThreeStages",
          "description": "",
          "args": "{\n    data: [\n      { name: \"Awareness\", value: 50000 },\n      { name: \"Interest\", value: 18000 },\n      { name: \"Purchase\", value: 4200 },\n    ],\n    title: \"Sales Funnel\",\n    subtitle: \"3-stage simplified view\",\n    height: 240,\n  },"
        },
        {
          "name": "CustomColors",
          "description": "",
          "args": "{\n    data: [\n      { name: \"Impressions\", value: 100000, color: \"var(--color-violet-500)\" },\n      { name: \"Clicks\", value: 32000, color: \"var(--color-indigo-500)\" },\n      { name: \"Signups\", value: 8400, color: \"var(--color-blue-500)\" },\n      { name: \"Active\", value: 3100, color: \"var(--color-cyan-500)\" },\n    ],\n    title: \"Product Adoption\",\n    height: 280,\n  },"
        }
      ]
    },
    {
      "name": "ds-gallery-filterable",
      "title": "GalleryFilterable",
      "description": "Galeria de imagens com filtro de categorias — composto de ds-image-gallery e ds-pill-group.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/gallery-filterable",
      "dependencies": [],
      "registryDependencies": [
        "ds-image-gallery",
        "ds-pill-group"
      ],
      "files": [
        "components/ds/gallery-filterable.tsx"
      ],
      "props": [
        {
          "name": "categories",
          "required": true,
          "type": "GalleryFilterCategory[]"
        },
        {
          "name": "items",
          "required": true,
          "type": "GalleryFilterableItem[]"
        },
        {
          "name": "allLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "layout",
          "required": false,
          "type": "ImageGalleryLayout"
        },
        {
          "name": "columns",
          "required": false,
          "type": "ImageGalleryColumns"
        },
        {
          "name": "aspect",
          "required": false,
          "type": "ImageGalleryAspect"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Gallery/GalleryFilterable",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        }
      ]
    },
    {
      "name": "ds-gallery-split",
      "title": "GallerySplit",
      "description": "Seção split com texto de um lado e colagem de imagens do outro — composto de ds-hero-section e ds-image-gallery.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/gallery-split",
      "dependencies": [],
      "registryDependencies": [
        "ds-hero-section",
        "ds-image-gallery",
        "badge"
      ],
      "files": [
        "components/ds/gallery-split.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "items",
          "required": true,
          "type": "ImageGalleryItem[]"
        },
        {
          "name": "columns",
          "required": false,
          "type": "ImageGalleryColumns"
        }
      ],
      "storyTitle": "Gallery/GallerySplit",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        }
      ]
    },
    {
      "name": "ds-gallery-video",
      "title": "GalleryVideo",
      "description": "Grid de vídeos que abrem em diálogo ao clicar — composto de ds-video-dialog.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/gallery-video",
      "dependencies": [],
      "registryDependencies": [
        "ds-video-dialog"
      ],
      "files": [
        "components/ds/gallery-video.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "GalleryVideoItem[]"
        },
        {
          "name": "columns",
          "required": false,
          "type": "2 | 3 | 4"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Gallery/GalleryVideo",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "TwoColumns",
          "description": "",
          "args": "{ columns: 2 },"
        }
      ]
    },
    {
      "name": "ds-gantt",
      "title": "Gantt",
      "description": "Timeline Gantt com barras e progresso — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/gantt",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton"
      ],
      "files": [
        "components/ds/gantt.tsx"
      ],
      "props": [
        {
          "name": "tasks",
          "required": true,
          "type": "GanttTask[]"
        },
        {
          "name": "range",
          "required": false,
          "type": "[number, number]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/Gantt",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ tasks }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ tasks, loading: true }"
        }
      ]
    },
    {
      "name": "ds-geomap-chart",
      "title": "Geomap Chart",
      "description": "A geographic map component for rendering GeoJSON/TopoJSON data with tooltips, zooming, choropleth, and point markers.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/geomap-chart",
      "dependencies": [
        "react-simple-maps",
        "geojson",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "tooltip",
        "format-utils"
      ],
      "files": [
        "components/ds/geomap-chart.tsx"
      ],
      "props": [
        {
          "name": "geoData",
          "required": true,
          "type": "FeatureCollection | string",
          "description": "GeoJSON FeatureCollection object **or** a URL string.\nWhen a string is passed, react-simple-maps fetches it internally —\nideal for files served from `/public` (e.g. `\"/geojson/world.geojson\"`)."
        },
        {
          "name": "featureIdProperty",
          "required": false,
          "type": "string",
          "description": "Which feature property to use as the ID when the GeoJSON features have no\ntop-level `id` field (e.g. `\"sigla\"` for Brazilian states, `\"ISO_A3\"` for\nNatural Earth country files). Takes precedence over `properties.id`."
        },
        {
          "name": "data",
          "required": false,
          "type": "GeoMapFeature[]",
          "description": "Values to overlay on features (choropleth / highlight) — matched by id"
        },
        {
          "name": "markers",
          "required": false,
          "type": "GeoMapMarker[]",
          "description": "Point markers to render on top of the map"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "height",
          "required": false,
          "type": "number",
          "description": "Chart canvas height in px — width is always 100%"
        },
        {
          "name": "projection",
          "required": false,
          "type": "GeoProjection",
          "description": "D3 projection name — defaults to \"geoMercator\""
        },
        {
          "name": "projectionConfig",
          "required": false,
          "type": "{ scale?: number center?: [number, number] rotate?: [number, number, number] }"
        },
        {
          "name": "enableZoom",
          "required": false,
          "type": "boolean",
          "description": "Enable zoom and pan via scroll / drag"
        },
        {
          "name": "zoomRange",
          "required": false,
          "type": "[number, number]",
          "description": "Min/max zoom multiplier when enableZoom is true"
        },
        {
          "name": "colorRange",
          "required": false,
          "type": "[string, string]",
          "description": "Choropleth: interpolate fill between these two colors by value"
        },
        {
          "name": "defaultFill",
          "required": false,
          "type": "string",
          "description": "Default fill for features with no matching data entry"
        },
        {
          "name": "selectedFeatureIds",
          "required": false,
          "type": "(string | number)[]",
          "description": "Feature IDs to highlight with a distinct stroke"
        },
        {
          "name": "selectedStroke",
          "required": false,
          "type": "string",
          "description": "Stroke color for selected features"
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showLegend",
          "required": false,
          "type": "boolean",
          "description": "Show a color scale legend when `colorRange` is set.\nDefaults to `true` whenever `colorRange` is provided."
        },
        {
          "name": "legendPosition",
          "required": false,
          "type": "LegendPosition",
          "description": "Where to render the legend.\nOverlay options (`top-left`, `top-right`, `bottom-left`, `bottom-right`) float\ninside the map canvas. `\"bottom\"` renders below the canvas.\nDefaults to `\"bottom-right\"`."
        },
        {
          "name": "legendLabel",
          "required": false,
          "type": "string",
          "description": "Short label displayed above the gradient bar in the legend"
        },
        {
          "name": "legendOrientation",
          "required": false,
          "type": "LegendOrientation",
          "description": "Gradient bar direction in the legend — defaults to `\"horizontal\"`"
        },
        {
          "name": "onFeatureClick",
          "required": false,
          "type": "( feature: GeoMapFeature | null, originalId: string | number ) => void"
        },
        {
          "name": "onMarkerClick",
          "required": false,
          "type": "(marker: GeoMapMarker) => void"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the map while data loads"
        }
      ],
      "storyTitle": "Data Display/GeoMapChart",
      "stories": [
        {
          "name": "Default",
          "description": "Neutral world map using the Natural Earth projection with a muted fill and no tooltip or data overlay.",
          "args": "{\n    title: \"World Map\",\n    subtitle: \"Neutral — no data overlay\",\n    geoData: \"/geojson/world.geojson\",\n    data: [],\n    markers: [],\n    projection: \"geoNaturalEarth1\",\n    enableZoom: false,\n    zoomRange: [1, 8],\n    selectedFeatureIds: [],\n    showTooltip: false,\n    legendPosition: \"bottom-right\",\n    legendOrientation: \"horizontal\",\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n    height: 420,\n    defaultFill: \"var(--muted)\",\n  },"
        },
        {
          "name": "Choropleth",
          "description": "South America choropleth map coloring countries by active student enrollment with a vertical color legend and footer summary.",
          "args": "{\n    title: \"Enrollment by Country\",\n    subtitle: \"Active students — South America 2025\",\n    geoData: \"/geojson/world.geojson\",\n    projection: \"geoMercator\",\n    projectionConfig: { scale: 350, center: [-60, -15] },\n    height: 420,\n    colorRange: [\"#dbeafe\", \"#1d4ed8\"],\n    legendOrientation: \"vertical\",\n\n    data: [\n      { id: \"BRA\", name: \"Brazil\", value: 98400 },\n      { id: \"ARG\", name: \"Argentina\", value: 64200 },\n      { id: \"COL\", name: \"Colombia\", value: 52100 },\n      { id: \"PER\", name: \"Peru\", value: 38700 },\n      { id: \"VEN\", name: \"Venezuela\", value: 31500 },\n      { id: \"CHL\", name: \"Chile\", value: 28900 },\n      { id: \"ECU\", name: \"Ecuador\", value: 22300 },\n      { id: \"BOL\", name: \"Bolivia\", value: 18600 },\n    ],\n    showTooltip: true,\n    valueFormatter: (v) =>\n      formatValue(v, \"integer\", { abbreviate: true }) + \" students\",\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-blue-500\" />\n          <span>Brazil leads with 98.4k active students</span>\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "WithLegend",
          "description": "Brazil states choropleth demonstrating configurable legend position and orientation via the Controls panel.",
          "args": "{\n    title: \"Legend — position & orientation\",\n    subtitle:\n      \"Switch legendPosition and legendOrientation in the controls panel\",\n    geoData: \"/geojson/brazil-states.geojson\",\n    projection: \"geoMercator\",\n    projectionConfig: { scale: 700, center: [-54, -15] },\n    height: 420,\n    featureIdProperty: \"postal\",\n    colorRange: [\"#dcfce7\", \"#16a34a\"],\n    legendLabel: \"Active students\",\n    legendPosition: \"bottom-right\",\n    legendOrientation: \"horizontal\",\n    data: [\n      { id: \"SP\", name: \"Sao Paulo\", value: 98400 },\n      { id: \"MG\", name: \"Minas Gerais\", value: 64200 },\n      { id: \"RJ\", name: \"Rio de Janeiro\", value: 52100 },\n      { id: \"BA\", name: \"Bahia\", value: 38700 },\n      { id: \"RS\", name: \"Rio Grande do Sul\", value: 31500 },\n      { id: \"PR\", name: \"Parana\", value: 28900 },\n      { id: \"SC\", name: \"Santa Catarina\", value: 22300 },\n      { id: \"GO\", name: \"Goias\", value: 18600 },\n    ],\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"integer\", { abbreviate: true }),\n  },"
        },
        {
          "name": "BrazilStates",
          "description": "Full Brazil states choropleth with enrollment data using feature ID mapping to postal codes and a green color gradient.",
          "args": "{\n    title: \"Enrollment by State — Brazil\",\n    subtitle: \"Active students 2025\",\n    geoData: \"/geojson/brazil-states.geojson\",\n    projection: \"geoMercator\",\n    projectionConfig: { scale: 700, center: [-54, -15] },\n    height: 480,\n    featureIdProperty: \"postal\",\n    colorRange: [\"#dcfce7\", \"#16a34a\"],\n    data: [\n      { id: \"SP\", name: \"Sao Paulo\", value: 98400 },\n      { id: \"MG\", name: \"Minas Gerais\", value: 64200 },\n      { id: \"RJ\", name: \"Rio de Janeiro\", value: 52100 },\n      { id: \"BA\", name: \"Bahia\", value: 38700 },\n      { id: \"RS\", name: \"Rio Grande do Sul\", value: 31500 },\n      { id: \"PR\", name: \"Parana\", value: 28900 },\n      { id: \"SC\", name: \"Santa Catarina\", value: 22300 },\n      { id: \"GO\", name: \"Goias\", value: 18600 },\n      { id: \"CE\", name: \"Ceara\", value: 15200 },\n      { id: \"PE\", name: \"Pernambuco\", value: 13800 },\n      { id: \"AM\", name: \"Amazonas\", value: 11200 },\n      { id: \"PA\", name: \"Para\", value: 10800 },\n      { id: \"MA\", name: \"Maranhao\", value: 9600 },\n      { id: \"MT\", name: \"Mato Grosso\", value: 8400 },\n      { id: \"ES\", name: \"Espirito Santo\", value: 7900 },\n      { id: \"PB\", name: \"Paraiba\", value: 7100 },\n      { id: \"RN\", name: \"Rio Grande do Norte\", value: 6800 },\n      { id: \"AL\", name: \"Alagoas\", value: 5900 },\n      { id: \"PI\", name: \"Piaui\", value: 5400 },\n      { id: \"MS\", name: \"Mato Grosso do Sul\", value: 5100 },\n      { id: \"SE\", name: \"Sergipe\", value: 4300 },\n      { id: \"RO\", name: \"Rondonia\", value: 3800 },\n      { id: \"TO\", name: \"Tocantins\", value: 3200 },\n      { id: \"AC\", name: \"Acre\", value: 2100 },\n      { id: \"DF\", name: \"Federal District\", value: 1900 },\n      { id: \"AP\", name: \"Amapa\", value: 1700 },\n      { id: \"RR\", name: \"Roraima\", value: 1200 },\n    ],\n    showTooltip: true,\n    valueFormatter: (v) =>\n      formatValue(v, \"integer\", { abbreviate: true }) + \" students\",\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-green-600\" />\n          <span>SP leads with 98.4k active students</span>\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "WithMarkers",
          "description": "World map zoomed to Brazil showing six campus location markers with tooltip values and interactive marker clicks.",
          "args": "{\n    title: \"Campus Locations\",\n    subtitle: \"Distribution of physical campuses\",\n    geoData: \"/geojson/world.geojson\",\n    projection: \"geoMercator\",\n    projectionConfig: { scale: 700, center: [-50, -15] },\n    height: 420,\n    defaultFill: \"var(--muted)\",\n    markers: [\n      {\n        id: \"campus-sp-1\",\n        coordinates: [-46.63, -23.55],\n        label: \"SP Central\",\n        value: 12400,\n      },\n      {\n        id: \"campus-sp-2\",\n        coordinates: [-47.93, -22.12],\n        label: \"SP Interior\",\n        value: 5200,\n      },\n      {\n        id: \"campus-rj\",\n        coordinates: [-43.17, -22.9],\n        label: \"Rio\",\n        value: 8800,\n      },\n      {\n        id: \"campus-mg\",\n        coordinates: [-43.93, -19.92],\n        label: \"BH\",\n        value: 6300,\n      },\n      {\n        id: \"campus-rs\",\n        coordinates: [-51.23, -30.03],\n        label: \"POA\",\n        value: 4100,\n      },\n      {\n        id: \"campus-pr\",\n        coordinates: [-49.26, -25.43],\n        label: \"CWB\",\n        value: 3700,\n      },\n    ],\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"integer\") + \" students\",\n    footer: (\n      <span className=\"flex items-center gap-1.5\">\n        <MapPin className=\"size-3.5 text-chart-1\" />\n        <span>6 campuses — click a marker for details</span>\n      </span>\n    ),\n  },"
        },
        {
          "name": "WithHighlight",
          "description": "Brazil states choropleth with SP, MG, and RJ highlighted using `selectedFeatureIds` and a custom primary stroke color.",
          "args": "{\n    title: \"Selected States\",\n    subtitle: \"SP, MG and RJ highlighted — control via selectedFeatureIds\",\n    geoData: \"/geojson/brazil-states.geojson\",\n    projection: \"geoMercator\",\n    projectionConfig: { scale: 700, center: [-54, -15] },\n    height: 480,\n    featureIdProperty: \"postal\",\n    data: [\n      { id: \"SP\", name: \"Sao Paulo\", value: 98400 },\n      { id: \"MG\", name: \"Minas Gerais\", value: 64200 },\n      { id: \"RJ\", name: \"Rio de Janeiro\", value: 52100 },\n    ],\n    colorRange: [\"#dbeafe\", \"#1d4ed8\"],\n    selectedFeatureIds: [\"SP\", \"MG\", \"RJ\"],\n    selectedStroke: \"var(--primary)\",\n    showTooltip: true,\n    valueFormatter: (v) =>\n      formatValue(v, \"integer\", { abbreviate: true }) + \" students\",\n  },"
        },
        {
          "name": "UsaStates",
          "description": "US states choropleth using the geoAlbersUsa projection with median household income data and an amber color gradient.",
          "args": "{\n    title: \"Median Household Income — US States\",\n    subtitle: \"Estimated annual income (USD thousands) — 2023\",\n    geoData: \"/geojson/us-states-topo.json\",\n    projection: \"geoAlbersUsa\",\n    height: 420,\n    colorRange: [\"#fef3c7\", \"#b45309\"],\n    defaultFill: \"var(--muted)\",\n    showTooltip: true,\n    valueFormatter: (v) =>\n      formatValue(v * 1000, \"currency\", {\n        currency: \"USD\",\n        abbreviate: true,\n        decimals: 0,\n      }) + \" / year\",\n    data: [\n      { id: \"01\", name: \"Alabama\", value: 58 },\n      { id: \"02\", name: \"Alaska\", value: 85 },\n      { id: \"04\", name: \"Arizona\", value: 72 },\n      { id: \"05\", name: \"Arkansas\", value: 57 },\n      { id: \"06\", name: \"California\", value: 84 },\n      { id: \"08\", name: \"Colorado\", value: 84 },\n      { id: \"09\", name: \"Connecticut\", value: 90 },\n      { id: \"10\", name: \"Delaware\", value: 75 },\n      { id: \"12\", name: \"Florida\", value: 67 },\n      { id: \"13\", name: \"Georgia\", value: 71 },\n      { id: \"15\", name: \"Hawaii\", value: 92 },\n      { id: \"16\", name: \"Idaho\", value: 67 },\n      { id: \"17\", name: \"Illinois\", value: 74 },\n      { id: \"18\", name: \"Indiana\", value: 67 },\n      { id: \"19\", name: \"Iowa\", value: 70 },\n      { id: \"20\", name: \"Kansas\", value: 68 },\n      { id: \"21\", name: \"Kentucky\", value: 61 },\n      { id: \"22\", name: \"Louisiana\", value: 57 },\n      { id: \"23\", name: \"Maine\", value: 68 },\n      { id: \"24\", name: \"Maryland\", value: 98 },\n      { id: \"25\", name: \"Massachusetts\", value: 93 },\n      { id: \"26\", name: \"Michigan\", value: 70 },\n      { id: \"27\", name: \"Minnesota\", value: 84 },\n      { id: \"28\", name: \"Mississippi\", value: 52 },\n      { id: \"29\", name: \"Missouri\", value: 67 },\n      { id: \"30\", name: \"Montana\", value: 68 },\n      { id: \"31\", name: \"Nebraska\", value: 71 },\n      { id: \"32\", name: \"Nevada\", value: 70 },\n      { id: \"33\", name: \"New Hampshire\", value: 87 },\n      { id: \"34\", name: \"New Jersey\", value: 92 },\n      { id: \"35\", name: \"New Mexico\", value: 60 },\n      { id: \"36\", name: \"New York\", value: 79 },\n      { id: \"37\", name: \"North Carolina\", value: 68 },\n      { id: \"38\", name: \"North Dakota\", value: 70 },\n      { id: \"39\", name: \"Ohio\", value: 68 },\n      { id: \"40\", name: \"Oklahoma\", value: 60 },\n      { id: \"41\", name: \"Oregon\", value: 73 },\n      { id: \"42\", name: \"Pennsylvania\", value: 71 },\n      { id: \"44\", name: \"Rhode Island\", value: 74 },\n      { id: \"45\", name: \"South Carolina\", value: 63 },\n      { id: \"46\", name: \"South Dakota\", value: 68 },\n      { id: \"47\", name: \"Tennessee\", value: 65 },\n      { id: \"48\", name: \"Texas\", value: 69 },\n      { id: \"49\", name: \"Utah\", value: 82 },\n      { id: \"50\", name: \"Vermont\", value: 74 },\n      { id: \"51\", name: \"Virginia\", value: 85 },\n      { id: \"53\", name: \"Washington\", value: 89 },\n      { id: \"54\", name: \"West Virginia\", value: 55 },\n      { id: \"55\", name: \"Wisconsin\", value: 72 },\n      { id: \"56\", name: \"Wyoming\", value: 71 },\n    ],\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-amber-600\" />\n          <span>MD highest ($98k) · MS lowest ($52k) — US Census ACS 2023</span>\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the geo map with an animated skeleton that mirrors the title and subtitle structure.",
          "args": "{\n    title: \"World Map\",\n    subtitle: \"Neutral — no data overlay\",\n    geoData: \"/geojson/world.geojson\",\n    projection: \"geoNaturalEarth1\",\n    height: 420,\n    showTooltip: false,\n    defaultFill: \"var(--muted)\",\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "ZoomPan",
          "description": "Brazil states choropleth with scroll-to-zoom and drag-to-pan enabled for interactive map exploration.",
          "args": "{\n    title: \"Zoom & Pan enabled\",\n    subtitle: \"Scroll to zoom · drag to pan\",\n    geoData: \"/geojson/brazil-states.geojson\",\n    projection: \"geoMercator\",\n    projectionConfig: { scale: 700, center: [-54, -15] },\n    height: 480,\n    featureIdProperty: \"postal\",\n    enableZoom: true,\n    zoomRange: [1, 10],\n    colorRange: [\"#dcfce7\", \"#16a34a\"],\n    data: [\n      { id: \"SP\", name: \"Sao Paulo\", value: 98400 },\n      { id: \"MG\", name: \"Minas Gerais\", value: 64200 },\n      { id: \"RJ\", name: \"Rio de Janeiro\", value: 52100 },\n      { id: \"BA\", name: \"Bahia\", value: 38700 },\n      { id: \"RS\", name: \"Rio Grande do Sul\", value: 31500 },\n      { id: \"PR\", name: \"Parana\", value: 28900 },\n      { id: \"SC\", name: \"Santa Catarina\", value: 22300 },\n      { id: \"GO\", name: \"Goias\", value: 18600 },\n    ],\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"integer\", { abbreviate: true }),\n  },"
        }
      ]
    },
    {
      "name": "ds-glass",
      "title": "Glass",
      "description": "Glassmorphism com 5 variantes (glass-1..5) e backdrop-blur — inspirado em Launch UI Glass.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/glass",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/glass.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"1\" | \"2\" | \"3\" | \"4\" | \"5\"",
          "options": [
            "1",
            "2",
            "3",
            "4",
            "5"
          ],
          "default": "1"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ variant: \"1\" },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-wrap gap-4 bg-gradient-to-br from-primary/15 to-muted p-6\">\n      {([\"1\", \"2\", \"3\", \"4\", \"5\"] as const).map((v) => (\n        <Glass\n          key={v}\n          variant={v}\n          className=\"flex size-28 items-center justify-center text-xs font-medium\"\n        >\n          glass-{v}\n        </Glass>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-globe-3d",
      "description": "3D Globe component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/globe-3d",
      "dependencies": [
        "cobe"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/globe-3d.tsx"
      ],
      "props": [
        {
          "name": "markers",
          "required": false,
          "type": "Array<{ location: [number, number]; size: number }>"
        },
        {
          "name": "baseColor",
          "required": false,
          "type": "[number, number, number]"
        },
        {
          "name": "glowColor",
          "required": false,
          "type": "[number, number, number]"
        },
        {
          "name": "markerColor",
          "required": false,
          "type": "[number, number, number]"
        }
      ],
      "storyTitle": "Data Display/Globe3D",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<div className=\"flex h-[400px] w-full max-w-[400px] items-center justify-center\">\n      <Globe3D />\n    </div>"
        },
        {
          "name": "WithMarkers",
          "description": "",
          "code": "<div className=\"flex h-[400px] w-full max-w-[400px] items-center justify-center\">\n      <Globe3D\n        markers={[\n          { location: [37.7595, -122.4367], size: 0.05 },\n          { location: [40.7128, -74.006], size: 0.1 },\n          { location: [-23.5505, -46.6333], size: 0.08 },\n          { location: [51.5074, -0.1278], size: 0.05 },\n          { location: [35.6762, 139.6503], size: 0.1 },\n        ]}\n        markerColor={[0, 1, 0.5]}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-glow",
      "title": "Glow",
      "description": "Glow posicional (top/above/center/below) com radial gradient blur — inspirado em Launch UI Glow.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/glow",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/glow.tsx"
      ],
      "props": [
        {
          "name": "color",
          "required": false,
          "type": "string"
        },
        {
          "name": "size",
          "required": false,
          "type": "number"
        },
        {
          "name": "position",
          "required": false,
          "type": "\"top\" | \"above\" | \"above-inner\" | \"center\" | \"bottom-inner\" | \"below\" | \"below-inner\"",
          "options": [
            "top",
            "above",
            "above-inner",
            "center",
            "bottom-inner",
            "below",
            "below-inner"
          ],
          "default": "top"
        },
        {
          "name": "intensity",
          "required": false,
          "type": "\"subtle\" | \"medium\" | \"strong\"",
          "options": [
            "subtle",
            "medium",
            "strong"
          ],
          "default": "medium"
        }
      ],
      "stories": [
        {
          "name": "Top",
          "description": "",
          "args": "{ position: \"top\" },"
        },
        {
          "name": "Center",
          "description": "",
          "args": "{ position: \"center\" },"
        },
        {
          "name": "AllPositions",
          "description": "",
          "code": "<div className=\"grid gap-4 md:grid-cols-3\">\n      {([\"top\", \"above\", \"center\", \"bottom-inner\", \"below\"] as const).map(\n        (p) => (\n          <div\n            key={p}\n            className=\"relative h-40 overflow-hidden rounded-xl border bg-background\"\n          >\n            <Glow position={p} size={360} />\n            <span className=\"relative p-3 text-xs font-medium\">{p}</span>\n          </div>\n        )\n      )}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-grid-pulse",
      "title": "Grid Pulse",
      "description": "Grid de pontos que pulsa de tamanho e opacidade perto do cursor, ocioso fora da interação — fundo de hero interativo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/grid-pulse",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/grid-pulse.tsx"
      ],
      "props": [
        {
          "name": "tone",
          "required": false,
          "type": "\"primary\" | \"violet\" | \"sky\" | \"neutral\"",
          "options": [
            "primary",
            "violet",
            "sky",
            "neutral"
          ],
          "default": "primary"
        },
        {
          "name": "radius",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Effects/GridPulse",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ tone: \"primary\", radius: \"md\" },"
        },
        {
          "name": "AllTones",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n      {([\"primary\", \"violet\", \"sky\", \"neutral\"] as const).map((tone) => (\n        <div\n          key={tone}\n          className=\"relative flex h-48 items-center justify-center overflow-hidden rounded-2xl border border-border bg-background\"\n        >\n          <GridPulse tone={tone} />\n          <p className=\"relative z-10 text-xs font-medium text-muted-foreground\">\n            {tone}\n          </p>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllRadii",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((radius) => (\n        <div\n          key={radius}\n          className=\"relative flex h-48 items-center justify-center overflow-hidden rounded-2xl border border-border bg-background\"\n        >\n          <GridPulse radius={radius} />\n          <p className=\"relative z-10 text-xs font-medium text-muted-foreground\">\n            {radius}\n          </p>\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-guided-tour",
      "title": "Guided Tour",
      "description": "A presentation component for a guided tour or onboarding card.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/guided-tour",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/guided-tour.tsx"
      ],
      "props": [
        {
          "name": "steps",
          "required": true,
          "type": "TourStep[]"
        },
        {
          "name": "currentStep",
          "required": true,
          "type": "number"
        },
        {
          "name": "onNext",
          "required": true,
          "type": "() => void"
        },
        {
          "name": "onPrev",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onSkip",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onFinish",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Feedback/GuidedTour",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    steps: sampleSteps,\n    currentStep: 0,\n    onNext: fn(),\n  },\n  render: () => {\n    const [currentStep, setCurrentStep] = useState(0)\n\n    const handleNext = () =>\n      setCurrentStep((prev) => Math.min(prev + 1, sampleSteps.length - 1))\n    const handlePrev = () => setCurrentStep((prev) => Math.max(prev - 1, 0))\n\n    return (\n      <GuidedTour\n        steps={sampleSteps}\n        currentStep={currentStep}\n        onNext={handleNext}\n        onPrev={handlePrev}\n        onSkip={fn()}\n        onFinish={fn()}\n      />\n    )\n  },",
          "code": "<GuidedTour\n        steps={sampleSteps}\n        currentStep={currentStep}\n        onNext={handleNext}\n        onPrev={handlePrev}\n        onSkip={fn()}\n        onFinish={fn()}\n      />"
        }
      ]
    },
    {
      "name": "ds-header",
      "title": "Header",
      "description": "Container semântico banner com variantes default/blurred/transparent/solid, sticky, tamanhos sm/md/lg e skip link i18n. Base para todos os headers.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/header.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"blurred\" | \"transparent\" | \"solid\"",
          "options": [
            "default",
            "blurred",
            "transparent",
            "solid"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/Header",
      "stories": [
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4 p-4\">\n      {([\"default\", \"blurred\", \"solid\"] as const).map((v, idx) => (\n        <div key={v}>\n          <Header\n            variant={v}\n            size=\"md\"\n            role={idx === 0 ? \"banner\" : \"region\"}\n            aria-label={idx === 0 ? undefined : `Header variant ${v}`}\n          >\n            <HeaderContainer>\n              <HeaderBrand title=\"LEMA\" />\n              <span className=\"text-xs text-muted-foreground\">{v}</span>\n            </HeaderContainer>\n          </Header>\n        </div>\n      ))}\n      <div className=\"bg-slate-900 p-4\">\n        <Header\n          variant=\"transparent\"\n          size=\"md\"\n          className=\"border-white/20\"\n          role=\"region\"\n          aria-label=\"Header variant transparent\"\n        >\n          <HeaderContainer>\n            <HeaderBrand title=\"LEMA\" className=\"[&_span]:text-white\" />\n            <span className=\"text-xs text-white/70\">transparent over hero</span>\n          </HeaderContainer>\n        </Header>\n      </div>\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4 p-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s, idx) => (\n        <div key={s}>\n          <Header\n            size={s}\n            role={idx === 0 ? \"banner\" : \"region\"}\n            aria-label={idx === 0 ? undefined : `Header size ${s}`}\n          >\n            <HeaderContainer size={s}>\n              <HeaderBrand title=\"LEMA\" size={s} />\n              <HeaderNav items={nav} size={s} className=\"hidden md:flex\" />\n            </HeaderContainer>\n          </Header>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "Sticky",
          "description": "",
          "code": "<div className=\"h-[300px] overflow-auto border\">\n      <Header sticky size=\"md\">\n        <HeaderContainer>\n          <HeaderBrand title=\"LEMA\" />\n          <span className=\"text-xs text-muted-foreground\">sticky top-0</span>\n        </HeaderContainer>\n      </Header>\n      <div className=\"h-[600px] bg-muted/30 p-6 text-sm text-muted-foreground\">\n        Scroll content\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-header-actions",
      "title": "Header Actions",
      "description": "Grupo de CTAs do header com variantes de Button, gap configurável e skeleton.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header-actions",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "button",
        "skeleton"
      ],
      "files": [
        "components/ds/header-actions.tsx"
      ],
      "props": [
        {
          "name": "actions",
          "required": true,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "gap",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/HeaderActions",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    actions: [\n      { label: \"Log in\", variant: \"ghost\" },\n      { label: \"Get started\", variant: \"default\" },\n    ],\n  },"
        },
        {
          "name": "WithIcons",
          "description": "",
          "args": "{\n    actions: [\n      { label: \"Contact\", variant: \"outline\", icon: <MailIcon /> },\n      {\n        label: \"Start\",\n        variant: \"default\",\n        icon: <ArrowRightIcon />,\n        iconPosition: \"end\",\n      },\n    ],\n  },"
        },
        {
          "name": "SingleAction",
          "description": "",
          "args": "{ actions: [{ label: \"Sign up\", variant: \"default\" }] },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ actions: [{ label: \"A\" }, { label: \"B\" }], loading: true },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    actions: [\n      { label: \"Primary\", variant: \"default\", disabled: true },\n      { label: \"Ghost\", variant: \"ghost\" },\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-header-announcement",
      "title": "Header Announcement",
      "description": "Faixa de anúncio dismissível com tag, link e variantes default/outline/glow.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header-announcement",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/header-announcement.tsx"
      ],
      "props": [
        {
          "name": "href",
          "required": false,
          "type": "string"
        },
        {
          "name": "tag",
          "required": false,
          "type": "string"
        },
        {
          "name": "dismissible",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onDismiss",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"outline\" | \"glow\"",
          "options": [
            "default",
            "outline",
            "glow"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Header/HeaderAnnouncement",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    children: \"v1.2 shipped — explore new headers and footers\",\n    tag: \"New\",\n  },"
        },
        {
          "name": "Dismissible",
          "description": "",
          "args": "{\n    children: \"Black Friday: 30% off all plans\",\n    tag: \"Sale\",\n    dismissible: true,\n  },"
        },
        {
          "name": "WithLink",
          "description": "",
          "args": "{ children: \"Read the announcement\", href: \"#\", tag: \"Update\" },"
        },
        {
          "name": "GlowVariant",
          "description": "",
          "args": "{\n    children: \"Join the waitlist — limited spots\",\n    tag: \"Early Access\",\n    variant: \"glow\",\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-2\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((l) => (\n        <HeaderAnnouncement key={l} locale={l} tag=\"New\">\n          Announcement — {l}\n        </HeaderAnnouncement>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-header-brand",
      "title": "Header Brand",
      "description": "Identidade do header com logo medallion, título e subtítulo, tamanhos sm/md/lg e skeleton.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header-brand",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton"
      ],
      "files": [
        "components/ds/header-brand.tsx"
      ],
      "props": [
        {
          "name": "href",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "logo",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "logoSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "logoAlt",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/HeaderBrand",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ title: \"LEMA\", subtitle: \"UFPB\", logo: <BoxIcon /> },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ title: \"LEMA\", subtitle: \"UFPB\", logo: <BoxIcon /> },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s) => (\n        <HeaderBrand\n          key={s}\n          title=\"LEMA\"\n          subtitle=\"UFPB\"\n          size={s}\n          logo={<BoxIcon />}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s) => (\n        <HeaderBrand\n          key={s}\n          title=\"LEMA\"\n          subtitle=\"UFPB\"\n          size={s}\n          logo={<BoxIcon />}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "WithLogoSrc",
          "description": "",
          "args": "{\n    title: \"LEMA\",\n    logoSrc: \"https://picsum.photos/80/80\",\n    logoAlt: \"LEMA logo\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ title: \"LEMA\", subtitle: \"Subtitle\", loading: true },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s) => (\n        <HeaderBrand\n          key={s}\n          title=\"LEMA\"\n          subtitle=\"Subtitle\"\n          size={s}\n          loading\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s) => (\n        <HeaderBrand\n          key={s}\n          title=\"LEMA\"\n          subtitle=\"Subtitle\"\n          size={s}\n          loading\n        />\n      ))}\n    </div>"
        },
        {
          "name": "LongTitle",
          "description": "",
          "args": "{\n    title: \"Laboratório de Engenharia e Mídias Avançadas da UFPB\",\n    subtitle: \"Universidade Federal da Paraíba\",\n    logo: <BoxIcon />,\n  },\n  render: (args) => (\n    <div className=\"max-w-[260px] border p-4\">\n      <HeaderBrand {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-header-centered",
      "title": "Header Centered",
      "description": "Header com brand centralizado e nav abaixo, com split actions laterais.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/header-centered",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-header",
        "ds-header-brand",
        "ds-header-nav",
        "ds-header-actions",
        "ds-header-mobile-drawer"
      ],
      "files": [
        "components/ds/header-centered.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": true,
          "type": "HeaderBrandProps"
        },
        {
          "name": "navItems",
          "required": false,
          "type": "HeaderNavItem[]"
        },
        {
          "name": "leftActions",
          "required": false,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "rightActions",
          "required": false,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "sticky",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/HeaderCentered",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    rightActions: [{ label: \"Cart (0)\", variant: \"outline\" as const }],\n  },"
        },
        {
          "name": "WithSplitActions",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    leftActions: [{ label: \"Search\", variant: \"ghost\" as const }],\n    rightActions: [\n      { label: \"Sign in\", variant: \"ghost\" as const },\n      { label: \"Cart\", variant: \"default\" as const },\n    ],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ brand, navItems: nav, loading: true }"
        }
      ]
    },
    {
      "name": "ds-header-command",
      "title": "Header Command",
      "description": "Header SaaS com command palette (⌘K), busca global, user menu e notificações.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/header-command",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "ds-header",
        "ds-header-brand",
        "ds-header-nav",
        "ds-header-actions",
        "ds-header-mobile-drawer",
        "ds-header-user-menu",
        "command",
        "kbd"
      ],
      "files": [
        "components/ds/header-command.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": true,
          "type": "HeaderBrandProps"
        },
        {
          "name": "navItems",
          "required": false,
          "type": "HeaderNavItem[]"
        },
        {
          "name": "commandGroups",
          "required": false,
          "type": "HeaderCommandGroup[]"
        },
        {
          "name": "searchPlaceholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "onSearch",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "user",
          "required": false,
          "type": "HeaderUserData | null"
        },
        {
          "name": "userGroups",
          "required": false,
          "type": "HeaderUserMenuItem[][]"
        },
        {
          "name": "notifications",
          "required": false,
          "type": "number"
        },
        {
          "name": "actions",
          "required": false,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "sticky",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/HeaderCommand",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    searchPlaceholder: \"Search or jump to...\",\n    commandGroups: [\n      {\n        heading: \"Suggestions\",\n        items: [\n          {\n            label: \"Create project\",\n            icon: <FileTextIcon className=\"size-4\" />,\n          },\n          { label: \"Invite team\", icon: <UsersIcon className=\"size-4\" /> },\n        ],\n      },\n      {\n        heading: \"Settings\",\n        items: [\n          { label: \"Preferences\", icon: <SettingsIcon className=\"size-4\" /> },\n        ],\n      },\n    ],\n    user: { name: \"Alex Silva\", email: \"alex@ufpb.br\" },\n    notifications: 3,\n    actions: [{ label: \"New\", variant: \"default\" as const }],\n  },"
        },
        {
          "name": "WithoutUser",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    commandGroups: [{ heading: \"Quick\", items: [{ label: \"Go to docs\" }] }],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    loading: true,\n    user: { name: \"Alex\", email: \"alex@ufpb.br\" },\n  },"
        }
      ]
    },
    {
      "name": "ds-header-mega",
      "title": "Header Mega",
      "description": "Mega dropdown com grid de links e feature card — e-commerce / docs.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/header-mega",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "ds-header",
        "ds-header-brand",
        "ds-header-nav",
        "ds-header-actions",
        "ds-header-mobile-drawer"
      ],
      "files": [
        "components/ds/header-mega.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": true,
          "type": "HeaderBrandProps"
        },
        {
          "name": "navItems",
          "required": true,
          "type": "HeaderNavItem[]"
        },
        {
          "name": "actions",
          "required": false,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "feature",
          "required": false,
          "type": "HeaderMegaFeature"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "sticky",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/HeaderMega",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    actions: [{ label: \"Book demo\", variant: \"default\" as const }],\n    feature: {\n      title: \"New: AI Analytics\",\n      description:\n        \"Ask questions in natural language and get instant visualizations.\",\n      imageSrc: \"https://picsum.photos/400/200\",\n      ctaLabel: \"Learn more\",\n      href: \"#\",\n    },\n  },"
        },
        {
          "name": "WithoutFeature",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    actions: [{ label: \"Sign in\", variant: \"ghost\" as const }],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ brand, navItems: nav, loading: true }"
        }
      ]
    },
    {
      "name": "ds-header-mobile-drawer",
      "title": "Header Mobile Drawer",
      "description": "Sheet lateral para navegação mobile com accordion, brand header e footer de CTAs.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header-mobile-drawer",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "sheet",
        "collapsible",
        "button",
        "separator",
        "ui-i18n"
      ],
      "files": [
        "components/ds/header-mobile-drawer.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "HeaderNavItem[]"
        },
        {
          "name": "actions",
          "required": false,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "brand",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "open",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onOpenChange",
          "required": false,
          "type": "(open: boolean) => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "side",
          "required": false,
          "type": "\"left\" | \"right\""
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "onNavigate",
          "required": false,
          "type": "(item: HeaderNavItem) => void"
        }
      ],
      "storyTitle": "Header/HeaderMobileDrawer",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    items,\n    actions: [\n      { label: \"Log in\", variant: \"ghost\" },\n      { label: \"Get started\", variant: \"default\" },\n    ],\n    brand: <HeaderBrand title=\"LEMA\" logo={<BoxIcon />} />,\n  },"
        },
        {
          "name": "WithBrandAndActions",
          "description": "",
          "args": "{\n    items,\n    brand: (\n      <HeaderBrand\n        title=\"LEMA UFPB\"\n        subtitle=\"Design System\"\n        logo={<BoxIcon />}\n      />\n    ),\n    actions: [{ label: \"Contact sales\", variant: \"outline\" }],\n  },"
        }
      ]
    },
    {
      "name": "ds-header-nav",
      "title": "Header Nav",
      "description": "Navegação horizontal baseada em NavigationMenu com suporte a dropdown, mega custom content, badge e estados active.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header-nav",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "navigation-menu",
        "skeleton"
      ],
      "files": [
        "components/ds/header-nav.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "HeaderNavItem[]"
        },
        {
          "name": "onNavigate",
          "required": false,
          "type": "(item: HeaderNavItem) => void"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "ariaLabel",
          "required": false,
          "type": "string",
          "description": "Accessible label for nav"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/HeaderNav",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items: baseItems }"
        },
        {
          "name": "ActiveState",
          "description": "",
          "args": "{ items: baseItems.map((i, idx) => ({ ...i, active: idx === 2 })) },"
        },
        {
          "name": "WithMegaContent",
          "description": "",
          "args": "{\n    items: [\n      { label: \"Home\", href: \"#\" },\n      {\n        label: \"Features\",\n        href: \"#\",\n        content: (\n          <div className=\"grid grid-cols-2 gap-2 p-2\">\n            <div className=\"rounded-lg bg-muted p-4 text-sm\">\n              Custom mega content\n            </div>\n            <div className=\"rounded-lg bg-muted p-4 text-sm\">Promo card</div>\n          </div>\n        ),\n      },\n    ],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ items: baseItems, loading: true }"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ items: baseItems },\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s) => (\n        <div key={s} className=\"flex flex-col gap-2\">\n          <span className=\"text-xs text-muted-foreground\">{s}</span>\n          <HeaderNav items={baseItems} size={s} />\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-6\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s) => (\n        <div key={s} className=\"flex flex-col gap-2\">\n          <span className=\"text-xs text-muted-foreground\">{s}</span>\n          <HeaderNav items={baseItems} size={s} />\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-header-search",
      "title": "Header Search",
      "description": "An expandable search button for use in page headers with smooth transition animations.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header-search",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "button",
        "input",
        "ui-i18n"
      ],
      "files": [
        "components/ds/header-search.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "string"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "onSearch",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "autoFocus",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "rounded",
          "required": false,
          "type": "\"full\" | \"md\" | \"none\""
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "isExpanded",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "storyTitle": "Header/HeaderSearch",
      "stories": [
        {
          "name": "Default",
          "description": "Compact search bar in collapsed state with full rounded corners.",
          "args": "{\n    placeholder: \"Search indicators...\",\n    rounded: \"full\",\n    locale: \"en-US\",\n    autoFocus: true,\n  },\n  render: (args) => (\n    <div className=\"flex h-20 w-full items-center justify-end rounded-lg border bg-card px-8\">\n      <HeaderSearch {...args} />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Compact search bar in collapsed state with full rounded corners.\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization — placeholder text translated.",
          "args": "{\n    placeholder: \"Search indicators...\",\n    rounded: \"full\",\n    locale: \"pt-BR\",\n  },\n  render: (args) => (\n    <div className=\"flex h-20 w-full items-center justify-end rounded-lg border bg-card px-8\">\n      <HeaderSearch {...args} />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story: \"Portuguese (pt-BR) localization — placeholder text translated.\",\n      },\n    },\n  },"
        },
        {
          "name": "Square",
          "description": "Search bar with square corners (rounded='none') and always-expanded state.",
          "args": "{\n    rounded: \"none\",\n    placeholder: \"Square search...\",\n    isExpanded: true,\n  },\n  render: (args) => (\n    <div className=\"flex h-20 w-full items-center justify-end rounded-lg border bg-card px-8\">\n      <HeaderSearch {...args} />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Search bar with square corners (rounded='none') and always-expanded state.\",\n      },\n    },\n  },"
        },
        {
          "name": "Expanded",
          "description": "Search bar pre-expanded with a custom placeholder.",
          "args": "{\n    isExpanded: true,\n    placeholder: \"Type something...\",\n  },\n  render: (args) => (\n    <div className=\"flex h-20 w-full items-center justify-end rounded-lg border bg-card px-8\">\n      <HeaderSearch {...args} />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story: \"Search bar pre-expanded with a custom placeholder.\",\n      },\n    },\n  },"
        },
        {
          "name": "InHeaderMock",
          "description": "Search bar rendered inside a mock header layout with navigation links.",
          "code": "<header className=\"flex h-16 w-full items-center justify-between border-b bg-background px-6\">\n      <div className=\"flex items-center gap-4\">\n        <div className=\"size-8 rounded bg-primary\" />\n        <span className=\"font-bold\">Lema DS</span>\n      </div>\n      <nav className=\"hidden gap-6 text-sm font-medium text-muted-foreground md:flex\">\n        <a href=\"#\" className=\"hover:text-foreground\">\n          Home\n        </a>\n        <a href=\"#\" className=\"hover:text-foreground\">\n          Analytics\n        </a>\n        <a href=\"#\" className=\"hover:text-foreground\">\n          Reports\n        </a>\n      </nav>\n      <div className=\"flex items-center gap-2\">\n        <HeaderSearch onSearch={(v) => alert(`Searching for: ${v}`)} />\n      </div>\n    </header>"
        }
      ]
    },
    {
      "name": "ds-header-simple",
      "title": "Header Simple",
      "description": "Bloco minimal SaaS: brand + nav desktop + search + actions + mobile drawer.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/header-simple",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "ds-header",
        "ds-header-brand",
        "ds-header-nav",
        "ds-header-actions",
        "ds-header-mobile-drawer",
        "ds-header-search"
      ],
      "files": [
        "components/ds/header-simple.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": true,
          "type": "HeaderBrandProps"
        },
        {
          "name": "navItems",
          "required": false,
          "type": "HeaderNavItem[]"
        },
        {
          "name": "actions",
          "required": false,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "showSearch",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onSearch",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "searchPlaceholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "sticky",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/HeaderSimple",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ brand, navItems, actions, size: \"md\" }"
        },
        {
          "name": "WithSearch",
          "description": "",
          "args": "{\n    brand,\n    navItems,\n    actions,\n    showSearch: true,\n    searchPlaceholder: \"Search docs...\",\n    size: \"md\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ brand, navItems, actions },\n  parameters: { a11y: { disable: true } },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s, idx) => (\n        <div key={s}>\n          <HeaderSimple\n            brand={brand}\n            navItems={navItems}\n            actions={actions}\n            size={s}\n            role={idx === 0 ? \"banner\" : \"region\"}\n            aria-label={idx === 0 ? undefined : `HeaderSimple size ${s}`}\n          />\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((s, idx) => (\n        <div key={s}>\n          <HeaderSimple\n            brand={brand}\n            navItems={navItems}\n            actions={actions}\n            size={s}\n            role={idx === 0 ? \"banner\" : \"region\"}\n            aria-label={idx === 0 ? undefined : `HeaderSimple size ${s}`}\n          />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ brand, navItems, actions, loading: true },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{ brand, navItems, actions },\n  parameters: { a11y: { disable: true } },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((l, idx) => (\n        <div key={l}>\n          <HeaderSimple\n            brand={brand}\n            navItems={navItems}\n            actions={actions}\n            locale={l}\n            role={idx === 0 ? \"banner\" : \"region\"}\n            aria-label={idx === 0 ? undefined : `HeaderSimple locale ${l}`}\n          />\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((l, idx) => (\n        <div key={l}>\n          <HeaderSimple\n            brand={brand}\n            navItems={navItems}\n            actions={actions}\n            locale={l}\n            role={idx === 0 ? \"banner\" : \"region\"}\n            aria-label={idx === 0 ? undefined : `HeaderSimple locale ${l}`}\n          />\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-header-topbar",
      "title": "Header Topbar",
      "description": "Barra utilitária acima do header com email, telefone, socials e locale selector.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header-topbar",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-social-links",
        "separator"
      ],
      "files": [
        "components/ds/header-topbar.tsx"
      ],
      "props": [
        {
          "name": "email",
          "required": false,
          "type": "string"
        },
        {
          "name": "phone",
          "required": false,
          "type": "string"
        },
        {
          "name": "announcement",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "socials",
          "required": false,
          "type": "SocialLinkItem[]"
        },
        {
          "name": "localeSelector",
          "required": false,
          "type": "React.ReactNode"
        }
      ],
      "storyTitle": "Header/HeaderTopbar",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    email: \"hello@ufpb.br\",\n    phone: \"+55 83 3216-7200\",\n    socials: [\n      { platform: \"github\", href: \"https://github.com\" },\n      { platform: \"x\", href: \"https://x.com\" },\n      { platform: \"linkedin\", href: \"https://linkedin.com\" },\n    ],\n  },"
        },
        {
          "name": "WithAnnouncement",
          "description": "",
          "args": "{\n    email: \"hello@ufpb.br\",\n    phone: \"+55 83 3216-7200\",\n    announcement: \"Free shipping on orders over R$ 200\",\n    socials: [{ platform: \"github\", href: \"https://github.com\" }],\n  },"
        },
        {
          "name": "Empty",
          "description": "",
          "args": "{}"
        }
      ]
    },
    {
      "name": "ds-header-transparent",
      "title": "Header Transparent",
      "description": "Header overlay hero que vira blurred ao scroll com threshold configurável.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/header-transparent",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-header",
        "ds-header-brand",
        "ds-header-nav",
        "ds-header-actions",
        "ds-header-mobile-drawer"
      ],
      "files": [
        "components/ds/header-transparent.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": true,
          "type": "HeaderBrandProps"
        },
        {
          "name": "navItems",
          "required": false,
          "type": "HeaderNavItem[]"
        },
        {
          "name": "actions",
          "required": false,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "threshold",
          "required": false,
          "type": "number"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        },
        {
          "name": "sticky",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Header/HeaderTransparent",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    actions: [{ label: \"Get started\", variant: \"default\" as const }],\n  },\n  decorators: [\n    (Story) => (\n      <div>\n        <div className=\"relative bg-slate-900\">\n          <Story />\n          <div className=\"flex h-80 items-center justify-center p-8 text-center\">\n            <div className=\"max-w-lg\">\n              <h1 className=\"text-3xl font-bold text-white\">\n                Hero overlay — header is transparent\n              </h1>\n              <p className=\"mt-2 text-white/70\">\n                Scroll down to see it turn blurred with shadow.\n              </p>\n            </div>\n          </div>\n        </div>\n        <div className=\"h-[800px] bg-muted/30 p-8 text-sm text-muted-foreground\">\n          Scroll content — header becomes blurred after {`8px`}\n        </div>\n      </div>\n    ),\n  ],"
        },
        {
          "name": "InHero",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    threshold: 0,\n    actions: [{ label: \"Sign in\", variant: \"ghost\" as const }],\n  },\n  decorators: [\n    (Story) => (\n      <div className=\"bg-gradient-to-br from-violet-600 to-indigo-800\">\n        <Story />\n        <div className=\"h-64\" />\n      </div>\n    ),\n  ],"
        }
      ]
    },
    {
      "name": "ds-header-user-menu",
      "title": "Header User Menu",
      "description": "Avatar com DropdownMenu, badge de notificações e grupos de ações para header.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/header-user-menu",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "avatar",
        "dropdown-menu",
        "button",
        "skeleton"
      ],
      "files": [
        "components/ds/header-user-menu.tsx"
      ],
      "props": [
        {
          "name": "user",
          "required": true,
          "type": "HeaderUserData | null"
        },
        {
          "name": "groups",
          "required": false,
          "type": "HeaderUserMenuItem[][]"
        },
        {
          "name": "notifications",
          "required": false,
          "type": "number"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Header/HeaderUserMenu",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    user,\n    groups: [\n      [\n        {\n          id: \"profile\",\n          label: \"Profile\",\n          icon: <UserIcon className=\"size-4\" />,\n        },\n        {\n          id: \"settings\",\n          label: \"Settings\",\n          icon: <SettingsIcon className=\"size-4\" />,\n        },\n      ],\n      [\n        {\n          id: \"logout\",\n          label: \"Log out\",\n          icon: <LogOutIcon className=\"size-4\" />,\n          variant: \"destructive\",\n        },\n      ],\n    ],\n  },"
        },
        {
          "name": "WithNotifications",
          "description": "",
          "args": "{ user, notifications: 3 }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ user, loading: true }"
        },
        {
          "name": "WithoutAvatar",
          "description": "",
          "args": "{ user: { name: \"Maria Santos\", email: \"maria@ufpb.br\" } },"
        }
      ]
    },
    {
      "name": "ds-header-with-topbar",
      "title": "Header With Topbar",
      "description": "HeaderSimple empilhado com Topbar e Announcement — padrão blockus com contato/social.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/header-with-topbar",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ds-header-topbar",
        "ds-header-announcement",
        "ds-header-simple"
      ],
      "files": [
        "components/ds/header-with-topbar.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": true,
          "type": "HeaderBrandProps"
        },
        {
          "name": "navItems",
          "required": false,
          "type": "HeaderNavItem[]"
        },
        {
          "name": "actions",
          "required": false,
          "type": "HeaderActionItem[]"
        },
        {
          "name": "email",
          "required": false,
          "type": "string"
        },
        {
          "name": "phone",
          "required": false,
          "type": "string"
        },
        {
          "name": "socials",
          "required": false,
          "type": "SocialLinkItem[]"
        },
        {
          "name": "localeSelector",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "topbarAnnouncement",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "announcement",
          "required": false,
          "type": "{ children: React.ReactNode href?: string tag?: string dismissible?: boolean onDismiss?: () => void variant?: \"default\" | \"outline\" | \"glow\" }"
        },
        {
          "name": "showSearch",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onSearch",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "searchPlaceholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"blurred\" | \"transparent\" | \"solid\""
        },
        {
          "name": "sticky",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Header/HeaderWithTopbar",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    actions: [{ label: \"Contact\", variant: \"default\" as const }],\n    email: \"hello@ufpb.br\",\n    phone: \"+55 83 3216-7200\",\n    socials: [{ platform: \"github\", href: \"https://github.com\" }],\n    topbarAnnouncement: \"Free shipping over R$ 200\",\n  },"
        },
        {
          "name": "WithAnnouncementDismissible",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    actions: [{ label: \"Get started\", variant: \"default\" as const }],\n    email: \"hello@ufpb.br\",\n    announcement: {\n      children: \"v2.0 is live — check the new header blocks\",\n      tag: \"New\",\n      href: \"#\",\n    },\n  },"
        },
        {
          "name": "WithoutTopbar",
          "description": "",
          "args": "{\n    brand,\n    navItems: nav,\n    actions: [{ label: \"Sign in\", variant: \"ghost\" as const }],\n  },"
        }
      ]
    },
    {
      "name": "ds-heatmap-chart",
      "title": "Heatmap Chart",
      "description": "A responsive heatmap chart built with pure CSS grid and color-mix for smooth color interpolation.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/heatmap-chart",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/heatmap-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "HeatmapCell[]"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "palette",
          "required": false,
          "type": "HeatmapPalette",
          "description": "Preset color palette for the gradient scale"
        },
        {
          "name": "colorFrom",
          "required": false,
          "type": "string",
          "description": "Low-end color for custom palette — any CSS color"
        },
        {
          "name": "colorTo",
          "required": false,
          "type": "string",
          "description": "High-end color for custom palette — any CSS color"
        },
        {
          "name": "showValues",
          "required": false,
          "type": "boolean",
          "description": "Display the numeric value inside each cell"
        },
        {
          "name": "showScale",
          "required": false,
          "type": "boolean",
          "description": "Show a gradient legend bar below the heatmap"
        },
        {
          "name": "cellSize",
          "required": false,
          "type": "number",
          "description": "Fixed cell width in px; auto-sizes when omitted"
        },
        {
          "name": "cellHeight",
          "required": false,
          "type": "number",
          "description": "Fixed cell height in px — defaults to `cellSize` when set, or `32` for fluid-width cells"
        },
        {
          "name": "gap",
          "required": false,
          "type": "number",
          "description": "Gap between cells in px"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Format cell values in tooltips and inside cells"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "min",
          "required": false,
          "type": "number",
          "description": "Override the computed min (floor of the color scale)"
        },
        {
          "name": "max",
          "required": false,
          "type": "number",
          "description": "Override the computed max (ceiling of the color scale)"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/HeatmapChart",
      "stories": [
        {
          "name": "Default",
          "description": "Default blue-palette heatmap showing average grades across five subjects and four class groups with a color scale legend.",
          "args": "{\n    title: \"Average Grade by Subject & Class Group\",\n    subtitle: \"Flat cells (default) — hover a cell for details\",\n    data: subjectVsClass,\n    palette: \"blue\",\n    showValues: false,\n    showScale: true,\n    gap: 3,\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n  },"
        },
        {
          "name": "WithValues",
          "description": "Heatmap with numeric grade values printed inside each cell for precise comparison across subjects and class groups.",
          "args": "{\n    title: \"Average Grade by Subject & Class Group\",\n    subtitle: \"Values printed inside each cell\",\n    data: subjectVsClass,\n    palette: \"blue\",\n    showValues: true,\n    showScale: true,\n  },"
        },
        {
          "name": "AbsenceRate",
          "description": "Red-palette heatmap showing rising absence rates across subjects from February to June with percentage values and a warning tone.",
          "args": "{\n    title: \"Absence Rate by Subject & Month\",\n    subtitle: \"Darker red = higher absence — a warning signal\",\n    data: absenceByMonth,\n    palette: \"red\",\n    showValues: true,\n    showScale: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "CorrelationMatrix",
          "description": "Purple-palette correlation matrix displaying Pearson r values for five academic indicators with a 0–1 range and fixed cell size.",
          "args": "{\n    title: \"Indicator Correlation Matrix\",\n    subtitle: \"Pearson r — values closer to 1 indicate stronger co-movement\",\n    data: corrMatrix,\n    palette: \"purple\",\n    showValues: true,\n    showScale: true,\n    min: 0,\n    max: 1,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 2 }),\n    cellSize: 56,\n  },"
        },
        {
          "name": "EngagementByDayAndHour",
          "description": "Green-palette heatmap showing platform login density across days of the week and hourly time blocks with a login count formatter.",
          "args": "{\n    title: \"Platform Logins — Day × Hour\",\n    subtitle: \"Weekly aggregate · darker = more active sessions\",\n    data: engagementData,\n    palette: \"green\",\n    showValues: false,\n    showScale: true,\n    valueFormatter: (v) => formatValue(v, \"integer\") + \" logins\",\n  },"
        },
        {
          "name": "CustomPalette",
          "description": "Heatmap using `palette=\"custom\"` with `colorFrom` and `colorTo` set to `var(--card)` and `var(--destructive)` for full control.",
          "args": "{\n    title: \"Average Grade — Custom Palette\",\n    subtitle: 'palette=\"custom\" · colorFrom / colorTo as CSS values',\n    data: subjectVsClass,\n    palette: \"custom\",\n    colorFrom: \"var(--card)\",\n    colorTo: \"var(--destructive)\",\n    showValues: true,\n    showScale: true,\n  },"
        },
        {
          "name": "Palettes",
          "description": "Grid of five heatmaps displaying all built-in color palettes (blue, green, orange, purple, red) side by side for comparison.",
          "args": "{ data: subjectVsClass },",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {([\"blue\", \"green\", \"orange\", \"purple\", \"red\"] as const).map((p) => (\n        <HeatmapChart\n          key={p}\n          title={`palette=\"${p}\"`}\n          data={subjectVsClass.slice(0, 8)}\n          palette={p}\n          showScale\n          cellSize={36}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "SmallCells",
          "description": "Compact heatmap with `cellSize=28` and reduced gap for a dense day-by-hour engagement density visualization.",
          "args": "{\n    title: \"Platform Logins — Compact View\",\n    subtitle: \"cellSize=28 · week × hour density map\",\n    data: engagementData,\n    palette: \"blue\",\n    showScale: true,\n    cellSize: 28,\n    gap: 2,\n  },"
        },
        {
          "name": "FlatCells",
          "description": "The default behavior: cells auto-fill the available width at a fixed `32px` height. Pass `cellHeight` to override — smaller for dense grids, larger for readability.",
          "args": "{\n    title: \"Absence Rate — Custom Cell Height\",\n    subtitle: \"cellHeight=48 · taller cells for better readability\",\n    data: absenceByMonth,\n    palette: \"red\",\n    showValues: true,\n    showScale: true,\n    cellHeight: 48,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Heatmap with Portuguese locale displaying average grade data with localized number formatting.",
          "args": "{\n    title: \"Average Grade by Subject & Class Group\",\n    subtitle: \"Semester 2025.1 — hover over cells for details\",\n    data: subjectVsClass,\n    palette: \"blue\",\n    showScale: true,\n    showValues: false,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the heatmap with an animated skeleton that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Average Grade by Subject & Class\",\n    subtitle: \"Semester 2025.1\",\n    data: subjectVsClass,\n    palette: \"blue\",\n    showValues: true,\n    showScale: true,\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the heatmap renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Average Grade by Subject & Class\",\n    subtitle: \"Semester 2025.1\",\n    data: [],\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Orange-palette heatmap showing absence rate trends with a custom footer highlighting the upward trend and best-performing subject.",
          "args": "{\n    title: \"Absence Rate — Semester 2025.1\",\n    subtitle: \"Month-over-month trend per subject\",\n    data: absenceByMonth,\n    palette: \"orange\",\n    showValues: true,\n    showScale: true,\n    valueFormatter: (v) => `${v}%`,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingDown className=\"size-3.5 text-destructive\" />\n          Absence climbs from Feb to Jun across all subjects\n        </span>\n        <span className=\"flex items-center gap-1.5 text-muted-foreground/70\">\n          <TrendingUp className=\"size-3.5 text-success\" />\n          Portuguese best-performing — under 13%\n        </span>\n      </div>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-hero-announcement",
      "title": "HeroAnnouncement",
      "description": "Hero centralizado com badge de anúncio e mural de logos em marquee — composto de ds-hero-section, ds-announcement-badge e ds-marquee.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-announcement",
      "dependencies": [],
      "registryDependencies": [
        "ds-hero-section",
        "ds-announcement-badge",
        "ds-marquee"
      ],
      "files": [
        "components/ds/hero-announcement.tsx"
      ],
      "props": [
        {
          "name": "announcement",
          "required": false,
          "type": "HeroAnnouncementItem"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "logos",
          "required": false,
          "type": "React.ReactNode[]",
          "description": "Logos rendered inside a Marquee below the actions."
        },
        {
          "name": "logosLabel",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Hero/HeroAnnouncement",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "WithoutLogos",
          "description": "",
          "args": "{ logos: [] },"
        }
      ]
    },
    {
      "name": "ds-hero-bento",
      "title": "HeroBento",
      "description": "Hero centralizado seguido de um grid bento — composto de ds-hero-section e ds-bento-grid.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-bento",
      "dependencies": [],
      "registryDependencies": [
        "ds-hero-section",
        "ds-bento-grid",
        "badge"
      ],
      "files": [
        "components/ds/hero-bento.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode",
          "description": "A `BentoGrid` (with its `BentoGridItem`s) rendered below the copy."
        }
      ],
      "storyTitle": "Hero/HeroBento",
      "stories": []
    },
    {
      "name": "ds-hero-cycling",
      "title": "HeroCycling",
      "description": "Hero centralizado com título que alterna palavras — composto de ds-hero-section e ds-text-rotator.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-cycling",
      "dependencies": [],
      "registryDependencies": [
        "badge",
        "ds-hero-section",
        "ds-text-rotator"
      ],
      "files": [
        "components/ds/hero-cycling.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "titlePrefix",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "titleSuffix",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "words",
          "required": true,
          "type": "string[]"
        },
        {
          "name": "rotatorInterval",
          "required": false,
          "type": "number"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        }
      ],
      "storyTitle": "Hero/HeroCycling",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "FastRotation",
          "description": "",
          "args": "{ rotatorInterval: 1200 },"
        }
      ]
    },
    {
      "name": "ds-hero-glow",
      "title": "Hero Glow",
      "description": "Hero com glow radial superior e grid sutil — inspirado em Launch UI Hero Top Glow.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-glow",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "badge",
        "skeleton"
      ],
      "files": [
        "components/ds/hero-glow.tsx"
      ],
      "props": [
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "glowColor",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "glow",
          "required": false,
          "type": "\"top\" | \"center\" | \"none\"",
          "options": [
            "top",
            "center",
            "none"
          ],
          "default": "top"
        }
      ],
      "stories": [
        {
          "name": "Top",
          "description": "",
          "args": "{ glow: \"top\" },\n  render: (args) => (\n    <HeroGlow\n      {...args}\n      actions={\n        <>\n          <Button className=\"rounded-full\">Get Started</Button>\n          <Button variant=\"outline\" className=\"rounded-full\">\n            GitHub\n          </Button>\n        </>\n      }\n    />\n  ),"
        },
        {
          "name": "Center",
          "description": "",
          "args": "{ glow: \"center\" },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        }
      ]
    },
    {
      "name": "ds-hero-layers",
      "title": "Hero Layers",
      "description": "Hero com screenshots em camadas sobrepostas (Layers) — inspirado em Launch UI Hero Layers.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-layers",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "badge",
        "skeleton"
      ],
      "files": [
        "components/ds/hero-layers.tsx"
      ],
      "props": [
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "layers",
          "required": false,
          "type": "HeroLayersItem[]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "inset",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},\n  render: (args) => (\n    <HeroLayers\n      {...args}\n      actions={\n        <>\n          <Button className=\"rounded-full\">Get Started</Button>\n          <Button variant=\"outline\" className=\"rounded-full\">\n            GitHub\n          </Button>\n        </>\n      }\n    />\n  ),"
        },
        {
          "name": "Inset",
          "description": "",
          "args": "{ inset: true },\n  render: (args) => (\n    <div className=\"bg-muted/30 p-6\">\n      <HeroLayers\n        {...args}\n        actions={<Button className=\"rounded-full\">Get Started</Button>}\n      />\n    </div>\n  ),"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        }
      ]
    },
    {
      "name": "ds-hero-section",
      "title": "HeroSection",
      "description": "Shell de layout de seção Hero composível em subcomponentes atômicos com alinhamentos center, left e split.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/hero-section",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/hero-section.tsx"
      ],
      "props": [
        {
          "name": "align",
          "required": false,
          "type": "\"center\" | \"left\" | \"split\"",
          "options": [
            "center",
            "left",
            "split"
          ],
          "default": "center"
        },
        {
          "name": "spacing",
          "required": false,
          "type": "\"compact\" | \"default\" | \"spacious\"",
          "options": [
            "compact",
            "default",
            "spacious"
          ],
          "default": "default"
        },
        {
          "name": "container",
          "required": false,
          "type": "\"default\" | \"narrow\" | \"wide\" | \"full\"",
          "options": [
            "default",
            "narrow",
            "wide",
            "full"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"default\" | \"large\" | \"display\"",
          "options": [
            "default",
            "large",
            "display"
          ],
          "default": "default"
        },
        {
          "name": "gradient",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "storyTitle": "Hero/HeroSection",
      "stories": [
        {
          "name": "CompleteCenteredHero",
          "description": "",
          "code": "<HeroSection align=\"center\" spacing=\"default\">\n      <BackgroundGlow variant=\"aurora\" tone=\"primary\" />\n\n      <HeroHeader>\n        <AnnouncementBadge tag=\"Novo\" ping variant=\"glow\">\n          LEMA Design System v2.0 disponível\n        </AnnouncementBadge>\n      </HeroHeader>\n\n      <HeroTitle size=\"large\" gradient>\n        Construa interfaces{\" \"}\n        <TextRotator\n          words={[\"elegantes\", \"acessíveis\", \"rápidas\", \"consistentes\"]}\n        />\n        <br />\n        para produtos digitais acadêmicos\n      </HeroTitle>\n\n      <HeroDescription size=\"large\">\n        O ecossistema definitivo de componentes React 19, Tailwind CSS v4 e\n        shadcn/ui padronizado pela Universidade Federal da Paraíba.\n      </HeroDescription>\n\n      <HeroActions align=\"center\">\n        <WaitlistForm\n          variant=\"pill\"\n          size=\"md\"\n          socialProof=\"Mais de 50 componentes prontos para produção.\"\n        />\n      </HeroActions>\n\n      <HeroMedia>\n        <BrowserMockup url=\"https://lema.ufpb.br/design-system\" glow>\n          <div className=\"flex h-72 flex-col items-center justify-center bg-card/60 p-8 text-center\">\n            <p className=\"text-lg font-semibold\">Preview da Aplicação</p>\n            <p className=\"mt-2 max-w-md text-xs text-muted-foreground\">\n              Moldura de alta fidelidade para demonstrar telas de sistemas\n              administrativos, dashboards de pesquisa e portais institucionais.\n            </p>\n          </div>\n        </BrowserMockup>\n      </HeroMedia>\n    </HeroSection>"
        },
        {
          "name": "SplitHeroWithVideo",
          "description": "",
          "code": "<HeroSection align=\"split\" spacing=\"spacious\">\n      <BackgroundGlow variant=\"spotlight\" tone=\"violet\" />\n\n      <div className=\"flex flex-col gap-6\">\n        <HeroHeader className=\"justify-start\">\n          <AnnouncementBadge tag=\"Demo\" variant=\"outline\">\n            Vídeo de demonstração interativa\n          </AnnouncementBadge>\n        </HeroHeader>\n\n        <HeroTitle size=\"default\">\n          Governança e design unificados para squads modernas\n        </HeroTitle>\n\n        <HeroDescription>\n          Elimine retrabalho entre design e engenharia com especificações\n          spec-first, testes automatizados de acessibilidade e documentação\n          interativa no Storybook.\n        </HeroDescription>\n\n        <HeroActions align=\"left\">\n          <Button size=\"lg\">Começar Agora</Button>\n          <Button variant=\"outline\" size=\"lg\">\n            Ver Documentação\n          </Button>\n        </HeroActions>\n      </div>\n\n      <HeroMedia>\n        <VideoDialog\n          title=\"Visão Geral do LEMA-DS\"\n          thumbnailSrc=\"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=1200&auto=format&fit=crop&q=80\"\n          videoSrc=\"https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ\"\n          variant=\"glow\"\n        />\n      </HeroMedia>\n    </HeroSection>"
        },
        {
          "name": "WithSocialProofMarquee",
          "description": "",
          "code": "<HeroSection align=\"center\" spacing=\"default\">\n      <BackgroundGlow variant=\"grid-dots\" />\n\n      <HeroTitle size=\"default\" gradient>\n        A tecnologia que move a inovação na UFPB\n      </HeroTitle>\n\n      <HeroDescription>\n        Utilizado por mais de 20 laboratórios e projetos estratégicos de\n        tecnologia e pesquisa.\n      </HeroDescription>\n\n      <div className=\"w-full pt-8\">\n        <Marquee speed=\"slow\" pauseOnHover>\n          {[\"LEMA\", \"CI UFPB\", \"STI\", \"PRPG\", \"CCEN\", \"CCS\", \"CE\"].map(\n            (item) => (\n              <div\n                key={item}\n                className=\"rounded-lg border border-border/50 bg-muted/40 px-6 py-2.5 text-xs font-semibold text-muted-foreground\"\n              >\n                {item}\n              </div>\n            )\n          )}\n        </Marquee>\n      </div>\n    </HeroSection>"
        }
      ]
    },
    {
      "name": "ds-hero-stats",
      "title": "HeroStats",
      "description": "Hero centralizado seguido de tira de estatísticas — composto de ds-hero-section e ds-card-stat.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-stats",
      "dependencies": [],
      "registryDependencies": [
        "badge",
        "ds-hero-section",
        "ds-card-stat"
      ],
      "files": [
        "components/ds/hero-stats.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "stats",
          "required": true,
          "type": "HeroStatsItem[]"
        }
      ],
      "storyTitle": "Hero/HeroStats",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "ThreeStats",
          "description": "",
          "args": "{ stats: stats.slice(0, 3) },"
        }
      ]
    },
    {
      "name": "ds-hero-terminal",
      "title": "HeroTerminal",
      "description": "Hero split com preview de terminal/navegador — composto de ds-hero-section, ds-background-glow e ds-browser-mockup.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-terminal",
      "dependencies": [],
      "registryDependencies": [
        "badge",
        "ds-hero-section",
        "ds-background-glow",
        "ds-browser-mockup"
      ],
      "files": [
        "components/ds/hero-terminal.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "browserUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "browserVariant",
          "required": false,
          "type": "BrowserMockupProps[\"variant\"]"
        },
        {
          "name": "glowTone",
          "required": false,
          "type": "BackgroundGlowProps[\"tone\"]"
        }
      ],
      "storyTitle": "Hero/HeroTerminal",
      "stories": [
        {
          "name": "VioletGlow",
          "description": "",
          "args": "{ glowTone: \"violet\", browserVariant: \"default\" },\n  render: (args) => (\n    <HeroTerminal {...args}>\n      <div className=\"flex h-64 items-center justify-center p-6 text-sm text-muted-foreground\">\n        Preview content\n      </div>\n    </HeroTerminal>\n  ),"
        }
      ]
    },
    {
      "name": "ds-hero-video",
      "title": "HeroVideo",
      "description": "Hero centralizado com thumbnail de vídeo em diálogo — composto de ds-hero-section e ds-video-dialog.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-video",
      "dependencies": [],
      "registryDependencies": [
        "badge",
        "ds-hero-section",
        "ds-video-dialog"
      ],
      "files": [
        "components/ds/hero-video.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "videoSrc",
          "required": true,
          "type": "string"
        },
        {
          "name": "thumbnailSrc",
          "required": true,
          "type": "string"
        },
        {
          "name": "videoTitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Hero/HeroVideo",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "WithoutActions",
          "description": "",
          "args": "{ actions: undefined },"
        }
      ]
    },
    {
      "name": "ds-hero-waitlist",
      "title": "HeroWaitlist",
      "description": "Hero centralizado com captura de e-mail — composto de ds-hero-section e ds-waitlist-form.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/hero-waitlist",
      "dependencies": [],
      "registryDependencies": [
        "badge",
        "ds-hero-section",
        "ds-waitlist-form"
      ],
      "files": [
        "components/ds/hero-waitlist.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "socialProof",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "onSubmit",
          "required": false,
          "type": "WaitlistFormProps[\"onSubmit\"]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Hero/HeroWaitlist",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "WithoutSocialProof",
          "description": "",
          "args": "{ socialProof: undefined },"
        }
      ]
    },
    {
      "name": "ds-how-it-works",
      "title": "How It Works",
      "description": "Seção explicativa em passos numerados com variante horizontal/vertical.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/how-it-works",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/how-it-works.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "steps",
          "required": true,
          "type": "HowItWorksStep[]"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"number\" | \"icon\" | \"card\""
        },
        {
          "name": "orientation",
          "required": false,
          "type": "\"horizontal\" | \"vertical\""
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Marketing/HowItWorks",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    steps,\n    title: \"How it works\",\n    description: \"Three simple steps to get started.\",\n  },"
        },
        {
          "name": "WithIcons",
          "description": "",
          "args": "{ steps, variant: \"icon\" }"
        },
        {
          "name": "Vertical",
          "description": "",
          "args": "{ steps, orientation: \"vertical\" }"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ steps },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      <HowItWorks steps={steps} size=\"sm\" title=\"Small\" />\n      <HowItWorks steps={steps} size=\"md\" title=\"Medium\" />\n      <HowItWorks steps={steps} size=\"lg\" title=\"Large\" />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      <HowItWorks steps={steps} size=\"sm\" title=\"Small\" />\n      <HowItWorks steps={steps} size=\"md\" title=\"Medium\" />\n      <HowItWorks steps={steps} size=\"lg\" title=\"Large\" />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ steps, loading: true }"
        }
      ]
    },
    {
      "name": "ds-how-it-works-timeline",
      "title": "How It Works Timeline",
      "description": "Timeline vertical com linha conectora — blockus #03 #10 #17.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/how-it-works-timeline",
      "dependencies": [],
      "registryDependencies": [
        "ds-how-it-works"
      ],
      "files": [
        "components/ds/how-it-works-timeline.tsx"
      ],
      "storyTitle": "Marketing/HowItWorksTimeline",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ steps }"
        },
        {
          "name": "WithIcons",
          "description": "",
          "args": "{\n    steps: steps.map((s, i) => ({ ...s, icon: <span>{i + 1}</span> })),\n    variant: \"icon\",\n  },"
        }
      ]
    },
    {
      "name": "ds-icon-button",
      "title": "Icon Button",
      "description": "An icon-only button with optional tooltip, loading state, size and rounded variants built on the Button and Tooltip primitives.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/icon-button",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "button",
        "tooltip"
      ],
      "files": [
        "components/ds/icon-button.tsx"
      ],
      "props": [
        {
          "name": "icon",
          "required": true,
          "type": "React.ReactNode",
          "description": "The icon to display. Typically a lucide icon."
        },
        {
          "name": "label",
          "required": true,
          "type": "string",
          "description": "Accessible label. Used as aria-label and default tooltip text."
        },
        {
          "name": "tooltip",
          "required": false,
          "type": "string | false",
          "description": "Tooltip text. Defaults to `label`. Pass `false` to disable the tooltip."
        },
        {
          "name": "tooltipSide",
          "required": false,
          "type": "\"top\" | \"right\" | \"bottom\" | \"left\"",
          "description": "Side the tooltip appears on. @default \"bottom\""
        },
        {
          "name": "variant",
          "required": false,
          "type": "IconButtonVariant",
          "description": "Visual variant. @default \"ghost\""
        },
        {
          "name": "size",
          "required": false,
          "type": "IconButtonSize",
          "description": "Button size. @default \"icon\""
        },
        {
          "name": "rounded",
          "required": false,
          "type": "IconButtonRounded",
          "description": "Border radius. @default \"md\""
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Shows a spinner and disables interaction."
        }
      ],
      "storyTitle": "Actions/IconButton",
      "stories": [
        {
          "name": "Default",
          "description": "Default IconButton with a Bell icon and ghost variant.",
          "args": "{\n    icon: <Bell />,\n    label: \"Notifications\",\n    tooltipSide: \"bottom\",\n    variant: \"ghost\",\n    size: \"icon\",\n    rounded: \"md\",\n    loading: false,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Default IconButton with a Bell icon and ghost variant.\",\n      },\n    },\n  },"
        },
        {
          "name": "Playground",
          "description": "Interactive playground with all control knobs exposed for experimentation.",
          "args": "{\n    icon: <Settings />,\n    label: \"Settings\",\n    variant: \"ghost\",\n    size: \"icon\",\n    rounded: \"md\",\n    tooltipSide: \"bottom\",\n    loading: false,\n    disabled: false,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Interactive playground with all control knobs exposed for experimentation.\",\n      },\n    },\n  },"
        },
        {
          "name": "Variants",
          "description": "All Button variants applied to IconButton.",
          "args": "{ icon: <Star />, label: \"Variant\" },\n  parameters: {\n    docs: {\n      description: {\n        story: \"All Button variants applied to IconButton.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-wrap items-center gap-3\">\n      <IconButton icon={<Star />} label=\"Default\" variant=\"default\" />\n      <IconButton icon={<Star />} label=\"Outline\" variant=\"outline\" />\n      <IconButton icon={<Star />} label=\"Secondary\" variant=\"secondary\" />\n      <IconButton icon={<Star />} label=\"Ghost\" variant=\"ghost\" />\n      <IconButton icon={<Trash2 />} label=\"Destructive\" variant=\"destructive\" />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-wrap items-center gap-3\">\n      <IconButton icon={<Star />} label=\"Default\" variant=\"default\" />\n      <IconButton icon={<Star />} label=\"Outline\" variant=\"outline\" />\n      <IconButton icon={<Star />} label=\"Secondary\" variant=\"secondary\" />\n      <IconButton icon={<Star />} label=\"Ghost\" variant=\"ghost\" />\n      <IconButton icon={<Trash2 />} label=\"Destructive\" variant=\"destructive\" />\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "Four icon sizes — icon-xs to icon-lg.",
          "args": "{ icon: <Search />, label: \"Size showcase\" },\n  parameters: {\n    docs: {\n      description: { story: \"Four icon sizes — icon-xs to icon-lg.\" },\n    },\n  },\n  render: () => (\n    <div className=\"flex items-end gap-3\">\n      <div className=\"flex flex-col items-center gap-2\">\n        <IconButton\n          icon={<Search />}\n          label=\"Search\"\n          size=\"icon-xs\"\n          variant=\"outline\"\n        />\n        <span className=\"text-xs text-muted-foreground\">xs · 24px</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <IconButton\n          icon={<Search />}\n          label=\"Search\"\n          size=\"icon-sm\"\n          variant=\"outline\"\n        />\n        <span className=\"text-xs text-muted-foreground\">sm · 32px</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <IconButton\n          icon={<Search />}\n          label=\"Search\"\n          size=\"icon\"\n          variant=\"outline\"\n        />\n        <span className=\"text-xs text-muted-foreground\">icon · 36px</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <IconButton\n          icon={<Search />}\n          label=\"Search\"\n          size=\"icon-lg\"\n          variant=\"outline\"\n        />\n        <span className=\"text-xs text-muted-foreground\">lg · 40px</span>\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex items-end gap-3\">\n      <div className=\"flex flex-col items-center gap-2\">\n        <IconButton\n          icon={<Search />}\n          label=\"Search\"\n          size=\"icon-xs\"\n          variant=\"outline\"\n        />\n        <span className=\"text-xs text-muted-foreground\">xs · 24px</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <IconButton\n          icon={<Search />}\n          label=\"Search\"\n          size=\"icon-sm\"\n          variant=\"outline\"\n        />\n        <span className=\"text-xs text-muted-foreground\">sm · 32px</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <IconButton\n          icon={<Search />}\n          label=\"Search\"\n          size=\"icon\"\n          variant=\"outline\"\n        />\n        <span className=\"text-xs text-muted-foreground\">icon · 36px</span>\n      </div>\n      <div className=\"flex flex-col items-center gap-2\">\n        <IconButton\n          icon={<Search />}\n          label=\"Search\"\n          size=\"icon-lg\"\n          variant=\"outline\"\n        />\n        <span className=\"text-xs text-muted-foreground\">lg · 40px</span>\n      </div>\n    </div>"
        },
        {
          "name": "Rounded",
          "description": "Three border radius options: `none` (square), `md` (default — inherited from Button), `full` (circular).",
          "args": "{ icon: <Star />, label: \"Rounded showcase\" },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Three border radius options: `none` (square), `md` (default — inherited from Button), `full` (circular).\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex items-end gap-8\">\n      {([\"none\", \"md\", \"full\"] as const).map((r) => (\n        <div key={r} className=\"flex flex-col items-center gap-3\">\n          <div className=\"flex items-center gap-2\">\n            <IconButton\n              icon={<Star />}\n              label={r}\n              rounded={r}\n              variant=\"outline\"\n              size=\"icon-sm\"\n            />\n            <IconButton\n              icon={<Star />}\n              label={r}\n              rounded={r}\n              variant=\"secondary\"\n              size=\"icon\"\n            />\n            <IconButton\n              icon={<Star />}\n              label={r}\n              rounded={r}\n              variant=\"default\"\n              size=\"icon-lg\"\n            />\n          </div>\n          <span className=\"font-mono text-xs text-muted-foreground\">{r}</span>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex items-end gap-8\">\n      {([\"none\", \"md\", \"full\"] as const).map((r) => (\n        <div key={r} className=\"flex flex-col items-center gap-3\">\n          <div className=\"flex items-center gap-2\">\n            <IconButton\n              icon={<Star />}\n              label={r}\n              rounded={r}\n              variant=\"outline\"\n              size=\"icon-sm\"\n            />\n            <IconButton\n              icon={<Star />}\n              label={r}\n              rounded={r}\n              variant=\"secondary\"\n              size=\"icon\"\n            />\n            <IconButton\n              icon={<Star />}\n              label={r}\n              rounded={r}\n              variant=\"default\"\n              size=\"icon-lg\"\n            />\n          </div>\n          <span className=\"font-mono text-xs text-muted-foreground\">{r}</span>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "TooltipSides",
          "description": "Tooltip can appear on any side.",
          "args": "{ icon: <Upload />, label: \"Tooltip sides\" },\n  parameters: {\n    layout: \"centered\",\n    docs: {\n      description: { story: \"Tooltip can appear on any side.\" },\n    },\n  },\n  render: () => (\n    <div className=\"grid grid-cols-3 place-items-center gap-4 p-8\">\n      <div />\n      <IconButton\n        icon={<Upload />}\n        label=\"Top\"\n        tooltipSide=\"top\"\n        variant=\"outline\"\n      />\n      <div />\n      <IconButton\n        icon={<Upload />}\n        label=\"Left\"\n        tooltipSide=\"left\"\n        variant=\"outline\"\n      />\n      <IconButton\n        icon={<Upload />}\n        label=\"Center\"\n        tooltip={false}\n        variant=\"secondary\"\n      />\n      <IconButton\n        icon={<Upload />}\n        label=\"Right\"\n        tooltipSide=\"right\"\n        variant=\"outline\"\n      />\n      <div />\n      <IconButton\n        icon={<Upload />}\n        label=\"Bottom\"\n        tooltipSide=\"bottom\"\n        variant=\"outline\"\n      />\n      <div />\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-3 place-items-center gap-4 p-8\">\n      <div />\n      <IconButton\n        icon={<Upload />}\n        label=\"Top\"\n        tooltipSide=\"top\"\n        variant=\"outline\"\n      />\n      <div />\n      <IconButton\n        icon={<Upload />}\n        label=\"Left\"\n        tooltipSide=\"left\"\n        variant=\"outline\"\n      />\n      <IconButton\n        icon={<Upload />}\n        label=\"Center\"\n        tooltip={false}\n        variant=\"secondary\"\n      />\n      <IconButton\n        icon={<Upload />}\n        label=\"Right\"\n        tooltipSide=\"right\"\n        variant=\"outline\"\n      />\n      <div />\n      <IconButton\n        icon={<Upload />}\n        label=\"Bottom\"\n        tooltipSide=\"bottom\"\n        variant=\"outline\"\n      />\n      <div />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "Loading state replaces the icon with a spinner and disables the button.",
          "args": "{ icon: <Download />, label: \"Loading\" },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading state replaces the icon with a spinner and disables the button.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex items-center gap-3\">\n      <IconButton\n        icon={<Download />}\n        label=\"Download\"\n        loading\n        variant=\"outline\"\n      />\n      <IconButton\n        icon={<RefreshCw />}\n        label=\"Refresh\"\n        loading\n        variant=\"secondary\"\n      />\n      <IconButton icon={<Upload />} label=\"Upload\" loading />\n    </div>\n  ),",
          "code": "<div className=\"flex items-center gap-3\">\n      <IconButton\n        icon={<Download />}\n        label=\"Download\"\n        loading\n        variant=\"outline\"\n      />\n      <IconButton\n        icon={<RefreshCw />}\n        label=\"Refresh\"\n        loading\n        variant=\"secondary\"\n      />\n      <IconButton icon={<Upload />} label=\"Upload\" loading />\n    </div>"
        },
        {
          "name": "States",
          "description": "Comparison between idle, loading, and disabled states.",
          "args": "{ icon: <Bookmark />, label: \"Save\" },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Comparison between idle, loading, and disabled states.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex items-center gap-6\">\n      {([\"Idle\", \"Loading\", \"Disabled\"] as const).map((state) => (\n        <div key={state} className=\"flex flex-col items-center gap-2\">\n          <IconButton\n            icon={<Bookmark />}\n            label=\"Save\"\n            variant=\"outline\"\n            loading={state === \"Loading\"}\n            disabled={state === \"Disabled\"}\n          />\n          <span className=\"text-xs text-muted-foreground\">{state}</span>\n        </div>\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"flex items-center gap-6\">\n      {([\"Idle\", \"Loading\", \"Disabled\"] as const).map((state) => (\n        <div key={state} className=\"flex flex-col items-center gap-2\">\n          <IconButton\n            icon={<Bookmark />}\n            label=\"Save\"\n            variant=\"outline\"\n            loading={state === \"Loading\"}\n            disabled={state === \"Disabled\"}\n          />\n          <span className=\"text-xs text-muted-foreground\">{state}</span>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "NoTooltip",
          "description": "`tooltip={false}` removes the tooltip but preserves the `aria-label`.",
          "args": "{\n    icon: <X />,\n    label: \"Close\",\n    tooltip: false,\n    variant: \"ghost\",\n  },"
        },
        {
          "name": "ToolbarExample",
          "description": "Real-world example: rich text editor toolbar with action groups.",
          "args": "{ icon: <Edit />, label: \"Toolbar\" },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Real-world example: rich text editor toolbar with action groups.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"inline-flex items-center gap-0.5 rounded-xl border border-border bg-background p-1 shadow-sm\">\n      <IconButton icon={<Edit />} label=\"Edit\" size=\"icon-sm\" />\n      <IconButton icon={<Copy />} label=\"Copy\" size=\"icon-sm\" />\n      <IconButton icon={<Link />} label=\"Copy link\" size=\"icon-sm\" />\n\n      <div className=\"mx-1 h-5 w-px bg-border\" />\n\n      <IconButton icon={<MessageSquare />} label=\"Comment\" size=\"icon-sm\" />\n      <IconButton icon={<Heart />} label=\"Like\" size=\"icon-sm\" />\n      <IconButton icon={<Bookmark />} label=\"Save\" size=\"icon-sm\" />\n\n      <div className=\"mx-1 h-5 w-px bg-border\" />\n\n      <IconButton icon={<Share2 />} label=\"Share\" size=\"icon-sm\" />\n      <IconButton\n        icon={<Trash2 />}\n        label=\"Delete\"\n        size=\"icon-sm\"\n        variant=\"destructive\"\n      />\n      <IconButton\n        icon={<EllipsisVertical />}\n        label=\"More options\"\n        size=\"icon-sm\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"inline-flex items-center gap-0.5 rounded-xl border border-border bg-background p-1 shadow-sm\">\n      <IconButton icon={<Edit />} label=\"Edit\" size=\"icon-sm\" />\n      <IconButton icon={<Copy />} label=\"Copy\" size=\"icon-sm\" />\n      <IconButton icon={<Link />} label=\"Copy link\" size=\"icon-sm\" />\n\n      <div className=\"mx-1 h-5 w-px bg-border\" />\n\n      <IconButton icon={<MessageSquare />} label=\"Comment\" size=\"icon-sm\" />\n      <IconButton icon={<Heart />} label=\"Like\" size=\"icon-sm\" />\n      <IconButton icon={<Bookmark />} label=\"Save\" size=\"icon-sm\" />\n\n      <div className=\"mx-1 h-5 w-px bg-border\" />\n\n      <IconButton icon={<Share2 />} label=\"Share\" size=\"icon-sm\" />\n      <IconButton\n        icon={<Trash2 />}\n        label=\"Delete\"\n        size=\"icon-sm\"\n        variant=\"destructive\"\n      />\n      <IconButton\n        icon={<EllipsisVertical />}\n        label=\"More options\"\n        size=\"icon-sm\"\n      />\n    </div>"
        },
        {
          "name": "CardActions",
          "description": "Common pattern: inline actions in cards or list items.",
          "args": "{ icon: <Pencil />, label: \"Edit\" },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Common pattern: inline actions in cards or list items.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex w-80 flex-col gap-2\">\n      {[\"Design System v2\", \"Component Library\", \"Storybook Setup\"].map(\n        (name) => (\n          <div\n            key={name}\n            className=\"flex items-center justify-between rounded-lg border border-border bg-card px-4 py-3\"\n          >\n            <span className=\"text-sm font-medium\">{name}</span>\n            <div className=\"flex items-center gap-0.5\">\n              <IconButton\n                icon={<Pencil />}\n                label={`Edit ${name}`}\n                size=\"icon-sm\"\n                tooltip=\"Edit\"\n              />\n              <IconButton\n                icon={<Star />}\n                label={`Star ${name}`}\n                size=\"icon-sm\"\n                tooltip=\"Star\"\n              />\n              <IconButton\n                icon={<Trash2 />}\n                label={`Delete ${name}`}\n                size=\"icon-sm\"\n                tooltip=\"Delete\"\n                variant=\"destructive\"\n              />\n            </div>\n          </div>\n        )\n      )}\n    </div>\n  ),",
          "code": "<div className=\"flex w-80 flex-col gap-2\">\n      {[\"Design System v2\", \"Component Library\", \"Storybook Setup\"].map(\n        (name) => (\n          <div\n            key={name}\n            className=\"flex items-center justify-between rounded-lg border border-border bg-card px-4 py-3\"\n          >\n            <span className=\"text-sm font-medium\">{name}</span>\n            <div className=\"flex items-center gap-0.5\">\n              <IconButton\n                icon={<Pencil />}\n                label={`Edit ${name}`}\n                size=\"icon-sm\"\n                tooltip=\"Edit\"\n              />\n              <IconButton\n                icon={<Star />}\n                label={`Star ${name}`}\n                size=\"icon-sm\"\n                tooltip=\"Star\"\n              />\n              <IconButton\n                icon={<Trash2 />}\n                label={`Delete ${name}`}\n                size=\"icon-sm\"\n                tooltip=\"Delete\"\n                variant=\"destructive\"\n              />\n            </div>\n          </div>\n        )\n      )}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-image-crop",
      "title": "Image Crop",
      "description": "Crop com drag e zoom slider — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/image-crop",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "button",
        "slider"
      ],
      "files": [
        "components/ds/image-crop.tsx"
      ],
      "props": [
        {
          "name": "src",
          "required": true,
          "type": "string"
        },
        {
          "name": "alt",
          "required": false,
          "type": "string"
        },
        {
          "name": "zoom",
          "required": false,
          "type": "number"
        },
        {
          "name": "onZoomChange",
          "required": false,
          "type": "(zoom: number) => void"
        },
        {
          "name": "onCrop",
          "required": false,
          "type": "(data: { x: number; y: number; zoom: number }) => void"
        }
      ],
      "storyTitle": "Media/ImageCrop",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ src: \"https://picsum.photos/600/400\" }"
        }
      ]
    },
    {
      "name": "ds-image-gallery",
      "title": "ImageGallery",
      "description": "Galeria de imagens flexível — grid, masonry ou linha com scroll-snap — com legenda/overlay opcional por item.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/image-gallery",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton"
      ],
      "files": [
        "components/ds/image-gallery.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "ImageGalleryItem[]"
        },
        {
          "name": "aspect",
          "required": false,
          "type": "ImageGalleryAspect"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "skeletonCount",
          "required": false,
          "type": "number",
          "description": "Number of skeleton tiles shown while loading."
        },
        {
          "name": "layout",
          "required": false,
          "type": "\"grid\" | \"masonry\" | \"row\"",
          "options": [
            "grid",
            "masonry",
            "row"
          ],
          "default": "grid"
        },
        {
          "name": "columns",
          "required": false,
          "type": "\"2\" | \"3\" | \"4\"",
          "options": [
            "2",
            "3",
            "4"
          ]
        }
      ],
      "storyTitle": "Gallery/ImageGallery",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Masonry",
          "description": "",
          "args": "{ layout: \"masonry\", aspect: \"auto\" },"
        },
        {
          "name": "Row",
          "description": "",
          "args": "{ layout: \"row\", aspect: \"video\" },"
        },
        {
          "name": "WithCaptions",
          "description": "",
          "args": "{\n    items: items.map((item, index) => ({\n      ...item,\n      caption: `Caption for photo ${index + 1}`,\n    })),\n  },"
        },
        {
          "name": "FourColumns",
          "description": "",
          "args": "{ columns: 4 },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true, skeletonCount: 6 },"
        }
      ]
    },
    {
      "name": "ds-image-zoom",
      "title": "Image Zoom",
      "description": "Zoom hover lens — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/image-zoom",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/image-zoom.tsx"
      ],
      "props": [
        {
          "name": "src",
          "required": true,
          "type": "string"
        },
        {
          "name": "alt",
          "required": true,
          "type": "string",
          "description": "Accessible description — required; falls back to UI_I18N[locale].imageZoom.alt when empty"
        },
        {
          "name": "zoom",
          "required": false,
          "type": "number"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Media/ImageZoom",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ src: \"https://picsum.photos/600/400\", alt: \"Demo zoom image\" },"
        }
      ]
    },
    {
      "name": "ds-inline-edit",
      "title": "Inline Edit",
      "description": "Edição in-place com click-to-edit, estados de salvamento e validação inline.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/inline-edit",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "input",
        "button",
        "spinner",
        "ui-i18n"
      ],
      "files": [
        "components/ds/inline-edit.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "string",
          "description": "The current text value."
        },
        {
          "name": "onSave",
          "required": true,
          "type": "(newValue: string) => void | Promise<void>",
          "description": "Callback fired when value is confirmed/saved."
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string",
          "description": "Placeholder shown when the value is empty."
        },
        {
          "name": "validate",
          "required": false,
          "type": "(val: string) => string | undefined",
          "description": "Validation function returning an error string or undefined if valid."
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean",
          "description": "Whether editing is disabled."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for tooltips and button labels."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/InlineEdit",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    value: \"Modelo Econométrico v1\",\n    locale: \"pt-BR\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    const trigger = canvas.getByRole(\"button\")\n    await expect(trigger).toBeInTheDocument()\n    await userEvent.click(trigger)\n    const input = canvas.getByRole(\"textbox\")\n    await expect(input).toBeInTheDocument()\n  },"
        },
        {
          "name": "WithValidation",
          "description": "",
          "args": "{\n    value: \"Modelo Válido\",\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "AsyncSave",
          "description": "",
          "args": "{\n    value: \"Simulação Fiscal 2026\",\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    disabled: true,\n    value: \"Campo Bloqueado\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex w-80 flex-col gap-6\">\n      <div>\n        <span className=\"block pb-1 text-xs text-muted-foreground\">\n          Pequeno (sm):\n        </span>\n        <InlineEdit size=\"sm\" value=\"Parâmetro Alpha\" onSave={() => {}} />\n      </div>\n      <div>\n        <span className=\"block pb-1 text-xs text-muted-foreground\">\n          Médio (md):\n        </span>\n        <InlineEdit size=\"md\" value=\"Taxa de Inflação IPCA\" onSave={() => {}} />\n      </div>\n      <div>\n        <span className=\"block pb-1 text-xs text-muted-foreground\">\n          Grande (lg):\n        </span>\n        <InlineEdit\n          size=\"lg\"\n          value=\"Relatório Trimestral LEMA\"\n          onSave={() => {}}\n        />\n      </div>\n    </div>"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex w-80 flex-col gap-4\">\n      <InlineEdit locale=\"pt-BR\" value=\"Português\" onSave={() => {}} />\n      <InlineEdit locale=\"en-US\" value=\"English\" onSave={() => {}} />\n      <InlineEdit locale=\"es-ES\" value=\"Español\" onSave={() => {}} />\n      <InlineEdit locale=\"fr-FR\" value=\"Français\" onSave={() => {}} />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-input",
      "title": "Input UI",
      "description": "Extended input with icon prefix/suffix, clearable button, character counter with maxLength, loading spinner, i18n labels, and error state.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/input",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "input",
        "label",
        "ui-i18n"
      ],
      "files": [
        "components/ds/input.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "iconPlacement",
          "required": false,
          "type": "\"left\" | \"right\""
        },
        {
          "name": "clearable",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showCount",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "error",
          "required": false,
          "type": "string"
        },
        {
          "name": "label",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "rounded",
          "required": false,
          "type": "\"none\" | \"light\" | \"full\"",
          "options": [
            "none",
            "light",
            "full"
          ],
          "default": "light"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\"",
          "options": [
            "default",
            "muted"
          ],
          "default": "default"
        },
        {
          "name": "bordered",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "storyTitle": "Form/Input",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    placeholder: \"Type something…\",\n  },"
        },
        {
          "name": "WithIcon",
          "description": "",
          "args": "{\n    placeholder: \"Search…\",\n    icon: <SearchIcon />,\n    iconPlacement: \"left\",\n  },"
        },
        {
          "name": "IconRight",
          "description": "",
          "args": "{\n    placeholder: \"Email\",\n    icon: <MailIcon />,\n    iconPlacement: \"right\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <Input size=\"sm\" placeholder=\"Small (no icon)\" />\n      <Input size=\"md\" placeholder=\"Medium (no icon)\" />\n      <Input size=\"lg\" placeholder=\"Large (no icon)\" />\n    </div>"
        },
        {
          "name": "SizesWithIcon",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <Input size=\"sm\" placeholder=\"Small\" icon={<SearchIcon />} />\n      <Input size=\"md\" placeholder=\"Medium\" icon={<SearchIcon />} />\n      <Input size=\"lg\" placeholder=\"Large\" icon={<SearchIcon />} />\n    </div>"
        },
        {
          "name": "SizesComparison",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">\n          Without icon\n        </span>\n        <Input size=\"md\" placeholder=\"No icon — text flush left\" />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">\n          With left icon\n        </span>\n        <Input\n          size=\"md\"\n          placeholder=\"With icon — padded left\"\n          icon={<SearchIcon />}\n          iconPlacement=\"left\"\n        />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">\n          With right icon\n        </span>\n        <Input\n          size=\"md\"\n          placeholder=\"With icon — padded right\"\n          icon={<MailIcon />}\n          iconPlacement=\"right\"\n        />\n      </div>\n    </div>"
        },
        {
          "name": "RoundedVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">None</span>\n        <Input rounded=\"none\" placeholder=\"rounded-none\" />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">Light</span>\n        <Input rounded=\"light\" placeholder=\"rounded-lg\" />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">Full</span>\n        <Input rounded=\"full\" placeholder=\"rounded-full\" />\n      </div>\n    </div>"
        },
        {
          "name": "BorderedVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">\n          Bordered (default)\n        </span>\n        <Input placeholder=\"Visible border\" />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">\n          Borderless\n        </span>\n        <Input bordered={false} placeholder=\"No border\" />\n      </div>\n    </div>"
        },
        {
          "name": "WithError",
          "description": "",
          "args": "{\n    placeholder: \"Email\",\n    \"aria-label\": \"Email\",\n    error: \"Please enter a valid email address.\",\n    defaultValue: \"invalid\",\n  },"
        },
        {
          "name": "WithCharCount",
          "description": "",
          "args": "{\n    placeholder: \"Username\",\n    \"aria-label\": \"Username\",\n    maxLength: 20,\n    showCount: true,\n    defaultValue: \"myuser\",\n  },"
        },
        {
          "name": "Clearable",
          "description": "",
          "args": "{\n    placeholder: \"Type to see clear button…\",\n    clearable: true,\n    defaultValue: \"Some value\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    placeholder: \"Loading…\",\n    loading: true,\n  },"
        },
        {
          "name": "WithLabel",
          "description": "",
          "args": "{\n    label: \"Full name\",\n    placeholder: \"Enter your full name\",\n  },"
        },
        {
          "name": "WithAllFeatures",
          "description": "",
          "args": "{\n    label: \"Search users\",\n    placeholder: \"Search by name or email…\",\n    icon: <SearchIcon />,\n    clearable: true,\n    maxLength: 50,\n    showCount: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-input-email",
      "title": "Input Email",
      "description": "An email input field with a built-in mail icon and customizable size and radius variants.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/input-email",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "input"
      ],
      "files": [
        "components/ds/input-email.tsx"
      ],
      "storyTitle": "Form/EmailInput",
      "props": [
        {
          "name": "disabled",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "placeholder",
          "control": "text",
          "default": ""
        },
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "sm",
            "default",
            "lg"
          ],
          "default": "default"
        },
        {
          "name": "radius",
          "control": "inline-radio",
          "options": [
            "pill",
            "rounded",
            "square"
          ],
          "default": "pill"
        },
        {
          "name": "variant",
          "control": "inline-radio",
          "options": [
            "default",
            "white"
          ],
          "default": "default"
        },
        {
          "name": "defaultValue",
          "control": "text",
          "default": ""
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Default email input with pill border radius and a placeholder example.",
          "args": "{\n    placeholder: \"e.g., user@example.com\",\n    size: \"default\",\n    radius: \"pill\",\n    variant: \"default\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default email input with pill border radius and a placeholder example.\",\n      },\n    },\n  },"
        },
        {
          "name": "Small",
          "description": "Email input in small size with compact padding.",
          "args": "{\n    size: \"sm\",\n    placeholder: \"e.g., user@example.com\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Email input in small size with compact padding.\",\n      },\n    },\n  },"
        },
        {
          "name": "Large",
          "description": "Email input in large size with spacious padding.",
          "args": "{\n    size: \"lg\",\n    placeholder: \"e.g., user@example.com\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Email input in large size with spacious padding.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllSizes",
          "description": "Comparison of all three size presets — sm, default, and lg.",
          "code": "<div className=\"flex w-72 flex-col gap-3\">\n      <EmailInput size=\"sm\" placeholder=\"Small\" />\n      <EmailInput size=\"default\" placeholder=\"Default\" />\n      <EmailInput size=\"lg\" placeholder=\"Large\" />\n    </div>"
        },
        {
          "name": "AllRadius",
          "description": "Comparison of all three border radius presets — pill, rounded, and square.",
          "code": "<div className=\"flex w-72 flex-col gap-3\">\n      <EmailInput radius=\"pill\" placeholder=\"Pill\" />\n      <EmailInput radius=\"rounded\" placeholder=\"Rounded\" />\n      <EmailInput radius=\"square\" placeholder=\"Square\" />\n    </div>"
        },
        {
          "name": "Variants",
          "description": "Comparison of default and white background variants.",
          "code": "<div className=\"flex w-72 flex-col gap-3\">\n      <EmailInput variant=\"default\" placeholder=\"Default\" />\n      <EmailInput variant=\"white\" placeholder=\"White\" />\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "Disabled state — input is non-interactive with muted background styling.",
          "args": "{\n    disabled: true,\n    placeholder: \"e.g., user@example.com\",\n    defaultValue: \"disabled.user@example.com\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Disabled state — input is non-interactive with muted background styling.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithValue",
          "description": "Email input pre-filled with a default email address.",
          "args": "{\n    defaultValue: \"support@lema.ufpb.br\",\n    \"aria-label\": \"Email address\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Email input pre-filled with a default email address.\",\n      },\n    },\n  },"
        },
        {
          "name": "Invalid",
          "description": "Invalid state with aria-invalid attribute triggering red border and focus ring styling.",
          "args": "{\n    \"aria-invalid\": true,\n    placeholder: \"e.g., user@example.com\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Invalid state with aria-invalid attribute triggering red border and focus ring styling.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-input-password",
      "title": "Input Password",
      "description": "A secure password input field with a toggle visibility button and custom size/radius options.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/input-password",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "input",
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/input-password.tsx"
      ],
      "storyTitle": "Form/PasswordInput",
      "props": [
        {
          "name": "disabled",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "placeholder",
          "control": "text",
          "default": ""
        },
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "sm",
            "default",
            "lg"
          ],
          "default": "default"
        },
        {
          "name": "radius",
          "control": "inline-radio",
          "options": [
            "pill",
            "rounded",
            "square"
          ],
          "default": "pill"
        },
        {
          "name": "variant",
          "control": "inline-radio",
          "options": [
            "default",
            "white"
          ],
          "default": "default"
        },
        {
          "name": "defaultValue",
          "control": "text",
          "default": ""
        },
        {
          "name": "locale",
          "control": "inline-radio",
          "options": [
            "en-US",
            "pt-BR",
            "es-ES",
            "fr-FR"
          ],
          "default": "en-US"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Default password input with pill border radius and a visibility toggle button.",
          "args": "{\n    placeholder: \"Enter your password...\",\n    size: \"default\",\n    radius: \"pill\",\n    variant: \"default\",\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default password input with pill border radius and a visibility toggle button.\",\n      },\n    },\n  },"
        },
        {
          "name": "Small",
          "description": "Password input in small size with compact padding.",
          "args": "{\n    size: \"sm\",\n    placeholder: \"Enter your password...\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Password input in small size with compact padding.\",\n      },\n    },\n  },"
        },
        {
          "name": "Large",
          "description": "Password input in large size with spacious padding.",
          "args": "{\n    size: \"lg\",\n    placeholder: \"Enter your password...\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Password input in large size with spacious padding.\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization — toggle button aria-label translated.",
          "args": "{\n    placeholder: \"Enter your password...\",\n    locale: \"pt-BR\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) localization — toggle button aria-label translated.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllSizes",
          "description": "Comparison of all three size presets — sm, default, and lg.",
          "code": "<div className=\"flex w-72 flex-col gap-3\">\n      <PasswordInput size=\"sm\" placeholder=\"Small\" />\n      <PasswordInput size=\"default\" placeholder=\"Default\" />\n      <PasswordInput size=\"lg\" placeholder=\"Large\" />\n    </div>"
        },
        {
          "name": "AllRadius",
          "description": "Comparison of all three border radius presets — pill, rounded, and square.",
          "code": "<div className=\"flex w-72 flex-col gap-3\">\n      <PasswordInput radius=\"pill\" placeholder=\"Pill\" />\n      <PasswordInput radius=\"rounded\" placeholder=\"Rounded\" />\n      <PasswordInput radius=\"square\" placeholder=\"Square\" />\n    </div>"
        },
        {
          "name": "Variants",
          "description": "Comparison of default and white background variants.",
          "code": "<div className=\"flex w-72 flex-col gap-3\">\n      <PasswordInput variant=\"default\" placeholder=\"Default\" />\n      <PasswordInput variant=\"white\" placeholder=\"White\" />\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "Disabled state — input is non-interactive with muted background styling.",
          "args": "{\n    disabled: true,\n    placeholder: \"Enter your password...\",\n    defaultValue: \"super_secret_password\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Disabled state — input is non-interactive with muted background styling.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithValue",
          "description": "Password input pre-filled with a default password value — initially hidden.",
          "args": "{\n    defaultValue: \"secret_password_123\",\n    \"aria-label\": \"Password\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Password input pre-filled with a default password value — initially hidden.\",\n      },\n    },\n  },"
        },
        {
          "name": "Invalid",
          "description": "Invalid state with aria-invalid attribute triggering red border and focus ring.",
          "args": "{\n    \"aria-invalid\": true,\n    placeholder: \"Enter your password...\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Invalid state with aria-invalid attribute triggering red border and focus ring.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-integration-tile",
      "title": "Integration Tile",
      "description": "Tile de integração com logo e status — átomo base integrations.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/integration-tile",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/integration-tile.tsx"
      ],
      "props": [
        {
          "name": "name",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "iconSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "iconAlt",
          "required": false,
          "type": "string"
        },
        {
          "name": "status",
          "required": false,
          "type": "\"connected\" | \"available\" | \"coming\""
        },
        {
          "name": "href",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Integrations/IntegrationTile",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    name: \"Slack\",\n    description: \"Team communication platform\",\n    icon: <BoxIcon />,\n    status: \"connected\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ name: \"Slack\" },\n  render: () => (\n    <div className=\"grid gap-4 md:grid-cols-3\">\n      <IntegrationTile\n        name=\"Slack\"\n        size=\"sm\"\n        description=\"Small\"\n        icon={<BoxIcon />}\n      />\n      <IntegrationTile\n        name=\"Slack\"\n        size=\"md\"\n        description=\"Medium\"\n        icon={<BoxIcon />}\n      />\n      <IntegrationTile\n        name=\"Slack\"\n        size=\"lg\"\n        description=\"Large\"\n        icon={<BoxIcon />}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid gap-4 md:grid-cols-3\">\n      <IntegrationTile\n        name=\"Slack\"\n        size=\"sm\"\n        description=\"Small\"\n        icon={<BoxIcon />}\n      />\n      <IntegrationTile\n        name=\"Slack\"\n        size=\"md\"\n        description=\"Medium\"\n        icon={<BoxIcon />}\n      />\n      <IntegrationTile\n        name=\"Slack\"\n        size=\"lg\"\n        description=\"Large\"\n        icon={<BoxIcon />}\n      />\n    </div>"
        },
        {
          "name": "Statuses",
          "description": "",
          "args": "{ name: \"App\" },\n  render: () => (\n    <div className=\"grid gap-4 md:grid-cols-3\">\n      <IntegrationTile\n        name=\"Slack\"\n        status=\"connected\"\n        description=\"Connected\"\n        icon={<BoxIcon />}\n      />\n      <IntegrationTile\n        name=\"Figma\"\n        status=\"available\"\n        description=\"Available\"\n        icon={<BoxIcon />}\n      />\n      <IntegrationTile\n        name=\"Notion\"\n        status=\"coming\"\n        description=\"Coming soon\"\n        icon={<BoxIcon />}\n      />\n    </div>\n  ),",
          "code": "<div className=\"grid gap-4 md:grid-cols-3\">\n      <IntegrationTile\n        name=\"Slack\"\n        status=\"connected\"\n        description=\"Connected\"\n        icon={<BoxIcon />}\n      />\n      <IntegrationTile\n        name=\"Figma\"\n        status=\"available\"\n        description=\"Available\"\n        icon={<BoxIcon />}\n      />\n      <IntegrationTile\n        name=\"Notion\"\n        status=\"coming\"\n        description=\"Coming soon\"\n        icon={<BoxIcon />}\n      />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ name: \"Loading\", loading: true }"
        }
      ]
    },
    {
      "name": "ds-integrations",
      "title": "Integrations",
      "description": "Grid de integrações com busca — blockus #01-12.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/integrations",
      "dependencies": [],
      "registryDependencies": [
        "ds-integration-tile",
        "input",
        "empty",
        "ui-i18n"
      ],
      "files": [
        "components/ds/integrations.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "integrations",
          "required": true,
          "type": "Integration[]"
        },
        {
          "name": "searchable",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "search",
          "required": false,
          "type": "string"
        },
        {
          "name": "onSearchChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "columns",
          "required": false,
          "type": "3 | 4"
        }
      ],
      "storyTitle": "Integrations/Integrations",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ integrations: tiles }"
        },
        {
          "name": "Searchable",
          "description": "",
          "args": "{ integrations: tiles, searchable: true },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ integrations: tiles, loading: true }"
        },
        {
          "name": "Empty",
          "description": "",
          "args": "{ integrations: [] }"
        }
      ]
    },
    {
      "name": "ds-integrations-marquee",
      "title": "Integrations Marquee",
      "description": "Parede de logos em marquee infinita — blockus #13-24.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/integrations-marquee",
      "dependencies": [],
      "registryDependencies": [
        "ds-integration-tile"
      ],
      "files": [
        "components/ds/integrations-marquee.tsx"
      ],
      "props": [
        {
          "name": "rows",
          "required": true,
          "type": "IntegrationTileProps[][]"
        },
        {
          "name": "speed",
          "required": false,
          "type": "\"slow\" | \"normal\" | \"fast\""
        },
        {
          "name": "pauseOnHover",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Integrations/IntegrationsMarquee",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ rows: [row, row.slice().reverse()] }"
        },
        {
          "name": "Speeds",
          "description": "",
          "args": "{ rows: [row] },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      <IntegrationsMarquee rows={[row]} speed=\"slow\" />\n      <IntegrationsMarquee rows={[row]} speed=\"normal\" />\n      <IntegrationsMarquee rows={[row]} speed=\"fast\" />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      <IntegrationsMarquee rows={[row]} speed=\"slow\" />\n      <IntegrationsMarquee rows={[row]} speed=\"normal\" />\n      <IntegrationsMarquee rows={[row]} speed=\"fast\" />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-kanban-board",
      "title": "Kanban Board",
      "description": "Kanban board com drag-and-drop real (@dnd-kit) — reordena e move cards entre colunas por ponteiro ou teclado.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/kanban-board",
      "dependencies": [
        "@dnd-kit/core",
        "@dnd-kit/sortable",
        "@dnd-kit/utilities"
      ],
      "registryDependencies": [
        "card",
        "badge",
        "scroll-area"
      ],
      "files": [
        "components/ds/kanban-board.tsx"
      ],
      "props": [
        {
          "name": "columns",
          "required": true,
          "type": "KanbanColumnData[]"
        },
        {
          "name": "onColumnsChange",
          "required": false,
          "type": "(columns: KanbanColumnData[]) => void"
        }
      ],
      "storyTitle": "Dashboard/KanbanBoard",
      "stories": []
    },
    {
      "name": "ds-keyboard-shortcut",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/keyboard-shortcut",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/keyboard-shortcut.tsx"
      ],
      "props": [
        {
          "name": "keys",
          "required": true,
          "type": "string[]",
          "description": "Array de teclas. Ex: [\"command\", \"k\"], [\"ctrl\", \"shift\", \"p\"]"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "sm"
        }
      ],
      "storyTitle": "Data Display/KeyboardShortcut",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    keys: [\"command\", \"k\"],\n  },"
        },
        {
          "name": "Sizes",
          "description": "",
          "args": "{\n    keys: [],\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      <div className=\"flex items-center gap-4\">\n        <span className=\"text-sm\">Small:</span>\n        <KeyboardShortcut keys={[\"ctrl\", \"shift\", \"p\"]} size=\"sm\" />\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <span className=\"text-sm\">Medium:</span>\n        <KeyboardShortcut keys={[\"command\", \"enter\"]} size=\"md\" />\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <span className=\"text-sm\">Large:</span>\n        <KeyboardShortcut keys={[\"option\", \"delete\"]} size=\"lg\" />\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div className=\"flex items-center gap-4\">\n        <span className=\"text-sm\">Small:</span>\n        <KeyboardShortcut keys={[\"ctrl\", \"shift\", \"p\"]} size=\"sm\" />\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <span className=\"text-sm\">Medium:</span>\n        <KeyboardShortcut keys={[\"command\", \"enter\"]} size=\"md\" />\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <span className=\"text-sm\">Large:</span>\n        <KeyboardShortcut keys={[\"option\", \"delete\"]} size=\"lg\" />\n      </div>\n    </div>"
        },
        {
          "name": "Navigation",
          "description": "",
          "args": "{\n    keys: [\"up\", \"down\", \"left\", \"right\"],\n    size: \"md\",\n  },"
        }
      ]
    },
    {
      "name": "ds-lightbox",
      "title": "Lightbox",
      "description": "Visualizador de imagem em tela cheia com navegação anterior/próxima, setas do teclado e tira de miniaturas.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/lightbox",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "dialog",
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/lightbox.tsx"
      ],
      "props": [
        {
          "name": "images",
          "required": true,
          "type": "LightboxImage[]"
        },
        {
          "name": "index",
          "required": true,
          "type": "number",
          "description": "Currently shown image index (controlled)."
        },
        {
          "name": "open",
          "required": true,
          "type": "boolean"
        },
        {
          "name": "onOpenChange",
          "required": true,
          "type": "(open: boolean) => void"
        },
        {
          "name": "onIndexChange",
          "required": true,
          "type": "(index: number) => void"
        },
        {
          "name": "showThumbnails",
          "required": false,
          "type": "boolean",
          "description": "Shows a strip of clickable thumbnails below the main image."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/Lightbox",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<>\n        <Button onClick={() => setOpen(true)}>Open lightbox</Button>\n        <Lightbox\n          images={images}\n          index={index}\n          open={open}\n          onOpenChange={setOpen}\n          onIndexChange={setIndex}\n        />\n      </>"
        },
        {
          "name": "SingleImage",
          "description": "",
          "code": "<>\n        <Button onClick={() => setOpen(true)}>Open single image</Button>\n        <Lightbox\n          images={[images[0]]}\n          index={0}\n          open={open}\n          onOpenChange={setOpen}\n          onIndexChange={() => {}}\n          showThumbnails={false}\n        />\n      </>"
        }
      ]
    },
    {
      "name": "ds-line-chart",
      "title": "Line Chart",
      "description": "A responsive line chart with plain lines, gradient area fills, stacked areas, reference lines, and brush zoom.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/line-chart",
      "dependencies": [
        "recharts",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils",
        "chart-axis-width"
      ],
      "files": [
        "components/ds/line-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "Record<string, string | number>[]"
        },
        {
          "name": "dataKeys",
          "required": true,
          "type": "LineChartKey[] | string[]",
          "description": "Keys to plot — accepts plain strings or { key, label, color, dashed } objects"
        },
        {
          "name": "categoryKey",
          "required": true,
          "type": "string",
          "description": "Object key mapped to the category (X) axis"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "variant",
          "required": false,
          "type": "LineChartVariant"
        },
        {
          "name": "curve",
          "required": false,
          "type": "LineCurve"
        },
        {
          "name": "dots",
          "required": false,
          "type": "LineDotVisibility",
          "description": "When to show data-point dots"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "showGrid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showLegend",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "legendPosition",
          "required": false,
          "type": "LegendPosition",
          "description": "@default \"bottom\""
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "connectNulls",
          "required": false,
          "type": "boolean",
          "description": "Bridge over null / undefined values instead of breaking the line"
        },
        {
          "name": "referenceLines",
          "required": false,
          "type": "LineChartReferenceLine[]",
          "description": "Horizontal threshold lines — targets, SLA limits, averages, etc."
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Format value-axis tick labels and tooltip values"
        },
        {
          "name": "showBrush",
          "required": false,
          "type": "boolean",
          "description": "Show a range brush below the chart to scroll and zoom the category axis.\nThe brush occupies ~30 px of the chart height, so increase `height`\naccordingly when enabling."
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "xAxisLabel",
          "required": false,
          "type": "string",
          "description": "Label centred on the horizontal (category/value) axis"
        },
        {
          "name": "yAxisLabel",
          "required": false,
          "type": "string",
          "description": "Label centred on the vertical (value/category) axis"
        }
      ],
      "storyTitle": "Data Display/LineChart",
      "stories": [
        {
          "name": "Default",
          "description": "Default smooth line chart showing weekly active user growth over 8 weeks with hover-activated dots.",
          "args": "{\n    title: \"Weekly Active Users\",\n    subtitle: \"Platform engagement over 8 weeks\",\n    data: weeklyActiveUsers,\n    dataKeys: [{ key: \"users\", label: \"Active Users\" }],\n    categoryKey: \"week\",\n    variant: \"line\",\n    curve: \"smooth\",\n    dots: \"hover\",\n    height: 280,\n    showGrid: true,\n    showLegend: false,\n    legendPosition: \"bottom\",\n    showTooltip: true,\n    connectNulls: false,\n    showBrush: false,\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n  },"
        },
        {
          "name": "Area",
          "description": "Line chart with a gradient area fill using `var(--chart-1)` for emphasizing the magnitude beneath the curve.",
          "args": "{\n    title: \"Weekly Active Users\",\n    subtitle: \"Gradient area fill using var(--chart-1)\",\n    data: weeklyActiveUsers,\n    dataKeys: [{ key: \"users\", label: \"Active Users\" }],\n    categoryKey: \"week\",\n    variant: \"area\",\n    curve: \"smooth\",\n    showGrid: true,\n    showTooltip: true,\n  },"
        },
        {
          "name": "WithAxisLabels",
          "description": "Pass `xAxisLabel` and `yAxisLabel` to render centred axis titles. The chart margins are automatically expanded to prevent clipping.",
          "args": "{\n    data: weeklyActiveUsers,\n    dataKeys: [{ key: \"users\", label: \"Active Users\" }],\n    categoryKey: \"week\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Pass `xAxisLabel` and `yAxisLabel` to render centred axis titles. The chart margins are automatically expanded to prevent clipping.\",\n      },\n    },\n  },\n  render: () => (\n    <LineChart\n      title=\"Weekly Active Users\"\n      subtitle=\"xAxisLabel + yAxisLabel\"\n      data={weeklyActiveUsers}\n      dataKeys={[{ key: \"users\", label: \"Active Users\" }]}\n      categoryKey=\"week\"\n      variant=\"line\"\n      curve=\"smooth\"\n      showGrid\n      showTooltip\n      xAxisLabel=\"Week\"\n      yAxisLabel=\"Number of Users\"\n      height={320}\n    />\n  ),",
          "code": "<LineChart\n      title=\"Weekly Active Users\"\n      subtitle=\"xAxisLabel + yAxisLabel\"\n      data={weeklyActiveUsers}\n      dataKeys={[{ key: \"users\", label: \"Active Users\" }]}\n      categoryKey=\"week\"\n      variant=\"line\"\n      curve=\"smooth\"\n      showGrid\n      showTooltip\n      xAxisLabel=\"Week\"\n      yAxisLabel=\"Number of Users\"\n      height={320}\n    />"
        },
        {
          "name": "AreaStacked",
          "description": "Stacked area chart comparing undergraduate, graduate, and distance learning enrollment trends with a legend.",
          "args": "{\n    title: \"Enrollment by Program\",\n    subtitle: \"Stacked area — total and breakdown per program type\",\n    data: enrollmentTrend,\n    dataKeys: [\n      { key: \"undergraduate\", label: \"Undergraduate\" },\n      { key: \"graduate\", label: \"Graduate\" },\n      { key: \"distance\", label: \"Distance Learning\" },\n    ],\n    categoryKey: \"month\",\n    variant: \"area-stacked\",\n    curve: \"smooth\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 300,\n  },"
        },
        {
          "name": "MultiSeries",
          "description": "Multi-series line chart comparing three enrollment program trends side by side with a legend for identification.",
          "args": "{\n    title: \"Enrollment Trends\",\n    subtitle: \"Three programs compared side-by-side\",\n    data: enrollmentTrend,\n    dataKeys: [\n      { key: \"undergraduate\", label: \"Undergraduate\" },\n      { key: \"graduate\", label: \"Graduate\" },\n      { key: \"distance\", label: \"Distance Learning\" },\n    ],\n    categoryKey: \"month\",\n    variant: \"line\",\n    curve: \"smooth\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 300,\n  },"
        },
        {
          "name": "WithReferenceLines",
          "description": "API response time line chart with P50, P95, and P99 latency series and dashed SLA threshold reference lines.",
          "args": "{\n    title: \"API Response Time\",\n    subtitle: \"P50 · P95 · P99 latency — with SLA thresholds\",\n    data: responseTime,\n    dataKeys: [\n      { key: \"p50\", label: \"P50 (median)\" },\n      { key: \"p95\", label: \"P95\" },\n      { key: \"p99\", label: \"P99\" },\n    ],\n    categoryKey: \"time\",\n    variant: \"line\",\n    curve: \"smooth\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    referenceLines: [\n      {\n        value: 200,\n        label: \"SLA target\",\n        color: \"var(--chart-2)\",\n        dashed: true,\n      },\n      {\n        value: 1000,\n        label: \"P99 limit\",\n        color: \"var(--destructive)\",\n        dashed: false,\n      },\n    ],\n    valueFormatter: (v) => formatValue(v, \"integer\") + \"ms\",\n    height: 320,\n  },"
        },
        {
          "name": "DashedForecast",
          "description": "Line chart combining a solid actual revenue line with a dashed forecast line and null-gap connection for missing data points.",
          "args": "{\n    title: \"Revenue vs. Forecast\",\n    subtitle: \"Solid line = actual · Dashed line = forecast\",\n    data: revenueVsForecast,\n    dataKeys: [\n      { key: \"actual\", label: \"Actual\", color: \"var(--chart-1)\" },\n      {\n        key: \"forecast\",\n        label: \"Forecast\",\n        color: \"var(--chart-2)\",\n        dashed: true,\n      },\n    ],\n    categoryKey: \"month\",\n    variant: \"line\",\n    curve: \"smooth\",\n    connectNulls: true,\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    valueFormatter: (v) =>\n      formatValue(v, \"currency\", {\n        currency: \"USD\",\n        abbreviate: true,\n        decimals: 0,\n      }),\n    height: 300,\n  },"
        },
        {
          "name": "StepCurve",
          "description": "Step-curve area chart showing the admission funnel from applied through enrolled with always-visible data points.",
          "args": "{\n    title: \"Admission Funnel\",\n    subtitle: \"Step curve — discrete stage transitions\",\n    data: stepData,\n    dataKeys: [{ key: \"count\", label: \"Candidates\", color: \"var(--chart-3)\" }],\n    categoryKey: \"stage\",\n    variant: \"area\",\n    curve: \"step\",\n    dots: \"always\",\n    showGrid: true,\n    showTooltip: true,\n    height: 260,\n  },"
        },
        {
          "name": "DotsAlways",
          "description": "Multi-series line chart with data points set to always visible for precise value reading across two programs.",
          "args": "{\n    title: \"Enrollment by Program\",\n    subtitle: \"Data points always visible\",\n    data: enrollmentTrend,\n    dataKeys: [\n      { key: \"undergraduate\", label: \"Undergraduate\" },\n      { key: \"graduate\", label: \"Graduate\" },\n    ],\n    categoryKey: \"month\",\n    variant: \"line\",\n    curve: \"smooth\",\n    dots: \"always\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 280,\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Area chart with a custom footer showing growth percentage and a scheduled maintenance dip annotation.",
          "args": "{\n    title: \"Weekly Active Users\",\n    subtitle: \"Last 8 weeks\",\n    data: weeklyActiveUsers,\n    dataKeys: [\n      { key: \"users\", label: \"Active Users\", color: \"var(--chart-2)\" },\n    ],\n    categoryKey: \"week\",\n    variant: \"area\",\n    curve: \"smooth\",\n    showGrid: true,\n    showTooltip: true,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-success\" />\n          <span>+81.7% growth since week 1</span>\n        </span>\n        <span className=\"flex items-center gap-1 text-muted-foreground/70\">\n          <AlertCircle className=\"size-3\" />\n          W6 dip: scheduled maintenance\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "LegendPositions",
          "description": "Grid of four line charts demonstrating all four legend positions (top, right, bottom, left) with enrollment data.",
          "args": "{\n    data: enrollmentTrend,\n    dataKeys: [\"undergraduate\", \"graduate\", \"distance\"],\n    categoryKey: \"month\",\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <LineChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={enrollmentTrend}\n          dataKeys={[\n            { key: \"undergraduate\", label: \"Undergraduate\" },\n            { key: \"graduate\", label: \"Graduate\" },\n            { key: \"distance\", label: \"Distance\" },\n          ]}\n          categoryKey=\"month\"\n          variant=\"line\"\n          curve=\"smooth\"\n          showLegend\n          legendPosition={pos}\n          showGrid\n          showTooltip\n          height={240}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <LineChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={enrollmentTrend}\n          dataKeys={[\n            { key: \"undergraduate\", label: \"Undergraduate\" },\n            { key: \"graduate\", label: \"Graduate\" },\n            { key: \"distance\", label: \"Distance\" },\n          ]}\n          categoryKey=\"month\"\n          variant=\"line\"\n          curve=\"smooth\"\n          showLegend\n          legendPosition={pos}\n          showGrid\n          showTooltip\n          height={240}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "WithBrush",
          "description": "Multi-series area chart with a brush slider for interactive zoom across 52 weeks of login and download data.",
          "args": "{\n    title: \"Platform Usage — Full Academic Year\",\n    subtitle: \"Drag the handles to zoom in on any stretch of weeks\",\n    data: weeklyPlatformUsage,\n    dataKeys: [\n      { key: \"logins\", label: \"Logins\" },\n      { key: \"downloads\", label: \"Downloads\" },\n    ],\n    categoryKey: \"week\",\n    variant: \"area\",\n    curve: \"smooth\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    showBrush: true,\n    height: 340,\n  },"
        },
        {
          "name": "WithBrushArea",
          "description": "Stacked area chart with a brush slider combining area-stacked series and interactive range zoom for weekly totals.",
          "args": "{\n    title: \"Stacked Area + Brush\",\n    subtitle: \"showBrush + area-stacked — scroll to explore weekly totals\",\n    data: weeklyPlatformUsage,\n    dataKeys: [\n      { key: \"logins\", label: \"Logins\" },\n      { key: \"downloads\", label: \"Downloads\" },\n    ],\n    categoryKey: \"week\",\n    variant: \"area-stacked\",\n    curve: \"smooth\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    showBrush: true,\n    height: 340,\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Line chart with Portuguese locale displaying weekly active users and platform engagement in localized format.",
          "args": "{\n    title: \"Weekly Active Users\",\n    subtitle: \"Platform engagement — 8 weeks\",\n    data: weeklyActiveUsers,\n    dataKeys: [{ key: \"users\", label: \"Active Users\" }],\n    categoryKey: \"week\",\n    variant: \"line\",\n    curve: \"smooth\",\n    dots: \"hover\",\n    showGrid: true,\n    showTooltip: true,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the line chart with an animated skeleton that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Weekly Active Users\",\n    subtitle: \"Platform engagement over 8 weeks\",\n    data: weeklyActiveUsers,\n    dataKeys: [{ key: \"users\", label: \"Active Users\" }],\n    categoryKey: \"week\",\n    variant: \"line\",\n    curve: \"smooth\",\n    showGrid: true,\n    showTooltip: true,\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the line chart renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Weekly Active Users\",\n    subtitle: \"Platform engagement over 8 weeks\",\n    data: [],\n    dataKeys: [\"users\"],\n    categoryKey: \"week\",\n    height: 280,\n  },"
        },
        {
          "name": "NegativeTrend",
          "description": "Area chart showing a declining dropout rate with a dashed target reference line and a footer confirming the target was reached.",
          "args": "{\n    title: \"Dropout Rate\",\n    subtitle: \"Monthly dropout percentage — target below 5%\",\n    data: [\n      { month: \"Jan\", rate: 8.2 },\n      { month: \"Feb\", rate: 7.6 },\n      { month: \"Mar\", rate: 9.1 },\n      { month: \"Apr\", rate: 6.8 },\n      { month: \"May\", rate: 5.4 },\n      { month: \"Jun\", rate: 4.9 },\n    ],\n    dataKeys: [\n      { key: \"rate\", label: \"Dropout %\", color: \"var(--destructive)\" },\n    ],\n    categoryKey: \"month\",\n    variant: \"area\",\n    curve: \"smooth\",\n    showGrid: true,\n    showTooltip: true,\n    referenceLines: [\n      { value: 5, label: \"Target\", color: \"var(--chart-2)\", dashed: true },\n    ],\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 1 }) + \"%\",\n    footer: (\n      <span className=\"flex items-center gap-1.5\">\n        <TrendingDown className=\"size-3.5 text-success\" />\n        Down from 8.2% to 4.9% — target reached in June\n      </span>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-location-picker",
      "description": "Address autocomplete picker with async search callback — decoupled from any geocoding API.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/location-picker",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "popover",
        "command",
        "badge",
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/location-picker.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "LocationSuggestion | null"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: LocationSuggestion | null) => void"
        },
        {
          "name": "onSearch",
          "required": false,
          "type": "(query: string) => Promise<LocationSuggestion[]>",
          "description": "Async search function — called with the query string.\nShould return a list of suggestions.\nConnect any API here: Google Places, Mapbox, ViaCEP, etc."
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "searchPlaceholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "clearable",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Form/LocationPicker",
      "stories": [
        {
          "name": "Default",
          "description": "Type 'João' or 'Praia' to see suggestions from the mock API.",
          "code": "<div className=\"max-w-sm\">\n        <LocationPicker\n          value={value}\n          onChange={setValue}\n          onSearch={mockSearch}\n          placeholder=\"Search for a location…\"\n        />\n        {value && (\n          <div className=\"mt-2 text-xs text-muted-foreground\">\n            Selected: {value.label}{\" \"}\n            {value.lat\n              ? `(${value.lat.toFixed(4)}, ${value.lng?.toFixed(4)})`\n              : \"\"}\n          </div>\n        )}\n      </div>"
        },
        {
          "name": "WithPreselectedValue",
          "description": "",
          "code": "<div className=\"max-w-sm\">\n      <LocationPicker value={MOCK_LOCATIONS[0]!} onSearch={mockSearch} />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<div className=\"max-w-sm\">\n      <LocationPicker value={null} onSearch={mockSearch} loading />\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "",
          "code": "<div className=\"max-w-sm\">\n      <LocationPicker\n        value={MOCK_LOCATIONS[1]!}\n        onSearch={mockSearch}\n        disabled\n      />\n    </div>"
        },
        {
          "name": "NoSearch",
          "description": "Without `onSearch`, shows an empty state inside the dropdown.",
          "code": "<div className=\"max-w-sm\">\n      <LocationPicker value={null} placeholder=\"No API connected\" />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-login-form",
      "title": "LoginForm",
      "description": "Bloco completo de formulário de login pronto para produção integrando social login, credenciais e passkey.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/login-form",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "ds-social-auth-group",
        "ds-auth-separator",
        "ds-passkey-prompt",
        "input",
        "button",
        "checkbox",
        "label",
        "ui-i18n"
      ],
      "files": [
        "components/ds/login-form.tsx"
      ],
      "props": [
        {
          "name": "onSubmit",
          "required": false,
          "type": "(data: LoginFormData) => Promise<boolean | void> | void"
        },
        {
          "name": "onSocialLogin",
          "required": false,
          "type": "(provider: SocialProvider) => Promise<void> | void"
        },
        {
          "name": "onForgotPassword",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onSignUp",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onPasskeyLogin",
          "required": false,
          "type": "() => Promise<boolean | void> | void"
        },
        {
          "name": "socialProviders",
          "required": false,
          "type": "SocialProvider[]"
        },
        {
          "name": "showPasskey",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "errorMessage",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"flat\"",
          "options": [
            "default",
            "flat"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Auth/LoginForm",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    variant: \"default\",\n    socialProviders: [\"google\", \"github\", \"govbr\"],\n  },"
        },
        {
          "name": "FlatVariant",
          "description": "",
          "args": "{\n    variant: \"flat\",\n    socialProviders: [\"google\", \"govbr\"],\n  },"
        },
        {
          "name": "WithError",
          "description": "",
          "args": "{\n    errorMessage:\n      \"Credenciais inválidas. Verifique seu e-mail e senha institucional.\",\n  },"
        },
        {
          "name": "LoadingState",
          "description": "",
          "args": "{\n    loading: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-logo-cloud-glow",
      "title": "LogoCloudGlow",
      "description": "Mural de logos centralizado dentro de um card com glow que reage ao ponteiro — composto de ds-press-wall e ds-cursor-spotlight.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/logo-cloud-glow",
      "dependencies": [],
      "registryDependencies": [
        "ds-press-wall",
        "ds-cursor-spotlight"
      ],
      "files": [
        "components/ds/logo-cloud-glow.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "tone",
          "required": false,
          "type": "CursorSpotlightTone"
        },
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode"
        }
      ],
      "storyTitle": "LogoCloud/LogoCloudGlow",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ kicker: \"Trusted by industry leaders\", children: [] as never },\n  render: (args) => (\n    <LogoCloudGlow {...args}>\n      {logos.map((name) => (\n        <PressWallLogo key={name} label={name}>\n          <Wordmark>{name}</Wordmark>\n        </PressWallLogo>\n      ))}\n    </LogoCloudGlow>\n  ),"
        },
        {
          "name": "VioletTone",
          "description": "",
          "args": "{ tone: \"violet\", children: [] as never },\n  render: (args) => (\n    <LogoCloudGlow {...args}>\n      {logos.map((name) => (\n        <PressWallLogo key={name} label={name}>\n          <Wordmark>{name}</Wordmark>\n        </PressWallLogo>\n      ))}\n    </LogoCloudGlow>\n  ),"
        }
      ]
    },
    {
      "name": "ds-logo-cloud-grouped",
      "title": "LogoCloudGrouped",
      "description": "Mural de logos com filtro de indústria/categoria — composto de ds-press-wall e ds-pill-group.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/logo-cloud-grouped",
      "dependencies": [],
      "registryDependencies": [
        "ds-press-wall",
        "ds-pill-group"
      ],
      "files": [
        "components/ds/logo-cloud-grouped.tsx"
      ],
      "props": [
        {
          "name": "groups",
          "required": true,
          "type": "LogoCloudGroup[]"
        },
        {
          "name": "items",
          "required": true,
          "type": "LogoCloudGroupedItem[]"
        },
        {
          "name": "allLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "LogoCloud/LogoCloudGrouped",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        }
      ]
    },
    {
      "name": "ds-logo-cloud-quotes",
      "title": "LogoCloudQuotes",
      "description": "Pares de logo do cliente + depoimento curto em grid de cartões — composto de ds-pull-quote.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/logo-cloud-quotes",
      "dependencies": [],
      "registryDependencies": [
        "ds-pull-quote"
      ],
      "files": [
        "components/ds/logo-cloud-quotes.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "LogoCloudQuoteItem[]"
        }
      ],
      "storyTitle": "LogoCloud/LogoCloudQuotes",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        }
      ]
    },
    {
      "name": "ds-logo-cloud-stats",
      "title": "LogoCloudStats",
      "description": "Estatística em destaque acima de um mural de logos — composto de ds-press-wall.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/logo-cloud-stats",
      "dependencies": [],
      "registryDependencies": [
        "ds-press-wall"
      ],
      "files": [
        "components/ds/logo-cloud-stats.tsx"
      ],
      "props": [
        {
          "name": "headline",
          "required": true,
          "type": "React.ReactNode",
          "description": "Big headline, e.g. \"Trusted by 500+ companies\"."
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "kicker",
          "required": false,
          "type": "string"
        },
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode",
          "description": "`PressWallLogo` items rendered below."
        }
      ],
      "storyTitle": "LogoCloud/LogoCloudStats",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    headline: \"Trusted by 500+ companies\",\n    description: \"From startups to Fortune 500 enterprises.\",\n    kicker: \"As seen in\",\n    children: [] as never,\n  },\n  render: (args) => (\n    <LogoCloudStats {...args}>\n      {logos.map((name) => (\n        <PressWallLogo key={name} label={name}>\n          <Wordmark>{name}</Wordmark>\n        </PressWallLogo>\n      ))}\n    </LogoCloudStats>\n  ),"
        }
      ]
    },
    {
      "name": "ds-magic-link-form",
      "title": "MagicLinkForm",
      "description": "Formulário de autenticação sem senha (magic link) com confirmação e temporizador de reenvio.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/magic-link-form",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "input",
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/magic-link-form.tsx"
      ],
      "props": [
        {
          "name": "onSendLink",
          "required": false,
          "type": "(email: string) => Promise<boolean | void> | void"
        },
        {
          "name": "onBack",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "resendCooldown",
          "required": false,
          "type": "number"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"clean\"",
          "options": [
            "default",
            "clean"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Auth/MagicLinkForm",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    resendCooldown: 30,\n  },\n  render: (args) => (\n    <div className=\"w-80 rounded-xl border bg-card p-6 shadow-sm\">\n      <MagicLinkForm {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-magnetic-element",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/magnetic-element",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/magnetic-element.tsx"
      ],
      "props": [
        {
          "name": "asChild",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "strengthValue",
          "required": false,
          "type": "number",
          "description": "Força do efeito magnético. Valores maiores puxam mais. Padrão: 20"
        },
        {
          "name": "strength",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Delight/MagneticElement",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    strengthValue: 30,\n    children: (\n      <Button size=\"lg\" className=\"rounded-full shadow-lg\">\n        Hover Me\n      </Button>\n    ),\n  },"
        },
        {
          "name": "Strong",
          "description": "",
          "args": "{\n    strengthValue: 60,\n    children: (\n      <Card className=\"w-64 cursor-pointer overflow-hidden border-2 transition-colors hover:border-primary\">\n        <CardContent className=\"flex flex-col items-center gap-4 p-8 text-center\">\n          <div className=\"flex size-12 items-center justify-center rounded-full bg-primary/10 text-primary\">\n            ✨\n          </div>\n          <div className=\"space-y-1\">\n            <h3 className=\"text-lg font-semibold\">Efeito Magnético</h3>\n            <p className=\"text-sm text-muted-foreground\">\n              Este card reage fortemente ao movimento do cursor.\n            </p>\n          </div>\n        </CardContent>\n      </Card>\n    ),\n  },"
        },
        {
          "name": "AsChild",
          "description": "",
          "args": "{\n    asChild: true,\n    strengthValue: 40,\n    children: (\n      <Button variant=\"outline\" size=\"lg\">\n        Usando asChild\n      </Button>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-manifesto-statement",
      "title": "Manifesto Statement",
      "description": "Declaração de manifesto institucional com tipografia editorial grande e citações autorais.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/manifesto-statement",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/manifesto-statement.tsx"
      ],
      "props": [
        {
          "name": "statement",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "eyebrow",
          "required": false,
          "type": "string"
        },
        {
          "name": "author",
          "required": false,
          "type": "string"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"default\" | \"lg\" | \"xl\"",
          "options": [
            "default",
            "lg",
            "xl"
          ],
          "default": "default"
        },
        {
          "name": "align",
          "required": false,
          "type": "\"left\" | \"center\"",
          "options": [
            "left",
            "center"
          ],
          "default": "left"
        }
      ],
      "stories": [
        {
          "name": "Centered",
          "description": "",
          "args": "{\n    align: \"center\",\n    size: \"lg\",\n    statement: (\n      <>\n        A tecnologia deve servir à{\" \"}\n        <span className=\"text-primary\">clareza cognitiva</span> e ao bem\n        público, sem ruídos desnecessários.\n      </>\n    ),\n  },"
        },
        {
          "name": "Large",
          "description": "",
          "args": "{\n    align: \"center\",\n    size: \"xl\",\n    statement: \"Construindo o futuro com rigor acadêmico e impacto real.\",\n    author: \"Diretoria Colegiada\",\n  },"
        }
      ]
    },
    {
      "name": "ds-markdown-editor",
      "description": "Markdown editor with edit/preview/split modes, toolbar, and fullscreen.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/markdown-editor",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "button",
        "separator",
        "toggle-group"
      ],
      "files": [
        "components/ds/markdown-editor.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "string"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "mode",
          "required": false,
          "type": "MarkdownEditorMode"
        },
        {
          "name": "showToolbar",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Form/MarkdownEditor",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    value: SAMPLE_MD,\n    mode: \"split\",\n    height: 400,\n  },"
        },
        {
          "name": "EditOnly",
          "description": "",
          "args": "{\n    value: SAMPLE_MD,\n    mode: \"edit\",\n    height: 400,\n  },"
        },
        {
          "name": "PreviewOnly",
          "description": "",
          "args": "{\n    value: SAMPLE_MD,\n    mode: \"preview\",\n    height: 400,\n  },"
        },
        {
          "name": "Empty",
          "description": "",
          "args": "{\n    value: \"\",\n    mode: \"split\",\n    height: 400,\n    placeholder: \"Start writing…\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    value: \"\",\n    loading: true,\n    height: 400,\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    value: SAMPLE_MD,\n    disabled: true,\n    height: 400,\n  },"
        },
        {
          "name": "NoToolbar",
          "description": "",
          "args": "{\n    value: SAMPLE_MD,\n    showToolbar: false,\n    mode: \"split\",\n    height: 360,\n  },"
        }
      ]
    },
    {
      "name": "ds-marquee",
      "title": "Marquee",
      "description": "Carrossel de rolagem contínua para logos de clientes, depoimentos ou cartões de dados.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/marquee",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/marquee.tsx"
      ],
      "props": [
        {
          "name": "pauseOnHover",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "fadeEdges",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "repeat",
          "required": false,
          "type": "number"
        },
        {
          "name": "direction",
          "required": false,
          "type": "\"left\" | \"right\" | \"up\" | \"down\"",
          "options": [
            "left",
            "right",
            "up",
            "down"
          ],
          "default": "left"
        },
        {
          "name": "speed",
          "required": false,
          "type": "\"slow\" | \"normal\" | \"fast\"",
          "options": [
            "slow",
            "normal",
            "fast"
          ],
          "default": "normal"
        }
      ],
      "storyTitle": "Data Display/Marquee",
      "stories": [
        {
          "name": "ReverseDirection",
          "description": "",
          "code": "<div className=\"mx-auto w-full max-w-2xl py-8\">\n      <Marquee direction=\"right\">\n        {logos.map((logo) => (\n          <div\n            key={logo}\n            className=\"flex items-center justify-center rounded-lg border border-border/50 bg-muted/30 px-6 py-3 text-sm font-medium text-muted-foreground shadow-xs hover:text-foreground\"\n          >\n            {logo}\n          </div>\n        ))}\n      </Marquee>\n    </div>"
        },
        {
          "name": "TestimonialCards",
          "description": "",
          "code": "<div className=\"mx-auto w-full max-w-3xl py-8\">\n      <Marquee speed=\"slow\" pauseOnHover>\n        {[\n          {\n            name: \"Ana Silva\",\n            role: \"Frontend Lead\",\n            text: \"O LEMA Design System acelerou nossa entrega em 4x.\",\n          },\n          {\n            name: \"Carlos Melo\",\n            role: \"Tech Lead\",\n            text: \"Acessibilidade e tipografia de alto padrão prontas para uso.\",\n          },\n          {\n            name: \"Mariana Costa\",\n            role: \"Product Manager\",\n            text: \"A consistência visual entre squads melhorou drasticamente.\",\n          },\n        ].map((item) => (\n          <Card\n            key={item.name}\n            className=\"w-72 shrink-0 border-border/60 bg-card/60\"\n          >\n            <CardContent className=\"flex flex-col gap-2 p-4\">\n              <div className=\"flex items-center gap-3\">\n                <Avatar className=\"size-8\">\n                  <AvatarFallback className=\"text-xs\">\n                    {item.name.slice(0, 2).toUpperCase()}\n                  </AvatarFallback>\n                </Avatar>\n                <div>\n                  <p className=\"text-xs leading-none font-medium\">\n                    {item.name}\n                  </p>\n                  <p className=\"text-xs text-muted-foreground\">{item.role}</p>\n                </div>\n              </div>\n              <p className=\"text-xs text-muted-foreground italic\">\n                &ldquo;{item.text}&rdquo;\n              </p>\n            </CardContent>\n          </Card>\n        ))}\n      </Marquee>\n    </div>"
        },
        {
          "name": "Vertical",
          "description": "",
          "code": "<div className=\"mx-auto h-64 w-64 overflow-hidden rounded-xl border py-4\">\n      <Marquee direction=\"up\" speed=\"normal\" className=\"h-full\">\n        {logos.map((logo) => (\n          <div\n            key={logo}\n            className=\"flex items-center justify-center rounded-lg border border-border/50 bg-muted/40 p-3 text-center text-xs font-medium\"\n          >\n            {logo}\n          </div>\n        ))}\n      </Marquee>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-marquee-duo",
      "title": "Marquee Duo",
      "description": "Marquee duplo (2 rows) com direção oposta e pause on hover — inspirado em Launch UI Social Proof Marquee 2 Rows.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/marquee-duo",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "card",
        "avatar",
        "skeleton"
      ],
      "files": [
        "components/ds/marquee-duo.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": false,
          "type": "MarqueeDuoItem[]"
        },
        {
          "name": "speed",
          "required": false,
          "type": "number"
        },
        {
          "name": "pauseOnHover",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\"",
          "options": [
            "default",
            "muted"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Muted",
          "description": "",
          "args": "{ variant: \"muted\" },"
        },
        {
          "name": "Fast",
          "description": "",
          "args": "{ speed: 14 },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        }
      ]
    },
    {
      "name": "ds-meteor-shower",
      "title": "Meteor Shower",
      "description": "Chuva de meteoros 100% CSS (sem canvas, sem RAF) para fundo de hero — posições determinísticas, custo de CPU essencialmente nulo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/meteor-shower",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/meteor-shower.tsx"
      ],
      "props": [
        {
          "name": "tone",
          "required": false,
          "type": "\"primary\" | \"violet\" | \"sky\" | \"neutral\"",
          "options": [
            "primary",
            "violet",
            "sky",
            "neutral"
          ],
          "default": "primary"
        },
        {
          "name": "density",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Effects/MeteorShower",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ tone: \"sky\", density: \"md\" },"
        },
        {
          "name": "AllTones",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n      {([\"primary\", \"violet\", \"sky\", \"neutral\"] as const).map((tone) => (\n        <div\n          key={tone}\n          className=\"relative flex h-48 items-center justify-center overflow-hidden rounded-2xl border border-border bg-background\"\n        >\n          <MeteorShower tone={tone} />\n          <p className=\"relative z-10 rounded-full bg-foreground px-2.5 py-1 text-xs font-medium text-background\">\n            {tone}\n          </p>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllDensities",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((density) => (\n        <div\n          key={density}\n          className=\"relative flex h-48 items-center justify-center overflow-hidden rounded-2xl border border-border bg-background\"\n        >\n          <MeteorShower density={density} />\n          <p className=\"relative z-10 rounded-full bg-foreground px-2.5 py-1 text-xs font-medium text-background\">\n            {density}\n          </p>\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-metric-comparison",
      "title": "Metric Comparison",
      "description": "Comparação direta entre dois pontos de dados com variação absoluta, relativa e barra proporcional.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/metric-comparison",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/metric-comparison.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string",
          "description": "Title of comparison."
        },
        {
          "name": "primaryMetric",
          "required": true,
          "type": "ComparisonItem",
          "description": "Primary metric (e.g. Current period or Scenario A)."
        },
        {
          "name": "secondaryMetric",
          "required": true,
          "type": "ComparisonItem",
          "description": "Secondary metric (e.g. Previous period or Baseline)."
        },
        {
          "name": "sentiment",
          "required": false,
          "type": "\"positiveIsGood\" | \"negativeIsGood\"",
          "description": "Whether an increase is considered positive or negative."
        },
        {
          "name": "layout",
          "required": false,
          "type": "\"horizontal\" | \"vertical\"",
          "description": "Horizontal (side-by-side) or vertical stacked layout."
        },
        {
          "name": "showBar",
          "required": false,
          "type": "boolean",
          "description": "Whether to display the visual relative proportion bar."
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Loading state."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for translations and formatting."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/MetricComparison",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    sentiment: \"positiveIsGood\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByText(\"$28,450\")).toBeInTheDocument()\n    await expect(canvas.getByText(\"+17.6%\")).toBeInTheDocument()\n  },"
        },
        {
          "name": "DeficitReduction",
          "description": "",
          "args": "{\n    title: \"Déficit Nominal (% PIB)\",\n    sentiment: \"negativeIsGood\",\n    primaryMetric: {\n      label: \"2025\",\n      value: 6.2,\n      format: (v) => `${v}%`,\n      subtext: \"Meta Fiscal\",\n    },\n    secondaryMetric: {\n      label: \"2024\",\n      value: 8.9,\n      format: (v) => `${v}%`,\n      subtext: \"Exercício Anterior\",\n    },\n  },"
        },
        {
          "name": "VerticalLayout",
          "description": "",
          "args": "{\n    layout: \"vertical\",\n    title: \"Consumo Energético Mensal\",\n    primaryMetric: {\n      label: \"Neste Mês\",\n      value: 1420,\n      format: (v) => `${v} kWh`,\n    },\n    secondaryMetric: {\n      label: \"Média Histórica\",\n      value: 1250,\n      format: (v) => `${v} kWh`,\n    },\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex w-96 flex-col gap-6\">\n      <MetricComparison\n        size=\"sm\"\n        title=\"Pequeno (sm)\"\n        primaryMetric={{ label: \"Atual\", value: 120 }}\n        secondaryMetric={{ label: \"Anterior\", value: 100 }}\n      />\n      <MetricComparison\n        size=\"md\"\n        title=\"Médio (md)\"\n        primaryMetric={{ label: \"Atual\", value: 120 }}\n        secondaryMetric={{ label: \"Anterior\", value: 100 }}\n      />\n      <MetricComparison\n        size=\"lg\"\n        title=\"Grande (lg)\"\n        primaryMetric={{ label: \"Atual\", value: 120 }}\n        secondaryMetric={{ label: \"Anterior\", value: 100 }}\n      />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-milestone-stepper",
      "title": "Milestone Stepper",
      "description": "Linha do tempo de marcos cronológicos e trajetória histórica com anos tabulares.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/milestone-stepper",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/milestone-stepper.tsx"
      ],
      "props": [
        {
          "name": "milestones",
          "required": true,
          "type": "MilestoneItem[]"
        },
        {
          "name": "orientation",
          "required": false,
          "type": "\"vertical\" | \"horizontal\"",
          "options": [
            "vertical",
            "horizontal"
          ],
          "default": "vertical"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "Horizontal",
          "description": "",
          "args": "{\n    orientation: \"horizontal\",\n  },"
        }
      ]
    },
    {
      "name": "ds-mini-card",
      "title": "Mini Card",
      "description": "Compact stat label+value unit for horizontal summary strips. Compose with MiniCardGroup (pill, outlined, elevated, ghost variants) and MiniCardStrip (auto-dividers). Supports icons, sub-values, intent colors, and delta change indicators. Size propagates via context.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/mini-card",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton"
      ],
      "files": [
        "components/ds/mini-card.tsx"
      ],
      "props": [
        {
          "name": "height",
          "required": false,
          "type": "\"short\" | \"tall\"",
          "description": "\"short\" (inset margins) for within-group, \"tall\" (full stretch) for between-groups"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Data Display/MiniCard",
      "stories": [
        {
          "name": "Default",
          "description": "Minimal — just a label and a value. No icon, no sub, no delta.",
          "args": "{\n    format: \"integer\",\n    decimals: 0,\n    locale: \"en-US\",\n    currency: \"USD\",\n    iconIntent: \"default\",\n    intent: \"default\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Minimal — just a label and a value. No icon, no sub, no delta.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithIcon",
          "description": "An icon placed before the label/value stack. Use `iconIntent` to color it independently from the value.",
          "args": "{\n    label: \"Contributors\",\n    value: 1450,\n    icon: UsersIcon,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"An icon placed before the label/value stack. Use `iconIntent` to color it independently from the value.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithSub",
          "description": "The `sub` prop renders a muted secondary value at baseline — ideal for \"used/total\" patterns.",
          "args": "{\n    label: \"Capacity Used\",\n    value: 53,\n    sub: \"/153\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'The `sub` prop renders a muted secondary value at baseline — ideal for \"used/total\" patterns.',\n      },\n    },\n  },"
        },
        {
          "name": "WithDelta",
          "description": "Pass a signed string like `\"+18%\"` and direction is inferred automatically. Or pass `\"up\"` / `\"down\"` / `\"neutral\"` for icon-only indicators.",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div className=\"flex items-center gap-6\">\n        <MiniCard label=\"Revenue\" value=\"R$ 2.4M\" delta=\"+18%\" />\n        <MiniCard label=\"Pending\" value={47} delta=\"-12\" />\n        <MiniCard label=\"Audited\" value={95} delta=\"neutral\" />\n        <MiniCard label=\"Selected\" value={53} delta=\"up\" />\n      </div>\n    </div>"
        },
        {
          "name": "FormatValues",
          "description": "Use `format`, `locale`, `currency`, and `decimals` to format numeric values. Set `locale` on `MiniCardGroup` and all children inherit it — override per-card when needed.",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          format: integer — pt-BR locale\n        </p>\n        <div className=\"flex items-center gap-6\">\n          <MiniCard\n            label=\"Contributors\"\n            value={1234567}\n            format=\"integer\"\n            locale=\"pt-BR\"\n          />\n          <MiniCard\n            label=\"Selected\"\n            value={53}\n            format=\"integer\"\n            locale=\"pt-BR\"\n          />\n        </div>\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          format: currency — pt-BR / BRL\n        </p>\n        <div className=\"flex items-center gap-6\">\n          <MiniCard\n            label=\"Total Potential\"\n            value={4200000}\n            format=\"currency\"\n            locale=\"pt-BR\"\n            currency=\"BRL\"\n            decimals={0}\n          />\n          <MiniCard\n            label=\"Recovery\"\n            value={1823000}\n            format=\"currency\"\n            locale=\"pt-BR\"\n            currency=\"BRL\"\n            decimals={0}\n            intent=\"success\"\n          />\n        </div>\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">format: percent</p>\n        <div className=\"flex items-center gap-6\">\n          <MiniCard\n            label=\"Capacity Used\"\n            value={0.346}\n            format=\"percent\"\n            locale=\"pt-BR\"\n          />\n          <MiniCard\n            label=\"Coverage\"\n            value={0.784}\n            format=\"percent\"\n            locale=\"pt-BR\"\n            intent=\"warning\"\n          />\n        </div>\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          format: float — 2 decimals\n        </p>\n        <div className=\"flex items-center gap-6\">\n          <MiniCard\n            label=\"Avg Score\"\n            value={7.83}\n            format=\"float\"\n            decimals={2}\n          />\n          <MiniCard\n            label=\"Deviation\"\n            value={1.241}\n            format=\"float\"\n            decimals={3}\n          />\n        </div>\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          Locale via MiniCardGroup — all children inherit\n        </p>\n        <MiniCardGroup locale=\"pt-BR\" divide>\n          <MiniCard\n            label=\"Total\"\n            value={4200000}\n            format=\"currency\"\n            currency=\"BRL\"\n            decimals={0}\n          />\n          <MiniCard label=\"Selected\" value={53} format=\"integer\" />\n          <MiniCard label=\"Coverage\" value={0.784} format=\"percent\" />\n        </MiniCardGroup>\n      </div>\n    </div>"
        },
        {
          "name": "Intents",
          "description": "The `intent` prop applies a semantic color to the primary value. Use it to communicate status at a glance.",
          "code": "<div className=\"flex flex-col gap-4\">\n      {(\n        [\n          [\"default\", \"Selected\", 53],\n          [\"success\", \"Completed\", 84],\n          [\"warning\", \"Medium Risk\", \"High (78.4)\"],\n          [\"destructive\", \"Pending\", 12],\n        ] as const\n      ).map(([intent, label, value]) => (\n        <div key={intent} className=\"flex items-center gap-4\">\n          <span className=\"w-24 shrink-0 text-xs font-medium text-muted-foreground\">\n            {intent}\n          </span>\n          <MiniCard label={label} value={value} intent={intent} />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "IconIntents",
          "description": "The `iconIntent` prop colors the icon independently from the value — useful when the icon signals a category but the value uses a different semantic.",
          "code": "<div className=\"flex items-center gap-6\">\n      <MiniCard\n        label=\"Total\"\n        value={1450}\n        icon={UsersIcon}\n        iconIntent=\"default\"\n      />\n      <MiniCard\n        label=\"Audited\"\n        value={84}\n        icon={FileSearchIcon}\n        iconIntent=\"success\"\n      />\n      <MiniCard\n        label=\"Medium Risk\"\n        value=\"High (78.4)\"\n        icon={ShieldAlertIcon}\n        iconIntent=\"warning\"\n      />\n      <MiniCard\n        label=\"Pending\"\n        value={12}\n        icon={ZapIcon}\n        iconIntent=\"destructive\"\n      />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "All three size presets. Typography scales with `text-xs / text-sm / text-base` for values and matching label sizes.",
          "code": "<div className=\"flex flex-col gap-6\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex items-center gap-6\">\n          <span className=\"w-6 shrink-0 text-xs font-medium text-muted-foreground\">\n            {size}\n          </span>\n          <MiniCard\n            label=\"Contributors\"\n            value={1450}\n            icon={UsersIcon}\n            size={size}\n          />\n          <MiniCard label=\"Capacity Used\" value={53} sub=\"/153\" size={size} />\n          <MiniCard\n            label=\"Medium Risk\"\n            value=\"High (78.4)\"\n            intent=\"warning\"\n            icon={ShieldAlertIcon}\n            iconIntent=\"warning\"\n            size={size}\n          />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "GroupVariants",
          "description": "Four group container styles. `divide` inserts short separators automatically between children.",
          "code": "<div className=\"flex flex-col gap-4\">\n      {(\n        [\n          [\"ghost\", \"No container\"],\n          [\"pill\", \"Muted fill\"],\n          [\"outlined\", \"Border + card bg\"],\n          [\"elevated\", \"Border + shadow\"],\n        ] as const\n      ).map(([variant, desc]) => (\n        <div key={variant} className=\"flex items-center gap-4\">\n          <span className=\"w-32 shrink-0 text-xs text-muted-foreground\">\n            {desc}\n          </span>\n          <MiniCardGroup variant={variant} size=\"md\" divide>\n            <MiniCard label=\"Selected\" value={53} />\n            <MiniCard label=\"Capacity Used\" value={53} sub=\"/153\" />\n            <MiniCard label=\"Remaining\" value={100} />\n          </MiniCardGroup>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "GroupAccents",
          "description": "The `accent` prop adds a semantic left-border highlight to the group container — useful for status-coded panels in dashboards.",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"success\", \"warning\", \"destructive\"] as const).map((accent) => (\n        <MiniCardGroup\n          key={accent}\n          variant=\"outlined\"\n          size=\"md\"\n          divide\n          accent={accent}\n        >\n          <MiniCard\n            label=\"Status\"\n            value={\n              accent === \"success\"\n                ? \"Normal\"\n                : accent === \"warning\"\n                  ? \"Attention\"\n                  : \"Critical\"\n            }\n            intent={accent}\n          />\n          <MiniCard\n            label=\"Contributors\"\n            value={accent === \"success\" ? 84 : accent === \"warning\" ? 32 : 8}\n          />\n          <MiniCard\n            label=\"% of Total\"\n            value={\n              accent === \"success\" ? \"88%\" : accent === \"warning\" ? \"33%\" : \"8%\"\n            }\n          />\n        </MiniCardGroup>\n      ))}\n    </div>"
        },
        {
          "name": "SizeFromGroup",
          "description": "Set `size` on the group and all children inherit it via context — no need to repeat the prop on each card.",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <MiniCardGroup key={size} variant=\"outlined\" size={size} divide>\n          <MiniCard label=\"Contributors\" value={1450} icon={UsersIcon} />\n          <MiniCard label=\"Selected\" value={53} />\n          <MiniCard label=\"Capacity Used\" value={53} sub=\"/153\" />\n          <MiniCard label=\"Remaining\" value={100} />\n        </MiniCardGroup>\n      ))}\n    </div>"
        },
        {
          "name": "StripLayout",
          "description": "Full horizontal strip — `MiniCardStrip` auto-inserts tall separators between its children. Groups can mix variants while the strip handles global spacing.",
          "code": "<MiniCardStrip>\n      <MiniCardGroup variant=\"outlined\" size=\"md\" divide>\n        <MiniCard label=\"Contributors\" value={1450} icon={UsersIcon} />\n        <MiniCard\n          label=\"Medium Risk\"\n          value=\"High (78.4)\"\n          intent=\"warning\"\n          icon={ShieldAlertIcon}\n          iconIntent=\"warning\"\n        />\n      </MiniCardGroup>\n\n      <MiniCardGroup variant=\"pill\" size=\"md\" divide>\n        <MiniCard label=\"Selected\" value={53} />\n        <MiniCard label=\"Capacity Used\" value={53} sub=\"/153\" />\n        <MiniCard label=\"Remaining\" value={100} />\n      </MiniCardGroup>\n\n      <MiniCardGroup size=\"md\" divide>\n        <MiniCard label=\"Standard Audit\" value={32} sub=\"/95\" />\n        <MiniCard label=\"Tax Audits\" value={21} sub=\"/75\" />\n      </MiniCardGroup>\n\n      <MiniCard label=\"Regional Units\" value={5} icon={MapPinIcon} />\n    </MiniCardStrip>"
        },
        {
          "name": "RiskMatrixSummaryBar",
          "description": "Replica of the risk-matrix summary bar from the design reference — a full horizontal strip inside a `h-16` toolbar.",
          "code": "<div className=\"flex h-16 w-full items-center border-b bg-background px-6\">\n      <MiniCardStrip scroll className=\"w-full justify-end\">\n        <MiniCardGroup variant=\"outlined\" size=\"md\" divide>\n          <MiniCard label=\"Contributors\" value={1450} icon={UsersIcon} />\n          <MiniCard\n            label=\"Medium Risk\"\n            value=\"High (78.4)\"\n            intent=\"warning\"\n            icon={ShieldAlertIcon}\n            iconIntent=\"warning\"\n          />\n        </MiniCardGroup>\n\n        <MiniCardGroup variant=\"pill\" size=\"md\" divide>\n          <MiniCard label=\"Selected\" value={53} />\n          <MiniCard label=\"Capacity Used\" value={53} sub=\"/153\" />\n          <MiniCard label=\"Remaining\" value={100} />\n        </MiniCardGroup>\n\n        <MiniCardGroup size=\"md\" divide>\n          <MiniCard label=\"Standard Audit\" value={32} sub=\"/95\" />\n          <MiniCard label=\"Tax Audits\" value={21} sub=\"/75\" />\n        </MiniCardGroup>\n\n        <MiniCard label=\"Regional Units\" value={5} icon={MapPinIcon} />\n      </MiniCardStrip>\n    </div>"
        },
        {
          "name": "FinancialStrip",
          "description": "Financial summary panel using `elevated` variant with accent border and delta indicators for value change.",
          "code": "<MiniCardStrip>\n      <MiniCardGroup variant=\"elevated\" size=\"md\" divide accent=\"success\">\n        <MiniCard\n          label=\"Total Potential\"\n          value=\"R$ 4,2M\"\n          icon={BanknoteIcon}\n          iconIntent=\"success\"\n        />\n        <MiniCard\n          label=\"Expected Recovery\"\n          value=\"R$ 1,8M\"\n          intent=\"success\"\n          delta=\"+22%\"\n        />\n      </MiniCardGroup>\n\n      <MiniCardGroup variant=\"pill\" size=\"md\" divide>\n        <MiniCard label=\"Regional Units\" value={8} icon={MapPinIcon} />\n        <MiniCard label=\"Segments\" value={14} icon={BuildingIcon} />\n      </MiniCardGroup>\n    </MiniCardStrip>"
        },
        {
          "name": "Loading",
          "description": "Skeleton loading state — dimensions match the real content to prevent layout shift.",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">Single card</p>\n        <MiniCard label=\"Contributors\" value={0} loading />\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">Group with divide</p>\n        <MiniCardGroup variant=\"pill\" size=\"md\" divide>\n          <MiniCard label=\"Selected\" value={0} loading />\n          <MiniCard label=\"Capacity Used\" value={0} loading />\n          <MiniCard label=\"Remaining\" value={0} loading />\n        </MiniCardGroup>\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">Full strip</p>\n        <MiniCardStrip>\n          <MiniCardGroup variant=\"outlined\" size=\"md\" divide>\n            <MiniCard label=\"Contributors\" value={0} loading />\n            <MiniCard label=\"Medium Risk\" value={0} loading />\n          </MiniCardGroup>\n          <MiniCardGroup variant=\"pill\" size=\"md\" divide>\n            <MiniCard label=\"Selected\" value={0} loading />\n            <MiniCard label=\"Capacity Used\" value={0} loading />\n            <MiniCard label=\"Remaining\" value={0} loading />\n          </MiniCardGroup>\n        </MiniCardStrip>\n      </div>\n    </div>"
        },
        {
          "name": "ResponsiveWrap",
          "description": "Pass `wrap` on `MiniCardStrip` to let groups flow onto multiple rows. Pass `wrap` on `MiniCardGroup` to let items wrap inside the group. Auto-dividers are disabled when wrapping — groups provide their own visual boundary.",
          "code": "<div className=\"flex flex-col gap-8\">\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          MiniCardStrip wrap — groups move to the next row when there is not\n          enough space\n        </p>\n        <div className=\"w-[480px] rounded-lg border p-4\">\n          <MiniCardStrip wrap>\n            <MiniCardGroup variant=\"outlined\" size=\"md\">\n              <MiniCard label=\"Contributors\" value={1450} icon={UsersIcon} />\n              <MiniCard\n                label=\"Medium Risk\"\n                value=\"High (78.4)\"\n                intent=\"warning\"\n                icon={ShieldAlertIcon}\n                iconIntent=\"warning\"\n              />\n            </MiniCardGroup>\n            <MiniCardGroup variant=\"pill\" size=\"md\">\n              <MiniCard label=\"Selected\" value={53} />\n              <MiniCard label=\"Capacity Used\" value={53} sub=\"/153\" />\n              <MiniCard label=\"Remaining\" value={100} />\n            </MiniCardGroup>\n            <MiniCardGroup size=\"md\">\n              <MiniCard label=\"Standard Audit\" value={32} sub=\"/95\" />\n              <MiniCard label=\"Tax Audits\" value={21} sub=\"/75\" />\n            </MiniCardGroup>\n          </MiniCardStrip>\n        </div>\n      </div>\n\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          MiniCardGroup wrap — items inside the group wrap on very narrow\n          screens\n        </p>\n        <div className=\"w-[260px] rounded-lg border p-4\">\n          <MiniCardGroup variant=\"pill\" size=\"md\" wrap>\n            <MiniCard label=\"Selected\" value={53} />\n            <MiniCard label=\"Capacity Used\" value={53} sub=\"/153\" />\n            <MiniCard label=\"Remaining\" value={100} />\n            <MiniCard label=\"Standard Audit\" value={32} sub=\"/95\" />\n          </MiniCardGroup>\n        </div>\n      </div>\n    </div>"
        },
        {
          "name": "Standalone",
          "description": "Manual composition using `MiniCardSeparator` directly — for layouts where auto-dividers aren't flexible enough.",
          "code": "<div className=\"flex items-center gap-4\">\n      <MiniCard label=\"Selected\" value={53} />\n      <MiniCardSeparator height=\"tall\" />\n      <MiniCard label=\"Capacity Used\" value={53} sub=\"/153\" />\n      <MiniCardSeparator height=\"short\" />\n      <MiniCard label=\"Remaining\" value={100} />\n    </div>"
        },
        {
          "name": "ColorTokens",
          "description": "The `accent` prop accepts any CSS color or `var(--my-token)`. It sets `--mini-card-accent` as a CSS custom property and applies to the icon (`text-(--mini-card-accent)`) and value (`text-(--mini-card-accent)`). Delta indicators keep their own semantic colors (`text-success`, `text-destructive`, `text-muted-foreground`) and are unaffected by `accent`.",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Direct CSS color values — icon and value inherit the accent\n        </p>\n        <div className=\"flex items-center gap-6\">\n          <MiniCard\n            label=\"Custom Purple\"\n            value={1450}\n            icon={UsersIcon}\n            accent=\"oklch(0.5 0.2 270)\"\n          />\n          <MiniCard\n            label=\"Custom Amber\"\n            value=\"R$ 4,2M\"\n            icon={BanknoteIcon}\n            accent=\"oklch(0.75 0.18 75)\"\n          />\n          <MiniCard\n            label=\"Custom Rose\"\n            value={12}\n            icon={ZapIcon}\n            accent=\"oklch(0.55 0.18 30)\"\n          />\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Design system token references\n        </p>\n        <div className=\"flex items-center gap-6\">\n          <MiniCard\n            label=\"Success\"\n            value={84}\n            icon={FileSearchIcon}\n            accent=\"var(--color-success)\"\n          />\n          <MiniCard\n            label=\"Warning\"\n            value=\"High (78.4)\"\n            icon={ShieldAlertIcon}\n            accent=\"var(--color-warning)\"\n          />\n          <MiniCard\n            label=\"Destructive\"\n            value={8}\n            icon={ZapIcon}\n            accent=\"var(--color-destructive)\"\n          />\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          accent in a group — simulating per-category KPI strips\n        </p>\n        <MiniCardStrip>\n          <MiniCardGroup variant=\"outlined\" size=\"md\" divide>\n            <MiniCard\n              label=\"Produto\"\n              value={91}\n              icon={BuildingIcon}\n              accent=\"var(--color-success)\"\n            />\n            <MiniCard\n              label=\"Marketing\"\n              value={62}\n              icon={MapPinIcon}\n              accent=\"var(--color-warning)\"\n            />\n          </MiniCardGroup>\n          <MiniCardGroup variant=\"outlined\" size=\"md\" divide>\n            <MiniCard\n              label=\"Brand\"\n              value=\"R$ 1,8M\"\n              icon={BanknoteIcon}\n              accent=\"var(--color-brand, oklch(0.4 0.2 240))\"\n            />\n            <MiniCard\n              label=\"Custom\"\n              value={74}\n              icon={UsersIcon}\n              accent=\"oklch(0.5 0.2 270)\"\n            />\n          </MiniCardGroup>\n        </MiniCardStrip>\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-mission-vision-cards",
      "title": "Mission Vision Cards",
      "description": "Par contrastante de cartões para declaração articulada de Missão e Visão institucionais.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/mission-vision-cards",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/mission-vision-cards.tsx"
      ],
      "props": [
        {
          "name": "missionTitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "missionText",
          "required": false,
          "type": "string"
        },
        {
          "name": "visionTitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "visionText",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"elevated\"",
          "options": [
            "default",
            "elevated"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "CustomContent",
          "description": "",
          "args": "{\n    missionTitle: \"Nossa Missão\",\n    missionText:\n      \"Desenvolver software público de alto impacto e promover a formação de recursos humanos qualificados.\",\n    visionTitle: \"Nossa Visão de Futuro\",\n    visionText:\n      \"Ser referência nacional em design systems e modelagem estatística aplicada até 2030.\",\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-8\">\n      <div>\n        <p className=\"mb-2 text-xs font-bold tracking-wider text-muted-foreground uppercase\">\n          English (en-US)\n        </p>\n        <MissionVisionCards locale=\"en-US\" />\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs font-bold tracking-wider text-muted-foreground uppercase\">\n          Español (es-ES)\n        </p>\n        <MissionVisionCards locale=\"es-ES\" />\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs font-bold tracking-wider text-muted-foreground uppercase\">\n          Français (fr-FR)\n        </p>\n        <MissionVisionCards locale=\"fr-FR\" />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-mockup",
      "title": "Mockup",
      "description": "Mockup com frames small/large/mobile e sombra — inspirado em Launch UI Mockup.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/mockup",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton"
      ],
      "files": [
        "components/ds/mockup.tsx"
      ],
      "props": [
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "frame",
          "required": false,
          "type": "\"small\" | \"large\" | \"mobile\"",
          "options": [
            "small",
            "large",
            "mobile"
          ],
          "default": "large"
        },
        {
          "name": "inset",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "stories": [
        {
          "name": "Small",
          "description": "",
          "args": "{ frame: \"small\", children: <Img /> },\n  render: (args) => (\n    <div className=\"w-[480px]\">\n      <Mockup {...args} />\n    </div>\n  ),"
        },
        {
          "name": "Large",
          "description": "",
          "args": "{ frame: \"large\", children: <Img /> },\n  render: (args) => (\n    <div className=\"w-[560px]\">\n      <Mockup {...args} />\n    </div>\n  ),"
        },
        {
          "name": "Mobile",
          "description": "",
          "args": "{ frame: \"mobile\" },\n  render: (args) => (\n    <Mockup {...args}>\n      <Screenshot\n        src=\"https://picsum.photos/seed/mobile-light2/400/800\"\n        srcDark=\"https://picsum.photos/seed/mobile-dark2/400/800\"\n        alt=\"Mobile\"\n        width={400}\n        height={800}\n        rounded=\"none\"\n        shadow=\"none\"\n      />\n    </Mockup>\n  ),"
        },
        {
          "name": "Inset",
          "description": "",
          "args": "{ frame: \"large\", inset: true, children: <Img /> },\n  render: (args) => (\n    <div className=\"w-[560px]\">\n      <Mockup {...args} />\n    </div>\n  ),"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        }
      ]
    },
    {
      "name": "ds-modal",
      "title": "Modal",
      "description": "A flexible modal dialog built on Dialog with size variants (sm/md/lg/xl/2xl/full), intent system (default/destructive/success/warning/info), defaultOpen for uncontrolled usage, scrollable body, auto async confirm tracking, loading skeleton, escape/pointer-down-outside/interact-outside event handlers, and i18n support.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/modal",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "dialog",
        "button",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/modal.tsx"
      ],
      "props": [
        {
          "name": "open",
          "required": false,
          "type": "boolean",
          "description": "Controlled open state"
        },
        {
          "name": "defaultOpen",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onOpenChange",
          "required": false,
          "type": "(open: boolean) => void"
        },
        {
          "name": "onEscapeKeyDown",
          "required": false,
          "type": "React.ComponentPropsWithoutRef< typeof DialogContent >[\"onEscapeKeyDown\"]"
        },
        {
          "name": "onPointerDownOutside",
          "required": false,
          "type": "React.ComponentPropsWithoutRef< typeof DialogContent >[\"onPointerDownOutside\"]"
        },
        {
          "name": "onInteractOutside",
          "required": false,
          "type": "React.ComponentPropsWithoutRef< typeof DialogContent >[\"onInteractOutside\"]"
        },
        {
          "name": "trigger",
          "required": false,
          "type": "React.ReactNode",
          "description": "Element that opens the modal when clicked"
        },
        {
          "name": "title",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "description",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "children",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode",
          "description": "Custom footer — replaces the auto-generated confirm/cancel buttons"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode",
          "description": "Custom icon — overrides the intent default icon"
        },
        {
          "name": "onConfirm",
          "required": false,
          "type": "() => void | Promise<void>",
          "description": "Quick-wire confirm action. Supports async — tracks loading automatically"
        },
        {
          "name": "onCancel",
          "required": false,
          "type": "() => void",
          "description": "Quick-wire cancel action. Called on cancel button click"
        },
        {
          "name": "confirmLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "cancelLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "confirmLoading",
          "required": false,
          "type": "boolean",
          "description": "Manual loading override for the confirm button"
        },
        {
          "name": "closeOnConfirm",
          "required": false,
          "type": "boolean",
          "description": "When true, wraps the confirm button in DialogClose so it closes after click"
        },
        {
          "name": "size",
          "required": false,
          "type": "ModalSize"
        },
        {
          "name": "intent",
          "required": false,
          "type": "ModalIntent"
        },
        {
          "name": "scrollable",
          "required": false,
          "type": "boolean",
          "description": "Makes the body scrollable with a sticky header and footer"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Shows skeleton placeholders instead of children"
        },
        {
          "name": "showCloseButton",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "maximize",
          "required": false,
          "type": "boolean",
          "description": "When true, shows a button to expand modal to full screen"
        },
        {
          "name": "onMaximized",
          "required": false,
          "type": "(maximized: boolean) => void",
          "description": "Callback fired when the maximize state changes"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "className",
          "required": false,
          "type": "string",
          "description": "Applied to the scrollable body wrapper (or directly to content when non-scrollable)"
        }
      ],
      "storyTitle": "Feedback/Modal",
      "stories": [
        {
          "name": "Default",
          "description": "Default modal with form fields and auto confirm/cancel footer.",
          "code": "<Modal\n      title=\"Edit Profile\"\n      description=\"Update your display name and email address.\"\n      trigger={<Button>Edit Profile</Button>}\n      onConfirm={() => {}}\n      closeOnConfirm\n    >\n      <div className=\"flex flex-col gap-4\">\n        <div className=\"flex flex-col gap-1.5\">\n          <Label htmlFor=\"modal-name\">Display name</Label>\n          <Input id=\"modal-name\" defaultValue=\"Ana Souza\" />\n        </div>\n        <div className=\"flex flex-col gap-1.5\">\n          <Label htmlFor=\"modal-email\">Email</Label>\n          <Input id=\"modal-email\" defaultValue=\"ana@ufpb.br\" type=\"email\" />\n        </div>\n      </div>\n    </Modal>"
        },
        {
          "name": "IntentDestructive",
          "description": "Destructive intent: red icon accent + matching confirm button. `onConfirm` returns a Promise — loading state is tracked automatically.",
          "code": "<Modal\n      intent=\"destructive\"\n      size=\"sm\"\n      title=\"Delete Account\"\n      description=\"This action is permanent and cannot be undone. All your data will be erased.\"\n      trigger={\n        <Button variant=\"destructive\">\n          <TrashIcon data-icon=\"inline-start\" />\n          Delete Account\n        </Button>\n      }\n      confirmLabel=\"Yes, delete\"\n      cancelLabel=\"Keep account\"\n      onConfirm={() => new Promise((r) => setTimeout(r, 1500))}\n      closeOnConfirm\n    />"
        },
        {
          "name": "IntentSuccess",
          "description": "Success intent: green icon + matching confirm button.",
          "code": "<Modal\n      intent=\"success\"\n      size=\"sm\"\n      title=\"Changes Saved\"\n      description=\"Your profile has been updated successfully.\"\n      trigger={<Button variant=\"outline\">Show Success</Button>}\n      confirmLabel=\"Done\"\n      closeOnConfirm\n    />"
        },
        {
          "name": "IntentWarning",
          "description": "Warning intent: amber icon accent.",
          "code": "<Modal\n      intent=\"warning\"\n      size=\"sm\"\n      title=\"Unsaved Changes\"\n      description=\"You have unsaved changes. Leaving now will discard them.\"\n      trigger={<Button variant=\"outline\">Show Warning</Button>}\n      confirmLabel=\"Discard\"\n      cancelLabel=\"Stay\"\n      onConfirm={() => {}}\n      closeOnConfirm\n    />"
        },
        {
          "name": "IntentInfo",
          "description": "Info intent: sky-blue icon accent.",
          "code": "<Modal\n      intent=\"info\"\n      size=\"sm\"\n      title=\"New Feature Available\"\n      description=\"We just launched dark mode across the entire dashboard. Toggle it from your profile settings.\"\n      trigger={<Button variant=\"outline\">What&apos;s New</Button>}\n      confirmLabel=\"Got it\"\n      closeOnConfirm\n    />"
        },
        {
          "name": "Sizes",
          "description": "All six size variants: sm, md, lg, xl, 2xl, full. Each adjusts `max-width` at the sm breakpoint.",
          "code": "<div className=\"flex flex-wrap gap-2\">\n      {([\"sm\", \"md\", \"lg\", \"xl\", \"2xl\", \"full\"] as const).map((size) => (\n        <Modal\n          key={size}\n          size={size}\n          title={`Modal — ${size}`}\n          description={`This dialog uses size=\"${size}\".`}\n          trigger={<Button variant=\"outline\">{size}</Button>}\n          onConfirm={() => {}}\n          closeOnConfirm\n        >\n          <p className=\"text-sm text-muted-foreground\">\n            Content area for a <strong>{size}</strong> modal. The max-width\n            adjusts per size, with responsive fallback to viewport − 2rem on\n            small screens.\n          </p>\n        </Modal>\n      ))}\n    </div>"
        },
        {
          "name": "Scrollable",
          "description": "Scrollable modal: the header and footer are sticky, only the body scrolls. Triggered with `scrollable` prop.",
          "code": "<Modal\n      size=\"md\"\n      scrollable\n      title=\"Terms of Service\"\n      description=\"Read the full terms before accepting.\"\n      trigger={<Button>View Terms</Button>}\n      confirmLabel=\"Accept\"\n      cancelLabel=\"Decline\"\n      onConfirm={() => {}}\n      closeOnConfirm\n    >\n      <div className=\"flex flex-col gap-4\">\n        {Array.from({ length: 8 }).map((_, i) => (\n          <React.Fragment key={i}>\n            <div className=\"flex flex-col gap-1\">\n              <p className=\"text-sm font-medium text-foreground\">\n                {i + 1}.{\" \"}\n                {\n                  [\n                    \"Acceptance\",\n                    \"Privacy Policy\",\n                    \"Data Usage\",\n                    \"User Conduct\",\n                    \"Intellectual Property\",\n                    \"Limitations\",\n                    \"Governing Law\",\n                    \"Contact\",\n                  ][i]\n                }\n              </p>\n              <p className=\"text-sm leading-relaxed text-muted-foreground\">\n                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do\n                eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut\n                enim ad minim veniam, quis nostrud exercitation ullamco laboris\n                nisi ut aliquip ex ea commodo consequat.\n              </p>\n            </div>\n            {i < 7 && <Separator />}\n          </React.Fragment>\n        ))}\n      </div>\n    </Modal>"
        },
        {
          "name": "LoadingSkeleton",
          "description": "Loading state renders skeleton lines matched to the modal size. Toggle the button inside to reveal content."
        },
        {
          "name": "CustomIcon",
          "description": "Custom icon via the `icon` prop overrides the intent default icon while keeping the intent color.",
          "code": "<Modal\n      intent=\"destructive\"\n      icon={<LogOutIcon />}\n      size=\"sm\"\n      title=\"Sign Out\"\n      description=\"You will be signed out of all devices and sessions.\"\n      trigger={<Button variant=\"outline\">Sign Out</Button>}\n      confirmLabel=\"Sign out\"\n      onConfirm={() => {}}\n      closeOnConfirm\n    />"
        },
        {
          "name": "AsyncConfirm",
          "description": "When `onConfirm` returns a Promise, the confirm button shows a spinner automatically. No extra state management needed.",
          "code": "<Modal\n      intent=\"success\"\n      size=\"md\"\n      title=\"Publish Report\"\n      description=\"This will make the report visible to all members of your organization.\"\n      trigger={<Button>Publish</Button>}\n      confirmLabel=\"Publish\"\n      onConfirm={() => new Promise((resolve) => setTimeout(resolve, 2000))}\n      closeOnConfirm\n    >\n      <div className=\"rounded-lg border border-border bg-muted/50 px-4 py-3\">\n        <p className=\"text-sm font-medium\">\n          Q1 2025 — Academic Performance Report\n        </p>\n        <p className=\"mt-0.5 text-xs text-muted-foreground\">\n          Last edited 2 hours ago · 42 pages\n        </p>\n      </div>\n    </Modal>"
        },
        {
          "name": "CustomFooter",
          "description": "Custom `footer` slot replaces the auto-generated buttons entirely.",
          "code": "<Modal\n      size=\"lg\"\n      title=\"Notification Preferences\"\n      description=\"Choose which updates you want to receive.\"\n      trigger={\n        <Button variant=\"outline\">\n          <BellIcon data-icon=\"inline-start\" />\n          Notifications\n        </Button>\n      }\n      footer={\n        <div className=\"flex w-full items-center justify-between gap-2\">\n          <Button variant=\"ghost\" size=\"sm\" className=\"text-muted-foreground\">\n            Reset to defaults\n          </Button>\n          <div className=\"flex gap-2\">\n            <DialogClose asChild>\n              <Button variant=\"outline\" size=\"sm\">\n                Cancel\n              </Button>\n            </DialogClose>\n            <Button size=\"sm\">\n              <SaveIcon data-icon=\"inline-start\" />\n              Save preferences\n            </Button>\n          </div>\n        </div>\n      }\n    >\n      <div className=\"flex flex-col gap-3\">\n        {[\n          { icon: BellIcon, label: \"Push notifications\", badge: \"On\" },\n          { icon: ShieldIcon, label: \"Security alerts\", badge: \"On\" },\n          { icon: UserIcon, label: \"Account activity\", badge: \"Off\" },\n          { icon: LockIcon, label: \"Two-factor prompts\", badge: \"On\" },\n        ].map(({ icon: Icon, label, badge }) => (\n          <div\n            key={label}\n            className=\"flex items-center justify-between rounded-lg border border-border px-4 py-3\"\n          >\n            <div className=\"flex items-center gap-3\">\n              <Icon className=\"size-4 text-muted-foreground\" />\n              <span className=\"text-sm\">{label}</span>\n            </div>\n            <Badge variant={badge === \"On\" ? \"default\" : \"secondary\"}>\n              {badge}\n            </Badge>\n          </div>\n        ))}\n      </div>\n    </Modal>"
        },
        {
          "name": "NoCloseButton",
          "description": "Hide the X button via `showCloseButton={false}` to force the user to pick an action.",
          "code": "<Modal\n      size=\"sm\"\n      intent=\"warning\"\n      showCloseButton={false}\n      title=\"Session Expiring\"\n      description=\"Your session will expire in 2 minutes due to inactivity.\"\n      trigger={<Button variant=\"outline\">Simulate session alert</Button>}\n      confirmLabel=\"Stay logged in\"\n      cancelLabel=\"Log out\"\n      onConfirm={() => {}}\n      closeOnConfirm\n    />"
        },
        {
          "name": "Maximize",
          "description": "Shows an **expand** button (`Maximize2` icon) beside the close button.\nClick toggles to fullscreen (`h-dvh w-full`), replacing the icon with `Minimize2`.\nClick again or close the modal to return to the original size.\n\n**Note:** `maximize` auto-suppresses DialogContent's built-in close button\nto avoid duplicates — both close and maximize are rendered inside the header.",
          "code": "<Modal\n      size=\"lg\"\n      maximize\n      title=\"Report Viewer\"\n      description=\"Toggle the expand button to view in fullscreen.\"\n      trigger={<Button>Open Report</Button>}\n      onConfirm={() => {}}\n      closeOnConfirm\n    >\n      <div className=\"flex flex-col gap-4\">\n        {Array.from({ length: 2 }).map((_, i) => (\n          <div\n            key={i}\n            className=\"rounded-lg border border-border bg-muted/30 p-4\"\n          >\n            <p className=\"text-sm font-medium text-foreground\">\n              Section {i + 1}\n            </p>\n            <p className=\"mt-1 text-sm text-muted-foreground\">\n              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do\n              eiusmod tempor incididunt ut labore et dolore magna aliqua.\n            </p>\n          </div>\n        ))}\n      </div>\n    </Modal>"
        },
        {
          "name": "Controlled",
          "description": "Fully controlled via `open` + `onOpenChange` — no trigger prop needed."
        },
        {
          "name": "Locales",
          "description": "Button labels adapt to `locale` prop: en-US, pt-BR, es-ES, fr-FR.",
          "code": "<div className=\"flex flex-wrap gap-2\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <Modal\n          key={locale}\n          locale={locale}\n          size=\"sm\"\n          intent=\"destructive\"\n          title=\"Confirm Action\"\n          description=\"This operation cannot be undone.\"\n          trigger={\n            <Button variant=\"outline\" size=\"sm\">\n              {locale}\n            </Button>\n          }\n          onConfirm={() => {}}\n          closeOnConfirm\n        />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-morphing-dialog",
      "description": "Morphing Dialog using framer-motion.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/morphing-dialog",
      "dependencies": [],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ds/morphing-dialog.tsx"
      ],
      "props": [
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode"
        }
      ],
      "storyTitle": "Layout/MorphingDialog",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ children: null },\n  render: () => {\n    return (\n      <MorphingDialog>\n        <MorphingDialogTrigger className=\"group flex w-[300px] flex-col overflow-hidden rounded-2xl border bg-card p-4 transition-colors hover:bg-accent/50\">\n          <MorphingDialogImage\n            src=\"https://images.unsplash.com/photo-1550745165-9bc0b252726f?q=80&w=600&auto=format&fit=crop\"\n            alt=\"Retro computer\"\n            className=\"mb-4 h-40 w-full rounded-xl object-cover\"\n          />\n          <MorphingDialogTitle className=\"text-lg\">\n            Retro Computing\n          </MorphingDialogTitle>\n          <MorphingDialogSubtitle>\n            A look back at the 80s\n          </MorphingDialogSubtitle>\n        </MorphingDialogTrigger>\n\n        <MorphingDialogContainer>\n          <MorphingDialogImage\n            src=\"https://images.unsplash.com/photo-1550745165-9bc0b252726f?q=80&w=1200&auto=format&fit=crop\"\n            alt=\"Retro computer\"\n            className=\"h-64 w-full object-cover\"\n          />\n          <div className=\"p-6\">\n            <div className=\"flex items-start justify-between\">\n              <div>\n                <MorphingDialogTitle className=\"mb-1 text-2xl\">\n                  Retro Computing\n                </MorphingDialogTitle>\n                <MorphingDialogSubtitle className=\"text-base\">\n                  A look back at the 80s\n                </MorphingDialogSubtitle>\n              </div>\n              <MorphingDialogClose />\n            </div>\n            <MorphingDialogDescription className=\"mt-6 text-base leading-relaxed\">\n              The 1980s was a decade of rapid technological advancement,\n              particularly in the realm of personal computing. Home computers\n              became increasingly accessible, transforming how people worked,\n              played, and communicated. Iconic machines like the Commodore 64,\n              ZX Spectrum, and early Apple Macintoshes defined a\n              generation&apos;s relationship with technology.\n            </MorphingDialogDescription>\n          </div>\n        </MorphingDialogContainer>\n      </MorphingDialog>\n    )\n  },",
          "code": "<MorphingDialog>\n        <MorphingDialogTrigger className=\"group flex w-[300px] flex-col overflow-hidden rounded-2xl border bg-card p-4 transition-colors hover:bg-accent/50\">\n          <MorphingDialogImage\n            src=\"https://images.unsplash.com/photo-1550745165-9bc0b252726f?q=80&w=600&auto=format&fit=crop\"\n            alt=\"Retro computer\"\n            className=\"mb-4 h-40 w-full rounded-xl object-cover\"\n          />\n          <MorphingDialogTitle className=\"text-lg\">\n            Retro Computing\n          </MorphingDialogTitle>\n          <MorphingDialogSubtitle>\n            A look back at the 80s\n          </MorphingDialogSubtitle>\n        </MorphingDialogTrigger>\n\n        <MorphingDialogContainer>\n          <MorphingDialogImage\n            src=\"https://images.unsplash.com/photo-1550745165-9bc0b252726f?q=80&w=1200&auto=format&fit=crop\"\n            alt=\"Retro computer\"\n            className=\"h-64 w-full object-cover\"\n          />\n          <div className=\"p-6\">\n            <div className=\"flex items-start justify-between\">\n              <div>\n                <MorphingDialogTitle className=\"mb-1 text-2xl\">\n                  Retro Computing\n                </MorphingDialogTitle>\n                <MorphingDialogSubtitle className=\"text-base\">\n                  A look back at the 80s\n                </MorphingDialogSubtitle>\n              </div>\n              <MorphingDialogClose />\n            </div>\n            <MorphingDialogDescription className=\"mt-6 text-base leading-relaxed\">\n              The 1980s was a decade of rapid technological advancement,\n              particularly in the realm of personal computing. Home computers\n              became increasingly accessible, transforming how people worked,\n              played, and communicated. Iconic machines like the Commodore 64,\n              ZX Spectrum, and early Apple Macintoshes defined a\n              generation&apos;s relationship with technology.\n            </MorphingDialogDescription>\n          </div>\n        </MorphingDialogContainer>\n      </MorphingDialog>"
        }
      ]
    },
    {
      "name": "ds-multi-select",
      "title": "MultiSelect",
      "description": "Combobox que permite selecionar múltiplos itens de uma lista.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/multi-select",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "popover",
        "command",
        "badge",
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/multi-select.tsx"
      ],
      "props": [
        {
          "name": "options",
          "required": true,
          "type": "Option[]"
        },
        {
          "name": "value",
          "required": true,
          "type": "string[]"
        },
        {
          "name": "onChange",
          "required": true,
          "type": "(value: string[]) => void"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "maxCount",
          "required": false,
          "type": "number"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/MultiSelect",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    options: MOCK_OPTIONS,\n    value: [],\n    onChange: () => {},\n  },"
        },
        {
          "name": "MaxCount",
          "description": "With `maxCount=2`, selecting 3 items shows the first 2 and '+1 selected'.",
          "args": "{\n    options: MOCK_OPTIONS,\n    value: [\"mobile\", \"tablet\", \"desktop\", \"watch\"],\n    maxCount: 2,\n    onChange: () => {},\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"With `maxCount=2`, selecting 3 items shows the first 2 and '+1 selected'.\",\n      },\n    },\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    options: MOCK_OPTIONS,\n    value: [\"mobile\"],\n    disabled: true,\n    onChange: () => {},\n  },"
        },
        {
          "name": "AllSizes",
          "description": "The component supports 3 badge sizes: sm, md and lg.",
          "args": "{\n    options: MOCK_OPTIONS,\n    value: [\"mobile\", \"tablet\"],\n    onChange: () => {},\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"The component supports 3 badge sizes: sm, md and lg.\",\n      },\n    },\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "args": "{\n    options: MOCK_OPTIONS,\n    value: [\"mobile\"],\n    onChange: () => {},\n  },"
        }
      ]
    },
    {
      "name": "ds-nav-dots",
      "title": "Nav Dots",
      "description": "Dot-based section navigation with automatic scroll tracking and tooltips.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/nav-dots",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "tooltip",
        "ui-i18n"
      ],
      "files": [
        "components/ds/nav-dots.tsx"
      ],
      "props": [
        {
          "name": "sections",
          "required": true,
          "type": "NavDotsSection[]",
          "description": "Array of sections to navigate between"
        },
        {
          "name": "active",
          "required": false,
          "type": "number",
          "description": "Initially active section index"
        },
        {
          "name": "scrollOnClick",
          "required": false,
          "type": "boolean",
          "description": "Enable smooth scroll when clicking a dot"
        },
        {
          "name": "scrollContainer",
          "required": false,
          "type": "React.RefObject<HTMLElement | null> | \"window\" | null",
          "description": "Scroll container to observe. Defaults to `null` which means the\ncomponent will walk up the DOM to find the nearest scrollable ancestor.\nPass a ref or `\"window\"` to override."
        },
        {
          "name": "scrollMargin",
          "required": false,
          "type": "string",
          "description": "IntersectionObserver rootMargin (default: \"0px\")"
        },
        {
          "name": "onActiveChange",
          "required": false,
          "type": "(index: number) => void",
          "description": "Callback when the active section changes"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Vertical dot navigation on the right side — scroll the container to see active dot tracking.",
          "args": "{\n    sections,\n    position: \"right\",\n    orientation: \"vertical\",\n    active: 0,\n    scrollOnClick: true,\n    scrollMargin: \"0px\",\n    locale: \"en-US\",\n  },\n  render: (args) => (\n    <ScrollDemo>\n      <NavDots\n        {...args}\n        className=\"sticky top-1/2 right-3 z-50 ml-auto -translate-y-1/2\"\n        style={{ position: \"sticky\", right: 12, float: \"right\" }}\n      />\n    </ScrollDemo>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Vertical dot navigation on the right side — scroll the container to see active dot tracking.\",\n      },\n    },\n  },"
        },
        {
          "name": "Horizontal",
          "description": "Horizontal dot navigation at the top center — active state changes as sections scroll into view.",
          "args": "{\n    sections,\n    orientation: \"horizontal\",\n    position: \"right\",\n  },\n  render: (args) => (\n    <ScrollDemo navPosition=\"before\">\n      <NavDots\n        {...args}\n        className=\"sticky top-3 left-1/2 z-50 -translate-x-1/2\"\n        style={{ position: \"sticky\", top: 12 }}\n      />\n    </ScrollDemo>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Horizontal dot navigation at the top center — active state changes as sections scroll into view.\",\n      },\n    },\n  },"
        },
        {
          "name": "LeftPosition",
          "description": "Vertical dot navigation pinned to the left edge of the scrollable container.",
          "args": "{\n    sections,\n    position: \"left\",\n    orientation: \"vertical\",\n  },\n  render: (args) => (\n    <ScrollDemo>\n      <NavDots\n        {...args}\n        className=\"sticky top-1/2 left-3 z-50 -translate-y-1/2\"\n        style={{ position: \"sticky\", left: 12, float: \"left\" }}\n      />\n    </ScrollDemo>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Vertical dot navigation pinned to the left edge of the scrollable container.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithActive",
          "description": "Dot navigation with initial active section set to index 2 (Features).",
          "args": "{\n    sections,\n    active: 2,\n  },\n  render: (args) => (\n    <ScrollDemo>\n      <NavDots\n        {...args}\n        className=\"sticky top-1/2 right-3 z-50 ml-auto -translate-y-1/2\"\n        style={{ position: \"sticky\", right: 12, float: \"right\" }}\n      />\n    </ScrollDemo>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dot navigation with initial active section set to index 2 (Features).\",\n      },\n    },\n  },"
        },
        {
          "name": "WithCallback",
          "description": "Dot navigation that fires an onActiveChange callback logged in the Actions panel.",
          "args": "{\n    sections,\n    onActiveChange: fn(),\n  },\n  render: (args) => (\n    <ScrollDemo>\n      <NavDots\n        {...args}\n        className=\"sticky top-1/2 right-3 z-50 ml-auto -translate-y-1/2\"\n        style={{ position: \"sticky\", right: 12, float: \"right\" }}\n      />\n    </ScrollDemo>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dot navigation that fires an onActiveChange callback logged in the Actions panel.\",\n      },\n    },\n  },"
        },
        {
          "name": "DisabledScroll",
          "description": "Dot navigation with scrollOnClick={false} — dots are display-only without scroll behavior.",
          "args": "{\n    sections,\n    scrollOnClick: false,\n  },\n  render: (args) => (\n    <ScrollDemo>\n      <NavDots\n        {...args}\n        className=\"sticky top-1/2 right-3 z-50 ml-auto -translate-y-1/2\"\n        style={{ position: \"sticky\", right: 12, float: \"right\" }}\n      />\n    </ScrollDemo>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dot navigation with scrollOnClick={false} — dots are display-only without scroll behavior.\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization — section labels and tooltip text translated.",
          "args": "{\n    sections: sections.map((s) => ({\n      ...s,\n      label:\n        s.id === \"s-intro\"\n          ? \"Introduction\"\n          : s.id === \"s-process\"\n            ? \"Process\"\n            : s.id === \"s-features\"\n              ? \"Features\"\n              : \"Tips\",\n    })),\n    position: \"right\",\n    orientation: \"vertical\",\n    locale: \"pt-BR\",\n  },\n  render: (args) => (\n    <ScrollDemo>\n      <NavDots\n        {...args}\n        className=\"sticky top-1/2 right-3 z-50 ml-auto -translate-y-1/2\"\n        style={{ position: \"sticky\", right: 12, float: \"right\" }}\n      />\n    </ScrollDemo>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) localization — section labels and tooltip text translated.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllStates",
          "description": "Side-by-side comparison of all active states (0–3) in a single view.",
          "args": "{\n    sections,\n  },\n  render: () => (\n    <div className=\"flex flex-wrap gap-8\">\n      {sections.map((_, idx) => (\n        <div key={idx} className=\"flex flex-col items-center gap-2\">\n          <p className=\"text-xs text-muted-foreground\">Active: {idx}</p>\n          <NavDots\n            sections={sections}\n            active={idx}\n            scrollOnClick={false}\n            orientation=\"vertical\"\n            className=\"relative\"\n            style={{ position: \"relative\" }}\n          />\n        </div>\n      ))}\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Side-by-side comparison of all active states (0–3) in a single view.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-wrap gap-8\">\n      {sections.map((_, idx) => (\n        <div key={idx} className=\"flex flex-col items-center gap-2\">\n          <p className=\"text-xs text-muted-foreground\">Active: {idx}</p>\n          <NavDots\n            sections={sections}\n            active={idx}\n            scrollOnClick={false}\n            orientation=\"vertical\"\n            className=\"relative\"\n            style={{ position: \"relative\" }}\n          />\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-nav-user",
      "title": "Nav User",
      "description": "A user profile dropdown menu for navigation headers, built on DropdownMenu and Avatar.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/nav-user",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "dropdown-menu",
        "avatar",
        "skeleton"
      ],
      "files": [
        "components/ds/nav-user.tsx"
      ],
      "storyTitle": "Navigation/NavUser",
      "props": [
        {
          "name": "loading",
          "control": "boolean",
          "default": "false"
        }
      ],
      "stories": [
        {
          "name": "Loading",
          "description": "Pass `loading={true}` (or omit `user`) to render the skeleton in place of the trigger button. The skeleton mirrors the exact dimensions of the loaded state — avatar slot, name line, and email line — so the layout does not shift when data arrives.\\n\\nClick **Simulate reload** to replay the transition.",
          "args": "{\n    user: mockUser,\n    groups: defaultGroups,\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "Default",
          "description": "Default NavUser with full avatar, name, email, and dropdown action groups.",
          "args": "{\n    user: mockUser,\n    groups: defaultGroups,\n    loading: false,\n  },\n  render: (args) => (\n    <div className=\"flex h-32 w-full items-center justify-end rounded-lg border bg-card px-12\">\n      <NavUser {...args} />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default NavUser with full avatar, name, email, and dropdown action groups.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithoutAvatar",
          "description": "NavUser without an avatar URL — uses initials fallback instead.",
          "args": "{\n    user: { ...mockUser, avatarUrl: undefined },\n    groups: defaultGroups,\n  },\n  render: (args) => (\n    <div className=\"flex h-32 w-full items-center justify-end rounded-lg border bg-card px-12\">\n      <NavUser {...args} />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"NavUser without an avatar URL — uses initials fallback instead.\",\n      },\n    },\n  },"
        },
        {
          "name": "DashboardMock",
          "description": "NavUser rendered inside a mock dashboard header with navigation links.",
          "args": "{\n    user: mockUser,\n    groups: defaultGroups,\n  },\n  render: (args) => (\n    <header className=\"flex h-16 w-full items-center justify-between border-b bg-background px-6\">\n      <div className=\"flex items-center gap-6\">\n        <div className=\"size-8 rounded bg-primary\" />\n        <nav className=\"flex gap-4 text-sm font-medium\">\n          <a href=\"#\" className=\"text-foreground\">\n            Dashboard\n          </a>\n          <a href=\"#\" className=\"text-muted-foreground hover:text-foreground\">\n            Projects\n          </a>\n          <a href=\"#\" className=\"text-muted-foreground hover:text-foreground\">\n            Team\n          </a>\n        </nav>\n      </div>\n      <NavUser {...args} />\n    </header>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"NavUser rendered inside a mock dashboard header with navigation links.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-navbar-floating",
      "title": "Navbar Floating",
      "description": "Navbar flutuante com blur, borda e menu mobile — inspirado em Launch UI Navbar Floating.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/navbar-floating",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "skeleton"
      ],
      "files": [
        "components/ds/navbar-floating.tsx"
      ],
      "props": [
        {
          "name": "brand",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "links",
          "required": false,
          "type": "NavbarFloatingLink[]"
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\"",
          "options": [
            "default",
            "muted"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Muted",
          "description": "",
          "args": "{ variant: \"muted\" },"
        },
        {
          "name": "WithActions",
          "description": "",
          "args": "{\n    actions: (\n      <>\n        <Button variant=\"ghost\" size=\"sm\" className=\"rounded-full\">\n          Entrar\n        </Button>\n        <Button size=\"sm\" className=\"rounded-full\">\n          Começar\n        </Button>\n      </>\n    ),\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        }
      ]
    },
    {
      "name": "ds-notification-center",
      "title": "Notification Center",
      "description": "A notification center component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/notification-center",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "popover",
        "button"
      ],
      "files": [
        "components/ds/notification-center.tsx"
      ],
      "props": [
        {
          "name": "notifications",
          "required": true,
          "type": "NotificationItem[]"
        },
        {
          "name": "onMarkAllAsRead",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "emptyText",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Dashboard/NotificationCenter",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    notifications: sampleNotifications,\n    onMarkAllAsRead: fn(),\n  },"
        },
        {
          "name": "Empty",
          "description": "",
          "args": "{\n    notifications: [],\n    onMarkAllAsRead: fn(),\n  },"
        }
      ]
    },
    {
      "name": "ds-number-field",
      "title": "Number Field",
      "description": "Campo numérico com spinbuttons — ReUI Number Field.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/number-field",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "input"
      ],
      "files": [
        "components/ds/number-field.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "number"
        },
        {
          "name": "defaultValue",
          "required": false,
          "type": "number"
        },
        {
          "name": "min",
          "required": false,
          "type": "number"
        },
        {
          "name": "max",
          "required": false,
          "type": "number"
        },
        {
          "name": "step",
          "required": false,
          "type": "number"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: number) => void"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/NumberField",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ defaultValue: 5, min: 0, max: 10 }"
        }
      ]
    },
    {
      "name": "ds-office-locations",
      "title": "OfficeLocations",
      "description": "Grid interativo de unidades e endereços com horários e status de funcionamento.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/office-locations",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/office-locations.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/OfficeLocations",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<div className=\"max-w-lg\">\n      <OfficeLocations>\n        {offices.map((office) => (\n          <OfficeLocationItem key={office.city} {...office} />\n        ))}\n      </OfficeLocations>\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex max-w-lg flex-col gap-8\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <OfficeLocations key={size}>\n          {offices.slice(0, 2).map((office) => (\n            <OfficeLocationItem key={office.city} {...office} size={size} />\n          ))}\n        </OfficeLocations>\n      ))}\n    </div>"
        },
        {
          "name": "CustomBusinessHours",
          "description": "",
          "code": "<div className=\"max-w-lg\">\n      <OfficeLocations>\n        <OfficeLocationItem\n          {...offices[0]}\n          businessHours={{ start: 8, end: 12 }}\n        />\n      </OfficeLocations>\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<div className=\"max-w-lg\">\n      <OfficeLocations>\n        {offices.slice(0, 3).map((office) => (\n          <OfficeLocationItem key={office.city} {...office} loading />\n        ))}\n      </OfficeLocations>\n    </div>"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex max-w-lg flex-col gap-8\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as UILocale[]).map((locale) => (\n        <OfficeLocations key={locale}>\n          <OfficeLocationItem\n            {...offices[0]}\n            locale={locale}\n            businessHours={{ start: 0, end: 0 }}\n          />\n        </OfficeLocations>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-onboarding",
      "title": "Onboarding",
      "description": "Passos de onboarding com progresso — ReUI Onboarding 9.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/onboarding",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "button",
        "progress",
        "skeleton"
      ],
      "files": [
        "components/ds/onboarding.tsx"
      ],
      "props": [
        {
          "name": "steps",
          "required": true,
          "type": "OnboardingStep[]"
        },
        {
          "name": "current",
          "required": false,
          "type": "number"
        },
        {
          "name": "onNext",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "onSkip",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Onboarding/Onboarding",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ steps: [{ title: \"Welcome\" }, { title: \"Setup\" }] },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ steps: [], loading: true }"
        }
      ]
    },
    {
      "name": "ds-otp-input",
      "title": "OTP Input",
      "description": "An OTP input for verification codes.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/otp-input",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "input-otp",
        "skeleton"
      ],
      "files": [
        "components/ds/otp-input.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/OtpInput",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Sizes",
          "description": "The component supports `sm`, `md`, and `lg` sizes."
        },
        {
          "name": "Invalid",
          "description": "Set `invalid` to true to apply error styling.",
          "args": "{\n    invalid: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Set `invalid` to true to apply error styling.\",\n      },\n    },\n  },"
        },
        {
          "name": "Disabled",
          "description": "Set `disabled` to true to disable interactions.",
          "args": "{\n    disabled: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Set `disabled` to true to disable interactions.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Set `loading` to true to render skeleton placeholders.",
          "args": "{\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Set `loading` to true to render skeleton placeholders.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-page-header",
      "title": "Page Header",
      "description": "Cabeçalho de página padronizado com breadcrumbs, título, tags, ações e navegação de retorno.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/page-header",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/page-header.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "React.ReactNode",
          "description": "Primary title of the page."
        },
        {
          "name": "description",
          "required": false,
          "type": "React.ReactNode",
          "description": "Secondary description or help text."
        },
        {
          "name": "breadcrumbs",
          "required": false,
          "type": "React.ReactNode",
          "description": "Breadcrumb navigation component or elements rendered above title."
        },
        {
          "name": "actions",
          "required": false,
          "type": "React.ReactNode",
          "description": "Actions or button group aligned to the right."
        },
        {
          "name": "badge",
          "required": false,
          "type": "React.ReactNode",
          "description": "Optional status badge rendered next to the title."
        },
        {
          "name": "metadata",
          "required": false,
          "type": "React.ReactNode",
          "description": "Additional metadata tags or info rendered below the description."
        },
        {
          "name": "onBack",
          "required": false,
          "type": "() => void",
          "description": "Callback fired when clicking the back button."
        },
        {
          "name": "backHref",
          "required": false,
          "type": "string",
          "description": "Optional URL for back button if functioning as a link."
        },
        {
          "name": "backLabel",
          "required": false,
          "type": "string",
          "description": "Accessible label for back button. Defaults to localized \"Back\"."
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Loading state showing matched skeleton components."
        },
        {
          "name": "as",
          "required": false,
          "type": "\"header\" | \"section\" | \"div\"",
          "description": "Root HTML element to render. Defaults to 'header'."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for text translation."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"compact\" | \"banner\"",
          "options": [
            "default",
            "compact",
            "banner"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Layout/PageHeader",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Projetos e Modelos\",\n    description: \"Gerencie modelos econômicos e conjuntos de dados do LEMA.\",\n    actions: (\n      <>\n        <Button variant=\"outline\" size=\"sm\">\n          <Download data-icon=\"inline-start\" />\n          Exportar\n        </Button>\n        <Button size=\"sm\">\n          <Plus data-icon=\"inline-start\" />\n          Novo Projeto\n        </Button>\n      </>\n    ),\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByRole(\"heading\", { level: 1 })).toHaveTextContent(\n      \"Projetos e Modelos\"\n    )\n  },"
        },
        {
          "name": "WithBreadcrumbsAndBadge",
          "description": "",
          "args": "{\n    breadcrumbs: (\n      <div className=\"flex items-center gap-1.5 pb-1 text-xs text-muted-foreground\">\n        <span>Home</span>\n        <span>/</span>\n        <span>Economia</span>\n        <span>/</span>\n        <span className=\"font-medium text-foreground\">Modelos</span>\n      </div>\n    ),\n    title: \"Modelo DSGE Brasil\",\n    badge: <Badge variant=\"secondary\">Produção v2.1</Badge>,\n    description: \"Parâmetros calibrados para o Banco Central do Brasil.\",\n    metadata: (\n      <>\n        <span className=\"text-xs text-muted-foreground\">\n          Criado em 12/03/2025\n        </span>\n        <span className=\"text-xs text-muted-foreground\">•</span>\n        <span className=\"text-xs text-muted-foreground\">Autor: Prof. LEMA</span>\n      </>\n    ),\n    actions: (\n      <Button size=\"sm\">\n        <Plus data-icon=\"inline-start\" />\n        Nova Simulação\n      </Button>\n    ),\n  },"
        },
        {
          "name": "WithBackButton",
          "description": "",
          "args": "{\n    title: \"Detalhes da Simulação #481\",\n    description: \"Convergência de equilíbrio atingida em 142 iterações.\",\n    onBack: () => alert(\"Voltar acionado!\"),\n    actions: (\n      <Button variant=\"outline\" size=\"sm\">\n        Baixar Relatório\n      </Button>\n    ),\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(\n      canvas.getByRole(\"button\", { name: \"Voltar\" })\n    ).toBeInTheDocument()\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col gap-8\">\n      <PageHeader\n        as=\"section\"\n        size=\"sm\"\n        title=\"Tamanho Pequeno (sm)\"\n        description=\"Ideal para subpáginas ou painéis compactos.\"\n        actions={<Button size=\"sm\">Ação sm</Button>}\n      />\n      <PageHeader\n        as=\"section\"\n        size=\"md\"\n        title=\"Tamanho Médio (md)\"\n        description=\"Padrão do design system para telas principais.\"\n        actions={<Button size=\"sm\">Ação md</Button>}\n      />\n      <PageHeader\n        as=\"section\"\n        size=\"lg\"\n        title=\"Tamanho Grande (lg)\"\n        description=\"Destaque para páginas de entrada ou relatórios executivos.\"\n        actions={<Button>Ação lg</Button>}\n      />\n    </div>"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-8\">\n      <PageHeader\n        as=\"section\"\n        variant=\"default\"\n        title=\"Variante Default\"\n        description=\"Possui linha divisória inferior discreta.\"\n        actions={<Button size=\"sm\">Default</Button>}\n      />\n      <PageHeader\n        as=\"section\"\n        variant=\"compact\"\n        title=\"Variante Compact\"\n        description=\"Sem borda inferior para layouts fluidos.\"\n        actions={<Button size=\"sm\">Compact</Button>}\n      />\n      <PageHeader\n        as=\"section\"\n        variant=\"banner\"\n        title=\"Variante Banner\"\n        description=\"Card estilizado com fundo destacado para áreas nobres.\"\n        actions={<Button size=\"sm\">Banner</Button>}\n      />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n    title: \"Carregando...\",\n    breadcrumbs: <span>Home / Modelos</span>,\n    actions: <Button size=\"sm\">Carregando</Button>,\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6\">\n      <PageHeader\n        as=\"section\"\n        locale=\"pt-BR\"\n        title=\"Português (pt-BR)\"\n        onBack={() => {}}\n      />\n      <PageHeader\n        as=\"section\"\n        locale=\"en-US\"\n        title=\"English (en-US)\"\n        onBack={() => {}}\n      />\n      <PageHeader\n        as=\"section\"\n        locale=\"es-ES\"\n        title=\"Español (es-ES)\"\n        onBack={() => {}}\n      />\n      <PageHeader\n        as=\"section\"\n        locale=\"fr-FR\"\n        title=\"Français (fr-FR)\"\n        onBack={() => {}}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-page-loader",
      "title": "Page Loader",
      "description": "Full-page loading overlay with two variants: a shimmer bar fixed at the top of the viewport (bar) and a centered XL spinner (spinner). Controlled by a single loading prop with fade-in/out transition, semantic color options, and i18n support.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/page-loader",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "spinner",
        "ui-i18n"
      ],
      "files": [
        "components/ds/page-loader.tsx"
      ],
      "props": [
        {
          "name": "loading",
          "required": true,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "PageLoaderVariant"
        },
        {
          "name": "size",
          "required": false,
          "type": "PageLoaderSize"
        },
        {
          "name": "color",
          "required": false,
          "type": "PageLoaderColor"
        },
        {
          "name": "overlay",
          "required": false,
          "type": "PageLoaderOverlay"
        },
        {
          "name": "blur",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "message",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Feedback/PageLoader",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    variant: \"bar\",\n    size: \"md\",\n    color: \"primary\",\n    overlay: \"soft\",\n    blur: false,\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "SpinnerVariant",
          "description": "",
          "args": "{\n    variant: \"spinner\",\n    color: \"primary\",\n    overlay: \"soft\",\n    blur: false,\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "SpinnerWithMessage",
          "description": "",
          "args": "{\n    variant: \"spinner\",\n    color: \"primary\",\n    overlay: \"subtle\",\n    message: \"Saving your changes…\",\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "WithBlur",
          "description": "",
          "args": "{\n    variant: \"bar\",\n    color: \"primary\",\n    overlay: \"subtle\",\n    blur: true,\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "SolidOverlay",
          "description": "",
          "args": "{\n    variant: \"spinner\",\n    color: \"primary\",\n    overlay: \"solid\",\n    blur: false,\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "GhostOverlay",
          "description": "",
          "args": "{\n    variant: \"bar\",\n    color: \"primary\",\n    overlay: \"ghost\",\n    blur: false,\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "SoftOverlay",
          "description": "",
          "args": "{\n    variant: \"spinner\",\n    color: \"primary\",\n    overlay: \"soft\",\n    blur: false,\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "ColorSuccess",
          "description": "",
          "args": "{\n    variant: \"bar\",\n    color: \"success\",\n    overlay: \"subtle\",\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "ColorDestructive",
          "description": "",
          "args": "{\n    variant: \"spinner\",\n    color: \"destructive\",\n    overlay: \"subtle\",\n    message: \"Something went wrong, retrying…\",\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "",
          "args": "{\n    variant: \"spinner\",\n    color: \"primary\",\n    overlay: \"subtle\",\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ loading: true },\n  parameters: { layout: \"fullscreen\" },",
          "code": "<div className=\"flex min-h-screen flex-row flex-wrap items-center justify-center gap-12 bg-background p-8\">\n      {(\n        [\n          { size: \"sm\", spinnerClass: \"size-6\" },\n          { size: \"md\", spinnerClass: \"size-10\" },\n          { size: \"lg\", spinnerClass: \"size-14\" },\n          { size: \"xl\", spinnerClass: \"size-20\" },\n          { size: \"2xl\", spinnerClass: \"size-28\" },\n          { size: \"4xl\", spinnerClass: \"size-40\" },\n        ] as const\n      ).map(({ size, spinnerClass }) => (\n        <div key={size} className=\"flex flex-col items-center gap-3\">\n          <svg\n            role=\"status\"\n            aria-label=\"Loading\"\n            className={`${spinnerClass} animate-spin text-primary`}\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            strokeWidth=\"2\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n          >\n            <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n          </svg>\n          <p className=\"text-xs font-medium text-muted-foreground\">{size}</p>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllSizesBar",
          "description": "",
          "args": "{ loading: true },\n  parameters: { layout: \"fullscreen\" },",
          "code": "<div className=\"flex min-h-screen flex-col justify-center gap-10 bg-background p-12\">\n      {(\n        [\n          { size: \"sm\", heightClass: \"h-0.5\" },\n          { size: \"md\", heightClass: \"h-1\" },\n          { size: \"lg\", heightClass: \"h-1.5\" },\n        ] as const\n      ).map(({ size, heightClass }) => (\n        <div key={size} className=\"flex flex-col gap-2\">\n          <span className=\"text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n            {size}\n          </span>\n          <div className={`w-full ${heightClass} overflow-hidden bg-muted`}>\n            <div\n              className={`h-full origin-left animate-loader-fill bg-primary`}\n            />\n          </div>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "NotLoading",
          "description": "",
          "args": "{\n    loading: false,\n    variant: \"bar\",\n    color: \"primary\",\n    overlay: \"subtle\",\n  },"
        }
      ]
    },
    {
      "name": "ds-pagination",
      "title": "Pagination UI",
      "description": "A pagination component with locale-aware aria labels, prev/next links, and ellipsis support.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/pagination",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/pagination.tsx"
      ],
      "props": [
        {
          "name": "rounded",
          "required": false,
          "type": "\"full\" | \"light\" | \"none\"",
          "options": [
            "full",
            "light",
            "none"
          ],
          "default": "full"
        }
      ],
      "storyTitle": "Navigation/Pagination",
      "stories": [
        {
          "name": "Default",
          "description": "Default pagination with previous, page numbers (1–3), ellipsis, and next buttons.",
          "code": "<Pagination>\n      <PaginationContent>\n        <PaginationItem>\n          <PaginationPrevious href=\"#\" />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">1</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" isActive>\n            2\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">3</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationEllipsis />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationNext href=\"#\" />\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization — previous/next button text translated.",
          "args": "{ locale: \"pt-BR\" },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) localization — previous/next button text translated.\",\n      },\n    },\n  },",
          "code": "<Pagination>\n      <PaginationContent>\n        <PaginationItem>\n          <PaginationPrevious href=\"#\" text=\"Previous\" />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">1</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" isActive>\n            2\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">3</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationEllipsis />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationNext href=\"#\" text=\"Next\" />\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>"
        },
        {
          "name": "RoundedFull",
          "description": "Fully rounded buttons via `rounded=\"full\"`. The default is `rounded=\"md\"` (`rounded-md`).",
          "code": "<Pagination>\n      <PaginationContent>\n        <PaginationItem>\n          <PaginationPrevious href=\"#\" rounded=\"full\" />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" rounded=\"full\">\n            1\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" isActive rounded=\"full\">\n            2\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" rounded=\"full\">\n            3\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationNext href=\"#\" rounded=\"full\" />\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>"
        },
        {
          "name": "RoundedLight",
          "description": "Lightly rounded buttons via `rounded=\"light\"`.",
          "code": "<Pagination>\n      <PaginationContent>\n        <PaginationItem>\n          <PaginationPrevious href=\"#\" rounded=\"light\" />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" rounded=\"light\">\n            1\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" isActive rounded=\"light\">\n            2\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" rounded=\"light\">\n            3\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationNext href=\"#\" rounded=\"light\" />\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>"
        },
        {
          "name": "RoundedNone",
          "description": "Square buttons via `rounded=\"none\"`.",
          "code": "<Pagination>\n      <PaginationContent>\n        <PaginationItem>\n          <PaginationPrevious href=\"#\" rounded=\"none\" />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" rounded=\"none\">\n            1\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" isActive rounded=\"none\">\n            2\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" rounded=\"none\">\n            3\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationNext href=\"#\" rounded=\"none\" />\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>"
        },
        {
          "name": "CustomText",
          "description": "Pagination with custom text labels for previous and next buttons.",
          "code": "<Pagination>\n      <PaginationContent>\n        <PaginationItem>\n          <PaginationPrevious href=\"#\" text=\"Previous\" />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">1</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" isActive>\n            2\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">3</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationNext href=\"#\" text=\"Next\" />\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>"
        }
      ]
    },
    {
      "name": "ds-particle-field",
      "title": "Particle Field",
      "description": "Fundo de constelação (partículas conectadas por linhas) para hero sections, em canvas 2D com DPR limitado e pausa automática fora da viewport.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/particle-field",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/particle-field.tsx"
      ],
      "props": [
        {
          "name": "tone",
          "required": false,
          "type": "\"primary\" | \"violet\" | \"sky\" | \"neutral\"",
          "options": [
            "primary",
            "violet",
            "sky",
            "neutral"
          ],
          "default": "primary"
        },
        {
          "name": "density",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Effects/ParticleField",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ tone: \"primary\", density: \"md\" },"
        },
        {
          "name": "AllTones",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n      {([\"primary\", \"violet\", \"sky\", \"neutral\"] as const).map((tone) => (\n        <div\n          key={tone}\n          className=\"relative flex h-48 items-center justify-center overflow-hidden rounded-2xl border border-border bg-background\"\n        >\n          <ParticleField tone={tone} />\n          <p className=\"relative z-10 text-xs font-medium text-muted-foreground\">\n            {tone}\n          </p>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllDensities",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((density) => (\n        <div\n          key={density}\n          className=\"relative flex h-48 items-center justify-center overflow-hidden rounded-2xl border border-border bg-background\"\n        >\n          <ParticleField density={density} />\n          <p className=\"relative z-10 text-xs font-medium text-muted-foreground\">\n            {density}\n          </p>\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-star-shower",
      "title": "Star Shower",
      "description": "Céu estrelado vivo em canvas 2D: estrelas pulsantes com cintilação, 18% em cruz com halo e estrelas cadentes com cauda degradê. Pausa fora da viewport e frame estático sob prefers-reduced-motion.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/star-shower",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/star-shower.tsx"
      ],
      "props": [
        {
          "name": "twinkle",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "shootingStars",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "interactive",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "tone",
          "required": false,
          "type": "\"primary\" | \"violet\" | \"sky\" | \"warm\" | \"cool\" | \"neutral\"",
          "options": [
            "primary",
            "violet",
            "sky",
            "warm",
            "cool",
            "neutral"
          ],
          "default": "primary"
        },
        {
          "name": "density",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "speed",
          "required": false,
          "type": "\"slow\" | \"normal\" | \"fast\"",
          "options": [
            "slow",
            "normal",
            "fast"
          ],
          "default": "normal"
        }
      ],
      "storyTitle": "Effects/StarShower",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    tone: \"primary\",\n    density: \"md\",\n    speed: \"normal\",\n    twinkle: true,\n    shootingStars: true,\n    interactive: true,\n  } as never,"
        },
        {
          "name": "AllTones",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      {([\"primary\", \"violet\", \"sky\", \"warm\", \"cool\", \"neutral\"] as const).map(\n        (tone) => (\n          <div\n            key={tone}\n            className=\"relative flex h-44 items-center justify-center overflow-hidden rounded-2xl border border-border bg-zinc-950\"\n          >\n            <StarShower tone={tone} density=\"md\" />\n            <span className=\"relative z-10 rounded-full bg-white/10 px-2.5 py-1 text-xs font-medium text-white capitalize backdrop-blur-sm\">\n              {tone}\n            </span>\n          </div>\n        )\n      )}\n    </div>"
        },
        {
          "name": "AllDensities",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((density) => (\n        <div\n          key={density}\n          className=\"relative flex h-48 items-center justify-center overflow-hidden rounded-2xl border border-border bg-zinc-950\"\n        >\n          <StarShower density={density} shootingStars={false} />\n          <span className=\"relative z-10 rounded-full bg-white/10 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm\">\n            {density} ·{\" \"}\n            {density === \"sm\" ? \"45\" : density === \"md\" ? \"90\" : \"140\"} estrelas\n          </span>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "AllSpeeds",
          "description": "",
          "code": "<div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n      {([\"slow\", \"normal\", \"fast\"] as const).map((speed) => (\n        <div\n          key={speed}\n          className=\"relative flex h-48 items-center justify-center overflow-hidden rounded-2xl border border-border bg-zinc-950\"\n        >\n          <StarShower speed={speed} />\n          <span className=\"relative z-10 rounded-full bg-white/10 px-2.5 py-1 text-xs font-medium text-white capitalize backdrop-blur-sm\">\n            {speed}\n          </span>\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "WithoutTwinkle",
          "description": "",
          "code": "<div className=\"grid grid-cols-2 gap-4\">\n      <div className=\"relative flex h-64 flex-col items-center justify-center overflow-hidden rounded-2xl border border-border bg-zinc-950 p-4\">\n        <StarShower twinkle />\n        <span className=\"relative z-10 inline-flex items-center gap-1.5 rounded-full bg-white/10 px-3 py-1 text-xs font-medium text-white backdrop-blur\">\n          <Sparkles className=\"size-3\" /> com cintilação\n        </span>\n      </div>\n      <div className=\"relative flex h-64 flex-col items-center justify-center overflow-hidden rounded-2xl border border-border bg-zinc-950 p-4\">\n        <StarShower twinkle={false} />\n        <span className=\"relative z-10 inline-flex items-center gap-1.5 rounded-full bg-white/10 px-3 py-1 text-xs font-medium text-white backdrop-blur\">\n          <EyeOff className=\"size-3\" /> só pulso\n        </span>\n      </div>\n    </div>"
        },
        {
          "name": "WithoutShooting",
          "description": "",
          "code": "<div className=\"grid grid-cols-2 gap-4\">\n      <div className=\"relative flex h-64 items-center justify-center overflow-hidden rounded-2xl border border-border bg-zinc-950\">\n        <StarShower shootingStars />\n        <Badge className=\"relative z-10 gap-1 bg-white/10 text-white backdrop-blur\">\n          <Zap className=\"size-3\" /> com cadentes\n        </Badge>\n      </div>\n      <div className=\"relative flex h-64 items-center justify-center overflow-hidden rounded-2xl border border-border bg-zinc-950\">\n        <StarShower shootingStars={false} />\n        <Badge\n          variant=\"secondary\"\n          className=\"relative z-10 bg-white/10 text-white backdrop-blur\"\n        >\n          só pulso\n        </Badge>\n      </div>\n    </div>"
        },
        {
          "name": "Interactive",
          "description": "",
          "code": "<div className=\"relative flex min-h-[420px] w-full flex-col items-center justify-center overflow-hidden rounded-2xl bg-zinc-950 p-8\">\n      <StarShower interactive tone=\"violet\" density=\"lg\" />\n      <div className=\"relative z-10 max-w-md rounded-2xl border border-white/10 bg-white/[0.06] p-6 backdrop-blur-md\">\n        <h3 className=\"font-semibold tracking-tight text-white\">\n          Parallax por profundidade\n        </h3>\n        <p className=\"mt-1.5 text-sm leading-relaxed text-white/60\">\n          Mova o cursor. Estrelas maiores (cross) deslocam até 6px; as menores,\n          quase nada. Profundidade = `0.4 + (raio/2.8)*0.6`.\n        </p>\n        <div className=\"mt-4 flex gap-2\">\n          <Badge className=\"bg-white text-zinc-900\">interactive</Badge>\n          <Badge variant=\"outline\" className=\"border-white/20 text-white\">\n            lg · violet\n          </Badge>\n        </div>\n      </div>\n    </div>"
        },
        {
          "name": "LightBackground",
          "description": "",
          "code": "<div className=\"relative flex min-h-[420px] w-full flex-col items-center justify-center overflow-hidden rounded-2xl border border-border bg-background p-8\">\n      <StarShower tone=\"primary\" density=\"md\" />\n      <div className=\"relative z-10 max-w-xl text-center\">\n        <h2 className=\"text-2xl font-bold tracking-tight text-foreground\">\n          Também funciona no claro\n        </h2>\n        <p className=\"mt-2 text-sm text-muted-foreground\">\n          Em `bg-background`, o `tone=primary` usa `var(--primary)` escuro. As\n          cadentes ainda riscam — teste em `bg-zinc-950` para o efeito hero\n          noturno completo.\n        </p>\n      </div>\n    </div>"
        },
        {
          "name": "WarmCool",
          "description": "",
          "code": "<div className=\"grid grid-cols-2 gap-4\">\n      <div className=\"relative flex h-64 items-center justify-center overflow-hidden rounded-2xl bg-[#1a1300] p-4\">\n        <StarShower tone=\"warm\" />\n        <span className=\"relative z-10 rounded-full bg-amber-500/20 px-3 py-1 text-xs font-medium text-amber-200\">\n          warm · amber\n        </span>\n      </div>\n      <div className=\"relative flex h-64 items-center justify-center overflow-hidden rounded-2xl bg-[#001a2e] p-4\">\n        <StarShower tone=\"cool\" />\n        <span className=\"relative z-10 rounded-full bg-sky-500/20 px-3 py-1 text-xs font-medium text-sky-200\">\n          cool · sky\n        </span>\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-passkey-prompt",
      "title": "PasskeyPrompt",
      "description": "Botão e prompt para autenticação biométrica e chaves de segurança WebAuthn / Passkeys.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/passkey-prompt",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/passkey-prompt.tsx"
      ],
      "props": [
        {
          "name": "onAuthenticate",
          "required": false,
          "type": "() => Promise<boolean | void> | void"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "supported",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"card\" | \"button\"",
          "options": [
            "card",
            "button"
          ],
          "default": "card"
        }
      ],
      "storyTitle": "Actions/PasskeyPrompt",
      "stories": [
        {
          "name": "CardVariant",
          "description": "",
          "args": "{\n    variant: \"card\",\n  },\n  render: (args) => (\n    <div className=\"w-96\">\n      <PasskeyPrompt {...args} />\n    </div>\n  ),"
        },
        {
          "name": "ButtonVariant",
          "description": "",
          "args": "{\n    variant: \"button\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <PasskeyPrompt {...args} />\n    </div>\n  ),"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    variant: \"card\",\n    loading: true,\n  },\n  render: (args) => (\n    <div className=\"w-96\">\n      <PasskeyPrompt {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-password-strength-meter",
      "title": "PasswordStrengthMeter",
      "description": "Indicador dinâmico de segurança de senha com 4 níveis semânticos e checklist de requisitos em tempo real.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/password-strength-meter",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/password-strength-meter.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Feedback/PasswordStrengthMeter",
      "stories": [
        {
          "name": "Empty",
          "description": "",
          "args": "{\n    password: \"\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <PasswordStrengthMeter {...args} />\n    </div>\n  ),"
        },
        {
          "name": "WeakPassword",
          "description": "",
          "args": "{\n    password: \"senha\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <PasswordStrengthMeter {...args} />\n    </div>\n  ),"
        },
        {
          "name": "MediumPassword",
          "description": "",
          "args": "{\n    password: \"SenhaLonga\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <PasswordStrengthMeter {...args} />\n    </div>\n  ),"
        },
        {
          "name": "StrongPassword",
          "description": "",
          "args": "{\n    password: \"SenhaForte123\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <PasswordStrengthMeter {...args} />\n    </div>\n  ),"
        },
        {
          "name": "ExcellentPassword",
          "description": "",
          "args": "{\n    password: \"SenhaExcepcional@2026\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <PasswordStrengthMeter {...args} />\n    </div>\n  ),"
        },
        {
          "name": "WithoutChecklist",
          "description": "",
          "args": "{\n    password: \"MinhaSenha@456\",\n    showChecklist: false,\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <PasswordStrengthMeter {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-phone-input",
      "title": "Phone Input",
      "description": "Phone input field with country code selection and flags.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/phone-input",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "command",
        "popover",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/phone-input.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "string"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "country",
          "required": false,
          "type": "string"
        },
        {
          "name": "onCountryChange",
          "required": false,
          "type": "(country: string) => void"
        },
        {
          "name": "countries",
          "required": false,
          "type": "CountryData[]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "invalid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    placeholder: \"(00) 00000-0000\",\n    \"aria-label\": \"Phone number\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    disabled: true,\n    value: \"11 98888-8888\",\n  },"
        },
        {
          "name": "Invalid",
          "description": "",
          "args": "{\n    invalid: true,\n    value: \"numero_invalido\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-pie-chart",
      "title": "Pie Chart",
      "description": "A responsive pie and donut chart with interactive center label, legend, and outer slice labels.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/pie-chart",
      "dependencies": [
        "recharts",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/pie-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "PieChartItem[]"
        },
        {
          "name": "variant",
          "required": false,
          "type": "PieChartVariant"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "showLegend",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "legendPosition",
          "required": false,
          "type": "LegendPosition",
          "description": "@default \"bottom\""
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showLabels",
          "required": false,
          "type": "boolean",
          "description": "Show percentage labels on the outside of each slice"
        },
        {
          "name": "innerLabel",
          "required": false,
          "type": "string",
          "description": "Center label shown when no slice is hovered (donut only) — defaults to \"Total\""
        },
        {
          "name": "paddingAngle",
          "required": false,
          "type": "number",
          "description": "Gap between slices in degrees"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Format slice values in the tooltip, legend, and donut center"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale used for default number and percentage formatting"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        }
      ],
      "storyTitle": "Data Display/PieChart",
      "stories": [
        {
          "name": "Default",
          "description": "Standard pie chart showing enrollment distribution across four program types with legend and tooltip.",
          "args": "{\n    title: \"Enrollment by Program\",\n    subtitle: \"Semester 2025.1 — 7,540 students total\",\n    data: enrollmentByProgram,\n    variant: \"pie\",\n    height: 280,\n    showLegend: true,\n    legendPosition: \"bottom\",\n    showTooltip: true,\n    showLabels: false,\n    paddingAngle: 0,\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n    valueFormatter: formatStudents,\n  },"
        },
        {
          "name": "Donut",
          "description": "Donut chart with an interactive center label showing the total student count; hover a slice to see its breakdown.",
          "args": "{\n    title: \"Enrollment by Program\",\n    subtitle: \"Hover a slice to see its breakdown in the center\",\n    data: enrollmentByProgram,\n    variant: \"donut\",\n    showLegend: true,\n    showTooltip: false,\n    innerLabel: \"Students\",\n    valueFormatter: formatStudents,\n  },"
        },
        {
          "name": "DonutBudget",
          "description": "Donut chart showing budget allocation percentages with a Budget center label and percentage value formatter.",
          "args": "{\n    title: \"Budget Allocation\",\n    subtitle: \"Fiscal year 2025 — percentage of total\",\n    data: budgetAllocation,\n    variant: \"donut\",\n    showLegend: true,\n    showTooltip: false,\n    innerLabel: \"Budget\",\n    valueFormatter: formatPct,\n    height: 300,\n  },"
        },
        {
          "name": "WithSliceLabels",
          "description": "Pie chart with percentage labels rendered outside each slice showing the breakdown of absence reasons.",
          "args": "{\n    title: \"Absences by Reason\",\n    subtitle: \"Labels show percentage per category\",\n    data: absencesByReason,\n    variant: \"pie\",\n    showLegend: true,\n    showTooltip: true,\n    showLabels: true,\n    height: 300,\n  },"
        },
        {
          "name": "DonutWithLabels",
          "description": "Donut chart combining a center label with outer slice labels for a comprehensive absence reason breakdown.",
          "args": "{\n    title: \"Absences by Reason\",\n    subtitle: \"Donut + outer labels — both at once\",\n    data: absencesByReason,\n    variant: \"donut\",\n    showLegend: false,\n    showTooltip: true,\n    showLabels: true,\n    innerLabel: \"Absences\",\n    height: 300,\n  },"
        },
        {
          "name": "PaddedSlices",
          "description": "Donut chart with `paddingAngle={4}` creating visible gaps between enrollment program slices for visual separation.",
          "args": "{\n    title: \"Enrollment by Program\",\n    subtitle: \"paddingAngle={4} — visible gap between slices\",\n    data: enrollmentByProgram,\n    variant: \"donut\",\n    paddingAngle: 4,\n    showLegend: true,\n    showTooltip: true,\n    innerLabel: \"Students\",\n    valueFormatter: formatStudents,\n  },"
        },
        {
          "name": "CustomColors",
          "description": "Donut chart using semantic color tokens for completed, in-progress, and dropped course status with padding between slices.",
          "args": "{\n    title: \"Course Completion Rate\",\n    subtitle:\n      \"Semantic tokens: var(--chart-2), var(--chart-3), var(--destructive)\",\n    data: completionRate,\n    variant: \"donut\",\n    showLegend: true,\n    showTooltip: true,\n    innerLabel: \"Students\",\n    valueFormatter: formatPct,\n    paddingAngle: 3,\n  },"
        },
        {
          "name": "NoLegend",
          "description": "Pie chart relying solely on tooltips for slice identification, with the legend hidden for a cleaner presentation.",
          "args": "{\n    title: \"Budget Allocation\",\n    subtitle: \"Tooltip only — no legend\",\n    data: budgetAllocation,\n    variant: \"pie\",\n    showLegend: false,\n    showTooltip: true,\n    height: 300,\n  },"
        },
        {
          "name": "WithLocale",
          "description": "Pie chart using Portuguese locale to format percentage values with a comma as the decimal separator and outer labels.",
          "args": "{\n    title: \"Budget (BR Locale)\",\n    subtitle: \"locale='pt-BR' formats percentages with a comma\",\n    data: budgetAllocation,\n    variant: \"pie\",\n    showLegend: true,\n    showTooltip: true,\n    showLabels: true,\n    locale: \"pt-BR\",\n    height: 300,\n  },"
        },
        {
          "name": "LegendPositions",
          "description": "Grid of four donut charts placing the legend at top, right, bottom, and left positions for comparison.",
          "args": "{ data: enrollmentByProgram },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <PieChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={enrollmentByProgram}\n          variant=\"donut\"\n          showLegend\n          legendPosition={pos}\n          showTooltip={false}\n          innerLabel=\"Students\"\n          valueFormatter={formatStudents}\n          height={300}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <PieChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={enrollmentByProgram}\n          variant=\"donut\"\n          showLegend\n          legendPosition={pos}\n          showTooltip={false}\n          innerLabel=\"Students\"\n          valueFormatter={formatStudents}\n          height={300}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the pie chart with an animated skeleton that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Enrollment by Program\",\n    subtitle: \"Semester 2025.1 — 7,540 students total\",\n    data: enrollmentByProgram,\n    variant: \"pie\",\n    showLegend: true,\n    showTooltip: true,\n    valueFormatter: formatStudents,\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the pie chart renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Enrollment by Program\",\n    subtitle: \"Semester 2025.1\",\n    data: [],\n    variant: \"pie\",\n    height: 280,\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Donut chart with a footer showing total enrollment count, number of courses, and an update timestamp.",
          "args": "{\n    title: \"Enrollment by Program\",\n    subtitle: \"Semester 2025.1\",\n    data: enrollmentByProgram,\n    variant: \"donut\",\n    showLegend: true,\n    showTooltip: false,\n    innerLabel: \"Students\",\n    valueFormatter: formatStudents,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <div className=\"flex items-center gap-3\">\n          <span className=\"flex items-center gap-1.5\">\n            <GraduationCap className=\"size-3.5 text-muted-foreground\" />\n            <span>7,540 enrolled</span>\n          </span>\n          <span className=\"flex items-center gap-1.5\">\n            <BookOpen className=\"size-3.5 text-muted-foreground\" />\n            <span>48 courses</span>\n          </span>\n        </div>\n        <span className=\"flex items-center gap-1.5 text-muted-foreground/70\">\n          <Users className=\"size-3\" />\n          Updated today\n        </span>\n      </div>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-pill-group",
      "title": "Pill Group",
      "description": "A horizontal filter bar with pill-shaped toggle buttons, item counts, per-item intent colors, icon support, and automatic scroll overflow with fade indicators.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/pill-group",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/pill-group.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "PillGroupItem[]"
        },
        {
          "name": "value",
          "required": false,
          "type": "string | string[] | null",
          "description": "Controlled selected value(s).\nPass a `string` for single-select or `string[]` for multi-select.\nPass `null` to represent \"nothing selected\"."
        },
        {
          "name": "defaultValue",
          "required": false,
          "type": "string | string[] | null",
          "description": "Initial selected value(s) for uncontrolled usage."
        },
        {
          "name": "multiple",
          "required": false,
          "type": "boolean",
          "description": "Allow selecting multiple items simultaneously."
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: string | string[] | null) => void"
        },
        {
          "name": "size",
          "required": false,
          "type": "PillGroupSize"
        },
        {
          "name": "showCount",
          "required": false,
          "type": "boolean",
          "description": "Show counts next to item labels.\nAuto-enabled when at least one item has a `count` field."
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "label",
          "required": false,
          "type": "string",
          "description": "Accessible label for the filter group. Falls back to i18n string."
        },
        {
          "name": "skeletonCount",
          "required": false,
          "type": "number",
          "description": "Number of skeleton pills shown while loading. Defaults to items.length or 3."
        },
        {
          "name": "active",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"success\" | \"warning\" | \"destructive\"",
          "options": [
            "default",
            "success",
            "warning",
            "destructive"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Form/PillGroup",
      "stories": [
        {
          "name": "Default",
          "description": "Default single-select filter bar. The first item acts as an \"All\" option. Counts are shown automatically because the items include `count` fields.",
          "args": "{\n    items: AUDIT_ITEMS,\n    defaultValue: \"all\",\n    multiple: false,\n    size: \"md\",\n    loading: false,\n    disabled: false,\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'Default single-select filter bar. The first item acts as an \"All\" option. Counts are shown automatically because the items include `count` fields.',\n      },\n    },\n  },"
        },
        {
          "name": "AllSizes",
          "description": "Comparison of the three size presets. Typography and pill height scale together following the design system size convention.",
          "args": "{ items: AUDIT_ITEMS },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison of the three size presets. Typography and pill height scale together following the design system size convention.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithIntents",
          "description": "Each item carries its own `intent` field. When active, the pill fills with the corresponding semantic color — useful for risk-matrix and status filters.",
          "args": "{\n    items: PRIORITY_ITEMS,\n    defaultValue: \"critical\",\n    label: \"Filter by priority\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Each item carries its own `intent` field. When active, the pill fills with the corresponding semantic color — useful for risk-matrix and status filters.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithIcons",
          "description": "Items can include a Lucide icon component via the `icon` field. The icon scales with the `size` prop and is always hidden from assistive technology.",
          "args": "{\n    items: STATUS_ITEMS,\n    defaultValue: \"all\",\n    label: \"Filter by status\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Items can include a Lucide icon component via the `icon` field. The icon scales with the `size` prop and is always hidden from assistive technology.\",\n      },\n    },\n  },"
        },
        {
          "name": "MultiSelect",
          "description": "Pass `multiple` to allow selecting any combination of items. Each pill toggles independently. The `onChange` callback receives a `string[]`.",
          "args": "{\n    items: AUDIT_ITEMS.filter((i) => i.value !== \"all\"),\n    label: \"Audit types\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Pass `multiple` to allow selecting any combination of items. Each pill toggles independently. The `onChange` callback receives a `string[]`.\",\n      },\n    },\n  },"
        },
        {
          "name": "ScrollOverflow",
          "description": "When items overflow the container width, gradient fade indicators appear on the overflowing edges. The bar scrolls horizontally while the fades update reactively via `ResizeObserver`.",
          "args": "{ items: MANY_ITEMS },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"When items overflow the container width, gradient fade indicators appear on the overflowing edges. The bar scrolls horizontally while the fades update reactively via `ResizeObserver`.\",\n      },\n    },\n  },"
        },
        {
          "name": "NoCount",
          "description": "Set `showCount={false}` to suppress counts globally — useful when the numbers are not meaningful in a given context.",
          "args": "{\n    items: AUDIT_ITEMS,\n    defaultValue: \"all\",\n    showCount: false,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Set `showCount={false}` to suppress counts globally — useful when the numbers are not meaningful in a given context.\",\n      },\n    },\n  },"
        },
        {
          "name": "PartialCounts",
          "description": "Items without a `count` field simply show no count, while others display their number. `showCount` is still auto-enabled because at least one item has a count.",
          "args": "{\n    items: PARTIAL_ITEMS,\n    defaultValue: \"all\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Items without a `count` field simply show no count, while others display their number. `showCount` is still auto-enabled because at least one item has a count.\",\n      },\n    },\n  },"
        },
        {
          "name": "Controlled",
          "description": "Controlled mode — value and setter are managed externally. Clicking the active pill deselects it (value becomes `null`).",
          "args": "{ items: PRIORITY_ITEMS },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Controlled mode — value and setter are managed externally. Clicking the active pill deselects it (value becomes `null`).\",\n      },\n    },\n  },"
        },
        {
          "name": "Disabled",
          "description": "The `disabled` prop disables the entire group. Individual items can be disabled via their own `disabled` field on the item object.",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          Group disabled (all items)\n        </p>\n        <PillGroup items={AUDIT_ITEMS} defaultValue=\"all\" disabled />\n      </div>\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          Individual items disabled\n        </p>\n        <PillGroup\n          items={[\n            { value: \"all\", label: \"All\", count: 120 },\n            { value: \"normal\", label: \"Normal Audit\", count: 45 },\n            { value: \"malha\", label: \"Tax Mesh\", count: 38, disabled: true },\n            { value: \"both\", label: \"Permanent\", count: 37, disabled: true },\n          ]}\n          defaultValue=\"all\"\n        />\n      </div>\n    </div>"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` while data is fetching. Skeleton pills matching the real layout prevent layout shift when data arrives. The number of skeleton pills matches `items.length` when items are known.",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex items-center gap-4\">\n          <span className=\"w-6 shrink-0 text-xs font-medium text-muted-foreground\">\n            {size}\n          </span>\n          <PillGroup items={AUDIT_ITEMS} size={size} loading />\n        </div>\n      ))}\n    </div>"
        },
        {
          "name": "LocalePTBR",
          "description": "The `locale` prop is forwarded to `Intl.NumberFormat` for count formatting and to the i18n dictionary for the group's accessible label.",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div>\n        <p className=\"mb-2 text-xs text-muted-foreground\">\n          Locale: pt-BR — contagens formatadas com separador brasileiro\n        </p>\n        <PillGroup\n          locale=\"pt-BR\"\n          items={[\n            { value: \"todos\", label: \"Todos\", count: 1234 },\n            { value: \"normal\", label: \"Auditoria Normal\", count: 456 },\n            { value: \"malha\", label: \"Malha Fiscal\", count: 389 },\n            { value: \"permanente\", label: \"Acomp. Permanente\", count: 389 },\n          ]}\n          defaultValue=\"todos\"\n          label=\"Filtrar por tipo de auditoria\"\n        />\n      </div>\n    </div>"
        },
        {
          "name": "RiskMatrixExample",
          "description": "Realistic usage above a data panel — mirrors the original `RiskMatrixFilterBar` use case with intent-colored pills and live count feedback.",
          "code": "<div className=\"flex flex-col gap-3 rounded-xl border p-4\">\n        <div className=\"flex items-center justify-between\">\n          <span className=\"text-sm font-medium\">Risk Matrix</span>\n          <span className=\"text-xs text-muted-foreground\">\n            Showing:{\" \"}\n            {filter ? (items.find((i) => i.value === filter)?.count ?? 0) : 95}{\" \"}\n            entries\n          </span>\n        </div>\n        <PillGroup\n          items={items}\n          value={filter}\n          onChange={(v) => setFilter(v as string | null)}\n          label=\"Filter by risk level\"\n        />\n        <div className=\"flex h-24 items-center justify-center rounded-lg bg-muted/40\">\n          <span className=\"text-xs text-muted-foreground\">\n            {filter\n              ? `Showing ${items.find((i) => i.value === filter)?.label} entries`\n              : \"Showing all entries\"}\n          </span>\n        </div>\n      </div>"
        }
      ]
    },
    {
      "name": "ds-press-wall",
      "title": "PressWall",
      "description": "Mural de menções na imprensa, veículos de mídia e notícias institucionais.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/press-wall",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "skeleton"
      ],
      "files": [
        "components/ds/press-wall.tsx"
      ],
      "props": [
        {
          "name": "kicker",
          "required": false,
          "type": "string",
          "description": "Small uppercase label above the logo grid, e.g. \"As seen in\"."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/PressWall",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<PressWall kicker=\"As seen in\">\n      {logos.map((name) => (\n        <PressWallLogo key={name} label={name}>\n          <Wordmark>{name}</Wordmark>\n        </PressWallLogo>\n      ))}\n    </PressWall>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col gap-10\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <PressWall key={size} kicker={`size=\"${size}\"`}>\n          {logos.slice(0, 4).map((name) => (\n            <PressWallLogo key={name} label={name} size={size}>\n              <Wordmark>{name}</Wordmark>\n            </PressWallLogo>\n          ))}\n        </PressWall>\n      ))}\n    </div>"
        },
        {
          "name": "AsLinks",
          "description": "",
          "code": "<PressWall kicker=\"Featured on\">\n      {logos.slice(0, 4).map((name) => (\n        <PressWallLogo key={name} label={`Read the ${name} article`} href=\"#\">\n          <Wordmark>{name}</Wordmark>\n        </PressWallLogo>\n      ))}\n    </PressWall>"
        },
        {
          "name": "WithAwards",
          "description": "",
          "code": "<div className=\"flex flex-col items-center gap-6\">\n      <PressWall kicker=\"Recognized by\">\n        {logos.slice(0, 3).map((name) => (\n          <PressWallLogo key={name} label={name}>\n            <Wordmark>{name}</Wordmark>\n          </PressWallLogo>\n        ))}\n      </PressWall>\n      <div className=\"flex flex-wrap justify-center gap-2\">\n        <PressWallAward label=\"Product of the Year\" icon={Trophy} />\n        <PressWallAward label=\"Editor's Choice\" icon={Award} />\n        <PressWallAward label=\"4.9/5 rating\" icon={Star} />\n      </div>\n    </div>"
        },
        {
          "name": "Labeled",
          "description": "",
          "code": "<PressWall kicker=\"Industry recognition\">\n      {logos.slice(0, 4).map((name) => (\n        <PressWallLogo key={name} label={name} showLabel>\n          <Wordmark>{name}</Wordmark>\n        </PressWallLogo>\n      ))}\n    </PressWall>"
        }
      ]
    },
    {
      "name": "ds-pricing-calculator",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/pricing-calculator",
      "dependencies": [],
      "registryDependencies": [
        "slider",
        "switch",
        "label",
        "button",
        "badge"
      ],
      "files": [
        "components/ds/pricing-calculator.tsx"
      ],
      "props": [
        {
          "name": "basePrice",
          "required": false,
          "type": "number"
        },
        {
          "name": "unitLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "unitPrice",
          "required": false,
          "type": "number"
        },
        {
          "name": "minUnits",
          "required": false,
          "type": "number"
        },
        {
          "name": "maxUnits",
          "required": false,
          "type": "number"
        },
        {
          "name": "step",
          "required": false,
          "type": "number"
        },
        {
          "name": "discountPercent",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "features",
          "required": false,
          "type": "string[]"
        }
      ],
      "storyTitle": "SaaS/PricingCalculator",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    basePrice: 0,\n    unitLabel: \"usuários\",\n    unitPrice: 45.5,\n    minUnits: 1,\n    maxUnits: 50,\n    step: 1,\n    discountPercent: 15,\n    title: \"Plano Corporativo\",\n    description:\n      \"Arraste o slider para simular o custo mensal para o seu time.\",\n    className: \"w-full max-w-4xl mx-auto\",\n  },"
        },
        {
          "name": "HighVolumeAPI",
          "description": "",
          "args": "{\n    basePrice: 99,\n    unitLabel: \"milhões de requisições\",\n    unitPrice: 5,\n    minUnits: 1,\n    maxUnits: 100,\n    step: 5,\n    discountPercent: 25,\n    currency: \"$\",\n    title: \"Plataforma de APIs\",\n    description:\n      \"Escale suas aplicações sem preocupações. O plano base inclui 1 milhão de requisições.\",\n    features: [\n      \"Rate limits personalizados\",\n      \"SLA de 99.99%\",\n      \"IPs dedicados\",\n      \"Suporte via Slack\",\n    ],\n    className: \"w-full max-w-4xl mx-auto\",\n  },"
        }
      ]
    },
    {
      "name": "ds-pricing-card",
      "title": "Pricing Card",
      "description": "Card de plano com preço, badge popular, features e CTA — átomo base pricing.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/pricing-card",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "button",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/pricing-card.tsx"
      ],
      "props": [
        {
          "name": "name",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "price",
          "required": true,
          "type": "number"
        },
        {
          "name": "originalPrice",
          "required": false,
          "type": "number"
        },
        {
          "name": "period",
          "required": false,
          "type": "\"month\" | \"year\" | \"lifetime\""
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "features",
          "required": false,
          "type": "PricingFeature[]"
        },
        {
          "name": "action",
          "required": false,
          "type": "{ label: string; href?: string; onClick?: () => void }"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "featured",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Pricing/PricingCard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    name: \"Pro\",\n    description: \"For growing teams\",\n    price: 49,\n    period: \"month\",\n    features: [\n      { label: \"10 seats\", included: true },\n      { label: \"Priority support\", included: true },\n      { label: \"SSO\", included: false },\n    ],\n    action: { label: \"Get started\" },\n  },"
        },
        {
          "name": "Featured",
          "description": "",
          "args": "{\n    name: \"Business\",\n    description: \"Most popular\",\n    price: 99,\n    period: \"month\",\n    featured: true,\n    badge: \"Most popular\",\n    features: [\n      { label: \"Unlimited\", included: true },\n      { label: \"SSO\", included: true },\n    ],\n    action: { label: \"Start free trial\" },\n  },"
        },
        {
          "name": "WithOriginalPrice",
          "description": "",
          "args": "{\n    name: \"Lifetime\",\n    description: \"Pay once\",\n    price: 119,\n    originalPrice: 199,\n    period: \"lifetime\",\n    features: [{ label: \"All access\", included: true }],\n    action: { label: \"Buy now\" },\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ name: \"Pro\", price: 49, loading: true },"
        }
      ]
    },
    {
      "name": "ds-pricing-comparison",
      "title": "Pricing Comparison",
      "description": "Tabela comparativa feature × plano — blockus #06.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/pricing-comparison",
      "dependencies": [],
      "registryDependencies": [
        "table"
      ],
      "files": [
        "components/ds/pricing-comparison.tsx"
      ],
      "props": [
        {
          "name": "plans",
          "required": true,
          "type": "PricingComparisonPlan[]"
        },
        {
          "name": "features",
          "required": true,
          "type": "PricingComparisonFeature[]"
        }
      ],
      "storyTitle": "Pricing/PricingComparison",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    plans: [\n      { name: \"Free\" },\n      { name: \"Pro\", featured: true, price: \"$49\" },\n      { name: \"Enterprise\", price: \"$99\" },\n    ],\n    features: [\n      {\n        category: \"Features\",\n        items: [\n          { label: \"Projects\", values: [\"1\", \"10\", \"Unlimited\"] },\n          { label: \"Support\", values: [false, true, true] },\n        ],\n      },\n      {\n        category: \"Security\",\n        items: [{ label: \"SSO\", values: [false, true, true] }],\n      },\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-pricing-grid",
      "title": "Pricing Grid",
      "description": "Grid 3 cards + toggle mensal/anual — blockus #02 #04 #12.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/pricing-grid",
      "dependencies": [],
      "registryDependencies": [
        "ds-pricing-card",
        "toggle-group",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/pricing-grid.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "plans",
          "required": true,
          "type": "PricingPlan[]"
        },
        {
          "name": "billing",
          "required": false,
          "type": "\"monthly\" | \"yearly\""
        },
        {
          "name": "onBillingChange",
          "required": false,
          "type": "(billing: \"monthly\" | \"yearly\") => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Pricing/PricingGrid",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ plans, title: \"Pricing\", description: \"Simple transparent pricing.\" },"
        },
        {
          "name": "Yearly",
          "description": "",
          "args": "{ plans, billing: \"yearly\" }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ plans, loading: true }"
        }
      ]
    },
    {
      "name": "ds-product-card",
      "title": "Product Card",
      "description": "Card de produto eCommerce — ReUI Product Card.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/product-card",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "badge",
        "button",
        "skeleton"
      ],
      "files": [
        "components/ds/product-card.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "price",
          "required": true,
          "type": "string"
        },
        {
          "name": "originalPrice",
          "required": false,
          "type": "string"
        },
        {
          "name": "imageSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "badge",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Commerce/ProductCard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Shoes\",\n    price: \"$99\",\n    imageSrc: \"https://picsum.photos/300/200\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ title: \"x\", price: \"x\", loading: true },"
        }
      ]
    },
    {
      "name": "ds-profile",
      "title": "Profile",
      "description": "Card de perfil — ReUI Profile 9.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/profile",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "avatar",
        "button",
        "badge",
        "skeleton"
      ],
      "files": [
        "components/ds/profile.tsx"
      ],
      "props": [
        {
          "name": "name",
          "required": true,
          "type": "string"
        },
        {
          "name": "role",
          "required": false,
          "type": "string"
        },
        {
          "name": "bio",
          "required": false,
          "type": "string"
        },
        {
          "name": "avatarUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "stats",
          "required": false,
          "type": "{ label: string; value: string }[]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Dashboard/Profile",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    name: \"Ana Silva\",\n    role: \"Designer\",\n    bio: \"Building DS\",\n    avatarUrl: \"https://picsum.photos/100/100\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ name: \"x\", loading: true }"
        }
      ]
    },
    {
      "name": "ds-progress-bar",
      "title": "Progress Bar",
      "description": "Horizontal progress indicator with animated fill, configurable label positions, size presets, custom fill/track color overrides via CSS tokens, getValueLabel for custom label formatting, max prop, and semantic color intents. Built on the Radix UI Progress primitive.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/progress-bar",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "tooltip"
      ],
      "files": [
        "components/ds/progress-bar.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "number"
        },
        {
          "name": "name",
          "required": false,
          "type": "string"
        },
        {
          "name": "namePosition",
          "required": false,
          "type": "\"left\" | \"right\""
        },
        {
          "name": "upper",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showLabel",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "labelPosition",
          "required": false,
          "type": "\"left\" | \"right\""
        },
        {
          "name": "labelLayout",
          "required": false,
          "type": "ProgressBarLabelLayout"
        },
        {
          "name": "labelWidth",
          "required": false,
          "type": "number"
        },
        {
          "name": "intent",
          "required": false,
          "type": "ProgressBarIntent"
        },
        {
          "name": "size",
          "required": false,
          "type": "ProgressBarSize"
        },
        {
          "name": "total",
          "required": false,
          "type": "number"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "precision",
          "required": false,
          "type": "number"
        },
        {
          "name": "max",
          "required": false,
          "type": "number"
        },
        {
          "name": "getValueLabel",
          "required": false,
          "type": "(value: number, max: number) => string"
        },
        {
          "name": "tooltip",
          "required": false,
          "type": "ReactNode"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale used for formatting the percentage label"
        },
        {
          "name": "fillColor",
          "required": false,
          "type": "string",
          "description": "Override fill color via CSS token `--progress-fill`.\nAccepts any CSS color value or `var(--my-token)`.\n@example fillColor=\"var(--color-brand)\""
        },
        {
          "name": "trackColor",
          "required": false,
          "type": "string",
          "description": "Override track (background) color via CSS token `--progress-track`.\nAccepts any CSS color value or `var(--my-token)`."
        },
        {
          "name": "position",
          "required": false,
          "type": "\"left\" | \"right\"",
          "options": [
            "left",
            "right"
          ],
          "default": "left"
        }
      ],
      "storyTitle": "Feedback/ProgressBar",
      "stories": [
        {
          "name": "Default",
          "description": "Default progress bar at 65% with primary intent and inline label.",
          "args": "{\n    value: 65,\n    name: \"Progress\",\n    namePosition: \"left\",\n    upper: false,\n    showLabel: true,\n    labelPosition: \"left\",\n    labelLayout: \"above\",\n    intent: \"primary\",\n    size: \"sm\",\n    loading: false,\n    precision: 0,\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default progress bar at 65% with primary intent and inline label.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllIntents",
          "description": "Comparison of all four intent colors — primary, secondary, success, and destructive.",
          "args": "{ value: 75 },\n  render: () => (\n    <div className=\"flex w-80 flex-col gap-4\">\n      <ProgressBar value={75} intent=\"primary\" name=\"Primary\" />\n      <ProgressBar value={60} intent=\"secondary\" name=\"Secondary\" />\n      <ProgressBar value={85} intent=\"success\" name=\"Success\" />\n      <ProgressBar value={40} intent=\"destructive\" name=\"Destructive\" />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison of all four intent colors — primary, secondary, success, and destructive.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex w-80 flex-col gap-4\">\n      <ProgressBar value={75} intent=\"primary\" name=\"Primary\" />\n      <ProgressBar value={60} intent=\"secondary\" name=\"Secondary\" />\n      <ProgressBar value={85} intent=\"success\" name=\"Success\" />\n      <ProgressBar value={40} intent=\"destructive\" name=\"Destructive\" />\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "Comparison of all three size presets — sm, md, and lg.",
          "args": "{ value: 70 },\n  render: () => (\n    <div className=\"flex w-80 flex-col gap-4\">\n      <ProgressBar value={70} size=\"sm\" name=\"Small\" />\n      <ProgressBar value={70} size=\"md\" name=\"Medium\" />\n      <ProgressBar value={70} size=\"lg\" name=\"Large\" />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story: \"Comparison of all three size presets — sm, md, and lg.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex w-80 flex-col gap-4\">\n      <ProgressBar value={70} size=\"sm\" name=\"Small\" />\n      <ProgressBar value={70} size=\"md\" name=\"Medium\" />\n      <ProgressBar value={70} size=\"lg\" name=\"Large\" />\n    </div>"
        },
        {
          "name": "WithPrecision",
          "description": "Progress bar with varying decimal precision — 2, 1, and 0 decimal places.",
          "args": "{\n    value: 75.642,\n    precision: 2,\n    name: \"Detailed Progress\",\n  },\n  render: (args) => (\n    <div className=\"flex w-96 flex-col gap-4\">\n      <ProgressBar {...args} value={75.642} precision={2} name=\"2 Decimals\" />\n      <ProgressBar {...args} value={75.642} precision={1} name=\"1 Decimal\" />\n      <ProgressBar\n        {...args}\n        value={75.642}\n        precision={0}\n        name=\"0 Decimals (Default)\"\n      />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Progress bar with varying decimal precision — 2, 1, and 0 decimal places.\",\n      },\n    },\n  },"
        },
        {
          "name": "DifferentLocales",
          "description": "By default, `ProgressBar` uses `en-US` to format percentages (e.g., `75.64%`). Passing other locales like `pt-BR` or `fr-FR` changes the decimal separator and symbol spacing.",
          "args": "{ value: 75.642 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"By default, `ProgressBar` uses `en-US` to format percentages (e.g., `75.64%`). Passing other locales like `pt-BR` or `fr-FR` changes the decimal separator and symbol spacing.\",\n      },\n    },\n  },\n  render: (args) => (\n    <div className=\"flex w-96 flex-col gap-4\">\n      <ProgressBar\n        {...args}\n        value={75.642}\n        precision={2}\n        locale=\"en-US\"\n        name=\"en-US (Default)\"\n      />\n      <ProgressBar\n        {...args}\n        value={75.642}\n        precision={2}\n        locale=\"pt-BR\"\n        name=\"pt-BR\"\n      />\n      <ProgressBar\n        {...args}\n        value={75.642}\n        precision={2}\n        locale=\"fr-FR\"\n        name=\"fr-FR\"\n      />\n    </div>\n  ),"
        },
        {
          "name": "Loading",
          "description": "Loading state with skeleton placeholder replacing the bar fill.",
          "args": "{\n    value: 50,\n    name: \"Loading\",\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading state with skeleton placeholder replacing the bar fill.\",\n      },\n    },\n  },"
        },
        {
          "name": "LoadingStates",
          "description": "Skeleton placeholders rendered by `loading={true}` across all three `labelLayout` values and all three sizes. Each skeleton matches the dimensions of the real content it replaces.",
          "args": "{ value: 50 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Skeleton placeholders rendered by `loading={true}` across all three `labelLayout` values and all three sizes. Each skeleton matches the dimensions of the real content it replaces.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex w-96 flex-col gap-8\">\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">inline</p>\n        <ProgressBar value={60} name=\"Standard Audit\" loading size=\"sm\" />\n        <ProgressBar value={60} name=\"Standard Audit\" loading size=\"md\" />\n        <ProgressBar value={60} name=\"Standard Audit\" loading size=\"lg\" />\n      </div>\n\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">above</p>\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"above\"\n          loading\n          size=\"sm\"\n        />\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"above\"\n          loading\n          size=\"md\"\n        />\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"above\"\n          loading\n          size=\"lg\"\n        />\n      </div>\n\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">below</p>\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"below\"\n          loading\n          size=\"sm\"\n        />\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"below\"\n          loading\n          size=\"md\"\n        />\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"below\"\n          loading\n          size=\"lg\"\n        />\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex w-96 flex-col gap-8\">\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">inline</p>\n        <ProgressBar value={60} name=\"Standard Audit\" loading size=\"sm\" />\n        <ProgressBar value={60} name=\"Standard Audit\" loading size=\"md\" />\n        <ProgressBar value={60} name=\"Standard Audit\" loading size=\"lg\" />\n      </div>\n\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">above</p>\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"above\"\n          loading\n          size=\"sm\"\n        />\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"above\"\n          loading\n          size=\"md\"\n        />\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"above\"\n          loading\n          size=\"lg\"\n        />\n      </div>\n\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">below</p>\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"below\"\n          loading\n          size=\"sm\"\n        />\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"below\"\n          loading\n          size=\"md\"\n        />\n        <ProgressBar\n          value={60}\n          name=\"Standard Audit\"\n          labelLayout=\"below\"\n          loading\n          size=\"lg\"\n        />\n      </div>\n    </div>"
        },
        {
          "name": "WithTooltip",
          "description": "Progress bar with a tooltip showing additional context on hover.",
          "args": "{\n    value: 85,\n    name: \"Storage\",\n    tooltip: \"85 GB of 100 GB used\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Progress bar with a tooltip showing additional context on hover.\",\n      },\n    },\n  },"
        },
        {
          "name": "NoLabel",
          "description": "Progress bar with the percentage label hidden via showLabel={false}.",
          "args": "{\n    value: 50,\n    name: \"Hidden Label\",\n    showLabel: false,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Progress bar with the percentage label hidden via showLabel={false}.\",\n      },\n    },\n  },"
        },
        {
          "name": "LabelRight",
          "description": "Progress bar with the percentage label positioned on the right side of the bar.",
          "args": "{\n    value: 60,\n    name: \"Progress\",\n    labelPosition: \"right\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Progress bar with the percentage label positioned on the right side of the bar.\",\n      },\n    },\n  },"
        },
        {
          "name": "NameRight",
          "description": "Progress bar with the name label positioned on the right side of the bar.",
          "args": "{\n    value: 70,\n    name: \"Progress\",\n    namePosition: \"right\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Progress bar with the name label positioned on the right side of the bar.\",\n      },\n    },\n  },"
        },
        {
          "name": "Uppercase",
          "description": "Progress bar with uppercase name label via the upper prop.",
          "args": "{\n    value: 55,\n    name: \"Progress Status\",\n    upper: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Progress bar with uppercase name label via the upper prop.\",\n      },\n    },\n  },"
        },
        {
          "name": "LabelLayoutInline",
          "description": "`labelLayout=\"inline\"` (default) — name and percentage share the same row as the bar.",
          "args": "{ value: 72 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          '`labelLayout=\"inline\"` (default) — name and percentage share the same row as the bar.',\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex w-96 flex-col gap-4\">\n      <ProgressBar\n        value={72}\n        name=\"Standard Audit\"\n        labelLayout=\"inline\"\n        intent=\"primary\"\n      />\n      <ProgressBar\n        value={45}\n        name=\"Tax Documents\"\n        labelLayout=\"inline\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={20}\n        name=\"Pending\"\n        labelLayout=\"inline\"\n        intent=\"destructive\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"flex w-96 flex-col gap-4\">\n      <ProgressBar\n        value={72}\n        name=\"Standard Audit\"\n        labelLayout=\"inline\"\n        intent=\"primary\"\n      />\n      <ProgressBar\n        value={45}\n        name=\"Tax Documents\"\n        labelLayout=\"inline\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={20}\n        name=\"Pending\"\n        labelLayout=\"inline\"\n        intent=\"destructive\"\n      />\n    </div>"
        },
        {
          "name": "LabelLayoutAbove",
          "description": "`labelLayout=\"above\"` — name (left) and percentage (right) appear in a row above the full-width bar.",
          "args": "{ value: 72 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          '`labelLayout=\"above\"` — name (left) and percentage (right) appear in a row above the full-width bar.',\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex w-96 flex-col gap-6\">\n      <ProgressBar\n        value={72}\n        name=\"Standard Audit\"\n        labelLayout=\"above\"\n        intent=\"primary\"\n      />\n      <ProgressBar\n        value={45}\n        name=\"Tax Documents\"\n        labelLayout=\"above\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={20}\n        name=\"Pending\"\n        labelLayout=\"above\"\n        intent=\"destructive\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"flex w-96 flex-col gap-6\">\n      <ProgressBar\n        value={72}\n        name=\"Standard Audit\"\n        labelLayout=\"above\"\n        intent=\"primary\"\n      />\n      <ProgressBar\n        value={45}\n        name=\"Tax Documents\"\n        labelLayout=\"above\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={20}\n        name=\"Pending\"\n        labelLayout=\"above\"\n        intent=\"destructive\"\n      />\n    </div>"
        },
        {
          "name": "LabelLayoutBelow",
          "description": "`labelLayout=\"below\"` — bar renders first, then name (left) and percentage (right) appear below it.",
          "args": "{ value: 72 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          '`labelLayout=\"below\"` — bar renders first, then name (left) and percentage (right) appear below it.',\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex w-96 flex-col gap-6\">\n      <ProgressBar\n        value={72}\n        name=\"Standard Audit\"\n        labelLayout=\"below\"\n        intent=\"primary\"\n      />\n      <ProgressBar\n        value={45}\n        name=\"Tax Documents\"\n        labelLayout=\"below\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={20}\n        name=\"Pending\"\n        labelLayout=\"below\"\n        intent=\"destructive\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"flex w-96 flex-col gap-6\">\n      <ProgressBar\n        value={72}\n        name=\"Standard Audit\"\n        labelLayout=\"below\"\n        intent=\"primary\"\n      />\n      <ProgressBar\n        value={45}\n        name=\"Tax Documents\"\n        labelLayout=\"below\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={20}\n        name=\"Pending\"\n        labelLayout=\"below\"\n        intent=\"destructive\"\n      />\n    </div>"
        },
        {
          "name": "LabelLayoutComparison",
          "description": "Side-by-side comparison of all three `labelLayout` values with the same data.",
          "args": "{ value: 60 },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Side-by-side comparison of all three `labelLayout` values with the same data.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex w-96 flex-col gap-8\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-sm font-medium text-muted-foreground\">inline</p>\n        <ProgressBar value={60} name=\"Standard Audit\" labelLayout=\"inline\" />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-sm font-medium text-muted-foreground\">above</p>\n        <ProgressBar value={60} name=\"Standard Audit\" labelLayout=\"above\" />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-sm font-medium text-muted-foreground\">below</p>\n        <ProgressBar value={60} name=\"Standard Audit\" labelLayout=\"below\" />\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex w-96 flex-col gap-8\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-sm font-medium text-muted-foreground\">inline</p>\n        <ProgressBar value={60} name=\"Standard Audit\" labelLayout=\"inline\" />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-sm font-medium text-muted-foreground\">above</p>\n        <ProgressBar value={60} name=\"Standard Audit\" labelLayout=\"above\" />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-sm font-medium text-muted-foreground\">below</p>\n        <ProgressBar value={60} name=\"Standard Audit\" labelLayout=\"below\" />\n      </div>\n    </div>"
        },
        {
          "name": "RatioLabel",
          "description": "When `total` is provided the bar fill is calculated as `value / total` and the label switches from percentage to `value / total` format. Compatible with all `labelLayout` values.",
          "args": "{\n    value: 20,\n    total: 95,\n    size: \"sm\",\n    name: \"Auditoria Normal\",\n    labelLayout: \"above\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"When `total` is provided the bar fill is calculated as `value / total` and the label switches from percentage to `value / total` format. Compatible with all `labelLayout` values.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex w-96 flex-col gap-6\">\n      <ProgressBar\n        value={20}\n        total={95}\n        name=\"Standard Audit\"\n        labelLayout=\"above\"\n      />\n      <ProgressBar\n        value={38}\n        total={95}\n        name=\"Tax Documents\"\n        labelLayout=\"above\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={91}\n        total={95}\n        name=\"Completed\"\n        labelLayout=\"above\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={12}\n        total={95}\n        name=\"Pending\"\n        labelLayout=\"above\"\n        intent=\"destructive\"\n      />\n    </div>\n  ),",
          "code": "<div className=\"flex w-96 flex-col gap-6\">\n      <ProgressBar\n        value={20}\n        total={95}\n        name=\"Standard Audit\"\n        labelLayout=\"above\"\n      />\n      <ProgressBar\n        value={38}\n        total={95}\n        name=\"Tax Documents\"\n        labelLayout=\"above\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={91}\n        total={95}\n        name=\"Completed\"\n        labelLayout=\"above\"\n        intent=\"success\"\n      />\n      <ProgressBar\n        value={12}\n        total={95}\n        name=\"Pending\"\n        labelLayout=\"above\"\n        intent=\"destructive\"\n      />\n    </div>"
        },
        {
          "name": "FixedLabelWidth",
          "description": "Progress bars with fixed label width for consistent alignment across multiple items.",
          "args": "{ value: 75 },\n  render: () => (\n    <div className=\"flex w-96 flex-col gap-4\">\n      <ProgressBar value={75} name=\"Inflation\" labelWidth={90} />\n      <ProgressBar value={42} name=\"GDP Growth\" labelWidth={90} />\n      <ProgressBar\n        value={88}\n        intent=\"success\"\n        name=\"Employment\"\n        labelWidth={90}\n      />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Progress bars with fixed label width for consistent alignment across multiple items.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex w-96 flex-col gap-4\">\n      <ProgressBar value={75} name=\"Inflation\" labelWidth={90} />\n      <ProgressBar value={42} name=\"GDP Growth\" labelWidth={90} />\n      <ProgressBar\n        value={88}\n        intent=\"success\"\n        name=\"Employment\"\n        labelWidth={90}\n      />\n    </div>"
        },
        {
          "name": "ColorTokens",
          "description": "The `fillColor` and `trackColor` props accept any CSS color or `var(--my-token)`. They set `--progress-fill` and `--progress-track` as CSS custom properties and apply via `bg-(--progress-fill)` / `bg-(--progress-track)` — bypassing the `intent` enum for per-instance customization.",
          "args": "{ value: 72 },\n  render: () => (\n    <div className=\"flex w-96 flex-col gap-6\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Direct CSS color values\n        </p>\n        <ProgressBar\n          value={72}\n          name=\"Custom Purple\"\n          fillColor=\"oklch(0.5 0.2 270)\"\n          trackColor=\"oklch(0.92 0.04 270)\"\n        />\n        <ProgressBar\n          value={55}\n          name=\"Custom Amber\"\n          fillColor=\"oklch(0.75 0.18 75)\"\n          trackColor=\"oklch(0.95 0.04 75)\"\n        />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Design system token references\n        </p>\n        <ProgressBar\n          value={85}\n          name=\"Success Token\"\n          fillColor=\"var(--color-success)\"\n        />\n        <ProgressBar\n          value={40}\n          name=\"Warning Token\"\n          fillColor=\"var(--color-warning)\"\n          trackColor=\"var(--color-warning-foreground)\"\n        />\n        <ProgressBar\n          value={20}\n          name=\"Destructive Token\"\n          fillColor=\"var(--color-destructive)\"\n        />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          External token with fallback\n        </p>\n        <ProgressBar\n          value={68}\n          name=\"Brand Color\"\n          fillColor=\"var(--color-brand, oklch(0.4 0.2 240))\"\n        />\n      </div>\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"The `fillColor` and `trackColor` props accept any CSS color or `var(--my-token)`. They set `--progress-fill` and `--progress-track` as CSS custom properties and apply via `bg-(--progress-fill)` / `bg-(--progress-track)` — bypassing the `intent` enum for per-instance customization.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex w-96 flex-col gap-6\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Direct CSS color values\n        </p>\n        <ProgressBar\n          value={72}\n          name=\"Custom Purple\"\n          fillColor=\"oklch(0.5 0.2 270)\"\n          trackColor=\"oklch(0.92 0.04 270)\"\n        />\n        <ProgressBar\n          value={55}\n          name=\"Custom Amber\"\n          fillColor=\"oklch(0.75 0.18 75)\"\n          trackColor=\"oklch(0.95 0.04 75)\"\n        />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Design system token references\n        </p>\n        <ProgressBar\n          value={85}\n          name=\"Success Token\"\n          fillColor=\"var(--color-success)\"\n        />\n        <ProgressBar\n          value={40}\n          name=\"Warning Token\"\n          fillColor=\"var(--color-warning)\"\n          trackColor=\"var(--color-warning-foreground)\"\n        />\n        <ProgressBar\n          value={20}\n          name=\"Destructive Token\"\n          fillColor=\"var(--color-destructive)\"\n        />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          External token with fallback\n        </p>\n        <ProgressBar\n          value={68}\n          name=\"Brand Color\"\n          fillColor=\"var(--color-brand, oklch(0.4 0.2 240))\"\n        />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-progress-circular",
      "title": "Progress Circular",
      "description": "Displays progress as a circular gauge with an animated stroke and centered value.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/progress-circular",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/progress-circular.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "number"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "intent",
          "required": false,
          "type": "ProgressCircularIntent"
        },
        {
          "name": "size",
          "required": false,
          "type": "ProgressCircularSize"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "precision",
          "required": false,
          "type": "number"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "fillColor",
          "required": false,
          "type": "string",
          "description": "Override indicator stroke via CSS token `--progress-fill`.\nAccepts any CSS color value or `var(--my-token)`."
        },
        {
          "name": "trackColor",
          "required": false,
          "type": "string",
          "description": "Override track stroke via CSS token `--progress-track`.\nAccepts any CSS color value or `var(--my-token)`."
        }
      ],
      "storyTitle": "Feedback/ProgressCircular",
      "stories": [
        {
          "name": "Default",
          "description": "Default circular progress at 75% with primary intent and medium size.",
          "args": "{\n    value: 75,\n    title: \"Upload Progress\",\n    size: \"md\",\n    intent: \"primary\",\n    loading: false,\n    precision: 0,\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default circular progress at 75% with primary intent and medium size.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllSizes",
          "description": "Comparison of all four size presets — sm, md, lg, and xl.",
          "args": "{ value: 75 },\n  render: () => (\n    <div className=\"flex flex-wrap items-center gap-8\">\n      <ProgressCircular value={75} size=\"sm\" title=\"Small\" />\n      <ProgressCircular value={75} size=\"md\" title=\"Medium\" />\n      <ProgressCircular value={75} size=\"lg\" title=\"Large\" />\n      <ProgressCircular value={75} size=\"xl\" title=\"Extra Large\" />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story: \"Comparison of all four size presets — sm, md, lg, and xl.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-wrap items-center gap-8\">\n      <ProgressCircular value={75} size=\"sm\" title=\"Small\" />\n      <ProgressCircular value={75} size=\"md\" title=\"Medium\" />\n      <ProgressCircular value={75} size=\"lg\" title=\"Large\" />\n      <ProgressCircular value={75} size=\"xl\" title=\"Extra Large\" />\n    </div>"
        },
        {
          "name": "WithPrecision",
          "description": "Circular progress with varying decimal precision — 2, 1, and 0 decimal places.",
          "args": "{ value: 75.642, precision: 2, title: \"Detailed Progress\" },\n  render: (args) => (\n    <div className=\"flex flex-wrap items-center gap-8\">\n      <ProgressCircular\n        {...args}\n        value={75.642}\n        precision={2}\n        title=\"2 Decimals\"\n      />\n      <ProgressCircular\n        {...args}\n        value={75.642}\n        precision={1}\n        title=\"1 Decimal\"\n      />\n      <ProgressCircular\n        {...args}\n        value={75.642}\n        precision={0}\n        title=\"0 Decimals (Default)\"\n      />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Circular progress with varying decimal precision — 2, 1, and 0 decimal places.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllIntents",
          "description": "Comparison of all four intent colors — primary, secondary, success, and destructive.",
          "args": "{ value: 75.6 },\n  render: () => (\n    <div className=\"flex flex-wrap items-center gap-8\">\n      <ProgressCircular value={25} intent=\"primary\" title=\"Primary\" />\n      <ProgressCircular value={50} intent=\"secondary\" title=\"Secondary\" />\n      <ProgressCircular value={75} intent=\"success\" title=\"Success\" />\n      <ProgressCircular value={90} intent=\"destructive\" title=\"Destructive\" />\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison of all four intent colors — primary, secondary, success, and destructive.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-wrap items-center gap-8\">\n      <ProgressCircular value={25} intent=\"primary\" title=\"Primary\" />\n      <ProgressCircular value={50} intent=\"secondary\" title=\"Secondary\" />\n      <ProgressCircular value={75} intent=\"success\" title=\"Success\" />\n      <ProgressCircular value={90} intent=\"destructive\" title=\"Destructive\" />\n    </div>"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) locale formatting applied to the progress value.",
          "args": "{\n    value: 75.642,\n    title: \"Progresso do Upload\",\n    size: \"md\",\n    intent: \"primary\",\n    precision: 2,\n    locale: \"pt-BR\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) locale formatting applied to the progress value.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading state with skeleton circle replacing the progress arc.",
          "args": "{\n    value: 0,\n    loading: true,\n    title: \"Computing...\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Loading state with skeleton circle replacing the progress arc.\",\n      },\n    },\n  },"
        },
        {
          "name": "ColorTokens",
          "description": "The `fillColor` and `trackColor` props accept any CSS color or `var(--my-token)`. They set `--progress-fill` and `--progress-track` as CSS custom properties. `fillColor` applies via `stroke-(--progress-fill)` on the indicator SVG circle; `trackColor` applies via `text-(--progress-track)` (currentColor) on the track circle — bypassing the `intent` enum for per-instance customization.",
          "args": "{ value: 72 },\n  render: () => (\n    <div className=\"flex flex-wrap gap-8\">\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Direct value\n        </p>\n        <ProgressCircular\n          value={72}\n          title=\"Custom Purple\"\n          fillColor=\"oklch(0.5 0.2 270)\"\n          trackColor=\"oklch(0.92 0.04 270)\"\n        />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Success token\n        </p>\n        <ProgressCircular\n          value={85}\n          title=\"Success Token\"\n          fillColor=\"var(--color-success)\"\n        />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Warning token\n        </p>\n        <ProgressCircular\n          value={40}\n          title=\"Warning Token\"\n          fillColor=\"var(--color-warning)\"\n        />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          External token\n        </p>\n        <ProgressCircular\n          value={60}\n          title=\"Brand Color\"\n          fillColor=\"var(--color-brand, oklch(0.4 0.2 240))\"\n        />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Custom track\n        </p>\n        <ProgressCircular\n          value={55}\n          title=\"Custom Track\"\n          fillColor=\"oklch(0.55 0.18 30)\"\n          trackColor=\"oklch(0.93 0.04 30)\"\n        />\n      </div>\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"The `fillColor` and `trackColor` props accept any CSS color or `var(--my-token)`. They set `--progress-fill` and `--progress-track` as CSS custom properties. `fillColor` applies via `stroke-(--progress-fill)` on the indicator SVG circle; `trackColor` applies via `text-(--progress-track)` (currentColor) on the track circle — bypassing the `intent` enum for per-instance customization.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-wrap gap-8\">\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Direct value\n        </p>\n        <ProgressCircular\n          value={72}\n          title=\"Custom Purple\"\n          fillColor=\"oklch(0.5 0.2 270)\"\n          trackColor=\"oklch(0.92 0.04 270)\"\n        />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Success token\n        </p>\n        <ProgressCircular\n          value={85}\n          title=\"Success Token\"\n          fillColor=\"var(--color-success)\"\n        />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Warning token\n        </p>\n        <ProgressCircular\n          value={40}\n          title=\"Warning Token\"\n          fillColor=\"var(--color-warning)\"\n        />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          External token\n        </p>\n        <ProgressCircular\n          value={60}\n          title=\"Brand Color\"\n          fillColor=\"var(--color-brand, oklch(0.4 0.2 240))\"\n        />\n      </div>\n      <div className=\"flex flex-col items-center gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Custom track\n        </p>\n        <ProgressCircular\n          value={55}\n          title=\"Custom Track\"\n          fillColor=\"oklch(0.55 0.18 30)\"\n          trackColor=\"oklch(0.93 0.04 30)\"\n        />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-pull-quote",
      "title": "PullQuote",
      "description": "Citação editorial destacada com avatar do autor e suporte a variantes de estilo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/pull-quote",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "avatar",
        "skeleton"
      ],
      "files": [
        "components/ds/pull-quote.tsx"
      ],
      "props": [
        {
          "name": "quote",
          "required": true,
          "type": "React.ReactNode",
          "description": "Quote body — accepts rich text (e.g. <strong> for emphasis)."
        },
        {
          "name": "name",
          "required": false,
          "type": "string"
        },
        {
          "name": "role",
          "required": false,
          "type": "string"
        },
        {
          "name": "avatarSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "avatarFallback",
          "required": false,
          "type": "string"
        },
        {
          "name": "size",
          "required": false,
          "type": "PullQuoteSize"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "align",
          "required": false,
          "type": "\"start\" | \"center\"",
          "options": [
            "start",
            "center"
          ],
          "default": "start"
        },
        {
          "name": "tone",
          "required": false,
          "type": "\"plain\" | \"violet\" | \"sky\"",
          "options": [
            "plain",
            "violet",
            "sky"
          ],
          "default": "plain"
        }
      ],
      "storyTitle": "Data Display/PullQuote",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Centered",
          "description": "",
          "args": "{\n    align: \"center\",\n    tone: \"violet\",\n  },\n  parameters: {\n    layout: \"fullscreen\",\n  },\n  render: (args) => (\n    <div className=\"mx-auto max-w-2xl px-6 py-16\">\n      <PullQuote {...args} />\n    </div>\n  ),"
        },
        {
          "name": "WithoutAvatar",
          "description": "",
          "args": "{\n    name: \"Product Team\",\n    role: undefined,\n    avatarFallback: undefined,\n  },"
        }
      ]
    },
    {
      "name": "ds-qr-code",
      "title": "Qr Code",
      "description": "QR code placeholder — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/qr-code",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/qr-code.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "string"
        },
        {
          "name": "size",
          "required": false,
          "type": "number"
        }
      ],
      "storyTitle": "Data Display/QrCode",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ value: \"https://lema.ufpb.br\", size: 128 },"
        }
      ]
    },
    {
      "name": "ds-radar-chart",
      "title": "Radar Chart",
      "description": "A responsive radar (spider) chart for comparing multiple entities across the same set of dimensions.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/radar-chart",
      "dependencies": [
        "recharts",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/radar-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "Record<string, string | number>[]"
        },
        {
          "name": "dataKeys",
          "required": true,
          "type": "RadarChartKey[] | string[]",
          "description": "Keys to plot — accepts plain strings or { key, label, color, filled } objects"
        },
        {
          "name": "categoryKey",
          "required": true,
          "type": "string",
          "description": "Object key whose values become the axis spoke labels"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "filled",
          "required": false,
          "type": "boolean",
          "description": "Fill each radar area with a semi-transparent color (default: true)"
        },
        {
          "name": "fillOpacity",
          "required": false,
          "type": "number",
          "description": "Fill opacity applied to every filled series (default: 0.18)"
        },
        {
          "name": "dots",
          "required": false,
          "type": "boolean",
          "description": "Show a dot at each data vertex"
        },
        {
          "name": "gridShape",
          "required": false,
          "type": "RadarGridShape",
          "description": "Background grid shape (default: \"polygon\")"
        },
        {
          "name": "showRadiusAxis",
          "required": false,
          "type": "boolean",
          "description": "Show the radial value axis ticks"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "showLegend",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "legendPosition",
          "required": false,
          "type": "LegendPosition",
          "description": "@default \"bottom\""
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Format radial axis ticks and tooltip values"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Data Display/RadarChart",
      "stories": [
        {
          "name": "Default",
          "description": "Default filled radar chart showing a single student's performance profile across six academic subjects.",
          "args": "{\n    title: \"Student Performance Profile\",\n    subtitle: \"Alice — semester 2025.1 scores\",\n    data: studentPerformance,\n    dataKeys: [{ key: \"alice\", label: \"Alice\" }],\n    categoryKey: \"subject\",\n    filled: true,\n    fillOpacity: 0.18,\n    dots: false,\n    gridShape: \"polygon\",\n    showRadiusAxis: false,\n    height: 300,\n    showLegend: false,\n    legendPosition: \"bottom\",\n    showTooltip: true,\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n    valueFormatter: (v) => formatValue(v, \"integer\"),\n  },"
        },
        {
          "name": "Unfilled",
          "description": "Outline-only radar chart with dots at each vertex for a clean, minimal single-series comparison.",
          "args": "{\n    title: \"Student Performance Profile\",\n    subtitle: \"Outline-only — no fill\",\n    data: studentPerformance,\n    dataKeys: [{ key: \"alice\", label: \"Alice\" }],\n    categoryKey: \"subject\",\n    filled: false,\n    dots: true,\n    showTooltip: true,\n  },"
        },
        {
          "name": "MultiSeries",
          "description": "Three-series radar chart comparing Alice, Bob, and Carol across six academic subjects with a legend.",
          "args": "{\n    title: \"Student Comparison\",\n    subtitle: \"Three students across six subjects\",\n    data: studentPerformance,\n    dataKeys: [\n      { key: \"alice\", label: \"Alice\" },\n      { key: \"bob\", label: \"Bob\" },\n      { key: \"carol\", label: \"Carol\" },\n    ],\n    categoryKey: \"subject\",\n    filled: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 340,\n  },"
        },
        {
          "name": "CurrentVsTarget",
          "description": "Radar chart combining a filled current-level series with an outlined target series for competency gap analysis.",
          "args": "{\n    title: \"Competency Assessment\",\n    subtitle: \"Current level vs. target — filled baseline, outline target\",\n    data: currentVsTarget,\n    dataKeys: [\n      {\n        key: \"current\",\n        label: \"Current\",\n        color: \"var(--chart-1)\",\n        filled: true,\n      },\n      {\n        key: \"target\",\n        label: \"Target\",\n        color: \"var(--chart-2)\",\n        filled: false,\n      },\n    ],\n    categoryKey: \"skill\",\n    showLegend: true,\n    showTooltip: true,\n    dots: true,\n    height: 340,\n  },"
        },
        {
          "name": "CircleGrid",
          "description": "Radar chart with circular grid lines comparing three departments across five capability dimensions.",
          "args": "{\n    title: \"Department Capability\",\n    subtitle: 'gridShape=\"circle\" — smooth circular grid',\n    data: departmentCapability,\n    dataKeys: [\n      { key: \"engineering\", label: \"Engineering\" },\n      { key: \"medicine\", label: \"Medicine\" },\n      { key: \"law\", label: \"Law\" },\n    ],\n    categoryKey: \"dimension\",\n    gridShape: \"circle\",\n    filled: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 340,\n  },"
        },
        {
          "name": "WithRadiusAxis",
          "description": "Radar chart with radial axis tick values enabled, comparing semester 1 and semester 2 scores across subjects.",
          "args": "{\n    title: \"Semester Comparison\",\n    subtitle: \"showRadiusAxis — tick values on the radial axis\",\n    data: semesterComparison,\n    dataKeys: [\n      { key: \"sem1\", label: \"Semester 1\" },\n      { key: \"sem2\", label: \"Semester 2\" },\n    ],\n    categoryKey: \"subject\",\n    filled: true,\n    showRadiusAxis: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 320,\n  },"
        },
        {
          "name": "WithDots",
          "description": "Two-series radar chart with visible vertex dots for precise value comparison across department capabilities.",
          "args": "{\n    title: \"Department Capability\",\n    subtitle: \"Dots visible at each vertex\",\n    data: departmentCapability,\n    dataKeys: [\n      { key: \"engineering\", label: \"Engineering\" },\n      { key: \"medicine\", label: \"Medicine\" },\n    ],\n    categoryKey: \"dimension\",\n    filled: true,\n    dots: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 320,\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Single-series radar chart with a footer showing the top score and average performance across all subjects.",
          "args": "{\n    title: \"Student Performance Profile\",\n    subtitle: \"Alice · Semester 2025.1\",\n    data: studentPerformance,\n    dataKeys: [{ key: \"alice\", label: \"Alice\", color: \"var(--chart-2)\" }],\n    categoryKey: \"subject\",\n    filled: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"integer\"),\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <Award className=\"size-3.5 text-warning\" />\n          <span>Top score: English (91)</span>\n        </span>\n        <span className=\"flex items-center gap-1.5 text-muted-foreground/70\">\n          <TrendingUp className=\"size-3.5\" />\n          Average: 83.5\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Radar chart with Portuguese locale displaying a student performance profile in localized number format.",
          "args": "{\n    title: \"Perfil de Desempenho do Aluno\",\n    subtitle: \"Alice — semestre 2025.1\",\n    data: studentPerformance,\n    dataKeys: [{ key: \"alice\", label: \"Alice\" }],\n    categoryKey: \"subject\",\n    filled: true,\n    showTooltip: true,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the radar chart with an animated skeleton that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Student Performance Profile\",\n    subtitle: \"Alice — semester 2025.1 scores\",\n    data: studentPerformance,\n    dataKeys: [{ key: \"alice\", label: \"Alice\" }],\n    categoryKey: \"subject\",\n    filled: true,\n    showTooltip: true,\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the radar chart renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Student Performance Profile\",\n    subtitle: \"Alice — semester 2025.1 scores\",\n    data: [],\n    dataKeys: [\"alice\"],\n    categoryKey: \"subject\",\n    height: 300,\n  },"
        },
        {
          "name": "LegendPositions",
          "description": "Grid of four radar charts demonstrating all four legend positions with semester comparison data.",
          "args": "{\n    data: semesterComparison,\n    dataKeys: [\"sem1\", \"sem2\"],\n    categoryKey: \"subject\",\n  },\n  render: () => (\n    <div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <RadarChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={semesterComparison}\n          dataKeys={[\n            { key: \"sem1\", label: \"Semester 1\" },\n            { key: \"sem2\", label: \"Semester 2\" },\n          ]}\n          categoryKey=\"subject\"\n          filled\n          showLegend\n          legendPosition={pos}\n          showTooltip\n          height={260}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <RadarChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={semesterComparison}\n          dataKeys={[\n            { key: \"sem1\", label: \"Semester 1\" },\n            { key: \"sem2\", label: \"Semester 2\" },\n          ]}\n          categoryKey=\"subject\"\n          filled\n          showLegend\n          legendPosition={pos}\n          showTooltip\n          height={260}\n        />\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-radial-chart",
      "title": "Radial Chart",
      "description": "A responsive radial bar chart with concentric rings, single-metric gauge mode, and legend support.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/radial-chart",
      "dependencies": [
        "recharts",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/radial-chart.tsx"
      ],
      "storyTitle": "Data Display/RadialChart",
      "props": [
        {
          "name": "showTrack",
          "control": "boolean",
          "default": "true"
        },
        {
          "name": "showLegend",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "legendPosition",
          "control": "inline-radio",
          "options": [
            "top",
            "bottom",
            "left",
            "right"
          ],
          "default": "bottom"
        },
        {
          "name": "showTooltip",
          "control": "boolean",
          "default": "true"
        },
        {
          "name": "innerLabel",
          "control": "text",
          "default": ""
        },
        {
          "name": "title",
          "control": "text",
          "default": ""
        },
        {
          "name": "subtitle",
          "control": "text",
          "default": ""
        },
        {
          "name": "locale",
          "control": "inline-radio",
          "options": [
            "en-US",
            "pt-BR",
            "es-ES",
            "fr-FR"
          ],
          "default": "en-US"
        },
        {
          "name": "loading",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "format",
          "control": "inline-radio",
          "options": [
            "number",
            "currency",
            "percent",
            "compact"
          ],
          "default": ""
        },
        {
          "name": "currency",
          "control": "text",
          "default": ""
        },
        {
          "name": "abbreviate",
          "control": "boolean",
          "default": "false"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Four concentric radial bars showing approval rate, attendance, completion, and satisfaction on a 0–100 scale with track and tooltip.",
          "args": "{\n    title: \"Semester Performance\",\n    subtitle: \"Key indicators — 0–100 scale\",\n    data: semesterMetrics,\n    height: 320,\n    showTrack: true,\n    showLegend: false,\n    legendPosition: \"bottom\",\n    showTooltip: true,\n    startAngle: 90,\n    endAngle: -270,\n    maxValue: 100,\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "WithLegend",
          "description": "Radial chart with an interactive legend allowing show/hide toggle for each semester performance metric.",
          "args": "{\n    title: \"Semester Performance\",\n    subtitle: \"Click a legend item to hide / show its bar\",\n    data: semesterMetrics,\n    maxValue: 100,\n    showTrack: true,\n    showLegend: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "GaugeSingle",
          "description": "Single-metric semicircular gauge showing attendance rate with a center label, track background, and compact height.",
          "args": "{\n    title: \"Attendance Rate\",\n    subtitle: \"Semester 2025.1\",\n    data: singleAttendance,\n    maxValue: 100,\n    startAngle: 180,\n    endAngle: 0,\n    innerLabel: \"Attendance\",\n    showTrack: true,\n    showTooltip: true,\n    height: 220,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "FullCircleWithLabel",
          "description": "Full-circle radial gauge displaying a single attendance metric with center label, track, and a custom color.",
          "args": "{\n    title: \"Overall Attendance\",\n    subtitle: \"Full-circle gauge — single metric\",\n    data: [{ name: \"Attendance\", value: 87, color: \"var(--chart-1)\" }],\n    maxValue: 100,\n    innerLabel: \"Attendance\",\n    showTrack: true,\n    showTooltip: true,\n    height: 280,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "MultiDepartment",
          "description": "Five-bar radial chart comparing average grades across schools with a legend for identification and tooltips.",
          "args": "{\n    title: \"Average Grade by School\",\n    subtitle: \"All departments · Semester 2025.1\",\n    data: departmentPerformance,\n    maxValue: 100,\n    showTrack: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 360,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "CustomColors",
          "description": "Radial chart using semantic color tokens for completed, in-progress, and dropped course status with a legend.",
          "args": "{\n    title: \"Course Completion\",\n    subtitle:\n      \"Semantic tokens: var(--chart-2), var(--chart-3), var(--destructive)\",\n    data: customColorMetrics,\n    maxValue: 100,\n    showTrack: true,\n    showLegend: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "NoTrack",
          "description": "Radial chart with background tracks hidden, displaying only the active colored bars for a cleaner look.",
          "args": "{\n    title: \"Semester Metrics\",\n    subtitle: \"showTrack={false} — bars only\",\n    data: semesterMetrics,\n    maxValue: 100,\n    showTrack: false,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Five-bar radial chart with a footer showing the top-performing department and overall average score.",
          "args": "{\n    title: \"Department Performance\",\n    subtitle: \"Semester 2025.1 average scores\",\n    data: departmentPerformance,\n    maxValue: 100,\n    showTrack: true,\n    showLegend: true,\n    showTooltip: true,\n    height: 360,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <Award className=\"size-3.5 text-warning\" />\n          Top: Health Sciences (91%)\n        </span>\n        <span className=\"flex items-center gap-1.5 text-muted-foreground/70\">\n          <TrendingUp className=\"size-3.5\" />\n          Avg: 82.8%\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "GaugeGrid",
          "description": "Grid of four semicircular gauges showing approval, attendance, completion, and satisfaction as independent KPI widgets.",
          "args": "{ data: semesterMetrics },",
          "code": "<div className=\"grid grid-cols-2 gap-6 sm:grid-cols-4\">\n      {[\n        { name: \"Approval\", value: 88, color: \"var(--chart-1)\" },\n        { name: \"Attendance\", value: 76, color: \"var(--chart-2)\" },\n        { name: \"Completion\", value: 92, color: \"var(--chart-3)\" },\n        { name: \"Satisfaction\", value: 81, color: \"var(--chart-4)\" },\n      ].map((item) => (\n        <RadialChart\n          key={item.name}\n          data={[item]}\n          maxValue={100}\n          startAngle={180}\n          endAngle={0}\n          innerLabel={item.name}\n          showTrack\n          showTooltip\n          height={160}\n          valueFormatter={(v) => `${v}%`}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "LegendPositions",
          "description": "Grid of four radial charts demonstrating all four legend positions (top, right, bottom, left) for semester metrics.",
          "args": "{ data: semesterMetrics },",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <RadialChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          data={semesterMetrics}\n          maxValue={100}\n          showTrack\n          showLegend\n          legendPosition={pos}\n          showTooltip\n          valueFormatter={(v) => `${v}%`}\n          height={260}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "LocalePTBR",
          "description": "Radial chart with Portuguese locale displaying semester performance indicators in localized number format.",
          "args": "{\n    title: \"Desempenho Semestral\",\n    subtitle: \"Indicadores principais — escala 0–100\",\n    data: semesterMetrics,\n    maxValue: 100,\n    showTrack: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the radial chart with an animated skeleton that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Semester Performance\",\n    subtitle: \"Key indicators — 0–100 scale\",\n    data: semesterMetrics,\n    maxValue: 100,\n    showTrack: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the radial chart renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Semester Performance\",\n    subtitle: \"Key indicators — 0–100 scale\",\n    data: [],\n    height: 320,\n  },"
        },
        {
          "name": "StudentKPIs",
          "description": "Dashboard of four semicircular gauges showing approval rate, attendance, completion, and dropout risk as independent RadialChart instances.",
          "args": "{ data: semesterMetrics },",
          "code": "<div className=\"flex w-full max-w-lg flex-col gap-1\">\n      <p className=\"mb-2 text-sm font-semibold text-foreground\">\n        Student KPI Dashboard\n      </p>\n      <p className=\"mb-4 text-xs text-muted-foreground\">\n        4 semicircle gauges — each is an independent RadialChart instance\n      </p>\n      <div className=\"grid grid-cols-2 gap-4\">\n        <RadialChart\n          title=\"Approval Rate\"\n          data={[{ name: \"Approved\", value: 88, color: \"var(--chart-2)\" }]}\n          maxValue={100}\n          startAngle={210}\n          endAngle={-30}\n          innerLabel=\"Approved\"\n          showTrack\n          showTooltip\n          height={200}\n          valueFormatter={(v) => `${v}%`}\n        />\n        <RadialChart\n          title=\"Attendance\"\n          data={[{ name: \"Attendance\", value: 76, color: \"var(--chart-1)\" }]}\n          maxValue={100}\n          startAngle={210}\n          endAngle={-30}\n          innerLabel=\"Attendance\"\n          showTrack\n          showTooltip\n          height={200}\n          valueFormatter={(v) => `${v}%`}\n        />\n        <RadialChart\n          title=\"Completion\"\n          data={[{ name: \"Completion\", value: 92, color: \"var(--chart-3)\" }]}\n          maxValue={100}\n          startAngle={210}\n          endAngle={-30}\n          innerLabel=\"Completion\"\n          showTrack\n          showTooltip\n          height={200}\n          valueFormatter={(v) => `${v}%`}\n        />\n        <RadialChart\n          title=\"Dropout Risk\"\n          data={[{ name: \"At Risk\", value: 12, color: \"var(--destructive)\" }]}\n          maxValue={100}\n          startAngle={210}\n          endAngle={-30}\n          innerLabel=\"At Risk\"\n          showTrack\n          showTooltip\n          height={200}\n          valueFormatter={(v) => `${v}%`}\n        />\n      </div>\n      <p className=\"mt-2 flex items-center gap-1.5 text-xs text-muted-foreground\">\n        <Users className=\"size-3.5\" />\n        Based on 9,740 students · Semester 2025.1\n      </p>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-radial-menu",
      "description": "Radial Menu using framer-motion.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/radial-menu",
      "dependencies": [],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ds/radial-menu.tsx"
      ],
      "props": [
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode"
        },
        {
          "name": "radius",
          "required": false,
          "type": "number"
        },
        {
          "name": "startAngle",
          "required": false,
          "type": "number"
        },
        {
          "name": "endAngle",
          "required": false,
          "type": "number"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"primary\"",
          "options": [
            "default",
            "primary"
          ],
          "default": "primary"
        }
      ],
      "storyTitle": "Actions/RadialMenu",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ children: null },\n  render: () => (\n    <div className=\"flex h-[300px] items-center justify-center\">\n      <RadialMenu radius={80} startAngle={-90} endAngle={270}>\n        <RadialMenuTrigger size=\"md\" intent=\"primary\" aria-label=\"Open menu\">\n          <PlusIcon className=\"size-6\" />\n        </RadialMenuTrigger>\n        <RadialMenuContent>\n          <RadialMenuItem title=\"Copy\">\n            <CopyIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem title=\"Edit\">\n            <EditIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem title=\"Share\">\n            <ShareIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem\n            title=\"Delete\"\n            className=\"text-destructive hover:text-destructive\"\n          >\n            <TrashIcon className=\"size-4\" />\n          </RadialMenuItem>\n        </RadialMenuContent>\n      </RadialMenu>\n    </div>\n  ),",
          "code": "<div className=\"flex h-[300px] items-center justify-center\">\n      <RadialMenu radius={80} startAngle={-90} endAngle={270}>\n        <RadialMenuTrigger size=\"md\" intent=\"primary\" aria-label=\"Open menu\">\n          <PlusIcon className=\"size-6\" />\n        </RadialMenuTrigger>\n        <RadialMenuContent>\n          <RadialMenuItem title=\"Copy\">\n            <CopyIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem title=\"Edit\">\n            <EditIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem title=\"Share\">\n            <ShareIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem\n            title=\"Delete\"\n            className=\"text-destructive hover:text-destructive\"\n          >\n            <TrashIcon className=\"size-4\" />\n          </RadialMenuItem>\n        </RadialMenuContent>\n      </RadialMenu>\n    </div>"
        },
        {
          "name": "HalfCircle",
          "description": "",
          "args": "{ children: null },\n  render: () => (\n    <div className=\"flex h-[300px] items-end justify-center pb-12\">\n      <RadialMenu radius={100} startAngle={180} endAngle={360}>\n        <RadialMenuTrigger size=\"lg\" aria-label=\"Open menu\">\n          <PlusIcon className=\"size-6\" />\n        </RadialMenuTrigger>\n        <RadialMenuContent>\n          <RadialMenuItem size=\"lg\" title=\"Heart\">\n            <HeartIcon className=\"size-5\" />\n          </RadialMenuItem>\n          <RadialMenuItem size=\"lg\" title=\"Comment\">\n            <MessageCircleIcon className=\"size-5\" />\n          </RadialMenuItem>\n          <RadialMenuItem size=\"lg\" title=\"Share\">\n            <ShareIcon className=\"size-5\" />\n          </RadialMenuItem>\n          <RadialMenuItem size=\"lg\" title=\"Download\">\n            <DownloadIcon className=\"size-5\" />\n          </RadialMenuItem>\n          <RadialMenuItem size=\"lg\" title=\"Copy\">\n            <CopyIcon className=\"size-5\" />\n          </RadialMenuItem>\n        </RadialMenuContent>\n      </RadialMenu>\n    </div>\n  ),",
          "code": "<div className=\"flex h-[300px] items-end justify-center pb-12\">\n      <RadialMenu radius={100} startAngle={180} endAngle={360}>\n        <RadialMenuTrigger size=\"lg\" aria-label=\"Open menu\">\n          <PlusIcon className=\"size-6\" />\n        </RadialMenuTrigger>\n        <RadialMenuContent>\n          <RadialMenuItem size=\"lg\" title=\"Heart\">\n            <HeartIcon className=\"size-5\" />\n          </RadialMenuItem>\n          <RadialMenuItem size=\"lg\" title=\"Comment\">\n            <MessageCircleIcon className=\"size-5\" />\n          </RadialMenuItem>\n          <RadialMenuItem size=\"lg\" title=\"Share\">\n            <ShareIcon className=\"size-5\" />\n          </RadialMenuItem>\n          <RadialMenuItem size=\"lg\" title=\"Download\">\n            <DownloadIcon className=\"size-5\" />\n          </RadialMenuItem>\n          <RadialMenuItem size=\"lg\" title=\"Copy\">\n            <CopyIcon className=\"size-5\" />\n          </RadialMenuItem>\n        </RadialMenuContent>\n      </RadialMenu>\n    </div>"
        },
        {
          "name": "QuarterCircle",
          "description": "",
          "args": "{ children: null },\n  render: () => (\n    <div className=\"flex h-[300px] w-[300px] items-end justify-end p-8\">\n      <RadialMenu radius={100} startAngle={180} endAngle={270}>\n        <RadialMenuTrigger size=\"md\" aria-label=\"Open menu\">\n          <PlusIcon className=\"size-6\" />\n        </RadialMenuTrigger>\n        <RadialMenuContent>\n          <RadialMenuItem title=\"Heart\">\n            <HeartIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem title=\"Comment\">\n            <MessageCircleIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem title=\"Share\">\n            <ShareIcon className=\"size-4\" />\n          </RadialMenuItem>\n        </RadialMenuContent>\n      </RadialMenu>\n    </div>\n  ),",
          "code": "<div className=\"flex h-[300px] w-[300px] items-end justify-end p-8\">\n      <RadialMenu radius={100} startAngle={180} endAngle={270}>\n        <RadialMenuTrigger size=\"md\" aria-label=\"Open menu\">\n          <PlusIcon className=\"size-6\" />\n        </RadialMenuTrigger>\n        <RadialMenuContent>\n          <RadialMenuItem title=\"Heart\">\n            <HeartIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem title=\"Comment\">\n            <MessageCircleIcon className=\"size-4\" />\n          </RadialMenuItem>\n          <RadialMenuItem title=\"Share\">\n            <ShareIcon className=\"size-4\" />\n          </RadialMenuItem>\n        </RadialMenuContent>\n      </RadialMenu>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-rating",
      "title": "Rating",
      "description": "Componente interativo para avaliação baseada em ícones (estrelas).",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/rating",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/rating.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "number",
          "description": "The current rating value."
        },
        {
          "name": "max",
          "required": false,
          "type": "number",
          "description": "The maximum rating value. Defaults to 5."
        },
        {
          "name": "readonly",
          "required": false,
          "type": "boolean",
          "description": "Disables interaction and hover states."
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean",
          "description": "Disables the component entirely (opacity)."
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: number) => void",
          "description": "Callback when a star is clicked."
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType",
          "description": "Custom icon component to render. Defaults to StarIcon."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/Rating",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    value: 3,\n    max: 5,\n    size: \"md\",\n  },"
        },
        {
          "name": "Readonly",
          "description": "",
          "args": "{\n    value: 4,\n    max: 5,\n    size: \"md\",\n    readonly: true,\n  },"
        },
        {
          "name": "AllSizes",
          "description": "The component supports 3 sizes: sm, md and lg.",
          "args": "{\n    value: 3,\n    readonly: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"The component supports 3 sizes: sm, md and lg.\",\n      },\n    },\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    value: 2,\n    max: 5,\n    size: \"md\",\n    disabled: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-reaction-bar",
      "description": "Interactive reaction bar component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/reaction-bar",
      "dependencies": [],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ds/reaction-bar.tsx"
      ],
      "props": [
        {
          "name": "reactions",
          "required": false,
          "type": "ReactionType[]"
        },
        {
          "name": "value",
          "required": false,
          "type": "string | null"
        },
        {
          "name": "onReact",
          "required": false,
          "type": "(id: string | null) => void"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"primary\"",
          "options": [
            "default",
            "primary"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Actions/ReactionBar",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    size: \"md\",\n    intent: \"default\",\n  },"
        },
        {
          "name": "Interactive",
          "description": "",
          "code": "<div className=\"flex h-[200px] items-end justify-center pb-8\">\n        <ReactionBar value={reaction} onReact={setReaction} intent=\"default\" />\n      </div>"
        },
        {
          "name": "PostFooter",
          "description": "",
          "code": "<div className=\"w-full max-w-[400px] rounded-2xl border bg-card p-4 shadow-sm\">\n        <div className=\"mb-4 flex items-center gap-3\">\n          <div className=\"size-10 rounded-full bg-muted\" />\n          <div className=\"flex flex-col\">\n            <span className=\"text-sm font-semibold\">Design Team</span>\n            <span className=\"text-xs text-muted-foreground\">2 hours ago</span>\n          </div>\n        </div>\n        <p className=\"mb-6 text-sm\">\n          We just shipped the new ReactionBar component! What do you all think?\n          🚀\n        </p>\n\n        <div className=\"flex items-center justify-between border-t pt-4\">\n          <ReactionBar value={reaction} onReact={setReaction} size=\"sm\" />\n          <div className=\"flex gap-2\">\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className=\"gap-2 rounded-full text-muted-foreground\"\n            >\n              <MessageCircleIcon className=\"size-4\" />\n              12\n            </Button>\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className=\"gap-2 rounded-full text-muted-foreground\"\n            >\n              <ShareIcon className=\"size-4\" />\n              Share\n            </Button>\n          </div>\n        </div>\n      </div>"
        },
        {
          "name": "Sizes",
          "description": "",
          "code": "<div className=\"flex h-[150px] items-end gap-6 pb-4\">\n      <ReactionBar size=\"sm\" />\n      <ReactionBar size=\"md\" />\n      <ReactionBar size=\"lg\" />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-reading-progress",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/reading-progress",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/reading-progress.tsx"
      ],
      "props": [
        {
          "name": "targetRef",
          "required": false,
          "type": "React.RefObject<HTMLElement | null>",
          "description": "Ref para o container que terá scroll monitorado.\nSe não fornecido, monitora o scroll da janela (window)."
        },
        {
          "name": "progressColor",
          "required": false,
          "type": "string",
          "description": "Cor da barra, por padrão usa a cor primária"
        },
        {
          "name": "height",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "description": "Altura da barra"
        }
      ],
      "storyTitle": "Navigation/ReadingProgress",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<div className=\"p-8\">\n        <ReadingProgress />\n        <h1 className=\"mb-8 text-4xl font-bold\">Faça scroll nesta página</h1>\n        {Array.from({ length: 30 }).map((_, i) => (\n          <p key={i} className=\"mb-6 text-muted-foreground\">\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed\n            vestibulum, neque sit amet dignissim varius, nisl magna consequat\n            arcu, vel finibus est turpis pretium eros. Phasellus quis ipsum vel\n            est fermentum mattis. Integer sodales interdum posuere. Morbi a arcu\n            varius, dapibus purus non, malesuada elit. Proin elementum id metus\n            eu dignissim. Aenean consectetur arcu a arcu sagittis, tincidunt\n            pulvinar sapien lacinia. Nulla at risus ut dolor condimentum\n            consequat sit amet nec magna. Praesent in arcu ac lorem feugiat\n            ultrices a elementum sem. Nam elementum turpis ut sapien consectetur\n            sagittis sit amet eget massa.\n          </p>\n        ))}\n      </div>"
        },
        {
          "name": "WithContainerTarget",
          "description": "",
          "code": "<div className=\"flex h-screen w-full items-center justify-center p-8\">\n        <div className=\"relative h-100 w-full max-w-2xl overflow-hidden rounded-xl border border-border bg-card shadow-sm\">\n          <ReadingProgress\n            targetRef={containerRef}\n            progressColor=\"bg-success\"\n            height=\"md\"\n          />\n          <div ref={containerRef} className=\"h-full w-full overflow-y-auto p-8\">\n            <h2 className=\"mb-6 text-2xl font-bold text-card-foreground\">\n              Scrolla o Container Interno\n            </h2>\n            {Array.from({ length: 15 }).map((_, i) => (\n              <p key={i} className=\"mb-4 text-sm text-muted-foreground\">\n                Este é um exemplo de ReadingProgress atrelado a um container\n                específico, em vez de toda a página. Observe que ele usa{\" \"}\n                <code>absolute</code> dentro do container ao invés de{\" \"}\n                <code>fixed</code>. Lorem ipsum, dolor sit amet consectetur\n                adipisicing elit. Nostrum magnam tempora ea sint eaque\n                inventore.\n              </p>\n            ))}\n          </div>\n        </div>\n      </div>"
        }
      ]
    },
    {
      "name": "ds-receipt-card",
      "description": "Receipt Card component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/receipt-card",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/receipt-card.tsx"
      ],
      "props": [
        {
          "name": "edges",
          "required": false,
          "type": "\"both\" | \"top\" | \"bottom\" | \"none\"",
          "options": [
            "both",
            "top",
            "bottom",
            "none"
          ],
          "default": "both"
        }
      ],
      "storyTitle": "Data Display/ReceiptCard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<ReceiptCard edges=\"both\">\n      <ReceiptCardHeader>\n        <ReceiptCardTitle>LEMA-DS STORE</ReceiptCardTitle>\n        <div className=\"mt-2 text-sm text-muted-foreground\">\n          Av. dos Ipês, S/N - Castelo Branco\n          <br />\n          João Pessoa - PB\n        </div>\n        <div className=\"mt-4 font-mono text-sm text-muted-foreground\">\n          23/10/2026 14:32:05\n        </div>\n      </ReceiptCardHeader>\n\n      <ReceiptCardDivider />\n\n      <ReceiptCardContent>\n        <div className=\"space-y-3 font-mono text-sm\">\n          <ReceiptCardItem>\n            <span>1x Radial Menu</span>\n            <span>R$ 29,90</span>\n          </ReceiptCardItem>\n          <ReceiptCardItem>\n            <span>2x Morphing Dialog</span>\n            <span>R$ 50,00</span>\n          </ReceiptCardItem>\n          <ReceiptCardItem>\n            <span>1x Dynamic Island</span>\n            <span>R$ 15,00</span>\n          </ReceiptCardItem>\n          <ReceiptCardItem>\n            <span>1x Feedback Widget</span>\n            <span>R$ 0,00</span>\n          </ReceiptCardItem>\n        </div>\n\n        <ReceiptCardTotal>\n          <span>TOTAL</span>\n          <span>R$ 94,90</span>\n        </ReceiptCardTotal>\n      </ReceiptCardContent>\n\n      <ReceiptCardDivider />\n\n      <ReceiptCardFooter>\n        <BarcodeIcon\n          className=\"mb-4 h-12 w-full text-foreground/80\"\n          strokeWidth={1}\n        />\n        <p>Obrigado por usar o LEMA-DS!</p>\n        <p>Volte sempre.</p>\n      </ReceiptCardFooter>\n    </ReceiptCard>"
        },
        {
          "name": "TopEdgeOnly",
          "description": "",
          "code": "<ReceiptCard edges=\"top\">\n      <ReceiptCardHeader>\n        <ReceiptCardTitle>TICKET #42</ReceiptCardTitle>\n      </ReceiptCardHeader>\n      <ReceiptCardDivider />\n      <ReceiptCardContent>\n        <ReceiptCardItem>\n          <span>Entrada VIP</span>\n          <span>R$ 150,00</span>\n        </ReceiptCardItem>\n      </ReceiptCardContent>\n    </ReceiptCard>"
        },
        {
          "name": "BottomEdgeOnly",
          "description": "",
          "code": "<ReceiptCard edges=\"bottom\">\n      <ReceiptCardContent>\n        <div className=\"text-center font-mono\">\n          <div className=\"text-4xl font-bold\">SENHA</div>\n          <div className=\"mt-4 text-6xl font-black text-primary\">A042</div>\n        </div>\n      </ReceiptCardContent>\n    </ReceiptCard>"
        }
      ]
    },
    {
      "name": "ds-register",
      "title": "Register",
      "description": "Formulário de cadastro com social — átomo base register.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/register",
      "dependencies": [],
      "registryDependencies": [
        "input",
        "button",
        "checkbox",
        "label",
        "ds-input-password",
        "ds-social-auth-group",
        "ds-auth-separator",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/register.tsx"
      ],
      "props": [
        {
          "name": "onSubmit",
          "required": false,
          "type": "(data: { name: string; email: string; password: string }) => void"
        },
        {
          "name": "showSocial",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "socials",
          "required": false,
          "type": "(\"google\" | \"github\" | \"apple\" | \"microsoft\")[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Auth/Register",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{}"
        },
        {
          "name": "WithoutSocial",
          "description": "",
          "args": "{ showSocial: false }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true }"
        }
      ]
    },
    {
      "name": "ds-register-simple",
      "title": "Register Simple",
      "description": "Card cadastro centrado — blockus register #01-08.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/register-simple",
      "dependencies": [],
      "registryDependencies": [
        "ds-register",
        "badge"
      ],
      "files": [
        "components/ds/register-simple.tsx"
      ],
      "storyTitle": "Auth/RegisterSimple",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{}"
        },
        {
          "name": "WithBadge",
          "description": "",
          "args": "{ badge: \"New\" }"
        }
      ]
    },
    {
      "name": "ds-register-split",
      "title": "Register Split",
      "description": "Split screen imagem + formulário — blockus #09-22.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/register-split",
      "dependencies": [],
      "registryDependencies": [
        "ds-register",
        "avatar"
      ],
      "files": [
        "components/ds/register-split.tsx"
      ],
      "props": [
        {
          "name": "imageSrc",
          "required": false,
          "type": "string"
        },
        {
          "name": "testimonial",
          "required": false,
          "type": "{ quote: string author: string role?: string avatarUrl?: string }"
        }
      ],
      "storyTitle": "Auth/RegisterSplit",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    testimonial: {\n      quote: \"LEMA DS accelerated our onboarding.\",\n      author: \"Ana Silva\",\n      role: \"Design Lead\",\n      avatarUrl: \"https://picsum.photos/100/100\",\n    },\n  },"
        },
        {
          "name": "WithoutTestimonial",
          "description": "",
          "args": "{}"
        }
      ]
    },
    {
      "name": "ds-rich-text-editor",
      "title": "Rich Text Editor",
      "description": "A presentation component that provides the structure for a rich text editor.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/rich-text-editor",
      "dependencies": [],
      "registryDependencies": [
        "toggle"
      ],
      "files": [
        "components/ds/rich-text-editor.tsx"
      ],
      "props": [
        {
          "name": "invalid",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Form/RichTextEditor",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<div className=\"w-full max-w-[600px]\">\n      <RichTextEditor>\n        <RichTextToolbar>\n          <Toggle size=\"sm\" aria-label=\"Toggle bold\">\n            <BoldIcon className=\"size-4\" />\n          </Toggle>\n          <Toggle size=\"sm\" aria-label=\"Toggle italic\">\n            <ItalicIcon className=\"size-4\" />\n          </Toggle>\n          <Toggle size=\"sm\" aria-label=\"Toggle underline\">\n            <UnderlineIcon className=\"size-4\" />\n          </Toggle>\n          <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n          <Toggle size=\"sm\" aria-label=\"Toggle bullet list\">\n            <ListIcon className=\"size-4\" />\n          </Toggle>\n          <Toggle size=\"sm\" aria-label=\"Toggle ordered list\">\n            <ListOrderedIcon className=\"size-4\" />\n          </Toggle>\n        </RichTextToolbar>\n        <RichTextContent contentEditable suppressContentEditableWarning>\n          <p>\n            This is a <strong>presentation component</strong>.\n          </p>\n          <p>\n            It provides the visual shell for a rich text editor. The consumer\n            should wire it up with a library like TipTap, Slate, or Lexical.\n          </p>\n          <ul>\n            <li>Customizable toolbar</li>\n            <li>Focus and error states</li>\n            <li>Ready for integration</li>\n          </ul>\n        </RichTextContent>\n      </RichTextEditor>\n    </div>"
        },
        {
          "name": "Invalid",
          "description": "",
          "code": "<div className=\"w-full max-w-[600px]\">\n      <RichTextEditor invalid>\n        <RichTextToolbar>\n          <Toggle size=\"sm\" aria-label=\"Toggle bold\">\n            <BoldIcon className=\"size-4\" />\n          </Toggle>\n        </RichTextToolbar>\n        <RichTextContent contentEditable suppressContentEditableWarning>\n          <p>Please enter a description.</p>\n        </RichTextContent>\n      </RichTextEditor>\n      <p className=\"mt-2 text-sm text-destructive\">Description is required.</p>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-risk-level-bar",
      "title": "Risk Level Bar",
      "description": "A segmented progress bar with a movable marker. Uses semantic tokens (--risk-1 to --risk-4) for flexible theming.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/risk-level-bar",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/risk-level-bar.tsx"
      ],
      "props": [
        {
          "name": "labelLeft",
          "required": true,
          "type": "string"
        },
        {
          "name": "labelRight",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "number"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "segments",
          "required": false,
          "type": "RiskSegment[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "RiskLevelBarSize"
        },
        {
          "name": "side",
          "required": false,
          "type": "\"left\" | \"right\"",
          "options": [
            "left",
            "right"
          ],
          "default": "left"
        }
      ],
      "storyTitle": "Feedback/RiskLevelBar",
      "stories": [
        {
          "name": "Default",
          "description": "Default risk level bar at 0.65 with four risk segments.",
          "args": "{\n    labelLeft: \"Risk Level Indicator\",\n    labelRight: \"Current Score\",\n    value: 0.65,\n    loading: false,\n    locale: \"en-US\",\n    size: \"sm\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Default risk level bar at 0.65 with four risk segments.\",\n      },\n    },\n  },"
        },
        {
          "name": "LowRisk",
          "description": "Low risk value (0.15) — marker positioned near the left (low-risk) end of the bar.",
          "args": "{\n    labelLeft: \"Project Health\",\n    labelRight: \"Status\",\n    value: 0.15,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Low risk value (0.15) — marker positioned near the left (low-risk) end of the bar.\",\n      },\n    },\n  },"
        },
        {
          "name": "HighRisk",
          "description": "High risk value (0.9) — marker positioned near the right (high-risk) end of the bar.",
          "args": "{\n    labelLeft: \"System Alert Level\",\n    labelRight: \"Severity\",\n    value: 0.9,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"High risk value (0.9) — marker positioned near the right (high-risk) end of the bar.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Loading state with skeleton placeholder replacing the bar and labels.",
          "args": "{\n    labelLeft: \"Risk Level Indicator\",\n    labelRight: \"Current Score\",\n    value: 0.65,\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading state with skeleton placeholder replacing the bar and labels.\",\n      },\n    },\n  },"
        },
        {
          "name": "AllSizes",
          "description": "Comparison of all three size presets — sm, md, and lg.",
          "args": "{\n    labelLeft: \"Risk Level Indicator\",\n    labelRight: \"Current Score\",\n    value: 0.65,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Comparison of all three size presets — sm, md, and lg.\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization applied to labels.",
          "args": "{\n    labelLeft: \"Risk Level\",\n    labelRight: \"Score\",\n    value: 0.65,\n    locale: \"pt-BR\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Portuguese (pt-BR) localization applied to labels.\",\n      },\n    },\n  },"
        },
        {
          "name": "CustomSegments",
          "description": "Custom two-segment configuration with blue and green color overrides.",
          "args": "{\n    labelLeft: \"Custom Scale\",\n    labelRight: \"Value\",\n    value: 0.5,\n    segments: [\n      { color: \"oklch(0.6 0.2 250)\", range: [0, 0.5] },\n      { color: \"oklch(0.6 0.2 150)\", range: [0.5, 1] },\n    ],\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Custom two-segment configuration with blue and green color overrides.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-sankey-chart",
      "description": "Sankey diagram using pure SVG — no external dependencies.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/sankey-chart",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "card",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/sankey-chart.tsx"
      ],
      "props": [
        {
          "name": "nodes",
          "required": true,
          "type": "SankeyNode[]"
        },
        {
          "name": "links",
          "required": true,
          "type": "SankeyLink[]"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "nodeWidth",
          "required": false,
          "type": "number"
        },
        {
          "name": "nodePadding",
          "required": false,
          "type": "number"
        },
        {
          "name": "showLabels",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showValues",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(v: number) => string"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Charts/SankeyChart",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    nodes: TRAFFIC_NODES,\n    links: TRAFFIC_LINKS,\n    title: \"Traffic Flow\",\n    subtitle: \"User journey from acquisition to conversion\",\n    height: 400,\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    nodes: [],\n    links: [],\n    title: \"Traffic Flow\",\n    loading: true,\n    height: 400,\n  },"
        },
        {
          "name": "EmptyData",
          "description": "",
          "args": "{\n    nodes: [],\n    links: [],\n    title: \"Sankey Chart\",\n    height: 400,\n  },"
        },
        {
          "name": "BudgetAllocation",
          "description": "",
          "args": "{\n    nodes: [\n      { id: \"budget\", name: \"Total Budget\" },\n      { id: \"ops\", name: \"Operations\" },\n      { id: \"rnd\", name: \"R&D\" },\n      { id: \"mkt\", name: \"Marketing\" },\n      { id: \"infra\", name: \"Infrastructure\" },\n      { id: \"salaries\", name: \"Salaries\" },\n      { id: \"tools\", name: \"Tools\" },\n      { id: \"campaigns\", name: \"Campaigns\" },\n    ],\n    links: [\n      { source: \"budget\", target: \"ops\", value: 500000 },\n      { source: \"budget\", target: \"rnd\", value: 350000 },\n      { source: \"budget\", target: \"mkt\", value: 200000 },\n      { source: \"ops\", target: \"infra\", value: 180000 },\n      { source: \"ops\", target: \"salaries\", value: 320000 },\n      { source: \"rnd\", target: \"salaries\", value: 280000 },\n      { source: \"rnd\", target: \"tools\", value: 70000 },\n      { source: \"mkt\", target: \"campaigns\", value: 200000 },\n    ],\n    title: \"Budget Allocation\",\n    subtitle: \"Annual spend breakdown\",\n    format: \"currency\",\n    currency: \"USD\",\n    abbreviate: true,\n    height: 380,\n  },"
        },
        {
          "name": "SimpleFlow",
          "description": "",
          "args": "{\n    nodes: [\n      { id: \"a\", name: \"Source A\" },\n      { id: \"b\", name: \"Source B\" },\n      { id: \"middle\", name: \"Processing\" },\n      { id: \"out1\", name: \"Output 1\" },\n      { id: \"out2\", name: \"Output 2\" },\n    ],\n    links: [\n      { source: \"a\", target: \"middle\", value: 300 },\n      { source: \"b\", target: \"middle\", value: 200 },\n      { source: \"middle\", target: \"out1\", value: 320 },\n      { source: \"middle\", target: \"out2\", value: 180 },\n    ],\n    title: \"Simple Flow\",\n    height: 280,\n  },"
        }
      ]
    },
    {
      "name": "ds-scatter-chart",
      "title": "Scatter Chart",
      "description": "A responsive scatter and bubble chart with trend lines, multi-series, and brush zoom.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/scatter-chart",
      "dependencies": [
        "recharts",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils",
        "chart-axis-width"
      ],
      "files": [
        "components/ds/scatter-chart.tsx"
      ],
      "props": [
        {
          "name": "series",
          "required": true,
          "type": "ScatterSeries[]"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "showGrid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showLegend",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "legendPosition",
          "required": false,
          "type": "LegendPosition",
          "description": "@default \"bottom\""
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showTrendLine",
          "required": false,
          "type": "boolean",
          "description": "Draw a dashed linear-regression line through each series.\nUseful for spotting correlations and outliers."
        },
        {
          "name": "xLabel",
          "required": false,
          "type": "string",
          "description": "Label displayed below the X axis"
        },
        {
          "name": "yLabel",
          "required": false,
          "type": "string",
          "description": "Label displayed beside the Y axis"
        },
        {
          "name": "xFormatter",
          "required": false,
          "type": "(value: number) => string"
        },
        {
          "name": "yFormatter",
          "required": false,
          "type": "(value: number) => string"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Unified value formatter (applies to all axes & tooltip)."
        },
        {
          "name": "bubbleRange",
          "required": false,
          "type": "[number, number]",
          "description": "Point size range for the z dimension `[min, max]`.\nIgnored when no data point has a `z` value.\n@default [40, 400]"
        },
        {
          "name": "showBrush",
          "required": false,
          "type": "boolean",
          "description": "Show a dual-handle range brush below the chart to pan and zoom the X axis.\nDrag either handle to change the visible range, or drag the selection bar\nto pan the entire window."
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/ScatterChart",
      "stories": [
        {
          "name": "Default",
          "description": "Default scatter plot of study hours versus final grade with each dot representing one student and axis labels.",
          "args": "{\n    title: \"Study Hours vs. Final Grade\",\n    subtitle: \"Each dot represents one student — semester 2025.1\",\n    series: [{ name: \"Students\", data: studyVsGrade }],\n    xLabel: \"Hours / week\",\n    yLabel: \"Final grade\",\n    height: 320,\n    showGrid: true,\n    showLegend: false,\n    legendPosition: \"bottom\",\n    showTooltip: true,\n    showTrendLine: false,\n    bubbleRange: [40, 400],\n    showBrush: false,\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n  },"
        },
        {
          "name": "WithTrendLine",
          "description": "Scatter plot with a dashed linear regression line revealing a strong positive correlation between study hours and grades.",
          "args": "{\n    title: \"Study Hours vs. Final Grade\",\n    subtitle:\n      \"Dashed line shows linear regression — strong positive correlation\",\n    series: [{ name: \"Students\", data: studyVsGrade }],\n    xLabel: \"Hours / week\",\n    yLabel: \"Final grade\",\n    showGrid: true,\n    showTooltip: true,\n    showTrendLine: true,\n    height: 320,\n  },"
        },
        {
          "name": "MultiSeries",
          "description": "Two-series scatter plot comparing male and female study patterns with separate trend lines and an interactive legend.",
          "args": "{\n    title: \"Study Hours vs. Grade — by Gender\",\n    subtitle: \"Click a legend item to hide or show a series\",\n    series: [\n      { name: \"Male\", data: studyVsGradeMale },\n      { name: \"Female\", data: studyVsGradeFemale },\n    ],\n    xLabel: \"Hours / week\",\n    yLabel: \"Final grade\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    showTrendLine: true,\n    height: 340,\n  },"
        },
        {
          "name": "AttendanceVsApproval",
          "description": "Scatter plot showing the positive correlation between attendance rate and approval rate with percentage axis formatters.",
          "args": "{\n    title: \"Attendance Rate vs. Approval Rate\",\n    subtitle: \"Class groups — each dot is a course section\",\n    series: [\n      {\n        name: \"Course sections\",\n        data: attendanceVsApproval,\n        color: \"var(--chart-3)\",\n      },\n    ],\n    xLabel: \"Attendance (%)\",\n    yLabel: \"Approval rate (%)\",\n    showGrid: true,\n    showTooltip: true,\n    showTrendLine: true,\n    xFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n    yFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n    height: 320,\n  },"
        },
        {
          "name": "BubbleChart",
          "description": "Bubble chart encoding faculty count as bubble area for three schools compared by research output and teaching score.",
          "args": "{\n    title: \"Research Output vs. Teaching Score\",\n    subtitle: \"Bubble size = faculty count · 3 schools compared\",\n    series: [\n      { name: \"Engineering\", data: engineering },\n      { name: \"Health Sciences\", data: healthSciences },\n      { name: \"Humanities\", data: humanities },\n    ],\n    xLabel: \"Research output\",\n    yLabel: \"Teaching score\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    bubbleRange: [60, 600],\n    height: 360,\n  },"
        },
        {
          "name": "CustomShapes",
          "description": "Grid of four scatter plots demonstrating circle, diamond, triangle, and square point marker shapes with custom colors.",
          "args": "{ series: [{ name: \"Students\", data: studyVsGrade }] },",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {(\n        [\n          { shape: \"circle\", color: \"var(--chart-1)\" },\n          { shape: \"diamond\", color: \"var(--chart-2)\" },\n          { shape: \"triangle\", color: \"var(--chart-3)\" },\n          { shape: \"square\", color: \"var(--chart-4)\" },\n        ] as const\n      ).map(({ shape, color }) => (\n        <ScatterChart\n          key={shape}\n          title={`shape=\"${shape}\"`}\n          series={[{ name: \"Students\", data: studyVsGrade, color, shape }]}\n          showGrid\n          showTooltip\n          height={220}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "LegendPositions",
          "description": "Grid of four scatter plots placing the legend at top, right, bottom, and left for series identification.",
          "args": "{ series: [{ name: \"Male\", data: studyVsGradeMale }] },",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((pos) => (\n        <ScatterChart\n          key={pos}\n          title={`legendPosition=\"${pos}\"`}\n          series={[\n            { name: \"Male\", data: studyVsGradeMale },\n            { name: \"Female\", data: studyVsGradeFemale },\n          ]}\n          showGrid\n          showLegend\n          legendPosition={pos}\n          showTooltip\n          height={240}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "WithFooter",
          "description": "Two-series scatter plot with trend lines and a footer showing the correlation coefficient and sample size.",
          "args": "{\n    title: \"Study Hours vs. Final Grade\",\n    subtitle: \"Semester 2025.1 — 20 students sampled\",\n    series: [\n      { name: \"Male\", data: studyVsGradeMale },\n      { name: \"Female\", data: studyVsGradeFemale },\n    ],\n    xLabel: \"Hours / week\",\n    yLabel: \"Final grade\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    showTrendLine: true,\n    height: 340,\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <span className=\"flex items-center gap-1.5\">\n          <TrendingUp className=\"size-3.5 text-success\" />\n          Strong positive correlation (r ≈ 0.91)\n        </span>\n        <span className=\"flex items-center gap-1.5 text-muted-foreground/70\">\n          <Users className=\"size-3\" />\n          20 students · CS-101\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "WithBrush",
          "description": "Scatter plot with a brush slider for interactive zoom on an 80-student absence versus grade dataset with trend line.",
          "args": "{\n    title: \"Absences vs. Final Grade\",\n    subtitle:\n      \"80 students — drag the handles below to zoom in on an absence range\",\n    series: [\n      { name: \"Students\", data: absenceVsGrade, color: \"var(--chart-1)\" },\n    ],\n    xLabel: \"Absences\",\n    yLabel: \"Final grade\",\n    showGrid: true,\n    showTooltip: true,\n    showTrendLine: true,\n    showBrush: true,\n    height: 320,\n  },"
        },
        {
          "name": "WithBrushMultiSeries",
          "description": "Two-series scatter plot with brush showing low-absence versus high-absence student clusters with separate trend lines.",
          "args": "{\n    title: \"Absences vs. Grade — Low vs. High Absenteeism\",\n    subtitle:\n      \"Drag handles to compare ranges · drag the bar between them to pan\",\n    series: [\n      { name: \"≤ 75 absences\", data: lowAbsence, color: \"var(--chart-2)\" },\n      { name: \"> 75 absences\", data: highAbsence, color: \"var(--destructive)\" },\n    ],\n    xLabel: \"Absences\",\n    yLabel: \"Final grade\",\n    showGrid: true,\n    showLegend: true,\n    showTooltip: true,\n    showTrendLine: true,\n    showBrush: true,\n    height: 340,\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Scatter plot with Portuguese locale displaying study hours versus final grade in localized number format.",
          "args": "{\n    title: \"Study Hours vs. Final Grade\",\n    subtitle: \"Each dot represents one student — semester 2025.1\",\n    series: [{ name: \"Students\", data: studyVsGrade }],\n    xLabel: \"Hours / week\",\n    yLabel: \"Final grade\",\n    showGrid: true,\n    showTooltip: true,\n    height: 320,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the scatter chart with an animated skeleton that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Study Hours vs. Final Grade\",\n    subtitle: \"Each dot represents one student — semester 2025.1\",\n    series: [{ name: \"Students\", data: studyVsGrade }],\n    xLabel: \"Hours / week\",\n    yLabel: \"Final grade\",\n    showGrid: true,\n    showTooltip: true,\n    height: 320,\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `series` is an empty array, the scatter chart renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Study Hours vs. Final Grade\",\n    subtitle: \"Each dot represents one student\",\n    series: [],\n    xLabel: \"Hours / week\",\n    yLabel: \"Final grade\",\n    height: 320,\n  },"
        },
        {
          "name": "OutlierDetection",
          "description": "Scatter plot with deliberate outlier points added and flagged in the footer, demonstrating trend-line-based outlier detection.",
          "args": "{\n    title: \"Outlier Detection — Study vs. Grade\",\n    subtitle: \"Trend line makes outliers (low study, high grade) easy to spot\",\n    series: [\n      {\n        name: \"Students\",\n        data: [\n          ...studyVsGrade,\n          // deliberate outliers\n          { x: 2, y: 90 },\n          { x: 14, y: 48 },\n        ],\n        color: \"var(--chart-1)\",\n      },\n    ],\n    xLabel: \"Hours / week\",\n    yLabel: \"Final grade\",\n    showGrid: true,\n    showTooltip: true,\n    showTrendLine: true,\n    height: 340,\n    footer: (\n      <span className=\"flex items-center gap-1.5\">\n        <AlertCircle className=\"size-3.5 text-warning\" />\n        Two outliers added manually — points far from the trend line warrant\n        review\n      </span>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-schedule",
      "title": "Schedule",
      "description": "Grade semanal com slots — ReUI Schedule 10.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/schedule",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/schedule.tsx"
      ],
      "props": [
        {
          "name": "days",
          "required": false,
          "type": "string[]"
        },
        {
          "name": "slots",
          "required": true,
          "type": "ScheduleSlot[][]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Dashboard/Schedule",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    slots: [\n      [{ time: \"09:00\", title: \"Standup\" }, {}, { time: \"09:00\" }],\n      [{ time: \"10:00\" }, { time: \"10:00\", title: \"Review\" }],\n    ],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ slots: [], loading: true }"
        }
      ]
    },
    {
      "name": "ds-score-row",
      "title": "Score Row",
      "description": "A scored list item pairing icon + label with a fractional score and optional progress bar. Includes ScoreRowList container for grouped items.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/score-row",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "progress",
        "skeleton",
        "tooltip",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/score-row.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ElementType",
          "description": "Lucide icon component. Defaults to FileTextIcon."
        },
        {
          "name": "score",
          "required": true,
          "type": "number",
          "description": "Current score value."
        },
        {
          "name": "total",
          "required": true,
          "type": "number",
          "description": "Maximum / total possible score."
        },
        {
          "name": "size",
          "required": false,
          "type": "ScoreRowSize"
        },
        {
          "name": "status",
          "required": false,
          "type": "ScoreRowStatus | \"auto\"",
          "description": "Color status for the icon container and score.\nUse `\"auto\"` to derive from the score ratio:\n≥70% → success, ≥40% → warning, <40% → destructive."
        },
        {
          "name": "scoreDisplay",
          "required": false,
          "type": "ScoreRowScoreDisplay",
          "description": "How the score is rendered on the right. Defaults to \"fraction\"."
        },
        {
          "name": "showProgress",
          "required": false,
          "type": "boolean",
          "description": "When true, renders a colored progress bar at the bottom of the row.\nHovering the bar shows a tooltip with locale-aware percentage."
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "percentDecimals",
          "required": false,
          "type": "number",
          "description": "Number of decimal places in the percentage display (progress tooltip and aria-label). Defaults to 0."
        },
        {
          "name": "accent",
          "required": false,
          "type": "string",
          "description": "Override all intent-based colors via CSS token `--score-accent`.\nDrives icon container bg/text, score value text, and progress fill.\nAccepts any CSS color or `var(--my-token)`."
        },
        {
          "name": "tooltip",
          "required": false,
          "type": "React.ReactNode",
          "description": "Optional tooltip content for the entire row. When provided, the row\nitself becomes the tooltip trigger (keyboard-focusable) and the\nbuilt-in progress-bar tooltip is suppressed, avoiding nested tooltips."
        }
      ],
      "storyTitle": "Data Display/ScoreRow",
      "stories": [
        {
          "name": "Default",
          "description": "Exact replica of the design reference: document icon, title, subtitle, and a `76 / 95` score.",
          "args": "{\n    title: \"Standard Audit\",\n    description: \"June 2025 baseline\",\n    icon: FileTextIcon,\n    score: 76,\n    total: 95,\n    size: \"md\",\n    status: \"default\",\n    scoreDisplay: \"fraction\",\n    showProgress: true,\n    loading: false,\n    locale: \"en-US\",\n    percentDecimals: 0,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Exact replica of the design reference: document icon, title, subtitle, and a `76 / 95` score.\",\n      },\n    },\n  },"
        },
        {
          "name": "Sizes",
          "description": "Three size presets — `sm`, `md`, and `lg` — stacked to compare density and typographic scale.",
          "args": "{ title: \"Standard Audit\", score: 48, total: 95 },\n  render: () => (\n    <div className=\"flex flex-col gap-0\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <ScoreRow\n          key={size}\n          size={size}\n          title=\"Standard Audit\"\n          description={`June 2025 baseline · size=\"${size}\"`}\n          icon={FileTextIcon}\n          score={48}\n          total={95}\n        />\n      ))}\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Three size presets — `sm`, `md`, and `lg` — stacked to compare density and typographic scale.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-col gap-0\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <ScoreRow\n          key={size}\n          size={size}\n          title=\"Standard Audit\"\n          description={`June 2025 baseline · size=\"${size}\"`}\n          icon={FileTextIcon}\n          score={48}\n          total={95}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "StatusVariants",
          "description": "All four status variants. The icon container background and score color reflect the status token.",
          "args": "{ title: \"Standard Audit\", score: 72, total: 95 },\n  render: () => (\n    <ScoreRowList>\n      <ScoreRow\n        title=\"Status: default\"\n        description=\"No score yet\"\n        icon={FileTextIcon}\n        score={0}\n        total={95}\n        status=\"default\"\n      />\n      <ScoreRow\n        title=\"Status: success\"\n        description=\"Goal achieved (≥70%)\"\n        icon={ShieldCheckIcon}\n        score={72}\n        total={95}\n        status=\"success\"\n      />\n      <ScoreRow\n        title=\"Status: warning\"\n        description=\"Attention needed (40–69%)\"\n        icon={ClipboardListIcon}\n        score={42}\n        total={95}\n        status=\"warning\"\n      />\n      <ScoreRow\n        title=\"Status: destructive\"\n        description=\"Below minimum (<40%)\"\n        icon={ActivityIcon}\n        score={18}\n        total={95}\n        status=\"destructive\"\n      />\n    </ScoreRowList>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"All four status variants. The icon container background and score color reflect the status token.\",\n      },\n    },\n  },",
          "code": "<ScoreRowList>\n      <ScoreRow\n        title=\"Status: default\"\n        description=\"No score yet\"\n        icon={FileTextIcon}\n        score={0}\n        total={95}\n        status=\"default\"\n      />\n      <ScoreRow\n        title=\"Status: success\"\n        description=\"Goal achieved (≥70%)\"\n        icon={ShieldCheckIcon}\n        score={72}\n        total={95}\n        status=\"success\"\n      />\n      <ScoreRow\n        title=\"Status: warning\"\n        description=\"Attention needed (40–69%)\"\n        icon={ClipboardListIcon}\n        score={42}\n        total={95}\n        status=\"warning\"\n      />\n      <ScoreRow\n        title=\"Status: destructive\"\n        description=\"Below minimum (<40%)\"\n        icon={ActivityIcon}\n        score={18}\n        total={95}\n        status=\"destructive\"\n      />\n    </ScoreRowList>"
        },
        {
          "name": "AutoStatus",
          "description": "With `status=\"auto\"`, the component derives the color from the ratio: <40% → destructive, 40–69% → warning, ≥70% → success.",
          "args": "{ title: \"Standard Audit\", score: 48, total: 95, status: \"auto\" },\n  render: () => (\n    <ScoreRowList>\n      {[\n        { score: 0, label: \"0 / 95 — no responses yet\" },\n        { score: 18, label: \"18 / 95 — below 40%\" },\n        { score: 42, label: \"42 / 95 — between 40–69%\" },\n        { score: 72, label: \"72 / 95 — ≥70%, approved\" },\n        { score: 95, label: \"95 / 95 — maximum score\" },\n      ].map(({ score, label }) => (\n        <ScoreRow\n          key={score}\n          title={label}\n          description={`status=\"auto\" → ${score === 0 ? \"default\" : score < 38 ? \"destructive\" : score < 67 ? \"warning\" : \"success\"}`}\n          icon={BarChart2Icon}\n          score={score}\n          total={95}\n          status=\"auto\"\n          showProgress\n        />\n      ))}\n    </ScoreRowList>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'With `status=\"auto\"`, the component derives the color from the ratio: <40% → destructive, 40–69% → warning, ≥70% → success.',\n      },\n    },\n  },",
          "code": "<ScoreRowList>\n      {[\n        { score: 0, label: \"0 / 95 — no responses yet\" },\n        { score: 18, label: \"18 / 95 — below 40%\" },\n        { score: 42, label: \"42 / 95 — between 40–69%\" },\n        { score: 72, label: \"72 / 95 — ≥70%, approved\" },\n        { score: 95, label: \"95 / 95 — maximum score\" },\n      ].map(({ score, label }) => (\n        <ScoreRow\n          key={score}\n          title={label}\n          description={`status=\"auto\" → ${score === 0 ? \"default\" : score < 38 ? \"destructive\" : score < 67 ? \"warning\" : \"success\"}`}\n          icon={BarChart2Icon}\n          score={score}\n          total={95}\n          status=\"auto\"\n          showProgress\n        />\n      ))}\n    </ScoreRowList>"
        },
        {
          "name": "ScoreDisplayModes",
          "description": "The same score (68/95) rendered as a fraction, a percentage, and a raw number.",
          "args": "{ title: \"Teaching Evaluation\", score: 68, total: 95 },\n  render: () => (\n    <ScoreRowList>\n      <ScoreRow\n        title=\"Fraction (default)\"\n        description='scoreDisplay=\"fraction\"'\n        icon={FileTextIcon}\n        score={68}\n        total={95}\n        scoreDisplay=\"fraction\"\n        status=\"auto\"\n      />\n      <ScoreRow\n        title=\"Percentage\"\n        description='scoreDisplay=\"percent\"'\n        icon={FileTextIcon}\n        score={68}\n        total={95}\n        scoreDisplay=\"percent\"\n        status=\"auto\"\n      />\n      <ScoreRow\n        title=\"Raw value\"\n        description='scoreDisplay=\"raw\"'\n        icon={FileTextIcon}\n        score={68}\n        total={95}\n        scoreDisplay=\"raw\"\n        status=\"auto\"\n      />\n    </ScoreRowList>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"The same score (68/95) rendered as a fraction, a percentage, and a raw number.\",\n      },\n    },\n  },",
          "code": "<ScoreRowList>\n      <ScoreRow\n        title=\"Fraction (default)\"\n        description='scoreDisplay=\"fraction\"'\n        icon={FileTextIcon}\n        score={68}\n        total={95}\n        scoreDisplay=\"fraction\"\n        status=\"auto\"\n      />\n      <ScoreRow\n        title=\"Percentage\"\n        description='scoreDisplay=\"percent\"'\n        icon={FileTextIcon}\n        score={68}\n        total={95}\n        scoreDisplay=\"percent\"\n        status=\"auto\"\n      />\n      <ScoreRow\n        title=\"Raw value\"\n        description='scoreDisplay=\"raw\"'\n        icon={FileTextIcon}\n        score={68}\n        total={95}\n        scoreDisplay=\"raw\"\n        status=\"auto\"\n      />\n    </ScoreRowList>"
        },
        {
          "name": "WithProgressBar",
          "description": "When `showProgress` is true, a 2px colored progress bar appears at the bottom of each row, filled proportionally to `score / total`.",
          "args": "{\n    title: \"Standard Audit\",\n    description: \"June 2025 baseline\",\n    icon: FileTextIcon,\n    score: 48,\n    total: 95,\n    showProgress: true,\n    status: \"auto\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"When `showProgress` is true, a 2px colored progress bar appears at the bottom of each row, filled proportionally to `score / total`.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithoutProgressBar",
          "description": "When `showProgress` is `false`, the progress bar at the bottom of the row is not rendered. This keeps the row more compact — useful for dense lists where the progress bar adds visual noise.",
          "args": "{\n    title: \"Standard Audit\",\n    description: \"June 2025 baseline — hidden progress bar\",\n    icon: FileTextIcon,\n    score: 48,\n    total: 95,\n    showProgress: false,\n    status: \"auto\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"When `showProgress` is `false`, the progress bar at the bottom of the row is not rendered. This keeps the row more compact — useful for dense lists where the progress bar adds visual noise.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Skeleton loading state for all three sizes. Uses `<Skeleton>` from shadcn/ui — no custom `animate-pulse` divs.",
          "args": "{ title: \"\", score: 0, total: 0, loading: true },\n  render: () => (\n    <ScoreRowList>\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <ScoreRow key={size} size={size} title=\"\" score={0} total={0} loading />\n      ))}\n    </ScoreRowList>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Skeleton loading state for all three sizes. Uses `<Skeleton>` from shadcn/ui — no custom `animate-pulse` divs.\",\n      },\n    },\n  },",
          "code": "<ScoreRowList>\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <ScoreRow key={size} size={size} title=\"\" score={0} total={0} loading />\n      ))}\n    </ScoreRowList>"
        },
        {
          "name": "Interactive",
          "description": "Pass an `onClick` handler to make the row interactive. The row renders as a `<button>` with hover and focus-visible states.",
          "args": "{\n    title: \"Standard Audit\",\n    description: \"June 2025 baseline\",\n    score: 48,\n    total: 95,\n    status: \"auto\",\n    showProgress: true,\n  },\n  render: () => {\n    const [selected, setSelected] = React.useState<string | null>(null)\n\n    const items = [\n      {\n        id: \"audit-1\",\n        title: \"Standard Audit\",\n        description: \"June 2025 baseline\",\n        icon: FileTextIcon,\n        score: 68,\n        total: 95,\n      },\n      {\n        id: \"audit-2\",\n        title: \"Teaching Evaluation\",\n        description: \"2025.1 cycle\",\n        icon: GraduationCapIcon,\n        score: 42,\n        total: 80,\n      },\n      {\n        id: \"audit-3\",\n        title: \"Infrastructure\",\n        description: \"Academic semester\",\n        icon: ShieldCheckIcon,\n        score: 12,\n        total: 60,\n      },\n      {\n        id: \"audit-4\",\n        title: \"Library\",\n        description: \"Digital collection\",\n        icon: BookOpenIcon,\n        score: 90,\n        total: 100,\n      },\n    ]\n\n    return (\n      <div className=\"flex flex-col gap-4\">\n        <ScoreRowList>\n          {items.map((item) => (\n            <ScoreRow\n              key={item.id}\n              title={item.title}\n              description={item.description}\n              icon={item.icon}\n              score={item.score}\n              total={item.total}\n              status=\"auto\"\n              showProgress\n              onClick={() => setSelected(item.id)}\n              className={item.id === selected ? \"bg-accent\" : \"\"}\n            />\n          ))}\n        </ScoreRowList>\n        {selected && (\n          <p className=\"text-xs text-muted-foreground\">\n            Selected:{\" \"}\n            <strong>{items.find((i) => i.id === selected)?.title}</strong>\n          </p>\n        )}\n      </div>\n    )\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Pass an `onClick` handler to make the row interactive. The row renders as a `<button>` with hover and focus-visible states.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-col gap-4\">\n        <ScoreRowList>\n          {items.map((item) => (\n            <ScoreRow\n              key={item.id}\n              title={item.title}\n              description={item.description}\n              icon={item.icon}\n              score={item.score}\n              total={item.total}\n              status=\"auto\"\n              showProgress\n              onClick={() => setSelected(item.id)}\n              className={item.id === selected ? \"bg-accent\" : \"\"}\n            />\n          ))}\n        </ScoreRowList>\n        {selected && (\n          <p className=\"text-xs text-muted-foreground\">\n            Selected:{\" \"}\n            <strong>{items.find((i) => i.id === selected)?.title}</strong>\n          </p>\n        )}\n      </div>"
        },
        {
          "name": "AuditList",
          "description": "A realistic audit checklist using `ScoreRowList` as a container. Each row derives its status automatically and shows a progress bar. Items at the bottom have no trailing border.",
          "args": "{ title: \"Standard Audit\", score: 0, total: 95 },\n  render: () => (\n    <ScoreRowList>\n      <ScoreRow\n        title=\"Standard Audit\"\n        description=\"June 2025 baseline\"\n        icon={FileTextIcon}\n        score={0}\n        total={95}\n        status=\"auto\"\n        showProgress\n      />\n      <ScoreRow\n        title=\"Teaching Evaluation\"\n        description=\"2025.1 cycle\"\n        icon={GraduationCapIcon}\n        score={58}\n        total={80}\n        status=\"auto\"\n        showProgress\n      />\n      <ScoreRow\n        title=\"Accessibility Conditions\"\n        description=\"2025 academic semester\"\n        icon={UsersIcon}\n        score={12}\n        total={60}\n        status=\"auto\"\n        showProgress\n      />\n      <ScoreRow\n        title=\"Infrastructure & Equipment\"\n        description=\"Annual report\"\n        icon={ShieldCheckIcon}\n        score={47}\n        total={50}\n        status=\"auto\"\n        showProgress\n      />\n      <ScoreRow\n        title=\"Bibliographic Collection\"\n        description=\"Central Library\"\n        icon={BookOpenIcon}\n        score={33}\n        total={40}\n        status=\"auto\"\n        showProgress\n      />\n    </ScoreRowList>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"A realistic audit checklist using `ScoreRowList` as a container. Each row derives its status automatically and shows a progress bar. Items at the bottom have no trailing border.\",\n      },\n    },\n  },",
          "code": "<ScoreRowList>\n      <ScoreRow\n        title=\"Standard Audit\"\n        description=\"June 2025 baseline\"\n        icon={FileTextIcon}\n        score={0}\n        total={95}\n        status=\"auto\"\n        showProgress\n      />\n      <ScoreRow\n        title=\"Teaching Evaluation\"\n        description=\"2025.1 cycle\"\n        icon={GraduationCapIcon}\n        score={58}\n        total={80}\n        status=\"auto\"\n        showProgress\n      />\n      <ScoreRow\n        title=\"Accessibility Conditions\"\n        description=\"2025 academic semester\"\n        icon={UsersIcon}\n        score={12}\n        total={60}\n        status=\"auto\"\n        showProgress\n      />\n      <ScoreRow\n        title=\"Infrastructure & Equipment\"\n        description=\"Annual report\"\n        icon={ShieldCheckIcon}\n        score={47}\n        total={50}\n        status=\"auto\"\n        showProgress\n      />\n      <ScoreRow\n        title=\"Bibliographic Collection\"\n        description=\"Central Library\"\n        icon={BookOpenIcon}\n        score={33}\n        total={40}\n        status=\"auto\"\n        showProgress\n      />\n    </ScoreRowList>"
        },
        {
          "name": "CustomIcons",
          "description": "Any Lucide icon can be passed via the `icon` prop. The container adapts its background tint to the resolved status.",
          "args": "{ title: \"Standard Audit\", score: 60, total: 95 },\n  render: () => (\n    <ScoreRowList>\n      {[\n        {\n          icon: ClipboardListIcon,\n          title: \"Compliance Checklist\",\n          score: 60,\n          total: 95,\n        },\n        {\n          icon: GraduationCapIcon,\n          title: \"Teacher Training\",\n          score: 30,\n          total: 60,\n        },\n        {\n          icon: ShieldCheckIcon,\n          title: \"Security & Privacy\",\n          score: 18,\n          total: 20,\n        },\n        {\n          icon: ActivityIcon,\n          title: \"Performance Indicators\",\n          score: 5,\n          total: 40,\n        },\n        {\n          icon: UsersIcon,\n          title: \"Student Engagement\",\n          score: 75,\n          total: 100,\n        },\n      ].map(({ icon, title, score, total }) => (\n        <ScoreRow\n          key={title}\n          title={title}\n          icon={icon}\n          score={score}\n          total={total}\n          status=\"auto\"\n        />\n      ))}\n    </ScoreRowList>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Any Lucide icon can be passed via the `icon` prop. The container adapts its background tint to the resolved status.\",\n      },\n    },\n  },",
          "code": "<ScoreRowList>\n      {[\n        {\n          icon: ClipboardListIcon,\n          title: \"Compliance Checklist\",\n          score: 60,\n          total: 95,\n        },\n        {\n          icon: GraduationCapIcon,\n          title: \"Teacher Training\",\n          score: 30,\n          total: 60,\n        },\n        {\n          icon: ShieldCheckIcon,\n          title: \"Security & Privacy\",\n          score: 18,\n          total: 20,\n        },\n        {\n          icon: ActivityIcon,\n          title: \"Performance Indicators\",\n          score: 5,\n          total: 40,\n        },\n        {\n          icon: UsersIcon,\n          title: \"Student Engagement\",\n          score: 75,\n          total: 100,\n        },\n      ].map(({ icon, title, score, total }) => (\n        <ScoreRow\n          key={title}\n          title={title}\n          icon={icon}\n          score={score}\n          total={total}\n          status=\"auto\"\n        />\n      ))}\n    </ScoreRowList>"
        },
        {
          "name": "LocalePtBR",
          "description": "With `locale=\"pt-BR\"`, the decimal separator in tooltips and `scoreDisplay=\"percent\"` uses a comma (`71,6%`) via `Intl.NumberFormat`. The `scoreLabel` in `aria-label` is translated to *Score*. Hover the progress bar to see the localized tooltip.",
          "args": "{\n    title: \"Standard Audit\",\n    description: \"June 2025 baseline\",\n    score: 68,\n    total: 95,\n    locale: \"pt-BR\",\n    percentDecimals: 1,\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Percentage with pt-BR decimal separator (comma)\n        </p>\n        <ScoreRowList>\n          <ScoreRow\n            title=\"Standard Audit\"\n            description=\"June 2025 baseline\"\n            icon={FileTextIcon}\n            score={68}\n            total={95}\n            locale=\"pt-BR\"\n            status=\"auto\"\n            showProgress\n            percentDecimals={1}\n          />\n          <ScoreRow\n            title=\"Teaching Evaluation\"\n            description=\"2025.1 cycle\"\n            icon={GraduationCapIcon}\n            score={42}\n            total={80}\n            locale=\"pt-BR\"\n            status=\"auto\"\n            showProgress\n            percentDecimals={1}\n          />\n          <ScoreRow\n            title=\"Bibliographic Collection\"\n            description=\"Central Library\"\n            icon={BookOpenIcon}\n            score={12}\n            total={60}\n            locale=\"pt-BR\"\n            status=\"auto\"\n            showProgress\n            percentDecimals={1}\n          />\n        </ScoreRowList>\n      </div>\n\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          scoreDisplay=&quot;percent&quot; — formatting via Intl.NumberFormat (1\n          decimal)\n        </p>\n        <ScoreRowList>\n          {(\n            [\n              { score: 68, total: 95, title: \"Standard Audit\" },\n              { score: 42, total: 80, title: \"Teaching Evaluation\" },\n              { score: 12, total: 60, title: \"Infrastructure\" },\n            ] as const\n          ).map(({ score, total, title }) => (\n            <ScoreRow\n              key={title}\n              title={title}\n              icon={BarChart2Icon}\n              score={score}\n              total={total}\n              locale=\"pt-BR\"\n              status=\"auto\"\n              scoreDisplay=\"percent\"\n              percentDecimals={1}\n            />\n          ))}\n        </ScoreRowList>\n      </div>\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'With `locale=\"pt-BR\"`, the decimal separator in tooltips and `scoreDisplay=\"percent\"` uses a comma (`71,6%`) via `Intl.NumberFormat`. The `scoreLabel` in `aria-label` is translated to *Score*. Hover the progress bar to see the localized tooltip.',\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Percentage with pt-BR decimal separator (comma)\n        </p>\n        <ScoreRowList>\n          <ScoreRow\n            title=\"Standard Audit\"\n            description=\"June 2025 baseline\"\n            icon={FileTextIcon}\n            score={68}\n            total={95}\n            locale=\"pt-BR\"\n            status=\"auto\"\n            showProgress\n            percentDecimals={1}\n          />\n          <ScoreRow\n            title=\"Teaching Evaluation\"\n            description=\"2025.1 cycle\"\n            icon={GraduationCapIcon}\n            score={42}\n            total={80}\n            locale=\"pt-BR\"\n            status=\"auto\"\n            showProgress\n            percentDecimals={1}\n          />\n          <ScoreRow\n            title=\"Bibliographic Collection\"\n            description=\"Central Library\"\n            icon={BookOpenIcon}\n            score={12}\n            total={60}\n            locale=\"pt-BR\"\n            status=\"auto\"\n            showProgress\n            percentDecimals={1}\n          />\n        </ScoreRowList>\n      </div>\n\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          scoreDisplay=&quot;percent&quot; — formatting via Intl.NumberFormat (1\n          decimal)\n        </p>\n        <ScoreRowList>\n          {(\n            [\n              { score: 68, total: 95, title: \"Standard Audit\" },\n              { score: 42, total: 80, title: \"Teaching Evaluation\" },\n              { score: 12, total: 60, title: \"Infrastructure\" },\n            ] as const\n          ).map(({ score, total, title }) => (\n            <ScoreRow\n              key={title}\n              title={title}\n              icon={BarChart2Icon}\n              score={score}\n              total={total}\n              locale=\"pt-BR\"\n              status=\"auto\"\n              scoreDisplay=\"percent\"\n              percentDecimals={1}\n            />\n          ))}\n        </ScoreRowList>\n      </div>\n    </div>"
        },
        {
          "name": "ColorTokens",
          "description": "The `accent` prop accepts any CSS color or `var(--my-token)`. It sets `--score-accent` as a CSS custom property and drives icon container background/text (`bg-(--score-accent)/10 text-(--score-accent)`), the score value text, and the progress fill — overriding all `status`-based colors for per-instance customization.",
          "args": "{ title: \"Categoria\", score: 72, total: 100 },\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Direct CSS color values\n        </p>\n        <ScoreRowList>\n          <ScoreRow\n            title=\"Vendas\"\n            description=\"Ciclo 2025.1\"\n            icon={BarChart2Icon}\n            score={85}\n            total={100}\n            accent=\"oklch(0.5 0.2 270)\"\n          />\n          <ScoreRow\n            title=\"Infraestrutura\"\n            description=\"Semestre acadêmico\"\n            icon={ShieldCheckIcon}\n            score={40}\n            total={100}\n            accent=\"oklch(0.55 0.18 30)\"\n          />\n        </ScoreRowList>\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Design system token references\n        </p>\n        <ScoreRowList>\n          <ScoreRow\n            title=\"Produto\"\n            description=\"Resultado trimestral\"\n            icon={ClipboardListIcon}\n            score={91}\n            total={100}\n            accent=\"var(--color-success)\"\n          />\n          <ScoreRow\n            title=\"Marketing\"\n            description=\"Campanha atual\"\n            icon={ActivityIcon}\n            score={62}\n            total={100}\n            accent=\"var(--color-warning)\"\n          />\n          <ScoreRow\n            title=\"Suporte\"\n            description=\"Chamados abertos\"\n            icon={UsersIcon}\n            score={30}\n            total={100}\n            accent=\"var(--color-destructive)\"\n          />\n        </ScoreRowList>\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          External token with fallback\n        </p>\n        <ScoreRowList>\n          <ScoreRow\n            title=\"Categoria Customizada\"\n            description=\"Token externo com fallback\"\n            icon={FileTextIcon}\n            score={74}\n            total={100}\n            accent=\"var(--color-brand, oklch(0.4 0.2 240))\"\n          />\n        </ScoreRowList>\n      </div>\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"The `accent` prop accepts any CSS color or `var(--my-token)`. It sets `--score-accent` as a CSS custom property and drives icon container background/text (`bg-(--score-accent)/10 text-(--score-accent)`), the score value text, and the progress fill — overriding all `status`-based colors for per-instance customization.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Direct CSS color values\n        </p>\n        <ScoreRowList>\n          <ScoreRow\n            title=\"Vendas\"\n            description=\"Ciclo 2025.1\"\n            icon={BarChart2Icon}\n            score={85}\n            total={100}\n            accent=\"oklch(0.5 0.2 270)\"\n          />\n          <ScoreRow\n            title=\"Infraestrutura\"\n            description=\"Semestre acadêmico\"\n            icon={ShieldCheckIcon}\n            score={40}\n            total={100}\n            accent=\"oklch(0.55 0.18 30)\"\n          />\n        </ScoreRowList>\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Design system token references\n        </p>\n        <ScoreRowList>\n          <ScoreRow\n            title=\"Produto\"\n            description=\"Resultado trimestral\"\n            icon={ClipboardListIcon}\n            score={91}\n            total={100}\n            accent=\"var(--color-success)\"\n          />\n          <ScoreRow\n            title=\"Marketing\"\n            description=\"Campanha atual\"\n            icon={ActivityIcon}\n            score={62}\n            total={100}\n            accent=\"var(--color-warning)\"\n          />\n          <ScoreRow\n            title=\"Suporte\"\n            description=\"Chamados abertos\"\n            icon={UsersIcon}\n            score={30}\n            total={100}\n            accent=\"var(--color-destructive)\"\n          />\n        </ScoreRowList>\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          External token with fallback\n        </p>\n        <ScoreRowList>\n          <ScoreRow\n            title=\"Categoria Customizada\"\n            description=\"Token externo com fallback\"\n            icon={FileTextIcon}\n            score={74}\n            total={100}\n            accent=\"var(--color-brand, oklch(0.4 0.2 240))\"\n          />\n        </ScoreRowList>\n      </div>\n    </div>"
        },
        {
          "name": "PercentDecimals",
          "description": "The `percentDecimals` prop controls decimal places in the progress bar tooltip and aria-label. Three presets (0, 1, 2) demonstrate the effect. Hover the progress bar to see the tooltip.",
          "args": "{\n    title: \"Standard Audit\",\n    score: 68,\n    total: 95,\n    status: \"auto\",\n    showProgress: true,\n    percentDecimals: 0,\n  },\n  render: () => (\n    <ScoreRowList>\n      {([0, 1, 2] as const).map((decimals) => (\n        <ScoreRow\n          key={decimals}\n          title={`percentDecimals=${decimals}`}\n          description={`68 / 95 → ${Math.round((68 / 95) * 100)}% w/ ${decimals} decimal place${decimals !== 1 ? \"s\" : \"\"}`}\n          icon={BarChart2Icon}\n          score={68}\n          total={95}\n          status=\"auto\"\n          showProgress\n          percentDecimals={decimals}\n        />\n      ))}\n    </ScoreRowList>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"The `percentDecimals` prop controls decimal places in the progress bar tooltip and aria-label. Three presets (0, 1, 2) demonstrate the effect. Hover the progress bar to see the tooltip.\",\n      },\n    },\n  },",
          "code": "<ScoreRowList>\n      {([0, 1, 2] as const).map((decimals) => (\n        <ScoreRow\n          key={decimals}\n          title={`percentDecimals=${decimals}`}\n          description={`68 / 95 → ${Math.round((68 / 95) * 100)}% w/ ${decimals} decimal place${decimals !== 1 ? \"s\" : \"\"}`}\n          icon={BarChart2Icon}\n          score={68}\n          total={95}\n          status=\"auto\"\n          showProgress\n          percentDecimals={decimals}\n        />\n      ))}\n    </ScoreRowList>"
        },
        {
          "name": "RowTooltip",
          "description": "The `tooltip` prop wraps the entire row in a single, keyboard-focusable tooltip trigger and suppresses the progress bar's own tooltip — avoiding the nested-tooltip problem that occurs when hovering the progress bar inside a row that already has an outer tooltip. Tab to a row to reveal the tooltip via focus, or hover anywhere on the row (including the progress bar).",
          "args": "{\n    title: \"Standard Audit\",\n    description: \"June 2025 baseline\",\n    icon: FileTextIcon,\n    score: 68,\n    total: 95,\n    status: \"auto\",\n    showProgress: true,\n    tooltip: \"68 of 95 items reviewed against the recommended capacity.\",\n  },\n  render: (args) => (\n    <ScoreRowList>\n      <ScoreRow {...args} />\n      <ScoreRow\n        title=\"Teaching Evaluation\"\n        description=\"2025.1 cycle\"\n        icon={GraduationCapIcon}\n        score={42}\n        total={80}\n        status=\"auto\"\n        showProgress\n        tooltip=\"42 of 80 evaluations submitted this cycle.\"\n      />\n    </ScoreRowList>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"The `tooltip` prop wraps the entire row in a single, keyboard-focusable tooltip trigger and suppresses the progress bar's own tooltip — avoiding the nested-tooltip problem that occurs when hovering the progress bar inside a row that already has an outer tooltip. Tab to a row to reveal the tooltip via focus, or hover anywhere on the row (including the progress bar).\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-scratch-to-reveal",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/scratch-to-reveal",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/scratch-to-reveal.tsx"
      ],
      "props": [
        {
          "name": "children",
          "required": true,
          "type": "React.ReactNode",
          "description": "Conteúdo escondido a ser revelado"
        },
        {
          "name": "width",
          "required": false,
          "type": "number",
          "description": "Largura do container (px)"
        },
        {
          "name": "height",
          "required": false,
          "type": "number",
          "description": "Altura do container (px)"
        },
        {
          "name": "brushSize",
          "required": false,
          "type": "number",
          "description": "Tamanho do pincel para raspar"
        },
        {
          "name": "revealThreshold",
          "required": false,
          "type": "number",
          "description": "Porcentagem raspada (0-100) para auto-revelar e disparar o callback"
        },
        {
          "name": "onReveal",
          "required": false,
          "type": "() => void",
          "description": "Função chamada quando o limite for alcançado"
        },
        {
          "name": "coverColor",
          "required": false,
          "type": "string",
          "description": "Cor hexadecimal ou rgba que cobre o canvas"
        }
      ],
      "storyTitle": "Delight/ScratchToReveal",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    width: 320,\n    height: 120,\n    coverColor: \"#475569\", // slate-600\n    brushSize: 40,\n    className: \"rounded-xl shadow-lg border border-border bg-muted/50\",\n    children: (\n      <div className=\"flex h-full w-full flex-col items-center justify-center p-4 text-center\">\n        <p className=\"text-sm font-semibold tracking-widest text-muted-foreground uppercase\">\n          Seu Cupom\n        </p>\n        <p className=\"mt-1 text-3xl font-black text-primary\">BEMVINDO20</p>\n      </div>\n    ),\n  },"
        },
        {
          "name": "RewardReveal",
          "description": "",
          "args": "{\n    width: 250,\n    height: 250,\n    coverColor: \"#eab308\", // yellow-500\n    brushSize: 50,\n    revealThreshold: 40,\n    className: \"rounded-full shadow-2xl overflow-hidden ring-4 ring-primary/20\",\n    children: (\n      <div className=\"flex h-full w-full flex-col items-center justify-center bg-linear-to-br from-violet-500 to-fuchsia-500 p-4 text-center text-white\">\n        <div className=\"text-5xl\">🎁</div>\n        <p className=\"mt-4 text-xl leading-tight font-bold\">\n          Você ganhou 1 Mês Grátis!\n        </p>\n      </div>\n    ),\n  },"
        }
      ]
    },
    {
      "name": "ds-screenshot",
      "title": "Screenshot",
      "description": "Screenshot theme-aware (light/dark) com otimização e skeleton — inspirado em Launch UI Screenshot.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/screenshot",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton"
      ],
      "files": [
        "components/ds/screenshot.tsx"
      ],
      "props": [
        {
          "name": "src",
          "required": true,
          "type": "string"
        },
        {
          "name": "srcDark",
          "required": false,
          "type": "string"
        },
        {
          "name": "alt",
          "required": true,
          "type": "string"
        },
        {
          "name": "width",
          "required": false,
          "type": "number"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "loadingState",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "priority",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "rounded",
          "required": false,
          "type": "\"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\"",
          "options": [
            "none",
            "sm",
            "md",
            "lg",
            "xl",
            "2xl"
          ],
          "default": "xl"
        },
        {
          "name": "shadow",
          "required": false,
          "type": "\"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\"",
          "options": [
            "none",
            "sm",
            "md",
            "lg",
            "xl"
          ],
          "default": "lg"
        },
        {
          "name": "aspect",
          "required": false,
          "type": "\"auto\" | \"video\" | \"square\"",
          "options": [
            "auto",
            "video",
            "square"
          ],
          "default": "auto"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    src: \"https://picsum.photos/seed/screenshot-light/1200/800\",\n    srcDark: \"https://picsum.photos/seed/screenshot-dark/1200/800\",\n    alt: \"Dashboard screenshot\",\n    width: 1200,\n    height: 800,\n  },"
        },
        {
          "name": "LightOnly",
          "description": "",
          "args": "{\n    src: \"https://picsum.photos/seed/light-only/1200/800\",\n    alt: \"App screenshot light only\",\n  },"
        },
        {
          "name": "Mobile",
          "description": "",
          "args": "{\n    src: \"https://picsum.photos/seed/mobile-light/400/800\",\n    srcDark: \"https://picsum.photos/seed/mobile-dark/400/800\",\n    alt: \"Mobile app\",\n    width: 400,\n    height: 800,\n    aspect: \"auto\",\n    rounded: \"2xl\",\n  },\n  render: (args) => (\n    <div className=\"w-64\">\n      <Screenshot {...args} />\n    </div>\n  ),"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ src: \"\", alt: \"\", loadingState: true, width: 800, height: 600 },"
        }
      ]
    },
    {
      "name": "ds-scroll-reveal",
      "title": "ScrollReveal",
      "description": "Wrapper que revela filhos com fade/slide ao entrar no viewport, via IntersectionObserver — visível de imediato em prefers-reduced-motion.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/scroll-reveal",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/scroll-reveal.tsx"
      ],
      "props": [
        {
          "name": "delay",
          "required": false,
          "type": "number",
          "description": "Delay before the transition starts, in ms."
        },
        {
          "name": "once",
          "required": false,
          "type": "boolean",
          "description": "Re-trigger every time the element re-enters the viewport."
        },
        {
          "name": "direction",
          "required": false,
          "type": "\"up\" | \"down\" | \"left\" | \"right\" | \"none\"",
          "options": [
            "up",
            "down",
            "left",
            "right",
            "none"
          ],
          "default": "up"
        }
      ],
      "storyTitle": "Data Display/ScrollReveal",
      "stories": [
        {
          "name": "AllDirections",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div className=\"h-64 shrink-0 rounded-2xl border border-dashed border-border\" />\n      <div className=\"grid grid-cols-2 gap-4\">\n        {([\"up\", \"down\", \"left\", \"right\"] as const).map((direction) => (\n          <ScrollReveal\n            key={direction}\n            direction={direction}\n            className=\"rounded-2xl border border-border bg-card p-4\"\n          >\n            <p className=\"text-xs text-muted-foreground\">{direction}</p>\n          </ScrollReveal>\n        ))}\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-scroll-to-top",
      "title": "Scroll to Top",
      "description": "Floating button with scroll-progress ring that reveals past a configurable scroll threshold. Tooltip, i18n support, and multiple positions.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/scroll-to-top",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "tooltip",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/scroll-to-top.tsx"
      ],
      "props": [
        {
          "name": "threshold",
          "required": false,
          "type": "number"
        },
        {
          "name": "showProgress",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"outline\" | \"fill\""
        },
        {
          "name": "position",
          "required": false,
          "type": "\"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\"",
          "options": [
            "bottom-right",
            "bottom-left",
            "top-right",
            "top-left"
          ],
          "default": "bottom-right"
        }
      ],
      "storyTitle": "Navigation/ScrollToTop",
      "stories": [
        {
          "name": "Default",
          "description": "Reveals once scrolled past 400px. Shows the progress ring."
        },
        {
          "name": "Fill",
          "description": "Filled variant with primary background and white icon — pops more against dark sections.",
          "args": "{ variant: \"fill\" },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "WithoutRing",
          "description": "Clean mode without the progress ring — just the arrow button.",
          "args": "{ showProgress: false },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "HighThreshold",
          "description": "Only appears after scrolling past 1200px — useful for very long documents.",
          "args": "{ threshold: 1200 },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "LowThreshold",
          "description": "Appears almost immediately — after just 50px of scroll.",
          "args": "{ threshold: 50 },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "TopLeft",
          "description": "Floats at the top‑left corner instead of the default bottom‑right.",
          "args": "{ position: \"top-left\" },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "BottomLeft",
          "description": "Bottom‑left corner placement.",
          "args": "{ position: \"bottom-left\" },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "TopRight",
          "description": "Top‑right corner placement.",
          "args": "{ position: \"top-right\" },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "Loading",
          "description": "Skeleton placeholder before the component hydrates or while data is loading.",
          "args": "{ loading: true },"
        },
        {
          "name": "LocalePTBR",
          "description": "Tooltip and aria‑label in Brazilian Portuguese.",
          "args": "{ locale: \"pt-BR\" },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "LocaleES",
          "description": "Tooltip and aria‑label in Spanish.",
          "args": "{ locale: \"es-ES\" },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        },
        {
          "name": "LocaleFR",
          "description": "Tooltip and aria‑label in French.",
          "args": "{ locale: \"fr-FR\" },\n  decorators: [\n    (StoryFn) => (\n      <TallContainer>\n        <StoryFn />\n      </TallContainer>\n    ),\n  ],"
        }
      ]
    },
    {
      "name": "ds-search-bar",
      "title": "Search Bar",
      "description": "A full-width composable search bar with visual variants, keyboard shortcut hint, voice input, debounce, custom icon, and skeleton loading.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/search-bar",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "input",
        "kbd",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/search-bar.tsx"
      ],
      "props": [
        {
          "name": "size",
          "required": false,
          "type": "SearchBarSize"
        },
        {
          "name": "rounded",
          "required": false,
          "type": "SearchBarRounded"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Form/SearchBar",
      "stories": [
        {
          "name": "Default",
          "description": "Uncontrolled search bar with default `outline` variant, `md` size, and `lg` radius. Type to reveal the clear button; press `Escape` to clear.",
          "args": "{\n    placeholder: \"Search anything…\",\n    defaultValue: \"\",\n    size: \"md\",\n    variant: \"outline\",\n    rounded: \"lg\",\n    loading: false,\n    debounceMs: 0,\n    voice: false,\n    disabled: false,\n    autoFocus: false,\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Uncontrolled search bar with default `outline` variant, `md` size, and `lg` radius. Type to reveal the clear button; press `Escape` to clear.\",\n      },\n    },\n  },"
        },
        {
          "name": "Variants",
          "description": "Three visual surfaces. `outline` suits most pages; `filled` works well inside cards or sidebars; `ghost` is ideal for toolbars where a border-free look is preferred."
        },
        {
          "name": "Sizes",
          "description": "Three density presets. `sm` (h-8 / text-xs) for compact toolbars; `md` (h-10 / text-sm) as the default; `lg` (h-12 / text-base) for prominent hero-style search."
        },
        {
          "name": "RoundedVariants",
          "description": "Six border-radius presets using the design system radius scale (`--radius-sm` → `--radius-4xl`). `lg` is the default. Use `full` for pill-shaped search bars in hero sections."
        },
        {
          "name": "WithShortcut",
          "description": "The `shortcut` prop renders a `Kbd` badge on the trailing edge when the input is empty. It disappears as soon as the user starts typing and reappears after clearing."
        },
        {
          "name": "WithTrailingSlot",
          "description": "The `trailingSlot` prop renders any ReactNode after the clear button. Use it for filter toggles, action buttons, or custom badges. A `Separator` between input and slot keeps visual hierarchy clear."
        },
        {
          "name": "VoiceInput",
          "description": "Enable voice input with `voice={true}`. A microphone button appears on the trailing edge when the browser supports the Web Speech API.\n\n- **Idle**: mic icon in muted color, `aria-pressed={false}`\n- **Listening**: mic pulses red, `aria-label` switches to *Stop recording*, `aria-pressed={true}`\n- **Result**: transcript is written into the input and `onChange` fires — same path as keyboard input\n\nThe button is silently hidden when the browser does not support the Web Speech API, so `voice` is safe to pass unconditionally.\n\nUse `onVoiceStart`, `onVoiceEnd`, and `onVoiceError` to react to the recognition lifecycle."
        },
        {
          "name": "Loading",
          "description": "When `loading` is true, the leading icon is replaced by an animated spinner and the clear button is hidden. `aria-busy` is set on the container so assistive technologies can announce the state.",
          "args": "{ loading: true },\n  render: (args) => (\n    <div className=\"flex flex-col gap-3\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-1.5\">\n          <p className=\"text-xs font-medium text-muted-foreground\">\n            size=&quot;{size}&quot;\n          </p>\n          <SearchBar {...args} size={size} loading defaultValue=\"university\" />\n        </div>\n      ))}\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"When `loading` is true, the leading icon is replaced by an animated spinner and the clear button is hidden. `aria-busy` is set on the container so assistive technologies can announce the state.\",\n      },\n    },\n  },"
        },
        {
          "name": "Disabled",
          "description": "Disabled state applies `opacity-50` and `pointer-events-none` to the wrapper. All three variants are shown to confirm the token-based appearance holds.",
          "args": "{ disabled: true },\n  render: (args) => (\n    <div className=\"flex flex-col gap-3\">\n      {([\"outline\", \"filled\", \"ghost\"] as const).map((variant) => (\n        <div key={variant} className=\"flex flex-col gap-1.5\">\n          <p className=\"text-xs font-medium text-muted-foreground\">\n            variant=&quot;{variant}&quot;\n          </p>\n          <SearchBar {...args} variant={variant} disabled />\n        </div>\n      ))}\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Disabled state applies `opacity-50` and `pointer-events-none` to the wrapper. All three variants are shown to confirm the token-based appearance holds.\",\n      },\n    },\n  },"
        },
        {
          "name": "Controlled",
          "description": "Controlled mode: pass `value` + `onChange` to manage state externally. `onSearch` fires on `Enter`; `onClear` fires when the clear button or `Escape` is pressed. The live readout below the bar shows both the current input value and the last submitted search."
        },
        {
          "name": "WithDebounce",
          "description": "With `debounceMs={500}`, `onChange` fires only after 500ms of idle typing — not on every keystroke. The input itself remains instantly responsive. Adjust `debounceMs` in the controls to see the effect in real time.",
          "args": "{ debounceMs: 500 },\n  render: (args) => {\n    const [debouncedValue, setDebouncedValue] = React.useState(\"\")\n    const [lastEnter, setLastEnter] = React.useState(\"\")\n    const [fireCount, setFireCount] = React.useState(0)\n\n    return (\n      <div className=\"flex flex-col gap-4\">\n        <SearchBar\n          {...args}\n          onChange={(v) => {\n            setDebouncedValue(v)\n            setFireCount((n) => n + 1)\n          }}\n          onSearch={setLastEnter}\n        />\n        <div className=\"rounded-lg border border-border bg-muted/40 p-3 font-mono text-xs\">\n          <div className=\"flex flex-col gap-1 text-muted-foreground\">\n            <span>\n              onChange fired:{\" \"}\n              <strong className=\"text-foreground\">{fireCount}×</strong>\n            </span>\n            <span>\n              Debounced value:{\" \"}\n              <strong className=\"text-foreground\">\n                &quot;{debouncedValue}&quot;\n              </strong>\n            </span>\n            {lastEnter && (\n              <span>\n                Last Enter:{\" \"}\n                <strong className=\"text-foreground\">\n                  &quot;{lastEnter}&quot;\n                </strong>\n              </span>\n            )}\n          </div>\n        </div>\n      </div>\n    )\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"With `debounceMs={500}`, `onChange` fires only after 500ms of idle typing — not on every keystroke. The input itself remains instantly responsive. Adjust `debounceMs` in the controls to see the effect in real time.\",\n      },\n    },\n  },"
        },
        {
          "name": "CustomIcon",
          "description": "The `icon` prop accepts any Lucide component. Swap the magnifying glass for a contextual icon that communicates what the search targets."
        },
        {
          "name": "Skeleton",
          "description": "`SearchBarSkeleton` mirrors the exact `size` and `rounded` props of `SearchBar`. Use it as a placeholder during server-side data fetching or lazy loading.",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div className=\"flex flex-col gap-1.5\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Sizes — rounded=&quot;lg&quot; (default)\n        </p>\n        <div className=\"flex flex-col gap-2\">\n          {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n            <SearchBarSkeleton key={size} size={size} />\n          ))}\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-1.5\">\n        <p className=\"text-xs font-medium text-muted-foreground\">\n          Rounded variants — size=&quot;md&quot;\n        </p>\n        <div className=\"flex flex-col gap-2\">\n          {([\"none\", \"md\", \"xl\", \"full\"] as const).map((rounded) => (\n            <SearchBarSkeleton key={rounded} rounded={rounded} />\n          ))}\n        </div>\n      </div>\n    </div>"
        },
        {
          "name": "Locales",
          "description": "All four supported locales. The `placeholder` and `aria-label` on the input, and `aria-label` on the clear button, are translated via `UI_I18N`. Type to reveal the clear button and inspect its accessible label in each locale."
        },
        {
          "name": "InContext",
          "description": "Realistic usage inside a card: live filter on `onChange`, simulated async search on `Enter` that triggers the loading spinner for 1.2 s. All visual props (`size`, `variant`, `rounded`, `placeholder`) are fully controllable via the Storybook panel.",
          "args": "{\n    placeholder: \"Search courses…\",\n    size: \"lg\",\n    rounded: \"xl\",\n    variant: \"filled\",\n    shortcut: \"⌘K\",\n  },\n  render: (args) => {\n    const [query, setQuery] = React.useState(\"\")\n    const [loading, setLoading] = React.useState(false)\n\n    const handleSearch = (v: string) => {\n      if (!v) return\n      setLoading(true)\n      setTimeout(() => setLoading(false), 1200)\n    }\n\n    const results = [\n      \"Introduction to Computer Science\",\n      \"Advanced Algorithms\",\n      \"Database Systems\",\n      \"Software Engineering\",\n      \"Distributed Systems\",\n      \"Machine Learning Fundamentals\",\n    ].filter((r) => r.toLowerCase().includes(query.toLowerCase()) && query)\n\n    return (\n      <div className=\"flex flex-col gap-4\">\n        <div className=\"rounded-xl border border-border bg-card p-6 shadow-sm\">\n          <h2 className=\"mb-4 text-base font-semibold text-foreground\">\n            Course Catalog\n          </h2>\n          <SearchBar\n            {...args}\n            value={query}\n            onChange={setQuery}\n            onSearch={handleSearch}\n            onClear={() => setQuery(\"\")}\n            loading={loading}\n          />\n          {results.length > 0 && (\n            <ul className=\"mt-3 flex flex-col gap-0 overflow-hidden rounded-lg border border-border\">\n              {results.map((r) => (\n                <li\n                  key={r}\n                  className=\"flex items-center gap-2 border-b border-border px-4 py-3 text-sm last:border-b-0 hover:bg-accent\"\n                >\n                  <BookOpenIcon className=\"size-4 shrink-0 text-muted-foreground\" />\n                  {r}\n                </li>\n              ))}\n            </ul>\n          )}\n          {query && results.length === 0 && !loading && (\n            <p className=\"mt-3 text-center text-sm text-muted-foreground\">\n              No courses found for &quot;{query}&quot;\n            </p>\n          )}\n        </div>\n      </div>\n    )\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Realistic usage inside a card: live filter on `onChange`, simulated async search on `Enter` that triggers the loading spinner for 1.2 s. All visual props (`size`, `variant`, `rounded`, `placeholder`) are fully controllable via the Storybook panel.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-search-combo",
      "title": "Search Combo",
      "description": "A search field with autocomplete dropdown, keyboard navigation, grouped results, voice recognition, and text highlighting.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/search-combo",
      "dependencies": [
        "radix-ui",
        "lucide-react",
        "@tanstack/react-virtual",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "popover",
        "ds-spinner"
      ],
      "files": [
        "components/ds/search-combo.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "string",
          "description": "The current value of the search input."
        },
        {
          "name": "onChange",
          "required": true,
          "type": "(value: string) => void",
          "description": "Callback fired when the input value changes."
        },
        {
          "name": "onSearch",
          "required": false,
          "type": "(value: string) => void",
          "description": "Callback fired when search is submitted (Enter key or button click)."
        },
        {
          "name": "options",
          "required": false,
          "type": "SearchComboItem[]",
          "description": "Array of items to display in the dropdown."
        },
        {
          "name": "onSelectResult",
          "required": false,
          "type": "(item: SearchComboItem) => void",
          "description": "Callback fired when a result item is selected."
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string",
          "description": "Placeholder text displayed when input is empty."
        },
        {
          "name": "button",
          "required": false,
          "type": "boolean",
          "description": "Whether to show the search submit button. @default true"
        },
        {
          "name": "rounded",
          "required": false,
          "type": "boolean",
          "description": "Whether the input has fully rounded (pill) corners. @default false"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "description": "Size variant controlling height and font size. @default \"md\""
        },
        {
          "name": "border",
          "required": false,
          "type": "boolean",
          "description": "Whether to render in border/header mode with inverted background. @default false"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean",
          "description": "Whether the input is disabled. @default false"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Whether to show loading state with spinner. @default false"
        },
        {
          "name": "autoFocus",
          "required": false,
          "type": "boolean",
          "description": "Whether to auto-focus the input on mount. @default true"
        },
        {
          "name": "label",
          "required": false,
          "type": "string",
          "description": "Accessible label for the search landmark. @default \"Search\""
        },
        {
          "name": "emptyMessage",
          "required": false,
          "type": "string",
          "description": "Message displayed when input has value but no results match. @default \"No results found.\""
        },
        {
          "name": "voice",
          "required": false,
          "type": "boolean",
          "description": "Whether to enable voice recognition. @default false"
        },
        {
          "name": "onVoiceStart",
          "required": false,
          "type": "() => void",
          "description": "Callback fired when voice recording starts."
        },
        {
          "name": "onVoiceEnd",
          "required": false,
          "type": "() => void",
          "description": "Callback fired when voice recording ends."
        },
        {
          "name": "onVoiceError",
          "required": false,
          "type": "(error: string) => void",
          "description": "Callback fired when voice recognition encounters an error."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    placeholder: \"Search...\",\n    button: true,\n    rounded: false,\n    size: \"md\",\n    border: false,\n    disabled: false,\n    loading: false,\n    autoFocus: true,\n    label: \"Search\",\n    emptyMessage: \"No results found.\",\n    voice: false,\n  },\n  render: (args) => <InteractiveSearchCombo {...args} />,"
        },
        {
          "name": "AllSizes",
          "description": "Available size variations: `sm`, `md`, and `lg`",
          "code": "<div className=\"flex w-[450px] flex-col gap-4\">\n      <InteractiveSearchCombo size=\"sm\" placeholder=\"Small (sm)\" />\n      <InteractiveSearchCombo size=\"md\" placeholder=\"Medium (md)\" />\n      <InteractiveSearchCombo size=\"lg\" placeholder=\"Large (lg)\" />\n    </div>"
        },
        {
          "name": "WithGroups",
          "description": "Results are grouped by the `group` field with visual headers separating each group."
        },
        {
          "name": "WithIcons",
          "description": "Each result item can display an icon for better visual recognition."
        },
        {
          "name": "BorderMode",
          "description": "The `border` mode renders the input with an inverted primary background, ideal for dark headers or navbars."
        },
        {
          "name": "Disabled",
          "description": "",
          "code": "<div className=\"w-[450px]\">\n        <SearchCombo\n          value={value}\n          onChange={setValue}\n          options={sampleOptions}\n          disabled\n          autoFocus={false}\n          placeholder=\"Disabled search...\"\n        />\n      </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<div className=\"w-[450px]\">\n        <SearchCombo\n          value={value}\n          onChange={setValue}\n          options={[]}\n          loading\n          autoFocus={false}\n          placeholder=\"Loading...\"\n        />\n      </div>"
        },
        {
          "name": "WithVoice",
          "description": "Enables the microphone button for speech-to-text. Note: This only appears in browsers that support the Web Speech API (like Chrome)."
        },
        {
          "name": "EmptyState",
          "description": "Shows the `emptyMessage` when the user has typed a query but no results match. Type anything to see the empty state."
        },
        {
          "name": "WithOnSearch",
          "description": "",
          "code": "<div className=\"flex w-[450px] flex-col gap-4\">\n        <SearchCombo\n          value={value}\n          onChange={handleChange}\n          options={results}\n          onSearch={(v) => setSearched(v)}\n          autoFocus={false}\n        />\n        {searched && (\n          <p className=\"text-sm text-muted-foreground\">\n            Searched: <strong>{searched}</strong>\n          </p>\n        )}\n      </div>"
        },
        {
          "name": "WithOnSelectResult",
          "description": "",
          "code": "<div className=\"flex w-[450px] flex-col gap-4\">\n        <SearchCombo\n          value={value}\n          onChange={handleChange}\n          options={results}\n          onSelectResult={(item) => setSelected(item.label)}\n          autoFocus={false}\n        />\n        {selected && (\n          <p className=\"text-sm text-muted-foreground\">\n            Selected: <strong>{selected}</strong>\n          </p>\n        )}\n      </div>"
        },
        {
          "name": "Virtualized",
          "description": "Dropdown renders 500 items via `@tanstack/react-virtual`. Only visible rows are mounted in the DOM at any time. Type `0` to match all 500 results and observe constant scroll performance.",
          "code": "<div className=\"flex w-[450px] flex-col gap-3\">\n        <p className=\"text-sm text-muted-foreground\">\n          500 items — only visible rows are in the DOM\n        </p>\n        <SearchCombo\n          value={value}\n          onChange={handleChange}\n          options={results}\n          autoFocus={false}\n          placeholder=\"Type User for all 500 results...\"\n        />\n        {results.length > 0 && (\n          <p className=\"text-xs text-muted-foreground\">\n            {results.length} result{results.length !== 1 ? \"s\" : \"\"}\n          </p>\n        )}\n      </div>"
        },
        {
          "name": "AllVariants",
          "description": "All available variant combinations side by side.",
          "code": "<div className=\"flex w-[450px] flex-col gap-4\">\n      <InteractiveSearchCombo placeholder=\"Default\" />\n      <InteractiveSearchCombo rounded placeholder=\"Rounded\" />\n      <InteractiveSearchCombo border placeholder=\"Border mode\" />\n      <InteractiveSearchCombo button={false} placeholder=\"No button\" />\n      <InteractiveSearchCombo size=\"sm\" placeholder=\"Small\" />\n      <InteractiveSearchCombo size=\"lg\" placeholder=\"Large\" />\n      <InteractiveSearchCombo voice placeholder=\"Voice recognition\" />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-section-cards",
      "title": "Section Cards",
      "description": "Grid de cards estatísticos com gradiente, badge trend e footer — extraído de shadcn dashboard-01 SectionCards.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/section-cards",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "card",
        "badge",
        "skeleton"
      ],
      "files": [
        "components/ds/section-cards.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "SectionCardItem[]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "columns",
          "required": false,
          "type": "\"2\" | \"4\"",
          "options": [
            "2",
            "4"
          ]
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"gradient\"",
          "options": [
            "default",
            "gradient"
          ],
          "default": "gradient"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items },"
        },
        {
          "name": "TwoColumns",
          "description": "",
          "args": "{ items: items.slice(0, 2), columns: 2 },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ items, loading: true },"
        },
        {
          "name": "WithoutBadge",
          "description": "",
          "args": "{\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    items: items.map(({ badge, ...rest }) => rest as unknown as never),\n  },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-8\">\n      <SectionCards items={items} variant=\"gradient\" />\n      <SectionCards items={items} variant=\"default\" />\n    </div>"
        },
        {
          "name": "A11y",
          "description": "",
          "args": "{ items },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByText(\"Total Revenue\")).toBeInTheDocument()\n  },"
        }
      ]
    },
    {
      "name": "ds-select",
      "title": "Select UI",
      "description": "Extended select with search filter, async option loading, grouped options, creatable new option, configurable popover positioning (side/align/offset), i18n placeholder/no-results, and skeleton loading.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/select",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "popover",
        "command",
        "button",
        "skeleton",
        "label",
        "ui-i18n"
      ],
      "files": [
        "components/ds/select.tsx"
      ],
      "props": [
        {
          "name": "options",
          "required": true,
          "type": "SelectOption[]"
        },
        {
          "name": "value",
          "required": false,
          "type": "string"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "searchable",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "async",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loadOptions",
          "required": false,
          "type": "(search: string) => Promise<SelectOption[]>"
        },
        {
          "name": "creatable",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onCreate",
          "required": false,
          "type": "(label: string) => Promise<string>"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "error",
          "required": false,
          "type": "string"
        },
        {
          "name": "label",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        },
        {
          "name": "side",
          "required": false,
          "type": "\"top\" | \"right\" | \"bottom\" | \"left\""
        },
        {
          "name": "align",
          "required": false,
          "type": "\"start\" | \"center\" | \"end\""
        },
        {
          "name": "sideOffset",
          "required": false,
          "type": "number"
        },
        {
          "name": "alignOffset",
          "required": false,
          "type": "number"
        }
      ],
      "storyTitle": "Form/Select",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    options: COUNTRIES,\n    placeholder: \"Select a country\",\n    searchable: false,\n    async: false,\n    creatable: false,\n    size: \"md\",\n    loading: false,\n    locale: \"pt-BR\",\n    disabled: false,\n  },"
        },
        {
          "name": "Searchable",
          "description": "",
          "args": "{\n    options: COUNTRIES,\n    searchable: true,\n    placeholder: \"Search countries…\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{ options: [] },\n  render: () => (\n    <div className=\"flex flex-col gap-4\">\n      <Select size=\"sm\" options={COUNTRIES.slice(0, 3)} placeholder=\"Small\" />\n      <Select size=\"md\" options={COUNTRIES.slice(0, 3)} placeholder=\"Medium\" />\n      <Select size=\"lg\" options={COUNTRIES.slice(0, 3)} placeholder=\"Large\" />\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-4\">\n      <Select size=\"sm\" options={COUNTRIES.slice(0, 3)} placeholder=\"Small\" />\n      <Select size=\"md\" options={COUNTRIES.slice(0, 3)} placeholder=\"Medium\" />\n      <Select size=\"lg\" options={COUNTRIES.slice(0, 3)} placeholder=\"Large\" />\n    </div>"
        },
        {
          "name": "Async",
          "description": "",
          "args": "{\n    options: [],\n    async: true,\n    searchable: true,\n    placeholder: \"Search users…\",\n    loadOptions: async (search: string) => {\n      await new Promise((r) => setTimeout(r, 800))\n      return COUNTRIES.filter(\n        (c) =>\n          c.label.toLowerCase().includes(search.toLowerCase()) ||\n          c.value.includes(search)\n      )\n    },\n  },"
        },
        {
          "name": "Creatable",
          "description": "",
          "args": "{\n    options: COUNTRIES.slice(0, 3),\n    searchable: true,\n    creatable: true,\n    placeholder: \"Select or create…\",\n    onCreate: async (label: string) => {\n      await new Promise((r) => setTimeout(r, 500))\n      return label.toLowerCase().replace(/\\s+/g, \"-\")\n    },\n  },"
        },
        {
          "name": "Grouped",
          "description": "",
          "args": "{\n    options: COUNTRIES,\n    placeholder: \"Select a country\",\n  },"
        },
        {
          "name": "WithError",
          "description": "",
          "args": "{\n    options: COUNTRIES,\n    placeholder: \"Select a country\",\n    error: \"Please select a country.\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    options: COUNTRIES,\n    placeholder: \"Loading…\",\n    loading: true,\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    options: COUNTRIES,\n    placeholder: \"Disabled select\",\n    disabled: true,\n  },"
        },
        {
          "name": "WithLabel",
          "description": "",
          "args": "{\n    options: COUNTRIES,\n    label: \"Country\",\n    placeholder: \"Select your country\",\n  },"
        }
      ]
    },
    {
      "name": "ds-select-list",
      "title": "Select List",
      "description": "A searchable list of items with selection state, support for groups, icons and virtual scrolling behavior.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/select-list",
      "dependencies": [
        "lucide-react",
        "@tanstack/react-virtual",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "button",
        "input",
        "badge",
        "skeleton",
        "ds-empty",
        "ui-i18n"
      ],
      "files": [
        "components/ds/select-list.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "SelectListItem[]"
        },
        {
          "name": "selectedId",
          "required": false,
          "type": "string | number"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        },
        {
          "name": "debounce",
          "required": false,
          "type": "number"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"default\" | \"primary\" | \"secondary\" | \"destructive\""
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onSelect",
          "required": true,
          "type": "(item: SelectListItem) => void"
        },
        {
          "name": "onSearch",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "search",
          "required": false,
          "type": "string"
        },
        {
          "name": "emptyMessage",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Form/SelectList",
      "stories": [
        {
          "name": "Default",
          "description": "Default select list with five user entries and a search bar.",
          "args": "{\n    data: mockData,\n    placeholder: \"Search by name...\",\n    height: 350,\n    onSelect: (item) => console.log(\"Selected:\", item),\n    debounce: 300,\n    intent: \"primary\",\n    size: \"md\",\n    disabled: false,\n    loading: false,\n    locale: \"en-US\",\n    emptyMessage: \"No results found\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Default select list with five user entries and a search bar.\",\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization with translated user data and placeholder.",
          "args": "{\n    data: [\n      {\n        id: 1,\n        name: \"João Silva\",\n        group: \"Engineering\",\n        value: \"Senior\",\n        icon: <User className=\"size-4\" />,\n      },\n      {\n        id: 2,\n        name: \"Maria Santos\",\n        group: \"Design\",\n        value: \"Mid-level\",\n        icon: <Shield className=\"size-4\" />,\n      },\n      {\n        id: 3,\n        name: \"Carlos Oliveira\",\n        group: \"Product\",\n        value: \"Junior\",\n        icon: <Zap className=\"size-4\" />,\n      },\n    ],\n    placeholder: \"Search by name...\",\n    height: 350,\n    locale: \"pt-BR\",\n    onSelect: (item) => console.log(\"Selected:\", item),\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) localization with translated user data and placeholder.\",\n      },\n    },\n  },"
        },
        {
          "name": "Controlled",
          "description": "Controlled select list — selectedId managed externally with onChange handler.",
          "args": "{ data: mockData, onSelect: () => {} },\n  render: () => {\n    const [selectedId, setSelectedId] = React.useState<string | number>(1)\n    return (\n      <div className=\"max-w-md\">\n        <SelectList\n          data={mockData}\n          selectedId={selectedId}\n          onSelect={(item) => setSelectedId(item.id)}\n          height={300}\n        />\n      </div>\n    )\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Controlled select list — selectedId managed externally with onChange handler.\",\n      },\n    },\n  },",
          "code": "<div className=\"max-w-md\">\n        <SelectList\n          data={mockData}\n          selectedId={selectedId}\n          onSelect={(item) => setSelectedId(item.id)}\n          height={300}\n        />\n      </div>"
        },
        {
          "name": "Intents",
          "description": "Comparison of all four intent colors — default, primary, secondary, and destructive.",
          "args": "{ data: mockData, onSelect: () => {} },\n  render: () => (\n    <div className=\"grid grid-cols-1 gap-8 md:grid-cols-2\">\n      {([\"primary\", \"secondary\", \"destructive\", \"default\"] as const).map(\n        (intent) => (\n          <div key={intent} className=\"flex flex-col gap-2\">\n            <span className=\"text-sm font-medium text-muted-foreground capitalize\">\n              {intent}\n            </span>\n            <SelectList\n              data={mockData}\n              selectedId={1}\n              intent={intent}\n              height={250}\n              onSelect={() => {}}\n            />\n          </div>\n        )\n      )}\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Comparison of all four intent colors — default, primary, secondary, and destructive.\",\n      },\n    },\n  },",
          "code": "<div className=\"grid grid-cols-1 gap-8 md:grid-cols-2\">\n      {([\"primary\", \"secondary\", \"destructive\", \"default\"] as const).map(\n        (intent) => (\n          <div key={intent} className=\"flex flex-col gap-2\">\n            <span className=\"text-sm font-medium text-muted-foreground capitalize\">\n              {intent}\n            </span>\n            <SelectList\n              data={mockData}\n              selectedId={1}\n              intent={intent}\n              height={250}\n              onSelect={() => {}}\n            />\n          </div>\n        )\n      )}\n    </div>"
        },
        {
          "name": "Loading",
          "description": "Loading state with skeleton placeholders in place of list rows.",
          "args": "{ data: [], loading: true, height: 300, onSelect: () => {} },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Loading state with skeleton placeholders in place of list rows.\",\n      },\n    },\n  },"
        },
        {
          "name": "Empty",
          "description": "Empty state displayed when no data is provided and loading is false.",
          "args": "{ data: [], loading: false, height: 200, onSelect: () => {} },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Empty state displayed when no data is provided and loading is false.\",\n      },\n    },\n  },"
        },
        {
          "name": "Virtualized",
          "description": "500 items rendered with `@tanstack/react-virtual`. Only the visible rows are mounted in the DOM at any time — scroll performance stays flat regardless of list size.",
          "args": "{ data: [], onSelect: () => {} },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"500 items rendered with `@tanstack/react-virtual`. Only the visible rows are mounted in the DOM at any time — scroll performance stays flat regardless of list size.\",\n      },\n    },\n  },\n  render: () => {\n    const [selectedId, setSelectedId] = React.useState<\n      string | number | undefined\n    >()\n\n    const largeData = React.useMemo(() => {\n      const groups = [\n        \"Engineering\",\n        \"Design\",\n        \"Product\",\n        \"Marketing\",\n        \"Operations\",\n      ]\n      const levels = [\"Junior\", \"Mid-level\", \"Senior\", \"Lead\", \"Principal\"]\n      return Array.from({ length: 500 }, (_, i) => ({\n        id: i + 1,\n        name: `User ${String(i + 1).padStart(3, \"0\")}`,\n        group: groups[i % groups.length],\n        value: levels[i % levels.length],\n      }))\n    }, [])\n\n    return (\n      <div className=\"flex max-w-md flex-col gap-2\">\n        <p className=\"text-sm text-muted-foreground\">\n          {largeData.length} items — only visible rows are in the DOM\n        </p>\n        <SelectList\n          data={largeData}\n          selectedId={selectedId}\n          onSelect={(item) => setSelectedId(item.id)}\n          height={400}\n          placeholder=\"Search 500 items...\"\n        />\n      </div>\n    )\n  },",
          "code": "<div className=\"flex max-w-md flex-col gap-2\">\n        <p className=\"text-sm text-muted-foreground\">\n          {largeData.length} items — only visible rows are in the DOM\n        </p>\n        <SelectList\n          data={largeData}\n          selectedId={selectedId}\n          onSelect={(item) => setSelectedId(item.id)}\n          height={400}\n          placeholder=\"Search 500 items...\"\n        />\n      </div>"
        },
        {
          "name": "InModal",
          "description": "Select list rendered inside a Dialog modal for user selection workflows.",
          "args": "{ data: mockData, onSelect: () => {} },\n  render: () => {\n    const [selectedId, setSelectedId] = React.useState<string | number>(1)\n    const selectedItem = mockData.find((item) => item.id === selectedId)\n\n    return (\n      <Dialog>\n        <DialogTrigger asChild>\n          <Button variant=\"outline\">\n            <Layout className=\"mr-2 size-4\" />\n            {selectedItem\n              ? `Selected: ${selectedItem.name}`\n              : \"Open Selection List\"}\n          </Button>\n        </DialogTrigger>\n        <DialogContent className=\"sm:max-w-[500px]\">\n          <DialogHeader>\n            <DialogTitle>Select User</DialogTitle>\n          </DialogHeader>\n          <div className=\"py-4\">\n            <SelectList\n              data={mockData}\n              selectedId={selectedId}\n              onSelect={(item) => setSelectedId(item.id)}\n              height={300}\n              intent=\"primary\"\n            />\n          </div>\n        </DialogContent>\n      </Dialog>\n    )\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Select list rendered inside a Dialog modal for user selection workflows.\",\n      },\n    },\n  },",
          "code": "<Dialog>\n        <DialogTrigger asChild>\n          <Button variant=\"outline\">\n            <Layout className=\"mr-2 size-4\" />\n            {selectedItem\n              ? `Selected: ${selectedItem.name}`\n              : \"Open Selection List\"}\n          </Button>\n        </DialogTrigger>\n        <DialogContent className=\"sm:max-w-[500px]\">\n          <DialogHeader>\n            <DialogTitle>Select User</DialogTitle>\n          </DialogHeader>\n          <div className=\"py-4\">\n            <SelectList\n              data={mockData}\n              selectedId={selectedId}\n              onSelect={(item) => setSelectedId(item.id)}\n              height={300}\n              intent=\"primary\"\n            />\n          </div>\n        </DialogContent>\n      </Dialog>"
        }
      ]
    },
    {
      "name": "ds-settings",
      "title": "Settings",
      "description": "Tabs de configurações — ReUI Settings 16.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/settings",
      "dependencies": [],
      "registryDependencies": [
        "tabs",
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/settings.tsx"
      ],
      "props": [
        {
          "name": "tabs",
          "required": true,
          "type": "SettingsTab[]"
        },
        {
          "name": "defaultTab",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Dashboard/Settings",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    tabs: [\n      { id: \"general\", label: \"General\", content: \"General settings\" },\n      { id: \"security\", label: \"Security\", content: \"Security settings\" },\n    ],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ tabs: [], loading: true }"
        }
      ]
    },
    {
      "name": "ds-settings-view",
      "title": "Settings View",
      "description": "A complex view for settings area separated by internal navigation.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/settings-view",
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "registryDependencies": [
        "tabs",
        "button",
        "separator"
      ],
      "files": [
        "components/ds/settings-view.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "sections",
          "required": true,
          "type": "SettingsSection[]"
        },
        {
          "name": "defaultSection",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Dashboard/SettingsView",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Settings\",\n    description: \"Manage your account settings and set e-mail preferences.\",\n    sections: [\n      {\n        id: \"profile\",\n        title: \"Profile\",\n        content: <ProfileForm />,\n      },\n      {\n        id: \"account\",\n        title: \"Account\",\n        content: (\n          <div className=\"text-sm text-muted-foreground\">\n            Account settings content goes here.\n          </div>\n        ),\n      },\n      {\n        id: \"appearance\",\n        title: \"Appearance\",\n        content: (\n          <div className=\"text-sm text-muted-foreground\">\n            Appearance settings content goes here.\n          </div>\n        ),\n      },\n      {\n        id: \"notifications\",\n        title: \"Notifications\",\n        content: <NotificationsForm />,\n      },\n      {\n        id: \"display\",\n        title: \"Display\",\n        content: (\n          <div className=\"text-sm text-muted-foreground\">\n            Display settings content goes here.\n          </div>\n        ),\n      },\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-shortcut-sheet",
      "title": "Shortcut Sheet",
      "description": "Painel modal de atalhos de teclado com busca, categorias e escuta global da tecla '?'.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/shortcut-sheet",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "dialog",
        "kbd",
        "input",
        "scroll-area",
        "ui-i18n"
      ],
      "files": [
        "components/ds/shortcut-sheet.tsx"
      ],
      "props": [
        {
          "name": "open",
          "required": false,
          "type": "boolean",
          "description": "Controlled open state."
        },
        {
          "name": "onOpenChange",
          "required": false,
          "type": "(open: boolean) => void",
          "description": "Callback fired on open state change."
        },
        {
          "name": "groups",
          "required": true,
          "type": "ShortcutGroup[]",
          "description": "Categorized shortcut groups."
        },
        {
          "name": "enableGlobalListener",
          "required": false,
          "type": "boolean",
          "description": "Whether pressing '?' globally toggles this sheet open."
        },
        {
          "name": "trigger",
          "required": false,
          "type": "React.ReactNode",
          "description": "Optional custom trigger button."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for titles and search placeholder."
        },
        {
          "name": "className",
          "required": false,
          "type": "string",
          "description": "Modal content className."
        }
      ],
      "storyTitle": "Navigation/ShortcutSheet",
      "stories": [
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-wrap gap-3\">\n      <ShortcutSheet\n        locale=\"pt-BR\"\n        groups={sampleGroups}\n        trigger={<Button size=\"sm\">pt-BR</Button>}\n      />\n      <ShortcutSheet\n        locale=\"en-US\"\n        groups={sampleGroups}\n        trigger={<Button size=\"sm\">en-US</Button>}\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-sidebar-search",
      "title": "Sidebar Search",
      "description": "Campo de busca para sidebar com label sr-only e ícone — inspirado em shadcn sidebar SearchForm.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/sidebar-search",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "sidebar",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/sidebar-search.tsx"
      ],
      "props": [
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "defaultValue",
          "required": false,
          "type": "string"
        },
        {
          "name": "onSearch",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "onSubmit",
          "required": false,
          "type": "(e: React.FormEvent<HTMLFormElement>) => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        },
        {
          "name": "AllLocales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-2\">\n      {([\"pt-BR\", \"en-US\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <SidebarProvider key={locale}>\n          <div className=\"w-64 border bg-sidebar p-2\">\n            <SidebarSearch locale={locale} />\n            <span className=\"mt-1 block text-xs text-muted-foreground\">\n              {locale}\n            </span>\n          </div>\n        </SidebarProvider>\n      ))}\n    </div>"
        },
        {
          "name": "A11y",
          "description": "",
          "args": "{},\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByRole(\"search\")).toBeInTheDocument()\n    const inputs = canvas.getAllByLabelText(/Search|Buscar|Rechercher/i)\n    await expect(inputs[0]).toBeInTheDocument()\n  },"
        }
      ]
    },
    {
      "name": "ds-signature-pad",
      "description": "Signature input using HTML Canvas with mouse/touch support and Base64 PNG export.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/signature-pad",
      "dependencies": [],
      "registryDependencies": [
        "skeleton",
        "button",
        "label"
      ],
      "files": [
        "components/ds/signature-pad.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "string | null",
          "description": "Base64 PNG value of the signature"
        },
        {
          "name": "onChange",
          "required": false,
          "type": "(value: string | null) => void"
        },
        {
          "name": "width",
          "required": false,
          "type": "number"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "strokeColor",
          "required": false,
          "type": "string"
        },
        {
          "name": "strokeWidth",
          "required": false,
          "type": "number"
        },
        {
          "name": "label",
          "required": false,
          "type": "string"
        },
        {
          "name": "clearLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Form/SignaturePad",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    label: \"Your Signature\",\n    clearLabel: \"Clear\",\n    placeholder: \"Sign here\",\n    width: 480,\n    height: 180,\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n    width: 480,\n    height: 180,\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    label: \"Signature (read-only)\",\n    disabled: true,\n    width: 480,\n    height: 180,\n  },"
        },
        {
          "name": "Controlled",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n        <SignaturePad\n          label=\"Sign the agreement\"\n          value={sig ?? undefined}\n          onChange={setSig}\n          width={480}\n          height={200}\n        />\n        <div className=\"text-xs text-muted-foreground\">\n          {sig\n            ? `✓ Signature captured (${Math.round(sig.length / 1024)} KB)`\n            : \"No signature yet\"}\n        </div>\n      </div>"
        },
        {
          "name": "CustomStroke",
          "description": "",
          "args": "{\n    label: \"Blue Signature\",\n    strokeColor: \"#3b82f6\",\n    strokeWidth: 3,\n    width: 480,\n    height: 180,\n  },"
        }
      ]
    },
    {
      "name": "ds-signup-form",
      "title": "SignUpForm",
      "description": "Bloco completo de cadastro de novos usuários com medidor de força de senha em tempo real.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/signup-form",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "ds-social-auth-group",
        "ds-auth-separator",
        "ds-password-strength-meter",
        "input",
        "button",
        "checkbox",
        "label",
        "ui-i18n"
      ],
      "files": [
        "components/ds/signup-form.tsx"
      ],
      "props": [
        {
          "name": "onSubmit",
          "required": false,
          "type": "(data: SignUpFormData) => Promise<boolean | void> | void"
        },
        {
          "name": "onSocialSignUp",
          "required": false,
          "type": "(provider: SocialProvider) => Promise<void> | void"
        },
        {
          "name": "onLogin",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "socialProviders",
          "required": false,
          "type": "SocialProvider[]"
        },
        {
          "name": "termsUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "privacyUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "errorMessage",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"flat\"",
          "options": [
            "default",
            "flat"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Auth/SignUpForm",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    variant: \"default\",\n    socialProviders: [\"google\", \"github\", \"govbr\"],\n  },"
        },
        {
          "name": "FlatVariant",
          "description": "",
          "args": "{\n    variant: \"flat\",\n    socialProviders: [\"google\", \"govbr\"],\n  },"
        },
        {
          "name": "WithError",
          "description": "",
          "args": "{\n    errorMessage:\n      \"Este e-mail já está cadastrado no sistema. Tente fazer login ou recuperar sua senha.\",\n  },"
        }
      ]
    },
    {
      "name": "ds-skeleton-layout",
      "title": "Skeleton Layout",
      "description": "Esqueletos pré-compostos para dashboard, tabela, perfil, formulário e lista.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/skeleton-layout",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "card",
        "ui-i18n"
      ],
      "files": [
        "components/ds/skeleton-layout.tsx"
      ],
      "props": [
        {
          "name": "pattern",
          "required": false,
          "type": "\"dashboard\" | \"table\" | \"profile\" | \"form\" | \"list\"",
          "description": "Layout pattern to render."
        },
        {
          "name": "rows",
          "required": false,
          "type": "number",
          "description": "Number of rows for table and list patterns."
        },
        {
          "name": "columns",
          "required": false,
          "type": "number",
          "description": "Number of columns for table pattern."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for accessibility label."
        }
      ],
      "storyTitle": "Feedback/SkeletonLayout",
      "stories": [
        {
          "name": "Dashboard",
          "description": "",
          "args": "{\n    pattern: \"dashboard\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    const el = canvas.getByRole(\"status\")\n    await expect(el).toHaveAttribute(\"aria-busy\", \"true\")\n  },"
        },
        {
          "name": "Table",
          "description": "",
          "args": "{\n    pattern: \"table\",\n    rows: 5,\n    columns: 4,\n  },"
        },
        {
          "name": "Profile",
          "description": "",
          "args": "{\n    pattern: \"profile\",\n  },"
        },
        {
          "name": "Form",
          "description": "",
          "args": "{\n    pattern: \"form\",\n  },"
        },
        {
          "name": "List",
          "description": "",
          "args": "{\n    pattern: \"list\",\n    rows: 4,\n  },"
        }
      ]
    },
    {
      "name": "ds-slider",
      "title": "Slider UI",
      "description": "Extended slider with value tooltip on hover, step marks/labels, range (dual handle) support, format-utils integration, i18n aria-labels, and skeleton loading.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/slider",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "slider",
        "tooltip",
        "skeleton",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/slider.tsx"
      ],
      "props": [
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showMarks",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "marks",
          "required": false,
          "type": "SliderMark[]"
        },
        {
          "name": "formatValue",
          "required": false,
          "type": "(value: number) => string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "label",
          "required": false,
          "type": "string"
        },
        {
          "name": "orientation",
          "required": false,
          "type": "\"horizontal\" | \"vertical\""
        }
      ],
      "storyTitle": "Form/Slider",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    defaultValue: [50],\n    min: 0,\n    max: 100,\n    showTooltip: false,\n    showMarks: false,\n    loading: false,\n    orientation: \"horizontal\",\n    label: \"Slider\",\n  },"
        },
        {
          "name": "Range",
          "description": "",
          "args": "{\n    defaultValue: [30, 70],\n    min: 0,\n    max: 100,\n    label: \"Range slider\",\n  },"
        },
        {
          "name": "WithMarks",
          "description": "",
          "args": "{\n    defaultValue: [50],\n    min: 0,\n    max: 100,\n    showMarks: true,\n    label: \"Slider with marks\",\n  },"
        },
        {
          "name": "CustomMarks",
          "description": "",
          "args": "{\n    defaultValue: [25],\n    min: 0,\n    max: 100,\n    marks: [\n      { value: 0, label: \"0%\" },\n      { value: 25, label: \"25%\" },\n      { value: 50, label: \"50%\" },\n      { value: 75, label: \"75%\" },\n      { value: 100, label: \"100%\" },\n    ],\n    label: \"Custom marks slider\",\n  },"
        },
        {
          "name": "WithTooltip",
          "description": "",
          "args": "{\n    defaultValue: [60],\n    min: 0,\n    max: 100,\n    showTooltip: true,\n    label: \"Slider with tooltip\",\n  },"
        },
        {
          "name": "Vertical",
          "description": "",
          "args": "{\n    defaultValue: [50],\n    min: 0,\n    max: 100,\n    orientation: \"vertical\",\n    showMarks: true,\n    label: \"Vertical slider\",\n  },"
        },
        {
          "name": "VerticalRange",
          "description": "",
          "args": "{\n    defaultValue: [20, 80],\n    min: 0,\n    max: 100,\n    orientation: \"vertical\",\n    label: \"Vertical range\",\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n    label: \"Volume\",\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    defaultValue: [45],\n    min: 0,\n    max: 100,\n    disabled: true,\n    label: \"Disabled slider\",\n  },"
        },
        {
          "name": "WithLabel",
          "description": "",
          "args": "{\n    defaultValue: [75],\n    min: 0,\n    max: 100,\n    label: \"Volume\",\n    showTooltip: true,\n  },"
        },
        {
          "name": "PriceRange",
          "description": "",
          "args": "{\n    defaultValue: [50, 200],\n    min: 0,\n    max: 500,\n    step: 10,\n    label: \"Price range\",\n    showTooltip: true,\n    formatValue: (v) => `$${v}`,\n  },"
        }
      ]
    },
    {
      "name": "ds-snippet",
      "title": "Snippet",
      "description": "Tabbed code com copy — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/snippet",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "tabs",
        "ui-i18n"
      ],
      "files": [
        "components/ds/snippet.tsx"
      ],
      "props": [
        {
          "name": "tabs",
          "required": true,
          "type": "SnippetTab[]"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/Snippet",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    tabs: [\n      { label: \"npm\", code: \"npx shadcn@latest add button\" },\n      { label: \"pnpm\", code: \"pnpm dlx shadcn@latest add button\" },\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-social-auth-group",
      "title": "SocialAuthGroup",
      "description": "Grupo de botões para login social e institucional (Google, GitHub, Microsoft, Apple, Gov.br, CAFe).",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/social-auth-group",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "ui-i18n"
      ],
      "files": [
        "components/ds/social-auth-group.tsx"
      ],
      "props": [
        {
          "name": "providers",
          "required": false,
          "type": "SocialProvider[]"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        },
        {
          "name": "loadingProvider",
          "required": false,
          "type": "SocialProvider | null"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onSelect",
          "required": false,
          "type": "(provider: SocialProvider) => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "layout",
          "required": false,
          "type": "\"stacked\" | \"inline\" | \"grid\"",
          "options": [
            "stacked",
            "inline",
            "grid"
          ],
          "default": "stacked"
        }
      ],
      "storyTitle": "Actions/SocialAuthGroup",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    layout: \"stacked\",\n    providers: [\"google\", \"github\"],\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <SocialAuthGroup {...args} />\n    </div>\n  ),"
        },
        {
          "name": "GridWithGovBr",
          "description": "",
          "args": "{\n    layout: \"grid\",\n    providers: [\"google\", \"govbr\", \"github\", \"cafe\"],\n  },\n  render: (args) => (\n    <div className=\"w-96\">\n      <SocialAuthGroup {...args} />\n    </div>\n  ),"
        },
        {
          "name": "InlineRow",
          "description": "",
          "args": "{\n    layout: \"inline\",\n    providers: [\"google\", \"github\", \"microsoft\", \"apple\", \"govbr\"],\n  },"
        },
        {
          "name": "LoadingState",
          "description": "",
          "args": "{\n    layout: \"stacked\",\n    providers: [\"google\", \"govbr\"],\n    loadingProvider: \"govbr\",\n  },\n  render: (args) => (\n    <div className=\"w-80\">\n      <SocialAuthGroup {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-social-links",
      "title": "Social Links",
      "description": "Linha acessível de canais sociais e comunitários com variantes visuais e detecção de ícones.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/social-links",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/social-links.tsx"
      ],
      "props": [
        {
          "name": "links",
          "required": true,
          "type": "SocialLinkItem[]"
        },
        {
          "name": "shape",
          "required": false,
          "type": "\"circle\" | \"rounded\" | \"square\""
        },
        {
          "name": "gap",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        },
        {
          "name": "navLabel",
          "required": false,
          "type": "string"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"ghost\" | \"outline\" | \"muted\"",
          "options": [
            "ghost",
            "outline",
            "muted"
          ],
          "default": "ghost"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">\n          Ghost:\n        </span>\n        <SocialLinks links={sampleLinks} variant=\"ghost\" />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">\n          Outline:\n        </span>\n        <SocialLinks links={sampleLinks} variant=\"outline\" />\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <span className=\"text-xs font-medium text-muted-foreground\">\n          Muted:\n        </span>\n        <SocialLinks links={sampleLinks} variant=\"muted\" />\n      </div>\n    </div>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div className=\"flex items-center gap-4\">\n        <span className=\"w-12 text-xs font-medium text-muted-foreground\">\n          SM:\n        </span>\n        <SocialLinks links={sampleLinks} size=\"sm\" variant=\"outline\" />\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <span className=\"w-12 text-xs font-medium text-muted-foreground\">\n          MD:\n        </span>\n        <SocialLinks links={sampleLinks} size=\"md\" variant=\"outline\" />\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <span className=\"w-12 text-xs font-medium text-muted-foreground\">\n          LG:\n        </span>\n        <SocialLinks links={sampleLinks} size=\"lg\" variant=\"outline\" />\n      </div>\n    </div>"
        },
        {
          "name": "Shapes",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div className=\"flex items-center gap-4\">\n        <span className=\"w-16 text-xs font-medium text-muted-foreground\">\n          Circle:\n        </span>\n        <SocialLinks links={sampleLinks} shape=\"circle\" variant=\"outline\" />\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <span className=\"w-16 text-xs font-medium text-muted-foreground\">\n          Rounded:\n        </span>\n        <SocialLinks links={sampleLinks} shape=\"rounded\" variant=\"outline\" />\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <span className=\"w-16 text-xs font-medium text-muted-foreground\">\n          Square:\n        </span>\n        <SocialLinks links={sampleLinks} shape=\"square\" variant=\"outline\" />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-sortable",
      "title": "Sortable",
      "description": "Lista arrastável vertical/grid — ReUI Sortable.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/sortable",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/sortable.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "SortableItem[]"
        },
        {
          "name": "onReorder",
          "required": false,
          "type": "(items: SortableItem[]) => void"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/Sortable",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    items: [\n      { id: \"1\", content: \"Item 1\" },\n      { id: \"2\", content: \"Item 2\" },\n      { id: \"3\", content: \"Item 3\" },\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-sparkline",
      "title": "Sparkline",
      "description": "Micro-gráfico SVG ultra-leve para tabelas e cards com modos line, area e bar.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/sparkline",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/sparkline.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "number[]",
          "description": "Numeric series data array."
        },
        {
          "name": "type",
          "required": false,
          "type": "\"line\" | \"area\" | \"bar\"",
          "description": "Sparkline type."
        },
        {
          "name": "strokeWidth",
          "required": false,
          "type": "number",
          "description": "Line stroke thickness in pixels."
        },
        {
          "name": "showLastPoint",
          "required": false,
          "type": "boolean",
          "description": "Shows a highlight circle at the latest (last) data point."
        },
        {
          "name": "height",
          "required": false,
          "type": "number",
          "description": "Height in pixels."
        },
        {
          "name": "width",
          "required": false,
          "type": "number | string",
          "description": "Width in pixels or CSS percentage string."
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Loading skeleton indicator."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for accessibility label formatting."
        },
        {
          "name": "intent",
          "required": false,
          "type": "\"primary\" | \"success\" | \"destructive\" | \"warning\"",
          "options": [
            "primary",
            "success",
            "destructive",
            "warning"
          ],
          "default": "primary"
        }
      ],
      "storyTitle": "Data Display/Sparkline",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    intent: \"primary\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    const svg = canvas.getByRole(\"img\")\n    await expect(svg).toBeInTheDocument()\n  },"
        },
        {
          "name": "AreaVariant",
          "description": "",
          "args": "{\n    type: \"area\",\n    intent: \"success\",\n    data: [15, 18, 14, 25, 22, 34, 30, 42],\n  },"
        },
        {
          "name": "BarVariant",
          "description": "",
          "args": "{\n    type: \"bar\",\n    intent: \"warning\",\n    data: [5, 12, 8, 15, 10, 20, 14, 18],\n  },"
        },
        {
          "name": "AllIntents",
          "description": "",
          "code": "<div className=\"grid w-80 grid-cols-2 gap-6\">\n      <div className=\"rounded-lg border border-border bg-card p-3\">\n        <span className=\"block pb-1 text-xs text-muted-foreground\">\n          Primary:\n        </span>\n        <Sparkline data={sampleData} intent=\"primary\" type=\"area\" />\n      </div>\n      <div className=\"rounded-lg border border-border bg-card p-3\">\n        <span className=\"block pb-1 text-xs text-muted-foreground\">\n          Success (+18%):\n        </span>\n        <Sparkline\n          data={[10, 12, 16, 20, 25, 32]}\n          intent=\"success\"\n          type=\"area\"\n        />\n      </div>\n      <div className=\"rounded-lg border border-border bg-card p-3\">\n        <span className=\"block pb-1 text-xs text-muted-foreground\">\n          Destructive (-8%):\n        </span>\n        <Sparkline\n          data={[32, 28, 25, 26, 20, 15]}\n          intent=\"destructive\"\n          type=\"area\"\n        />\n      </div>\n      <div className=\"rounded-lg border border-border bg-card p-3\">\n        <span className=\"block pb-1 text-xs text-muted-foreground\">\n          Warning:\n        </span>\n        <Sparkline\n          data={[15, 18, 12, 24, 18, 22]}\n          intent=\"warning\"\n          type=\"line\"\n        />\n      </div>\n    </div>"
        },
        {
          "name": "InTableCell",
          "description": "",
          "code": "<div className=\"w-96 overflow-hidden rounded-lg border border-border bg-card\">\n      <table className=\"w-full text-xs\">\n        <thead className=\"border-b border-border bg-muted/40\">\n          <tr>\n            <th className=\"p-2.5 text-left font-medium text-muted-foreground\">\n              Indicador\n            </th>\n            <th className=\"p-2.5 text-right font-medium text-muted-foreground\">\n              Último\n            </th>\n            <th className=\"p-2.5 text-center font-medium text-muted-foreground\">\n              Tendência (30d)\n            </th>\n          </tr>\n        </thead>\n        <tbody className=\"divide-y divide-border\">\n          <tr>\n            <td className=\"p-2.5 font-medium text-foreground\">Taxa Selic</td>\n            <td className=\"p-2.5 text-right font-semibold tabular-nums\">\n              10.75%\n            </td>\n            <td className=\"w-28 p-2.5\">\n              <Sparkline\n                data={[12.25, 11.75, 11.25, 10.75, 10.75]}\n                height={22}\n                intent=\"destructive\"\n              />\n            </td>\n          </tr>\n          <tr>\n            <td className=\"p-2.5 font-medium text-foreground\">\n              PIB Trimestral\n            </td>\n            <td className=\"p-2.5 text-right font-semibold tabular-nums\">\n              +2.8%\n            </td>\n            <td className=\"w-28 p-2.5\">\n              <Sparkline\n                data={[1.2, 1.8, 2.1, 2.4, 2.8]}\n                height={22}\n                intent=\"success\"\n                type=\"area\"\n              />\n            </td>\n          </tr>\n        </tbody>\n      </table>\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-spinner",
      "title": "Spinner UI",
      "description": "An animated loader with locale-aware aria-labels, built on lucide-react Loader2Icon.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/spinner",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "spinner",
        "ui-i18n"
      ],
      "files": [
        "components/ds/spinner.tsx"
      ],
      "props": [
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Localized fallback for the accessible name when no `label` is given."
        },
        {
          "name": "label",
          "required": false,
          "type": "string",
          "description": "Optional visible text rendered next to the spinner."
        },
        {
          "name": "thickness",
          "required": false,
          "type": "SpinnerThickness",
          "description": "Stroke thickness of the spinner ring."
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"4xl\" | \"5xl\" | \"6xl\" | \"7xl\"",
          "options": [
            "sm",
            "md",
            "lg",
            "xl",
            "2xl",
            "3xl",
            "4xl",
            "5xl",
            "6xl",
            "7xl"
          ],
          "default": "md"
        },
        {
          "name": "tone",
          "required": false,
          "type": "\"current\" | \"muted\" | \"primary\" | \"success\" | \"warning\" | \"destructive\"",
          "options": [
            "current",
            "muted",
            "primary",
            "success",
            "warning",
            "destructive"
          ],
          "default": "current"
        }
      ],
      "storyTitle": "Feedback/Spinner",
      "stories": [
        {
          "name": "Default",
          "description": "Default spinner with no additional props — renders at default size, inheriting the current text color.",
          "args": "{\n    size: \"md\",\n    tone: \"current\",\n    thickness: \"regular\",\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default spinner with no additional props — renders at default size, inheriting the current text color.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithLabel",
          "description": "Optional visible label. The wrapper carries `role=\"status\"` and the label provides the accessible name.",
          "args": "{\n    label: \"Loading indicators…\",\n    tone: \"primary\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          'Optional visible label. The wrapper carries `role=\"status\"` and the label provides the accessible name.',\n      },\n    },\n  },"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization applied to the accessible name (no visible label).",
          "args": "{\n    locale: \"pt-BR\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) localization applied to the accessible name (no visible label).\",\n      },\n    },\n  },"
        },
        {
          "name": "Sizes",
          "description": "The full size scale: `sm` (14px), `md` (16px), `lg` (20px), `xl` (24px), `2xl` (32px), `3xl` (40px), `4xl` (48px), `5xl` (64px), `6xl` (80px), `7xl` (96px).",
          "code": "<div className=\"flex flex-wrap items-center gap-6\">\n      <Spinner size=\"sm\" />\n      <Spinner size=\"md\" />\n      <Spinner size=\"lg\" />\n      <Spinner size=\"xl\" />\n      <Spinner size=\"2xl\" />\n      <Spinner size=\"3xl\" />\n      <Spinner size=\"4xl\" />\n      <Spinner size=\"5xl\" />\n      <Spinner size=\"6xl\" />\n      <Spinner size=\"7xl\" />\n    </div>"
        },
        {
          "name": "Tones",
          "description": "Semantic color tones — `muted`, `primary`, `success`, `warning`, and `destructive`.",
          "code": "<div className=\"flex flex-wrap items-center gap-6\">\n      <Spinner size=\"xl\" tone=\"muted\" />\n      <Spinner size=\"xl\" tone=\"primary\" />\n      <Spinner size=\"xl\" tone=\"success\" />\n      <Spinner size=\"xl\" tone=\"warning\" />\n      <Spinner size=\"xl\" tone=\"destructive\" />\n    </div>"
        },
        {
          "name": "Thickness",
          "description": "Ring stroke thickness — `thin` (1.5), `regular` (2), `bold` (2.5), `bolder` (3).",
          "code": "<div className=\"flex flex-wrap items-center gap-6\">\n      <Spinner size=\"3xl\" thickness=\"thin\" />\n      <Spinner size=\"3xl\" thickness=\"regular\" />\n      <Spinner size=\"3xl\" thickness=\"bold\" />\n      <Spinner size=\"3xl\" thickness=\"bolder\" />\n    </div>"
        },
        {
          "name": "LargeWithLabel",
          "description": "A large, centered spinner suitable for full-section or page-level loading states.",
          "code": "<div className=\"flex flex-col items-center gap-3\">\n      <Spinner size=\"3xl\" tone=\"primary\" />\n      <span className=\"text-sm text-muted-foreground\">\n        Processing 2030 Agenda data…\n      </span>\n    </div>"
        },
        {
          "name": "InButton",
          "description": "Spinner used inline inside disabled buttons. With `tone: current` it inherits each button's text color automatically.",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Button disabled>\n        <Spinner data-icon=\"inline-start\" />\n        Loading\n      </Button>\n      <Button variant=\"outline\" disabled>\n        <Spinner data-icon=\"inline-start\" />\n        Processing\n      </Button>\n      <Button variant=\"secondary\" disabled>\n        <Spinner data-icon=\"inline-start\" />\n        Saving\n      </Button>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-spotlight-card",
      "title": "Spotlight Card",
      "description": "Card com spotlight radial seguindo o mouse — inspirado em Aceternity Card Spotlight.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/spotlight-card",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/spotlight-card.tsx"
      ],
      "props": [
        {
          "name": "spotlightColor",
          "required": false,
          "type": "string"
        },
        {
          "name": "spotlightRadius",
          "required": false,
          "type": "number"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "radius",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\" | \"xl\"",
          "options": [
            "sm",
            "md",
            "lg",
            "xl"
          ],
          "default": "xl"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\" | \"outline\"",
          "options": [
            "default",
            "muted",
            "outline"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Passos de autenticação\",\n    description: \"Siga os passos para proteger sua conta\",\n    children: (\n      <ol className=\"flex flex-col gap-2 text-sm\">\n        <li>• Digite seu e-mail</li>\n        <li>• Crie uma senha forte</li>\n        <li>• Ative a verificação em duas etapas</li>\n        <li>• Verifique sua identidade</li>\n      </ol>\n    ),\n  },\n  render: (args) => <SpotlightCard {...args} className=\"w-96\" />,"
        },
        {
          "name": "CustomColor",
          "description": "",
          "args": "{\n    title: \"Segurança em primeiro lugar\",\n    description: \"Seus dados protegidos com criptografia\",\n    spotlightColor: \"hsl(var(--success) / 0.15)\",\n    children: (\n      <div className=\"flex items-center gap-3 text-sm\">\n        <ShieldCheckIcon className=\"size-5 text-success\" />\n        <span>Conta verificada com sucesso</span>\n      </div>\n    ),\n  },\n  render: (args) => <SpotlightCard {...args} className=\"w-80\" />,"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"grid gap-4 md:grid-cols-3\">\n      {([\"default\", \"muted\", \"outline\"] as const).map((v) => (\n        <SpotlightCard\n          key={v}\n          variant={v}\n          title={v}\n          description=\"Hover para spotlight\"\n        >\n          <p className=\"text-sm text-muted-foreground\">\n            Mova o mouse sobre o card\n          </p>\n        </SpotlightCard>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-stats",
      "title": "Stats",
      "description": "Faixa de métricas com trend — átomo base stats.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/stats",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "badge",
        "ui-i18n"
      ],
      "files": [
        "components/ds/stats.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": true,
          "type": "string"
        },
        {
          "name": "value",
          "required": true,
          "type": "string | number"
        },
        {
          "name": "trend",
          "required": false,
          "type": "{ value: string; direction: \"up\" | \"down\" }"
        },
        {
          "name": "period",
          "required": false,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Stats/Stats",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    label: \"Total users\",\n    value: \"12,345\",\n    trend: { value: \"+12%\", direction: \"up\" },\n    period: \"vs last month\",\n    icon: <UsersIcon />,\n  },"
        },
        {
          "name": "WithoutTrend",
          "description": "",
          "args": "{ label: \"Revenue\", value: \"$48,290\" },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ label: \"Loading\", value: \"0\", loading: true },"
        }
      ]
    },
    {
      "name": "ds-stats-grid",
      "title": "Stats Grid",
      "description": "Grid de métricas 2-4 cols — blockus stats.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/stats-grid",
      "dependencies": [],
      "registryDependencies": [
        "ds-stats"
      ],
      "files": [
        "components/ds/stats-grid.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "StatsProps[]"
        },
        {
          "name": "columns",
          "required": false,
          "type": "2 | 3 | 4"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Stats/StatsGrid",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items }"
        },
        {
          "name": "ThreeCols",
          "description": "",
          "args": "{ items: items.slice(0, 3), columns: 3 },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ items, loading: true }"
        }
      ]
    },
    {
      "name": "ds-status-page",
      "title": "Status Page",
      "description": "Painel de saúde operacional com histórico de 90 dias e cálculo de uptime.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/status-page",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/status-page.tsx"
      ],
      "props": [
        {
          "name": "services",
          "required": true,
          "type": "StatusService[]",
          "description": "List of monitored services."
        },
        {
          "name": "overallStatus",
          "required": false,
          "type": "\"operational\" | \"degraded\" | \"outage\"",
          "description": "System overall status."
        },
        {
          "name": "showUptimeBars",
          "required": false,
          "type": "boolean",
          "description": "Whether to display 90-day uptime bars."
        },
        {
          "name": "incidents",
          "required": false,
          "type": "StatusIncident[]",
          "description": "List of recent incidents."
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Loading state."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Locale for labels and messages."
        }
      ],
      "storyTitle": "Data Display/StatusPage",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    locale: \"pt-BR\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(\n      canvas.getByText(\"Todos os sistemas operacionais\")\n    ).toBeInTheDocument()\n    await expect(\n      canvas.getByText(\"API de Modelos Econométricos\")\n    ).toBeInTheDocument()\n  },"
        },
        {
          "name": "DegradedPerformance",
          "description": "",
          "args": "{\n    overallStatus: \"degraded\",\n    services: [\n      sampleServices[0],\n      {\n        ...sampleServices[1],\n        status: \"degraded\",\n        uptimePercentage: 98.42,\n      },\n      sampleServices[2],\n      sampleServices[3],\n    ],\n  },"
        },
        {
          "name": "MajorOutageWithIncidents",
          "description": "",
          "args": "{\n    overallStatus: \"outage\",\n    services: [\n      {\n        ...sampleServices[0],\n        status: \"outage\",\n        uptimePercentage: 94.1,\n      },\n      sampleServices[1],\n      sampleServices[2],\n    ],\n    incidents: [\n      {\n        id: \"inc-1\",\n        title: \"Interrupção na API de Modelos Econométricos\",\n        date: \"Hoje às 14:22\",\n        status: \"investigating\",\n        description:\n          \"Identificamos latência elevada e timeouts em consultas de simulação de longo prazo. A equipe de engenharia está aplicando correção no cluster de workers.\",\n      },\n    ],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-step-progress",
      "title": "Step Progress",
      "description": "A visual guide through a sequential multi-step process with horizontal and vertical orientations.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/step-progress",
      "dependencies": [
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/step-progress.tsx"
      ],
      "props": [
        {
          "name": "orientation",
          "required": false,
          "type": "\"horizontal\" | \"vertical\"",
          "options": [
            "horizontal",
            "vertical"
          ],
          "default": "horizontal"
        }
      ],
      "storyTitle": "Navigation/StepProgress",
      "stories": [
        {
          "name": "Horizontal",
          "description": "Horizontal step progress with step 2 (Payment) as the current active step.",
          "args": "{ steps, currentStepId: \"2\", orientation: \"horizontal\" },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Horizontal step progress with step 2 (Payment) as the current active step.\",\n      },\n    },\n  },"
        },
        {
          "name": "Vertical",
          "description": "Vertical step progress with step 2 (Payment) as the current active step.",
          "args": "{ steps, currentStepId: \"2\", orientation: \"vertical\" },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Vertical step progress with step 2 (Payment) as the current active step.\",\n      },\n    },\n  },"
        },
        {
          "name": "Interactive",
          "description": "Interactive step progress with Previous/Next buttons to navigate between steps.",
          "args": "{ steps, currentStepId: \"1\" },\n  render: () => {\n    const [currentStepId, setCurrentStepId] = React.useState(\"1\")\n    return (\n      <div className=\"mx-auto max-w-4xl p-8\">\n        <StepProgress\n          steps={steps}\n          currentStepId={currentStepId}\n          onStepClick={setCurrentStepId}\n        />\n        <div className=\"mt-12 rounded-xl border bg-muted/30 p-8 text-center\">\n          <p className=\"text-lg font-medium\">\n            Current Step: {steps.find((s) => s.id === currentStepId)?.title}\n          </p>\n          <div className=\"mt-4 flex justify-center gap-4\">\n            <button\n              className=\"rounded-lg bg-primary px-4 py-2 text-primary-foreground disabled:opacity-50\"\n              onClick={() => {\n                const idx = steps.findIndex((s) => s.id === currentStepId)\n                if (idx > 0) setCurrentStepId(steps[idx - 1].id)\n              }}\n              disabled={currentStepId === \"1\"}\n            >\n              Previous\n            </button>\n            <button\n              className=\"rounded-lg bg-primary px-4 py-2 text-primary-foreground disabled:opacity-50\"\n              onClick={() => {\n                const idx = steps.findIndex((s) => s.id === currentStepId)\n                if (idx < steps.length - 1) setCurrentStepId(steps[idx + 1].id)\n              }}\n              disabled={currentStepId === \"4\"}\n            >\n              Next\n            </button>\n          </div>\n        </div>\n      </div>\n    )\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Interactive step progress with Previous/Next buttons to navigate between steps.\",\n      },\n    },\n  },",
          "code": "<div className=\"mx-auto max-w-4xl p-8\">\n        <StepProgress\n          steps={steps}\n          currentStepId={currentStepId}\n          onStepClick={setCurrentStepId}\n        />\n        <div className=\"mt-12 rounded-xl border bg-muted/30 p-8 text-center\">\n          <p className=\"text-lg font-medium\">\n            Current Step: {steps.find((s) => s.id === currentStepId)?.title}\n          </p>\n          <div className=\"mt-4 flex justify-center gap-4\">\n            <button\n              className=\"rounded-lg bg-primary px-4 py-2 text-primary-foreground disabled:opacity-50\"\n              onClick={() => {\n                const idx = steps.findIndex((s) => s.id === currentStepId)\n                if (idx > 0) setCurrentStepId(steps[idx - 1].id)\n              }}\n              disabled={currentStepId === \"1\"}\n            >\n              Previous\n            </button>\n            <button\n              className=\"rounded-lg bg-primary px-4 py-2 text-primary-foreground disabled:opacity-50\"\n              onClick={() => {\n                const idx = steps.findIndex((s) => s.id === currentStepId)\n                if (idx < steps.length - 1) setCurrentStepId(steps[idx + 1].id)\n              }}\n              disabled={currentStepId === \"4\"}\n            >\n              Next\n            </button>\n          </div>\n        </div>\n      </div>"
        },
        {
          "name": "LocalePTBR",
          "description": "Portuguese (pt-BR) localization with translated step titles and descriptions.",
          "args": "{\n    steps: [\n      {\n        id: \"1\",\n        title: \"Account\",\n        description: \"Create your account\",\n        icon: <User className=\"size-4\" />,\n      },\n      {\n        id: \"2\",\n        title: \"Payment\",\n        description: \"Add payment method\",\n        icon: <CreditCard className=\"size-4\" />,\n      },\n      {\n        id: \"3\",\n        title: \"Review\",\n        description: \"Review your order\",\n        icon: <CheckCircle className=\"size-4\" />,\n      },\n      {\n        id: \"4\",\n        title: \"Delivery\",\n        description: \"Track your delivery\",\n        icon: <Truck className=\"size-4\" />,\n      },\n    ],\n    currentStepId: \"2\",\n    orientation: \"horizontal\",\n    locale: \"pt-BR\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) localization with translated step titles and descriptions.\",\n      },\n    },\n  },"
        },
        {
          "name": "Sizes",
          "description": "Comparison of all three size presets — sm, md, and lg.",
          "args": "{ steps, currentStepId: \"2\" },\n  render: () => (\n    <div className=\"flex flex-col gap-16\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-4\">\n          <span className=\"text-sm font-medium text-muted-foreground\">\n            {size === \"sm\"\n              ? \"Small (sm)\"\n              : size === \"md\"\n                ? \"Medium (md)\"\n                : \"Large (lg)\"}\n          </span>\n          <StepProgress steps={steps} currentStepId=\"2\" size={size} />\n        </div>\n      ))}\n    </div>\n  ),\n  parameters: {\n    docs: {\n      description: {\n        story: \"Comparison of all three size presets — sm, md, and lg.\",\n      },\n    },\n  },",
          "code": "<div className=\"flex flex-col gap-16\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <div key={size} className=\"flex flex-col gap-4\">\n          <span className=\"text-sm font-medium text-muted-foreground\">\n            {size === \"sm\"\n              ? \"Small (sm)\"\n              : size === \"md\"\n                ? \"Medium (md)\"\n                : \"Large (lg)\"}\n          </span>\n          <StepProgress steps={steps} currentStepId=\"2\" size={size} />\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-stepper",
      "title": "Stepper",
      "description": "Wizard com validação per-step — ReUI Stepper.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/stepper",
      "dependencies": [],
      "registryDependencies": [
        "ds-step-progress",
        "card",
        "button"
      ],
      "files": [
        "components/ds/stepper.tsx"
      ],
      "props": [
        {
          "name": "steps",
          "required": true,
          "type": "StepItem[]"
        },
        {
          "name": "currentId",
          "required": true,
          "type": "string"
        },
        {
          "name": "onStepChange",
          "required": false,
          "type": "(id: string) => void"
        },
        {
          "name": "orientation",
          "required": false,
          "type": "\"horizontal\" | \"vertical\""
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\""
        }
      ],
      "storyTitle": "Onboarding/Stepper",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    currentId: \"1\",\n    steps: [\n      { id: \"1\", title: \"Account\" },\n      { id: \"2\", title: \"Details\" },\n      { id: \"3\", title: \"Confirm\" },\n    ],\n  },"
        }
      ]
    },
    {
      "name": "ds-sticky-feature-list",
      "title": "StickyFeatureList",
      "description": "Lista de recursos com barra lateral fixa e navegação contextual por seção.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/sticky-feature-list",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/sticky-feature-list.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": false,
          "type": "string"
        },
        {
          "name": "defaultValue",
          "required": false,
          "type": "string"
        },
        {
          "name": "onValueChange",
          "required": false,
          "type": "(value: string) => void"
        },
        {
          "name": "label",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Layout/StickyFeatureList",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<StickyFeatureList defaultValue=\"insights\" label=\"Product capabilities\">\n      <StickyFeatureListNav>\n        {features.map((feature) => (\n          <StickyFeatureListItem\n            key={feature.value}\n            value={feature.value}\n            title={feature.title}\n            description={feature.description}\n          />\n        ))}\n      </StickyFeatureListNav>\n      <StickyFeatureListPanels>\n        {features.map((feature) => (\n          <StickyFeatureListPanel key={feature.value} value={feature.value}>\n            <FeatureMedia icon={feature.icon} tone={feature.tone} />\n          </StickyFeatureListPanel>\n        ))}\n      </StickyFeatureListPanels>\n    </StickyFeatureList>"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col gap-16\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <StickyFeatureList key={size} defaultValue=\"insights\" size={size}>\n          <StickyFeatureListNav>\n            {features.slice(0, 2).map((feature) => (\n              <StickyFeatureListItem\n                key={feature.value}\n                value={feature.value}\n                title={feature.title}\n                description={feature.description}\n              />\n            ))}\n          </StickyFeatureListNav>\n          <StickyFeatureListPanels>\n            {features.slice(0, 2).map((feature) => (\n              <StickyFeatureListPanel key={feature.value} value={feature.value}>\n                <FeatureMedia icon={feature.icon} tone={feature.tone} />\n              </StickyFeatureListPanel>\n            ))}\n          </StickyFeatureListPanels>\n        </StickyFeatureList>\n      ))}\n    </div>"
        },
        {
          "name": "Controlled",
          "description": "",
          "code": "<StickyFeatureList value={value} onValueChange={setValue}>\n        <StickyFeatureListNav>\n          {features.map((feature) => (\n            <StickyFeatureListItem\n              key={feature.value}\n              value={feature.value}\n              title={feature.title}\n              description={feature.description}\n            />\n          ))}\n        </StickyFeatureListNav>\n        <StickyFeatureListPanels>\n          {features.map((feature) => (\n            <StickyFeatureListPanel key={feature.value} value={feature.value}>\n              <FeatureMedia icon={feature.icon} tone={feature.tone} />\n            </StickyFeatureListPanel>\n          ))}\n        </StickyFeatureListPanels>\n      </StickyFeatureList>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<StickyFeatureList defaultValue=\"insights\">\n      <StickyFeatureListNav>\n        {features.slice(0, 3).map((feature) => (\n          <StickyFeatureListItem\n            key={feature.value}\n            value={feature.value}\n            title={feature.title}\n            description={feature.description}\n          />\n        ))}\n      </StickyFeatureListNav>\n      <StickyFeatureListPanels>\n        {features.slice(0, 3).map((feature) => (\n          <StickyFeatureListPanel key={feature.value} value={feature.value}>\n            <Skeleton className=\"aspect-4/3 w-full rounded-2xl\" />\n          </StickyFeatureListPanel>\n        ))}\n      </StickyFeatureListPanels>\n    </StickyFeatureList>"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"en-US\", \"pt-BR\", \"es-ES\", \"fr-FR\"] as UILocale[]).map((locale) => (\n        <StickyFeatureList key={locale} locale={locale} defaultValue=\"insights\">\n          <StickyFeatureListNav>\n            {features.slice(0, 2).map((feature) => (\n              <StickyFeatureListItem\n                key={feature.value}\n                value={feature.value}\n                title={feature.title}\n                description={feature.description}\n              />\n            ))}\n          </StickyFeatureListNav>\n          <StickyFeatureListPanels>\n            {features.slice(0, 2).map((feature) => (\n              <StickyFeatureListPanel key={feature.value} value={feature.value}>\n                <FeatureMedia icon={feature.icon} tone={feature.tone} />\n              </StickyFeatureListPanel>\n            ))}\n          </StickyFeatureListPanels>\n        </StickyFeatureList>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-switch",
      "title": "Switch UI",
      "description": "Extended switch with label positioning, semantic color variants (success/destructive/warning), skeleton loading, and error state.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/switch",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "switch",
        "label",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/switch.tsx"
      ],
      "props": [
        {
          "name": "label",
          "required": false,
          "type": "string"
        },
        {
          "name": "labelPosition",
          "required": false,
          "type": "\"left\" | \"right\""
        },
        {
          "name": "color",
          "required": false,
          "type": "SwitchColor"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "error",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/Switch",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    color: \"default\",\n    size: \"md\",\n    labelPosition: \"right\",\n    loading: false,\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "WithLabel",
          "description": "",
          "args": "{\n    label: \"Enable notifications\",\n  },"
        },
        {
          "name": "LabelLeft",
          "description": "",
          "args": "{\n    label: \"Notifications\",\n    labelPosition: \"left\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <Switch size=\"sm\" label=\"Small\" />\n      <Switch size=\"md\" label=\"Medium\" />\n      <Switch size=\"lg\" label=\"Large\" />\n    </div>"
        },
        {
          "name": "AllColors",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <Switch color=\"default\" label=\"Default\" defaultChecked />\n      <Switch color=\"success\" label=\"Success\" defaultChecked />\n      <Switch color=\"destructive\" label=\"Destructive\" defaultChecked />\n      <Switch color=\"warning\" label=\"Warning\" defaultChecked />\n    </div>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <Switch loading size=\"sm\" label=\"Small\" />\n      <Switch loading size=\"md\" label=\"Medium\" />\n      <Switch loading size=\"lg\" label=\"Large\" />\n    </div>"
        },
        {
          "name": "WithError",
          "description": "",
          "args": "{\n    label: \"Accept terms\",\n    error: \"You must accept the terms to continue.\",\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    label: \"Disabled switch\",\n    disabled: true,\n  },"
        },
        {
          "name": "DisabledChecked",
          "description": "",
          "args": "{\n    label: \"Always active\",\n    disabled: true,\n    defaultChecked: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-system-status-badge",
      "title": "System Status Badge",
      "description": "Indicador de disponibilidade operacional e saúde dos serviços em tempo real com dot animado.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/system-status-badge",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "components/ds/system-status-badge.tsx"
      ],
      "props": [
        {
          "name": "status",
          "required": false,
          "type": "SystemHealthStatus"
        },
        {
          "name": "label",
          "required": false,
          "type": "string"
        },
        {
          "name": "uptime",
          "required": false,
          "type": "string"
        },
        {
          "name": "href",
          "required": false,
          "type": "string"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "AllStatuses",
          "description": "",
          "code": "<div className=\"flex flex-col items-start gap-4\">\n      <SystemStatusBadge status=\"operational\" />\n      <SystemStatusBadge status=\"degraded\" />\n      <SystemStatusBadge status=\"outage\" />\n      <SystemStatusBadge status=\"maintenance\" />\n    </div>"
        },
        {
          "name": "WithUptime",
          "description": "",
          "args": "{\n    status: \"operational\",\n    uptime: \"99.98%\",\n  },"
        },
        {
          "name": "AsLink",
          "description": "",
          "args": "{\n    status: \"operational\",\n    uptime: \"99.99%\",\n    href: \"https://status.ufpb.br\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "code": "<div className=\"flex items-center gap-4\">\n      <SystemStatusBadge size=\"sm\" uptime=\"99.9%\" />\n      <SystemStatusBadge size=\"md\" uptime=\"99.9%\" />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-table-of-contents",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/table-of-contents",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/table-of-contents.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "TocItem[]"
        },
        {
          "name": "activeId",
          "required": false,
          "type": "string",
          "description": "Se providenciado, sobrescreve o rastreamento automático do scroll e controla o id ativo."
        },
        {
          "name": "offset",
          "required": false,
          "type": "number",
          "description": "Offset superior para acionar a troca do active element via scroll (em px)"
        },
        {
          "name": "onItemClick",
          "required": false,
          "type": "(id: string, e: React.MouseEvent<HTMLAnchorElement>) => void",
          "description": "Se passado, intercepta o clique do link"
        }
      ],
      "storyTitle": "Navigation/TableOfContents",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    items: [],\n  },\n  render: () => {\n    return (\n      <div className=\"mx-auto flex w-full max-w-5xl gap-12 p-8\">\n        <div className=\"flex-1 space-y-32\">\n          {/* Falso conteúdo para mockar âncoras */}\n          <section id=\"introducao\" className=\"space-y-4 pt-16\">\n            <h2 className=\"text-3xl font-bold\">1. Introdução</h2>\n            <div className=\"h-64 rounded-md bg-muted p-4\">\n              Conteúdo introdução...\n            </div>\n          </section>\n\n          <section id=\"funcionalidades\" className=\"space-y-4 pt-16\">\n            <h2 className=\"text-3xl font-bold\">2. Funcionalidades</h2>\n            <div className=\"h-48 rounded-md bg-muted p-4\">\n              Conteúdo funcionalidades...\n            </div>\n          </section>\n\n          <section id=\"funcionalidade-1\" className=\"space-y-4 pt-16\">\n            <h3 className=\"text-xl font-bold\">2.1 Primeira Funcionalidade</h3>\n            <div className=\"h-64 rounded-md bg-muted p-4\">Conteúdo 2.1...</div>\n          </section>\n\n          <section id=\"funcionalidade-2\" className=\"space-y-4 pt-16\">\n            <h3 className=\"text-xl font-bold\">2.2 Segunda Funcionalidade</h3>\n            <div className=\"h-125 rounded-md bg-muted p-4\">Conteúdo 2.2...</div>\n          </section>\n\n          <section id=\"conclusao\" className=\"space-y-4 pt-16\">\n            <h2 className=\"text-3xl font-bold\">3. Conclusão</h2>\n            <div className=\"h-96 rounded-md bg-muted p-4\">\n              Conteúdo final...\n            </div>\n          </section>\n        </div>\n\n        <div className=\"hidden w-64 md:block\">\n          <div className=\"sticky top-16\">\n            <h4 className=\"mb-4 text-sm font-semibold\">Nesta página</h4>\n            <TableOfContents\n              items={[\n                { id: \"introducao\", title: \"1. Introdução\", level: 2 },\n                {\n                  id: \"funcionalidades\",\n                  title: \"2. Funcionalidades\",\n                  level: 2,\n                },\n                {\n                  id: \"funcionalidade-1\",\n                  title: \"2.1 Primeira Funcionalidade\",\n                  level: 3,\n                },\n                {\n                  id: \"funcionalidade-2\",\n                  title: \"2.2 Segunda Funcionalidade\",\n                  level: 3,\n                },\n                { id: \"conclusao\", title: \"3. Conclusão\", level: 2 },\n              ]}\n              offset={80}\n            />\n          </div>\n        </div>\n      </div>\n    )\n  },",
          "code": "<div className=\"mx-auto flex w-full max-w-5xl gap-12 p-8\">\n        <div className=\"flex-1 space-y-32\">\n          {/* Falso conteúdo para mockar âncoras */}\n          <section id=\"introducao\" className=\"space-y-4 pt-16\">\n            <h2 className=\"text-3xl font-bold\">1. Introdução</h2>\n            <div className=\"h-64 rounded-md bg-muted p-4\">\n              Conteúdo introdução...\n            </div>\n          </section>\n\n          <section id=\"funcionalidades\" className=\"space-y-4 pt-16\">\n            <h2 className=\"text-3xl font-bold\">2. Funcionalidades</h2>\n            <div className=\"h-48 rounded-md bg-muted p-4\">\n              Conteúdo funcionalidades...\n            </div>\n          </section>\n\n          <section id=\"funcionalidade-1\" className=\"space-y-4 pt-16\">\n            <h3 className=\"text-xl font-bold\">2.1 Primeira Funcionalidade</h3>\n            <div className=\"h-64 rounded-md bg-muted p-4\">Conteúdo 2.1...</div>\n          </section>\n\n          <section id=\"funcionalidade-2\" className=\"space-y-4 pt-16\">\n            <h3 className=\"text-xl font-bold\">2.2 Segunda Funcionalidade</h3>\n            <div className=\"h-125 rounded-md bg-muted p-4\">Conteúdo 2.2...</div>\n          </section>\n\n          <section id=\"conclusao\" className=\"space-y-4 pt-16\">\n            <h2 className=\"text-3xl font-bold\">3. Conclusão</h2>\n            <div className=\"h-96 rounded-md bg-muted p-4\">\n              Conteúdo final...\n            </div>\n          </section>\n        </div>\n\n        <div className=\"hidden w-64 md:block\">\n          <div className=\"sticky top-16\">\n            <h4 className=\"mb-4 text-sm font-semibold\">Nesta página</h4>\n            <TableOfContents\n              items={[\n                { id: \"introducao\", title: \"1. Introdução\", level: 2 },\n                {\n                  id: \"funcionalidades\",\n                  title: \"2. Funcionalidades\",\n                  level: 2,\n                },\n                {\n                  id: \"funcionalidade-1\",\n                  title: \"2.1 Primeira Funcionalidade\",\n                  level: 3,\n                },\n                {\n                  id: \"funcionalidade-2\",\n                  title: \"2.2 Segunda Funcionalidade\",\n                  level: 3,\n                },\n                { id: \"conclusao\", title: \"3. Conclusão\", level: 2 },\n              ]}\n              offset={80}\n            />\n          </div>\n        </div>\n      </div>"
        }
      ]
    },
    {
      "name": "ds-tabs",
      "title": "Tabs UI",
      "description": "Extended tabs with 4 variants (default/line/pill/segmented), 3 sizes, icons, count badges, loading skeletons, vertical orientation, activation mode (automatic/manual), and responsive accordion fallback on mobile. Wraps the shadcn Tabs primitive.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/tabs",
      "dependencies": [
        "class-variance-authority",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [
        "tabs",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/tabs.tsx"
      ],
      "storyTitle": "Navigation/Tabs",
      "props": [
        {
          "name": "variant",
          "control": "inline-radio",
          "options": [
            "default",
            "line",
            "pill",
            "segmented"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        },
        {
          "name": "orientation",
          "control": "inline-radio",
          "options": [
            "horizontal",
            "vertical"
          ],
          "default": "horizontal"
        },
        {
          "name": "loading",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "responsive",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "forceAccordion",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "defaultValue",
          "control": "text",
          "default": ""
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Basic tabs with the `default` variant. Three tabs with account, security, and notification panels.",
          "args": "{\n    items: defaultItems,\n    defaultValue: \"account\",\n    variant: \"default\",\n    size: \"md\",\n    orientation: \"horizontal\",\n    responsive: false,\n    forceAccordion: false,\n    loading: false,\n    locale: \"en-US\",\n  },"
        },
        {
          "name": "Variants",
          "description": "Four visual variants rendered side by side.",
          "args": "{ items: defaultItems, defaultValue: \"account\" },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Four visual variants rendered side by side.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-10\">\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          default\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" variant=\"default\" />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          line\n        </p>\n        <Tabs\n          items={defaultItems.map((it) => ({ ...it, icon: undefined }))}\n          defaultValue=\"account\"\n          variant=\"line\"\n        />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          pill\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" variant=\"pill\" />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          segmented\n        </p>\n        <Tabs\n          items={defaultItems.map((it) => ({ ...it, icon: undefined }))}\n          defaultValue=\"account\"\n          variant=\"segmented\"\n        />\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-10\">\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          default\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" variant=\"default\" />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          line\n        </p>\n        <Tabs\n          items={defaultItems.map((it) => ({ ...it, icon: undefined }))}\n          defaultValue=\"account\"\n          variant=\"line\"\n        />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          pill\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" variant=\"pill\" />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          segmented\n        </p>\n        <Tabs\n          items={defaultItems.map((it) => ({ ...it, icon: undefined }))}\n          defaultValue=\"account\"\n          variant=\"segmented\"\n        />\n      </div>\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "Three size presets in the `default` variant.",
          "args": "{ items: defaultItems, defaultValue: \"account\" },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Three size presets in the `default` variant.\",\n      },\n    },\n  },\n  render: () => (\n    <div className=\"flex flex-col gap-8\">\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          sm\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" size=\"sm\" />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          md\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" size=\"md\" />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          lg\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" size=\"lg\" />\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-8\">\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          sm\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" size=\"sm\" />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          md\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" size=\"md\" />\n      </div>\n      <div>\n        <p className=\"mb-3 text-xs font-medium tracking-wide text-muted-foreground uppercase\">\n          lg\n        </p>\n        <Tabs items={defaultItems} defaultValue=\"account\" size=\"lg\" />\n      </div>\n    </div>"
        },
        {
          "name": "WithIcons",
          "description": "Each tab displays a Lucide icon before its label via the `icon` field.",
          "args": "{\n    items: [\n      {\n        value: \"profile\",\n        label: \"Profile\",\n        icon: User,\n        content: (\n          <ContentPanel>\n            Profile settings with avatar, name, and contact info.\n          </ContentPanel>\n        ),\n      },\n      {\n        value: \"security\",\n        label: \"Security\",\n        icon: Lock,\n        content: (\n          <ContentPanel>Password, 2FA, and session management.</ContentPanel>\n        ),\n      },\n      {\n        value: \"billing\",\n        label: \"Billing\",\n        icon: CreditCard,\n        content: (\n          <ContentPanel>\n            Invoices, payments, and subscription plan.\n          </ContentPanel>\n        ),\n      },\n    ],\n    defaultValue: \"profile\",\n  },"
        },
        {
          "name": "WithBadges",
          "description": "The `count` field adds a numeric badge next to the tab label.\n\nUseful for notification counts, pending items, or cart quantities.",
          "args": "{\n    items: [\n      {\n        value: \"inbox\",\n        label: \"Inbox\",\n        icon: Mail,\n        count: 12,\n        content: <ContentPanel>12 unread messages in your inbox.</ContentPanel>,\n      },\n      {\n        value: \"activity\",\n        label: \"Activity\",\n        icon: Activity,\n        count: 3,\n        content: (\n          <ContentPanel>3 recent activities from your team.</ContentPanel>\n        ),\n      },\n      {\n        value: \"messages\",\n        label: \"Messages\",\n        icon: MessageSquare,\n        count: 7,\n        content: (\n          <ContentPanel>7 unread messages across all channels.</ContentPanel>\n        ),\n      },\n      {\n        value: \"cart\",\n        label: \"Cart\",\n        icon: ShoppingCart,\n        count: 2,\n        content: <ContentPanel>2 items in your shopping cart.</ContentPanel>,\n      },\n    ],\n    defaultValue: \"inbox\",\n    variant: \"default\",\n  },"
        },
        {
          "name": "Vertical",
          "description": "Vertical orientation places the tab list on the left and content on the right.",
          "args": "{ items: iconItems, defaultValue: \"profile\" },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Vertical orientation places the tab list on the left and content on the right.\",\n      },\n    },\n  },\n  render: () => (\n    <Tabs\n      items={iconItems}\n      defaultValue=\"profile\"\n      orientation=\"vertical\"\n      variant=\"default\"\n    />\n  ),",
          "code": "<Tabs\n      items={iconItems}\n      defaultValue=\"profile\"\n      orientation=\"vertical\"\n      variant=\"default\"\n    />"
        },
        {
          "name": "Loading",
          "description": "Pass `loading` to show skeleton placeholders while tab data is being fetched.",
          "args": "{\n    items: defaultItems,\n    loading: true,\n    skeletonCount: 5,\n    defaultValue: \"account\",\n  },"
        },
        {
          "name": "ResponsiveAccordion",
          "description": "When `responsive` is enabled and the viewport is below 768px, the tabs transform into a collapsible accordion.\n\nThis story uses `forceAccordion` to simulate the mobile experience at any viewport width.\nEach item becomes an accordion section with a chevron indicator, expanding to reveal its content.",
          "args": "{\n    items: [\n      {\n        value: \"account\",\n        label: \"Account\",\n        icon: User,\n        content: (\n          <ContentPanel>\n            Account settings panel rendered inside an accordion section.\n          </ContentPanel>\n        ),\n      },\n      {\n        value: \"security\",\n        label: \"Security\",\n        icon: Shield,\n        count: 2,\n        content: (\n          <ContentPanel>\n            Security settings with pending 2FA setup and active sessions.\n          </ContentPanel>\n        ),\n      },\n      {\n        value: \"notifications\",\n        label: \"Notifications\",\n        icon: Bell,\n        count: 12,\n        content: (\n          <ContentPanel>\n            Notification preferences with email, push, and SMS options.\n          </ContentPanel>\n        ),\n      },\n    ],\n    defaultValue: \"account\",\n    forceAccordion: true,\n    variant: \"default\",\n  },"
        },
        {
          "name": "Controlled",
          "description": "External control via `value` and `onValueChange`.\nClick the buttons below to programmatically switch tabs.",
          "args": "{ items: defaultItems, defaultValue: \"account\" },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          \"External control via `value` and `onValueChange`.\",\n          \"Click the buttons below to programmatically switch tabs.\",\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: (args) => {\n    const [tab, setTab] = React.useState(\n      args.defaultValue ?? args.items[0]?.value ?? \"\"\n    )\n\n    const controlItems: TabItem[] = args.items.map((item) => ({\n      value: item.value,\n      label: item.label,\n      content: item.content,\n      disabled: item.disabled,\n      icon: item.icon,\n      count: item.count,\n    }))\n\n    const noIconItems = controlItems.map((item) => ({\n      ...item,\n      icon: undefined,\n    }))\n\n    return (\n      <div className=\"flex flex-col gap-6\">\n        <div className=\"flex gap-2\">\n          {controlItems.map((item) => {\n            const Icon = item.icon\n            return (\n              <Button\n                key={item.value}\n                size=\"sm\"\n                variant={tab === item.value ? \"default\" : \"outline\"}\n                startIcon={Icon ? <Icon className=\"size-3.5\" /> : undefined}\n                onClick={() => setTab(item.value)}\n              >\n                {item.label}\n              </Button>\n            )\n          })}\n        </div>\n        <Tabs items={noIconItems} value={tab} onValueChange={setTab} />\n        <p className=\"text-xs text-muted-foreground\">\n          Active tab:{\" \"}\n          <code className=\"rounded bg-muted px-1.5 py-0.5 font-mono\">\n            {tab}\n          </code>\n        </p>\n      </div>\n    )\n  },"
        },
        {
          "name": "KitchenSink",
          "description": "All features combined: pill variant, icons, badges, and vertical orientation.\nDemonstrates a feature-rich tab bar ready for production use.",
          "args": "{ items: defaultItems, defaultValue: \"overview\" },\n  parameters: {\n    docs: {\n      description: {\n        story: [\n          \"All features combined: pill variant, icons, badges, and vertical orientation.\",\n          \"Demonstrates a feature-rich tab bar ready for production use.\",\n        ].join(\"\\n\"),\n      },\n    },\n  },\n  render: () => {\n    const items: TabItem[] = [\n      {\n        value: \"overview\",\n        label: \"Overview\",\n        icon: Eye,\n        count: 1,\n        content: (\n          <div className=\"grid grid-cols-3 gap-4 pt-4\">\n            {[\"Users\", \"Revenue\", \"Growth\"].map((label) => (\n              <div\n                key={label}\n                className=\"rounded-xl border bg-card p-4 text-card-foreground\"\n              >\n                <p className=\"text-xs text-muted-foreground\">{label}</p>\n                <p className=\"mt-1 text-2xl font-semibold\">\n                  {Math.floor(Math.random() * 1000)}\n                </p>\n              </div>\n            ))}\n          </div>\n        ),\n      },\n      {\n        value: \"activity\",\n        label: \"Activity\",\n        icon: Activity,\n        count: 3,\n        content: (\n          <div className=\"flex flex-col gap-3 pt-4\">\n            {Array.from({ length: 4 }).map((_, i) => (\n              <div\n                key={i}\n                className=\"flex items-center gap-3 rounded-lg border px-4 py-3 text-sm\"\n              >\n                <div className=\"size-2 rounded-full bg-primary\" />\n                <span className=\"flex-1 text-muted-foreground\">\n                  Activity event #{i + 1}\n                </span>\n                <span className=\"text-xs text-muted-foreground\">\n                  {i + 1}h ago\n                </span>\n              </div>\n            ))}\n          </div>\n        ),\n      },\n      {\n        value: \"team\",\n        label: \"Team\",\n        icon: Users,\n        count: 5,\n        content: (\n          <div className=\"flex flex-col gap-3 pt-4\">\n            {[\n              { name: \"Alice\", role: \"Designer\" },\n              { name: \"Bob\", role: \"Developer\" },\n              { name: \"Carol\", role: \"PM\" },\n            ].map((member) => (\n              <div\n                key={member.name}\n                className=\"flex items-center gap-3 rounded-lg border px-4 py-3 text-sm\"\n              >\n                <div className=\"flex size-8 items-center justify-center rounded-full bg-muted text-xs font-medium\">\n                  {member.name[0]}\n                </div>\n                <div>\n                  <p className=\"font-medium\">{member.name}</p>\n                  <p className=\"text-xs text-muted-foreground\">{member.role}</p>\n                </div>\n              </div>\n            ))}\n          </div>\n        ),\n      },\n      {\n        value: \"alerts\",\n        label: \"Alerts\",\n        icon: Zap,\n        count: 12,\n        content: (\n          <ContentPanel>\n            12 active alerts requiring attention across your projects.\n          </ContentPanel>\n        ),\n      },\n    ]\n\n    return (\n      <Tabs\n        items={items}\n        defaultValue=\"overview\"\n        variant=\"pill\"\n        size=\"md\"\n        className=\"max-w-2xl\"\n      />\n    )\n  },",
          "code": "<Tabs\n        items={items}\n        defaultValue=\"overview\"\n        variant=\"pill\"\n        size=\"md\"\n        className=\"max-w-2xl\"\n      />"
        }
      ]
    },
    {
      "name": "ds-tag-input",
      "title": "Tag Input",
      "description": "Input field that converts typed text into removable tags or pills.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/tag-input",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "badge",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/tag-input.tsx"
      ],
      "props": [
        {
          "name": "value",
          "required": true,
          "type": "string[]"
        },
        {
          "name": "onChange",
          "required": true,
          "type": "(tags: string[]) => void"
        },
        {
          "name": "maxTags",
          "required": false,
          "type": "number"
        },
        {
          "name": "allowDuplicates",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "separator",
          "required": false,
          "type": "string | RegExp | (string | RegExp)[]"
        },
        {
          "name": "placeholder",
          "required": false,
          "type": "string"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "invalid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    value: [],\n    placeholder: \"Digite tags e aperte Enter\",\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{\n    value: [\"React\", \"Next.js\"],\n  },"
        },
        {
          "name": "MaxTags",
          "description": "",
          "args": "{\n    value: [\"Design\", \"System\"],\n    maxTags: 3,\n    placeholder: \"Máximo 3 tags\",\n  },"
        },
        {
          "name": "WithInitialValues",
          "description": "",
          "args": "{\n    value: [\"Frontend\", \"Backend\", \"Fullstack\", \"DevOps\", \"UX\", \"UI\", \"QA\"],\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    value: [\"Inativo\", \"Não clicável\"],\n    disabled: true,\n  },"
        },
        {
          "name": "Invalid",
          "description": "",
          "args": "{\n    value: [\"Erro\"],\n    invalid: true,\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    loading: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-team-card",
      "title": "Team Card",
      "description": "Card de membro com avatar, cargo e bio — átomo base Team.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/team-card",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "avatar",
        "skeleton"
      ],
      "files": [
        "components/ds/team-card.tsx"
      ],
      "props": [
        {
          "name": "name",
          "required": true,
          "type": "string"
        },
        {
          "name": "role",
          "required": false,
          "type": "string"
        },
        {
          "name": "bio",
          "required": false,
          "type": "string"
        },
        {
          "name": "avatarUrl",
          "required": false,
          "type": "string"
        },
        {
          "name": "socials",
          "required": false,
          "type": "SocialLinkItem[]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Team/TeamCard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    name: \"Ana Silva\",\n    role: \"Design Lead\",\n    bio: \"Building design systems at LEMA.\",\n    avatarUrl: \"https://picsum.photos/200/200\",\n    socials: [{ platform: \"github\", href: \"https://github.com\" }],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ name: \"x\", loading: true }"
        }
      ]
    },
    {
      "name": "ds-team-grid",
      "title": "Team Grid",
      "description": "Grid de equipe com heading — blockus Team.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/team-grid",
      "dependencies": [],
      "registryDependencies": [
        "ds-team-card",
        "ui-i18n"
      ],
      "files": [
        "components/ds/team-grid.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "members",
          "required": true,
          "type": "TeamMember[]"
        },
        {
          "name": "columns",
          "required": false,
          "type": "3 | 4"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Team/TeamGrid",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ members }"
        },
        {
          "name": "FourCols",
          "description": "",
          "args": "{ members, columns: 4 }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ members, loading: true }"
        }
      ]
    },
    {
      "name": "ds-team-roster",
      "title": "TeamRoster",
      "description": "Grid de apresentação de equipe, pesquisadores e colaboradores institucionais.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/team-roster",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "avatar",
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/team-roster.tsx"
      ],
      "props": [
        {
          "name": "columns",
          "required": false,
          "type": "TeamRosterColumns"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/TeamRoster",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<TeamRoster columns={4}>\n      {members.map((member) => (\n        <TeamRosterCard key={member.name} {...member} social={social} />\n      ))}\n    </TeamRoster>"
        },
        {
          "name": "TwoColumns",
          "description": "",
          "code": "<TeamRoster columns={2}>\n      {members.map((member) => (\n        <TeamRosterCard key={member.name} {...member} social={social} />\n      ))}\n    </TeamRoster>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<TeamRoster columns={4}>\n      {Array.from({ length: 4 }).map((_, index) => (\n        <TeamRosterCard key={index} name=\"\" loading />\n      ))}\n    </TeamRoster>"
        }
      ]
    },
    {
      "name": "ds-team-switcher",
      "title": "Team Switcher",
      "description": "Seletor de equipe para sidebar com DropdownMenu, logo, plano e atalho — inspirado em shadcn sidebar-07 TeamSwitcher.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/team-switcher",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "sidebar",
        "dropdown-menu",
        "skeleton",
        "ui-i18n"
      ],
      "files": [
        "components/ds/team-switcher.tsx"
      ],
      "props": [
        {
          "name": "teams",
          "required": true,
          "type": "TeamSwitcherTeam[]"
        },
        {
          "name": "defaultTeam",
          "required": false,
          "type": "string"
        },
        {
          "name": "onTeamChange",
          "required": false,
          "type": "(team: TeamSwitcherTeam) => void"
        },
        {
          "name": "onAddTeam",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ teams },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ teams, loading: true },"
        },
        {
          "name": "AllLocales",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      {([\"pt-BR\", \"en-US\", \"es-ES\", \"fr-FR\"] as const).map((locale) => (\n        <SidebarProvider key={locale}>\n          <div className=\"w-64 border bg-sidebar p-2\">\n            <TeamSwitcher teams={teams} locale={locale} />\n            <span className=\"mt-1 block text-xs text-muted-foreground\">\n              {locale}\n            </span>\n          </div>\n        </SidebarProvider>\n      ))}\n    </div>"
        },
        {
          "name": "Interaction",
          "description": "",
          "args": "{ teams },\n  parameters: { a11y: { disable: true } },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    const btn = canvas.getByRole(\"button\")\n    await expect(btn).toBeInTheDocument()\n    await userEvent.click(btn)\n    const menu = await within(document.body).findByText(\"Acme Corp.\")\n    await expect(menu).toBeInTheDocument()\n  },"
        }
      ]
    },
    {
      "name": "ds-testimonial-card",
      "title": "Testimonial Card",
      "description": "Card depoimento com quote e rating — átomo base Testimonials.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/testimonial-card",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "avatar",
        "skeleton"
      ],
      "files": [
        "components/ds/testimonial-card.tsx"
      ],
      "props": [
        {
          "name": "quote",
          "required": true,
          "type": "string"
        },
        {
          "name": "author",
          "required": true,
          "type": "{ name: string; avatarUrl?: string; role?: string }"
        },
        {
          "name": "rating",
          "required": false,
          "type": "number"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Testimonials/TestimonialCard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    quote: \"LEMA DS accelerated our delivery by 3x.\",\n    author: { name: \"João Costa\", role: \"CTO\" },\n    rating: 5,\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ quote: \"x\", author: { name: \"x\" }, loading: true },"
        }
      ]
    },
    {
      "name": "ds-testimonials",
      "title": "Testimonials",
      "description": "Grid de depoimentos 2-3 cols — blockus Testimonials.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/testimonials",
      "dependencies": [],
      "registryDependencies": [
        "ds-testimonial-card",
        "ui-i18n"
      ],
      "files": [
        "components/ds/testimonials.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "description",
          "required": false,
          "type": "string"
        },
        {
          "name": "items",
          "required": true,
          "type": "TestimonialCardProps[]"
        },
        {
          "name": "columns",
          "required": false,
          "type": "2 | 3"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Testimonials/Testimonials",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items }"
        },
        {
          "name": "TwoCols",
          "description": "",
          "args": "{ items: items.slice(0, 2), columns: 2 }"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ items, loading: true }"
        }
      ]
    },
    {
      "name": "ds-text-rotator",
      "title": "TextRotator",
      "description": "Alternador animado de palavras-chave para headlines de destaque com suporte a acessibilidade e prefers-reduced-motion.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/text-rotator",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/text-rotator.tsx"
      ],
      "props": [
        {
          "name": "words",
          "required": true,
          "type": "string[]"
        },
        {
          "name": "interval",
          "required": false,
          "type": "number"
        },
        {
          "name": "pauseOnHover",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "transition",
          "required": false,
          "type": "\"slide\" | \"fade\"",
          "options": [
            "slide",
            "fade"
          ],
          "default": "slide"
        }
      ],
      "storyTitle": "Data Display/TextRotator",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    words: [\"inovadores\", \"acessíveis\", \"escaláveis\", \"consistentes\"],\n    interval: 2500,\n    transition: \"slide\",\n  },"
        },
        {
          "name": "FadeTransition",
          "description": "",
          "args": "{\n    words: [\n      \"desenvolvedores\",\n      \"designers\",\n      \"gerentes de produto\",\n      \"pesquisadores\",\n    ],\n    interval: 2000,\n    transition: \"fade\",\n  },"
        },
        {
          "name": "InHeadline",
          "description": "",
          "args": "{\n    words: [\"mais rápidos\", \"acessíveis\", \"modernos\", \"robustos\"],\n  },\n  render: () => (\n    <div className=\"max-w-xl py-6 text-center\">\n      <h1 className=\"text-3xl font-bold tracking-tight text-foreground sm:text-4xl\">\n        Crie produtos digitais{\" \"}\n        <TextRotator\n          words={[\"mais rápidos\", \"acessíveis\", \"modernos\", \"robustos\"]}\n          interval={2500}\n        />\n        <br />\n        para toda a universidade.\n      </h1>\n      <p className=\"mt-4 text-sm text-muted-foreground\">\n        Passe o mouse sobre a palavra em destaque para pausar a rotação\n        automática.\n      </p>\n    </div>\n  ),",
          "code": "<div className=\"max-w-xl py-6 text-center\">\n      <h1 className=\"text-3xl font-bold tracking-tight text-foreground sm:text-4xl\">\n        Crie produtos digitais{\" \"}\n        <TextRotator\n          words={[\"mais rápidos\", \"acessíveis\", \"modernos\", \"robustos\"]}\n          interval={2500}\n        />\n        <br />\n        para toda a universidade.\n      </h1>\n      <p className=\"mt-4 text-sm text-muted-foreground\">\n        Passe o mouse sobre a palavra em destaque para pausar a rotação\n        automática.\n      </p>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-text-scramble",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/text-scramble",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "components/ds/text-scramble.tsx"
      ],
      "props": [
        {
          "name": "children",
          "required": true,
          "type": "string",
          "description": "Texto a ser animado e revelado"
        },
        {
          "name": "characters",
          "required": false,
          "type": "string",
          "description": "Caracteres usados para o embaralhamento"
        },
        {
          "name": "speed",
          "required": false,
          "type": "number",
          "description": "Velocidade (ms) entre os frames"
        },
        {
          "name": "trigger",
          "required": false,
          "type": "boolean",
          "description": "Gatilho para (re)iniciar a animação. Dispara quando o valor muda."
        },
        {
          "name": "asChild",
          "required": false,
          "type": "boolean",
          "description": "Usar o elemento filho sem criar wrapper adicional"
        }
      ],
      "storyTitle": "Delight/TextScramble",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    children: \"SISTEMA DESBLOQUEADO\",\n    className: \"text-4xl font-mono font-bold tracking-widest text-primary\",\n  },"
        },
        {
          "name": "Trigger",
          "description": "",
          "args": "{\n    children: \"Hover para decodificar...\",\n  },"
        }
      ]
    },
    {
      "name": "ds-ticker",
      "title": "Ticker",
      "description": "Faixa financeira scroll — adaptado Kibo.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/ticker",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/ticker.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "TickerItem[]"
        },
        {
          "name": "speed",
          "required": false,
          "type": "\"slow\" | \"normal\" | \"fast\""
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\"",
          "options": [
            "sm",
            "md"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Data Display/Ticker",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ items }"
        }
      ]
    },
    {
      "name": "ds-tilt-card",
      "title": "Tilt Card",
      "description": "Card 3D com tilt no mousemove, glare radial e fallback prefers-reduced-motion — inspirado em Aceternity 3D Card + Wobble Card.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/tilt-card",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "card",
        "skeleton"
      ],
      "files": [
        "components/ds/tilt-card.tsx"
      ],
      "props": [
        {
          "name": "glare",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "intensity",
          "required": false,
          "type": "number"
        },
        {
          "name": "scaleOnHover",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"muted\" | \"ghost\"",
          "options": [
            "default",
            "muted",
            "ghost"
          ],
          "default": "default"
        },
        {
          "name": "radius",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\" | \"xl\"",
          "options": [
            "sm",
            "md",
            "lg",
            "xl"
          ],
          "default": "xl"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{ variant: \"default\", radius: \"xl\", glare: true, intensity: 12 },"
        },
        {
          "name": "Muted",
          "description": "",
          "code": "<TiltCard variant=\"muted\" className=\"w-80 p-6\">\n      <h3 className=\"text-base font-semibold\">Sem camisa, sem sapatos</h3>\n      <p className=\"mt-2 text-sm text-muted-foreground\">\n        Se alguém gritar “pare!”, a luta termina.\n      </p>\n    </TiltCard>"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ loading: true },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"grid gap-4 md:grid-cols-3\">\n      {([\"default\", \"muted\", \"ghost\"] as const).map((v) => (\n        <TiltCard key={v} variant={v} className=\"p-6\">\n          <h3 className=\"text-sm font-semibold\">{v}</h3>\n          <p className=\"mt-1 text-xs text-muted-foreground\">\n            Hover para tilt 3D + glare\n          </p>\n        </TiltCard>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-time-picker",
      "title": "Time Picker",
      "description": "A time picker input.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/time-picker",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "input",
        "skeleton"
      ],
      "files": [
        "components/ds/time-picker.tsx"
      ],
      "props": [
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "invalid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Form/TimePicker",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Sizes",
          "description": "The component supports `sm`, `md`, and `lg` sizes."
        },
        {
          "name": "Invalid",
          "description": "Set `invalid` to true to apply error styling.",
          "args": "{\n    invalid: true,\n    defaultValue: \"25:99\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Set `invalid` to true to apply error styling.\",\n      },\n    },\n  },"
        },
        {
          "name": "Disabled",
          "description": "Set `disabled` to true to disable interactions.",
          "args": "{\n    disabled: true,\n    defaultValue: \"10:00\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Set `disabled` to true to disable interactions.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "Set `loading` to true to render skeleton placeholders.",
          "args": "{\n    loading: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"Set `loading` to true to render skeleton placeholders.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-timeline",
      "title": "Timeline",
      "description": "Exibe uma lista de eventos conectados por uma linha vertical.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/timeline",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/timeline.tsx"
      ],
      "props": [
        {
          "name": "status",
          "required": false,
          "type": "\"default\" | \"primary\" | \"success\" | \"warning\" | \"destructive\"",
          "options": [
            "default",
            "primary",
            "success",
            "warning",
            "destructive"
          ],
          "default": "default"
        },
        {
          "name": "solid",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "storyTitle": "Data Display/Timeline",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<Timeline>\n      <TimelineItem>\n        <TimelineSeparator>\n          <TimelineDot />\n          <TimelineConnector />\n        </TimelineSeparator>\n        <TimelineContent>\n          <h4 className=\"font-medium\">Pedido recebido</h4>\n          <p className=\"text-sm text-muted-foreground\">\n            O pedido foi recebido no sistema.\n          </p>\n          <span className=\"text-xs text-muted-foreground\">10:00 AM</span>\n        </TimelineContent>\n      </TimelineItem>\n      <TimelineItem>\n        <TimelineSeparator>\n          <TimelineDot />\n          <TimelineConnector />\n        </TimelineSeparator>\n        <TimelineContent>\n          <h4 className=\"font-medium\">Em processamento</h4>\n          <p className=\"text-sm text-muted-foreground\">\n            O pedido está sendo separado no estoque.\n          </p>\n          <span className=\"text-xs text-muted-foreground\">11:30 AM</span>\n        </TimelineContent>\n      </TimelineItem>\n      <TimelineItem>\n        <TimelineSeparator>\n          <TimelineDot />\n        </TimelineSeparator>\n        <TimelineContent>\n          <h4 className=\"font-medium\">Enviado</h4>\n          <p className=\"text-sm text-muted-foreground\">\n            O pedido está a caminho.\n          </p>\n          <span className=\"text-xs text-muted-foreground\">02:15 PM</span>\n        </TimelineContent>\n      </TimelineItem>\n    </Timeline>"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-8\">\n      <div>\n        <h3 className=\"mb-2 text-sm font-medium text-muted-foreground\">\n          Outline (solid=false)\n        </h3>\n        <Timeline>\n          {STATUSES.map((status, i) => (\n            <TimelineItem key={status}>\n              <TimelineSeparator>\n                <TimelineDot status={status} />\n                {i < STATUSES.length - 1 && <TimelineConnector />}\n              </TimelineSeparator>\n              <TimelineContent>\n                <h4 className=\"font-medium capitalize\">{status}</h4>\n              </TimelineContent>\n            </TimelineItem>\n          ))}\n        </Timeline>\n      </div>\n      <div>\n        <h3 className=\"mb-2 text-sm font-medium text-muted-foreground\">\n          Solid (solid=true)\n        </h3>\n        <Timeline>\n          {STATUSES.map((status, i) => (\n            <TimelineItem key={status}>\n              <TimelineSeparator>\n                <TimelineDot status={status} solid />\n                {i < STATUSES.length - 1 && <TimelineConnector />}\n              </TimelineSeparator>\n              <TimelineContent>\n                <h4 className=\"font-medium capitalize\">{status}</h4>\n              </TimelineContent>\n            </TimelineItem>\n          ))}\n        </Timeline>\n      </div>\n    </div>"
        },
        {
          "name": "WithIcons",
          "description": "",
          "code": "<Timeline>\n      <TimelineItem>\n        <TimelineSeparator>\n          <TimelineDot\n            status=\"success\"\n            className=\"size-6 border-none bg-success text-success-foreground\"\n          >\n            <CheckIcon className=\"size-3\" />\n          </TimelineDot>\n          <TimelineConnector />\n        </TimelineSeparator>\n        <TimelineContent>\n          <h4 className=\"mt-0.5 font-medium\">Sucesso</h4>\n          <p className=\"text-sm text-muted-foreground\">\n            Aprovado pelo sistema.\n          </p>\n        </TimelineContent>\n      </TimelineItem>\n      <TimelineItem>\n        <TimelineSeparator>\n          <TimelineDot\n            status=\"warning\"\n            className=\"size-6 border-none bg-warning text-warning-foreground\"\n          >\n            <AlertTriangleIcon className=\"size-3\" />\n          </TimelineDot>\n          <TimelineConnector />\n        </TimelineSeparator>\n        <TimelineContent>\n          <h4 className=\"mt-0.5 font-medium\">Aviso</h4>\n          <p className=\"text-sm text-muted-foreground\">\n            Requer atenção manual.\n          </p>\n        </TimelineContent>\n      </TimelineItem>\n      <TimelineItem>\n        <TimelineSeparator>\n          <TimelineDot className=\"size-6 border-none bg-muted text-muted-foreground\">\n            <InfoIcon className=\"size-3\" />\n          </TimelineDot>\n        </TimelineSeparator>\n        <TimelineContent>\n          <h4 className=\"mt-0.5 font-medium\">Informação</h4>\n          <p className=\"text-sm text-muted-foreground\">Apenas para registro.</p>\n        </TimelineContent>\n      </TimelineItem>\n    </Timeline>"
        }
      ]
    },
    {
      "name": "ds-toggle-theme",
      "title": "Toggle Theme",
      "description": "A dropdown button to switch between light, dark, and system themes. Re-exports ThemeProvider for app-level setup.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/toggle-theme",
      "dependencies": [
        "lucide-react",
        "next-themes"
      ],
      "registryDependencies": [
        "button",
        "dropdown-menu",
        "ui-i18n"
      ],
      "files": [
        "components/ds/toggle-theme.tsx"
      ],
      "storyTitle": "Actions/ToggleTheme",
      "props": [
        {
          "name": "locale",
          "control": "inline-radio",
          "options": [
            "en-US",
            "pt-BR",
            "es-ES",
            "fr-FR"
          ],
          "description": "Locale for menu item and trigger labels",
          "default": "en-US"
        },
        {
          "name": "loading",
          "control": "boolean",
          "default": "false"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Default theme toggle with system/light/dark options and English labels.",
          "args": "{\n    locale: \"en-US\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default theme toggle with system/light/dark options and English labels.\",\n      },\n    },\n  },"
        },
        {
          "name": "Portuguese",
          "description": "Portuguese (pt-BR) labels for theme options — Claro, Escuro, and Sistema.",
          "args": "{\n    locale: \"pt-BR\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Portuguese (pt-BR) labels for theme options — Claro, Escuro, and Sistema.\",\n      },\n    },\n  },"
        },
        {
          "name": "InHeader",
          "description": "Theme toggle rendered inside a mock header layout with navigation links."
        }
      ]
    },
    {
      "name": "ds-tracing-beam",
      "title": "Tracing Beam",
      "description": "Feixe vertical que acompanha o scroll com thumb e gradiente — inspirado em Aceternity Tracing Beam.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/tracing-beam",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/tracing-beam.tsx"
      ],
      "props": [
        {
          "name": "beamColor",
          "required": false,
          "type": "string"
        },
        {
          "name": "inset",
          "required": false,
          "type": "\"true\" | \"false\"",
          "options": [
            "true",
            "false"
          ]
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "",
          "code": "<div className=\"py-10\">\n      <TracingBeam>\n        <TracingBeamItem>\n          <h3 className=\"text-base font-semibold\">React</h3>\n          <p className=\"text-sm text-muted-foreground\">\n            Minim proident non nisi velit non consectetur. Esse adipisicing\n            laboris consectetur enim ipsum.\n          </p>\n          {/* eslint-disable-next-line @next/next/no-img-element */}\n          <img\n            src=\"https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?auto=format&fit=crop&q=80&w=800\"\n            alt=\"Paisagem\"\n            loading=\"lazy\"\n            decoding=\"async\"\n            className=\"rounded-lg\"\n          />\n        </TracingBeamItem>\n        <TracingBeamItem>\n          <h3 className=\"text-base font-semibold\">Changelog</h3>\n          <p className=\"text-sm text-muted-foreground\">\n            Ex irure dolore veniam ex velit non aute nisi labore ipsum occaecat\n            deserunt cupidatat.\n          </p>\n        </TracingBeamItem>\n        <TracingBeamItem>\n          <h3 className=\"text-base font-semibold\">Launch Week</h3>\n          <p className=\"text-sm text-muted-foreground\">\n            In dolore veniam excepteur eu est et sunt velit. Ipsum sint esse\n            veniam fugiat.\n          </p>\n        </TracingBeamItem>\n      </TracingBeam>\n    </div>"
        },
        {
          "name": "WithoutInset",
          "description": "",
          "args": "{ inset: false },\n  render: (args) => (\n    <TracingBeam {...args}>\n      <TracingBeamItem>\n        <h3 className=\"text-sm font-semibold\">Item 1</h3>\n        <p className=\"text-sm text-muted-foreground\">\n          Conteúdo com inset false — sem padding lateral.\n        </p>\n      </TracingBeamItem>\n      <TracingBeamItem>\n        <h3 className=\"text-sm font-semibold\">Item 2</h3>\n        <p className=\"text-sm text-muted-foreground\">\n          Segundo bloco para testar progresso.\n        </p>\n      </TracingBeamItem>\n    </TracingBeam>\n  ),"
        }
      ]
    },
    {
      "name": "ds-transfer-list",
      "title": "Transfer List",
      "description": "Seleção entre dois conjuntos com busca, ações em lote e contadores.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/transfer-list",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "checkbox",
        "button",
        "input",
        "scroll-area",
        "ui-i18n"
      ],
      "files": [
        "components/ds/transfer-list.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "TransferListItem[]",
          "description": "Complete array of items."
        },
        {
          "name": "value",
          "required": true,
          "type": "string[]",
          "description": "IDs of items selected in the right panel."
        },
        {
          "name": "onChange",
          "required": true,
          "type": "(newValues: string[]) => void",
          "description": "Callback fired when item transfers occur."
        },
        {
          "name": "titles",
          "required": false,
          "type": "[string, string]",
          "description": "Panel titles [leftTitle, rightTitle]."
        },
        {
          "name": "searchable",
          "required": false,
          "type": "boolean",
          "description": "Enables search input inside each panel."
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean",
          "description": "Disables all interactions."
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale",
          "description": "Localization locale."
        }
      ],
      "storyTitle": "Form/TransferList",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    locale: \"pt-BR\",\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    const item = canvas.getByText(\"Taxa de Inflação\")\n    await expect(item).toBeInTheDocument()\n    await expect(canvas.getByText(\"PIB Per Capita\")).toBeInTheDocument()\n    await userEvent.click(item)\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    disabled: true,\n  },"
        },
        {
          "name": "Locales",
          "description": "",
          "code": "<div className=\"flex w-full max-w-2xl flex-col gap-6\">\n      <div>\n        <span className=\"block pb-1 text-xs font-semibold text-muted-foreground\">\n          pt-BR:\n        </span>\n        <InteractiveTransferList locale=\"pt-BR\" />\n      </div>\n      <div>\n        <span className=\"block pb-1 text-xs font-semibold text-muted-foreground\">\n          en-US:\n        </span>\n        <InteractiveTransferList locale=\"en-US\" />\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "ds-tree-view",
      "title": "Tree View",
      "description": "A hierarchical data display component.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/tree-view",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "collapsible"
      ],
      "files": [
        "components/ds/tree-view.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "TreeDataItem[]"
        },
        {
          "name": "onSelect",
          "required": false,
          "type": "(item: TreeDataItem) => void"
        },
        {
          "name": "selectedId",
          "required": false,
          "type": "string"
        },
        {
          "name": "defaultExpandedIds",
          "required": false,
          "type": "string[]"
        },
        {
          "name": "expandAll",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "className",
          "required": false,
          "type": "string"
        }
      ],
      "storyTitle": "Data Display/TreeView",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{},"
        },
        {
          "name": "Selected",
          "description": "",
          "args": "{\n    selectedId: \"tree-view\",\n    defaultExpandedIds: [\"components\", \"ds\"],\n  },"
        },
        {
          "name": "ExpandAll",
          "description": "",
          "args": "{\n    expandAll: true,\n  },"
        }
      ]
    },
    {
      "name": "ds-treemap-chart",
      "title": "Treemap Chart",
      "description": "A responsive treemap chart with hierarchical drill-down, breadcrumb navigation, and aspect ratio control.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/treemap-chart",
      "dependencies": [
        "recharts",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "skeleton",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/treemap-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "TreeMapItem[]"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "aspectRatio",
          "required": false,
          "type": "number"
        },
        {
          "name": "showLabels",
          "required": false,
          "type": "boolean",
          "description": "Show name + value labels inside each cell (hidden below size threshold)"
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string",
          "description": "Format the numeric value displayed in labels and tooltip"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show animated skeleton in place of the chart while data loads"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Data Display/TreeMapChart",
      "stories": [
        {
          "name": "Default",
          "description": "Flat treemap showing budget allocation percentages across five spending categories with labels and tooltips.",
          "args": "{\n    title: \"Budget Allocation\",\n    subtitle: \"Fiscal year 2025 — percentage of total\",\n    data: budgetAllocation,\n    height: 360,\n    aspectRatio: 4 / 3,\n    showLabels: true,\n    showTooltip: true,\n    loading: false,\n    locale: \"en-US\",\n    format: undefined,\n    decimals: 0,\n    abbreviate: false,\n    currency: undefined,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "Hierarchical",
          "description": "Multi-level treemap of enrollment by school with click-to-explore drill-down into individual programs.",
          "args": "{\n    title: \"Enrollment by School\",\n    subtitle: \"Click any school to explore its programs\",\n    data: enrollmentBySchool,\n    showLabels: true,\n    showTooltip: true,\n    height: 420,\n    valueFormatter: (v) => formatValue(v, \"integer\"),\n  },"
        },
        {
          "name": "CustomColors",
          "description": "Treemap using semantic color tokens for approved, recovering, and failing student status categories.",
          "args": "{\n    title: \"Course Completion Rate\",\n    subtitle:\n      \"Semantic tokens: var(--chart-2), var(--chart-3), var(--destructive)\",\n    data: performanceByDept,\n    showLabels: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },"
        },
        {
          "name": "NoLabels",
          "description": "Treemap with labels hidden, relying entirely on tooltip interaction for identifying research output categories.",
          "args": "{\n    title: \"Research Output\",\n    subtitle: \"Hover cells to see details — labels hidden\",\n    data: researchOutput,\n    showLabels: false,\n    showTooltip: true,\n    height: 300,\n  },"
        },
        {
          "name": "DenseData",
          "description": "Treemap displaying seven research output categories where labels only appear on larger cells to avoid overcrowding.",
          "args": "{\n    title: \"Research Output by Type\",\n    subtitle: \"Many categories — labels appear only on larger cells\",\n    data: researchOutput,\n    showLabels: true,\n    showTooltip: true,\n    height: 320,\n  },"
        },
        {
          "name": "WideAspectRatio",
          "description": "Treemap with `aspectRatio={2}` producing wider, shorter cells for an alternative layout of budget allocation data.",
          "args": "{\n    title: \"Budget Allocation\",\n    subtitle: \"aspectRatio={2} — wider, shorter cells\",\n    data: budgetAllocation,\n    aspectRatio: 2,\n    showLabels: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n    height: 260,\n  },"
        },
        {
          "name": "WithFooter",
          "description": "Hierarchical treemap with a footer showing total enrollment, school count, and year-over-year growth percentage.",
          "args": "{\n    title: \"Enrollment by School\",\n    subtitle: \"Semester 2025.1 — 9,740 students total\",\n    data: enrollmentBySchool,\n    showLabels: true,\n    showTooltip: true,\n    height: 380,\n    valueFormatter: (v) => formatValue(v, \"integer\"),\n    footer: (\n      <div className=\"flex w-full items-center justify-between\">\n        <div className=\"flex items-center gap-4\">\n          <span className=\"flex items-center gap-1.5\">\n            <GraduationCap className=\"size-3.5 text-muted-foreground\" />\n            <span>9,740 enrolled</span>\n          </span>\n          <span className=\"flex items-center gap-1.5\">\n            <BookOpen className=\"size-3.5 text-muted-foreground\" />\n            <span>5 schools</span>\n          </span>\n        </div>\n        <span className=\"flex items-center gap-1.5 text-muted-foreground/70\">\n          <TrendingUp className=\"size-3 text-success\" />\n          +4.2% vs. 2024.2\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "FlatComparison",
          "description": "Grid of four treemaps comparing different aspect ratios and label visibility settings side by side for the same budget data.",
          "args": "{ data: budgetAllocation },",
          "code": "<div className=\"grid grid-cols-2 gap-6\">\n      <TreeMapChart\n        title=\"Budget Allocation\"\n        subtitle=\"aspectRatio={4/3} (default)\"\n        data={budgetAllocation}\n        aspectRatio={4 / 3}\n        showLabels\n        showTooltip\n        valueFormatter={(v) => `${v}%`}\n        height={260}\n      />\n      <TreeMapChart\n        title=\"Budget Allocation\"\n        subtitle=\"aspectRatio={1} — square grid\"\n        data={budgetAllocation}\n        aspectRatio={1}\n        showLabels\n        showTooltip\n        valueFormatter={(v) => `${v}%`}\n        height={260}\n      />\n      <TreeMapChart\n        title=\"Budget Allocation\"\n        subtitle=\"aspectRatio={2} — wide cells\"\n        data={budgetAllocation}\n        aspectRatio={2}\n        showLabels\n        showTooltip\n        valueFormatter={(v) => `${v}%`}\n        height={260}\n      />\n      <TreeMapChart\n        title=\"Budget Allocation\"\n        subtitle=\"showLabels={false} — tooltip only\"\n        data={budgetAllocation}\n        aspectRatio={4 / 3}\n        showLabels={false}\n        showTooltip\n        valueFormatter={(v) => `${v}%`}\n        height={260}\n      />\n    </div>"
        },
        {
          "name": "LocalePTBR",
          "description": "Treemap with Portuguese locale displaying budget allocation with localized percentage formatting.",
          "args": "{\n    title: \"Budget Allocation\",\n    subtitle: \"Fiscal year 2025 — percentage of total\",\n    data: budgetAllocation,\n    showLabels: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "Loading",
          "description": "Pass `loading={true}` to replace the treemap with an animated skeleton that mirrors the title, subtitle, and footer structure.",
          "args": "{\n    title: \"Budget Allocation\",\n    subtitle: \"Fiscal year 2025 — percentage of total\",\n    data: budgetAllocation,\n    showLabels: true,\n    showTooltip: true,\n    valueFormatter: (v) => formatValue(v, \"float\", { decimals: 0 }) + \"%\",\n  },\n  render: (args) => <LoadingDemo {...args} />,"
        },
        {
          "name": "EmptyState",
          "description": "When `data` is an empty array, the treemap renders a dashed-border placeholder while preserving the title and subtitle for context.",
          "args": "{\n    title: \"Budget Allocation\",\n    subtitle: \"Fiscal year 2025\",\n    data: [],\n    height: 360,\n  },"
        },
        {
          "name": "DrillDown",
          "description": "Hierarchical enrollment treemap with explicit breadcrumb navigation for drill-down exploration through schools and programs.",
          "args": "{ data: enrollmentBySchool },",
          "code": "<div className=\"flex w-full max-w-2xl flex-col gap-2\">\n      <p className=\"text-xs text-muted-foreground\">\n        Click any colored rectangle to drill into its sub-categories. Use the\n        breadcrumb at the top to navigate back.\n      </p>\n      <TreeMapChart\n        title=\"Enrollment by School & Program\"\n        subtitle=\"Click a school to see its programs\"\n        data={enrollmentBySchool}\n        showLabels\n        showTooltip\n        height={400}\n        valueFormatter={(v) => v.toLocaleString(\"en-US\")}\n        footer={\n          <span className=\"flex items-center gap-1.5\">\n            <Users className=\"size-3.5\" />\n            9,740 students across 5 schools · 20 programs\n          </span>\n        }\n      />\n    </div>"
        }
      ]
    },
    {
      "name": "ds-two-factor-auth",
      "title": "TwoFactorAuth",
      "description": "Desafio de autenticação em duas etapas (2FA) com suporte a código OTP de 6 dígitos e expiração.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/two-factor-auth",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "input-otp",
        "button",
        "checkbox",
        "label",
        "ui-i18n"
      ],
      "files": [
        "components/ds/two-factor-auth.tsx"
      ],
      "props": [
        {
          "name": "onVerify",
          "required": false,
          "type": "( code: string, trustDevice: boolean ) => Promise<boolean | void> | void"
        },
        {
          "name": "onResend",
          "required": false,
          "type": "() => Promise<void> | void"
        },
        {
          "name": "resendCooldown",
          "required": false,
          "type": "number"
        },
        {
          "name": "destination",
          "required": false,
          "type": "string"
        },
        {
          "name": "method",
          "required": false,
          "type": "\"authenticator\" | \"email\" | \"sms\""
        },
        {
          "name": "allowAlternative",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "onAlternativeMethod",
          "required": false,
          "type": "() => void"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"clean\"",
          "options": [
            "default",
            "clean"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Form/TwoFactorAuth",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    destination: \"estudante@ufpb.br\",\n    method: \"email\",\n    resendCooldown: 45,\n  },"
        },
        {
          "name": "AuthenticatorApp",
          "description": "",
          "args": "{\n    method: \"authenticator\",\n    destination: \"Google Authenticator\",\n    resendCooldown: 30,\n  },"
        },
        {
          "name": "CleanVariant",
          "description": "",
          "args": "{\n    variant: \"clean\",\n    destination: \"(83) 9****-9988\",\n    method: \"sms\",\n  },"
        }
      ]
    },
    {
      "name": "ds-typewriter",
      "title": "Typewriter",
      "description": "Texto com efeito typewriter/flip/generate, cursor piscante e suporte a reduced-motion — inspirado em Aceternity Text Generate + Typewriter + Flip Words.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/typewriter",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/typewriter.tsx"
      ],
      "props": [
        {
          "name": "words",
          "required": true,
          "type": "string[]"
        },
        {
          "name": "speed",
          "required": false,
          "type": "number"
        },
        {
          "name": "deleteSpeed",
          "required": false,
          "type": "number"
        },
        {
          "name": "delayBetween",
          "required": false,
          "type": "number"
        },
        {
          "name": "loop",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "cursor",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "cursorChar",
          "required": false,
          "type": "string"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"typewriter\" | \"flip\" | \"generate\"",
          "options": [
            "typewriter",
            "flip",
            "generate"
          ],
          "default": "typewriter"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\" | \"xl\" | \"display\"",
          "options": [
            "sm",
            "md",
            "lg",
            "xl",
            "display"
          ],
          "default": "md"
        }
      ],
      "stories": [
        {
          "name": "TypewriterEffect",
          "description": "",
          "args": "{\n    words: [\"Design System\", \"LEMA-DS\", \"UFPB\", \"Aceternity inspirado\"],\n    variant: \"typewriter\",\n    size: \"lg\",\n    loop: true,\n  },"
        },
        {
          "name": "FlipWords",
          "description": "",
          "args": "{\n    words: [\"rápido\", \"moderno\", \"acessível\", \"lindo\"],\n    variant: \"flip\",\n    size: \"display\",\n    loop: true,\n  },\n  render: (args) => (\n    <p className=\"text-xl\">\n      Construa produtos <Typewriter {...args} className=\"text-primary\" /> em\n      segundos\n    </p>\n  ),"
        },
        {
          "name": "GenerateEffect",
          "description": "",
          "args": "{\n    words: [\"O que este componente resolve? Quando usar vs alternativas?\"],\n    variant: \"generate\",\n    size: \"md\",\n    speed: 30,\n  },"
        },
        {
          "name": "WithoutCursor",
          "description": "",
          "args": "{\n    words: [\"Sem cursor\", \"Apenas texto\"],\n    variant: \"typewriter\",\n    cursor: false,\n  },"
        },
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-6\">\n      {([\"typewriter\", \"flip\", \"generate\"] as const).map((v) => (\n        <div key={v} className=\"flex flex-col gap-1\">\n          <span className=\"text-xs font-medium text-muted-foreground\">{v}</span>\n          <Typewriter words={[\"Hello\", \"World\", \"LEMA\"]} variant={v} />\n        </div>\n      ))}\n    </div>"
        }
      ]
    },
    {
      "name": "ds-users-table",
      "title": "Users Table",
      "description": "Tabela de usuários com avatar e status — ReUI Users.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/users-table",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "avatar",
        "badge",
        "skeleton"
      ],
      "files": [
        "components/ds/users-table.tsx"
      ],
      "props": [
        {
          "name": "users",
          "required": true,
          "type": "UserRow[]"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Data Display/UsersTable",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    users: [\n      {\n        name: \"Ana Silva\",\n        email: \"ana@ufpb.br\",\n        role: \"Admin\",\n        status: \"active\",\n      },\n    ],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ users: [], loading: true }"
        }
      ]
    },
    {
      "name": "ds-values-card",
      "title": "Values Card",
      "description": "Cartão atômico de princípio ou valor institucional com ícone, índice ordinal e variantes.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/values-card",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ds/values-card.tsx"
      ],
      "props": [
        {
          "name": "title",
          "required": true,
          "type": "string"
        },
        {
          "name": "description",
          "required": true,
          "type": "string"
        },
        {
          "name": "icon",
          "required": false,
          "type": "React.ComponentType<{ className?: string }>"
        },
        {
          "name": "index",
          "required": false,
          "type": "string | number"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"outline\" | \"accent\" | \"muted\"",
          "options": [
            "default",
            "outline",
            "accent",
            "muted"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "AllVariants",
          "description": "",
          "code": "<div className=\"grid max-w-4xl grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n      <ValuesCard\n        title=\"Default\"\n        description=\"Borda suave e cartão neutro elevado com hover sutil.\"\n        icon={Sparkles}\n        index=\"01\"\n        variant=\"default\"\n      />\n      <ValuesCard\n        title=\"Outline\"\n        description=\"Fundo transparente e borda delineada com contraste moderado.\"\n        icon={Shield}\n        index=\"02\"\n        variant=\"outline\"\n      />\n      <ValuesCard\n        title=\"Accent\"\n        description=\"Superfície sutilmente tingida pela cor primária do tema.\"\n        icon={Heart}\n        index=\"03\"\n        variant=\"accent\"\n      />\n      <ValuesCard\n        title=\"Muted\"\n        description=\"Fundo atenuado para hierarquia secundária ou repouso visual.\"\n        icon={Lightbulb}\n        index=\"04\"\n        variant=\"muted\"\n      />\n    </div>"
        },
        {
          "name": "WithIndex",
          "description": "",
          "args": "{\n    title: \"Inclusão e Acessibilidade\",\n    description:\n      \"Projetamos interfaces e sistemas abertos e acessíveis para toda a sociedade.\",\n    icon: Heart,\n    index: 5,\n    variant: \"accent\",\n  },"
        },
        {
          "name": "WithoutIcon",
          "description": "",
          "args": "{\n    title: \"Autonomia Acadêmica\",\n    description:\n      \"Pesquisa livre e dedicada à geração de conhecimento transformador.\",\n    icon: undefined,\n    index: \"03\",\n    variant: \"default\",\n  },"
        }
      ]
    },
    {
      "name": "ds-video-dialog",
      "title": "VideoDialog",
      "description": "Thumbnail de vídeo com overlay interativo, botão play pulsante e abertura de modal responsivo em Dialog.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/video-dialog",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "dialog",
        "ui-i18n"
      ],
      "files": [
        "components/ds/video-dialog.tsx"
      ],
      "props": [
        {
          "name": "videoSrc",
          "required": true,
          "type": "string"
        },
        {
          "name": "thumbnailSrc",
          "required": true,
          "type": "string"
        },
        {
          "name": "thumbnailAlt",
          "required": false,
          "type": "string"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "aspectRatio",
          "required": false,
          "type": "\"16/9\" | \"4/3\" | \"1/1\" | \"21/9\""
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"minimal\" | \"glow\"",
          "options": [
            "default",
            "minimal",
            "glow"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Media/VideoDialog",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    title: \"Apresentação do LEMA Design System\",\n    thumbnailSrc:\n      \"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=1200&auto=format&fit=crop&q=80\",\n    thumbnailAlt: \"Thumbnail com formas abstratas elegantes\",\n    videoSrc: \"https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ\",\n    variant: \"default\",\n    aspectRatio: \"16/9\",\n    locale: \"pt-BR\",\n  },\n  render: (args) => (\n    <div className=\"mx-auto max-w-2xl py-6\">\n      <VideoDialog {...args} />\n    </div>\n  ),"
        },
        {
          "name": "GlowVariant",
          "description": "",
          "args": "{\n    title: \"Visão Geral da Arquitetura de Componentes\",\n    thumbnailSrc:\n      \"https://images.unsplash.com/photo-1550745165-9bc0b252726f?w=1200&auto=format&fit=crop&q=80\",\n    videoSrc: \"https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ\",\n    variant: \"glow\",\n    aspectRatio: \"16/9\",\n  },\n  render: (args) => (\n    <div className=\"mx-auto max-w-2xl py-8\">\n      <VideoDialog {...args} />\n    </div>\n  ),"
        },
        {
          "name": "MinimalVariant",
          "description": "",
          "args": "{\n    title: \"Demo rápida de 30 segundos\",\n    thumbnailSrc:\n      \"https://images.unsplash.com/photo-1518770660439-4636190af475?w=1200&auto=format&fit=crop&q=80\",\n    videoSrc: \"https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ\",\n    variant: \"minimal\",\n    aspectRatio: \"16/9\",\n  },\n  render: (args) => (\n    <div className=\"mx-auto max-w-2xl py-6\">\n      <VideoDialog {...args} />\n    </div>\n  ),"
        }
      ]
    },
    {
      "name": "ds-virtual-list",
      "description": "Virtualized list for rendering large datasets without performance degradation.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/virtual-list",
      "dependencies": [
        "@tanstack/react-virtual"
      ],
      "registryDependencies": [
        "skeleton",
        "scroll-area"
      ],
      "files": [
        "components/ds/virtual-list.tsx"
      ],
      "props": [
        {
          "name": "items",
          "required": true,
          "type": "T[]"
        },
        {
          "name": "renderItem",
          "required": true,
          "type": "(item: T, index: number) => React.ReactNode",
          "description": "Render function for each item"
        },
        {
          "name": "estimateSize",
          "required": false,
          "type": "number",
          "description": "Estimated item height in px — used for initial layout, refined after measurement"
        },
        {
          "name": "overscan",
          "required": false,
          "type": "number",
          "description": "Number of extra items to render above and below the visible window"
        },
        {
          "name": "height",
          "required": false,
          "type": "number",
          "description": "Container height in px"
        },
        {
          "name": "size",
          "required": false,
          "type": "VirtualListSize"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean",
          "description": "Show skeleton rows while loading"
        },
        {
          "name": "loadingCount",
          "required": false,
          "type": "number",
          "description": "Number of skeleton rows to show when loading"
        },
        {
          "name": "emptyContent",
          "required": false,
          "type": "React.ReactNode",
          "description": "Empty state content — shown when items is empty and not loading"
        }
      ],
      "storyTitle": "Data Display/VirtualList",
      "stories": [
        {
          "name": "Default",
          "description": "10,000 items rendered virtually. Scroll smoothly.",
          "args": "{\n    items: ITEMS,\n    height: 400,\n    renderItem: (rawItem) => {\n      const item = rawItem as Item\n      return (\n        <div className=\"flex h-8 items-center gap-3 border-b border-border px-4 text-sm\">\n          <span className=\"w-12 font-mono text-xs text-muted-foreground tabular-nums\">\n            #{item.id}\n          </span>\n          <span className=\"flex-1 truncate font-medium\">{item.name}</span>\n          <span className=\"text-xs text-muted-foreground\">{item.category}</span>\n          <span className=\"w-16 text-right tabular-nums\">\n            {item.value.toLocaleString()}\n          </span>\n          <Badge variant={statusVariant[item.status]} className=\"shrink-0\">\n            {item.status}\n          </Badge>\n        </div>\n      )\n    },\n  },\n  parameters: {\n    docs: {\n      description: {\n        story: \"10,000 items rendered virtually. Scroll smoothly.\",\n      },\n    },\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    items: [],\n    loading: true,\n    height: 400,\n    loadingCount: 8,\n    renderItem: () => null,\n  },"
        },
        {
          "name": "EmptyState",
          "description": "",
          "args": "{\n    items: [],\n    height: 300,\n    renderItem: () => null,\n    emptyContent: (\n      <div className=\"flex flex-col items-center gap-1 text-center\">\n        <span className=\"text-sm font-medium text-foreground\">\n          No results found\n        </span>\n        <span className=\"text-xs text-muted-foreground\">\n          Try adjusting your filters\n        </span>\n      </div>\n    ),\n  },"
        },
        {
          "name": "AllSizes",
          "description": "",
          "args": "{\n    items: [],\n    renderItem: () => null,\n  },\n  render: () => (\n    <div className=\"grid grid-cols-3 gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <VirtualList\n          key={size}\n          items={generateItems(1000)}\n          size={size}\n          height={300}\n          renderItem={(rawItem) => {\n            const item = rawItem as Item\n            return (\n              <div\n                className={`flex items-center gap-2 border-b border-border px-3 ${\n                  size === \"sm\"\n                    ? \"h-7 text-xs\"\n                    : size === \"lg\"\n                      ? \"h-9 text-base\"\n                      : \"h-8 text-sm\"\n                }`}\n              >\n                <span className=\"truncate font-medium\">{item.name}</span>\n                <span className=\"ml-auto text-muted-foreground tabular-nums\">\n                  {item.value}\n                </span>\n              </div>\n            )\n          }}\n        />\n      ))}\n    </div>\n  ),",
          "code": "<div className=\"grid grid-cols-3 gap-4\">\n      {([\"sm\", \"md\", \"lg\"] as const).map((size) => (\n        <VirtualList\n          key={size}\n          items={generateItems(1000)}\n          size={size}\n          height={300}\n          renderItem={(rawItem) => {\n            const item = rawItem as Item\n            return (\n              <div\n                className={`flex items-center gap-2 border-b border-border px-3 ${\n                  size === \"sm\"\n                    ? \"h-7 text-xs\"\n                    : size === \"lg\"\n                      ? \"h-9 text-base\"\n                      : \"h-8 text-sm\"\n                }`}\n              >\n                <span className=\"truncate font-medium\">{item.name}</span>\n                <span className=\"ml-auto text-muted-foreground tabular-nums\">\n                  {item.value}\n                </span>\n              </div>\n            )\n          }}\n        />\n      ))}\n    </div>"
        },
        {
          "name": "FewItems",
          "description": "",
          "args": "{\n    items: generateItems(5),\n    height: 400,\n    renderItem: (rawItem) => {\n      const item = rawItem as Item\n      return (\n        <div className=\"flex h-8 items-center gap-3 border-b border-border px-4 text-sm\">\n          <span className=\"flex-1 font-medium\">{item.name}</span>\n          <Badge variant={statusVariant[item.status]}>{item.status}</Badge>\n        </div>\n      )\n    },\n  },"
        }
      ]
    },
    {
      "name": "ds-waitlist-form",
      "title": "WaitlistForm",
      "description": "Formulário inline de pré-lançamento ou lista de espera para heróis de landing pages com feedback visual.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/waitlist-form",
      "dependencies": [
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "input",
        "ui-i18n"
      ],
      "files": [
        "components/ds/waitlist-form.tsx"
      ],
      "props": [
        {
          "name": "onSubmit",
          "required": false,
          "type": "(email: string) => Promise<boolean | void> | void"
        },
        {
          "name": "socialProof",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        },
        {
          "name": "disabled",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "autoFocus",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"pill\" | \"floating\" | \"minimal\"",
          "options": [
            "default",
            "pill",
            "floating",
            "minimal"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"sm\" | \"md\" | \"lg\"",
          "options": [
            "sm",
            "md",
            "lg"
          ],
          "default": "md"
        }
      ],
      "storyTitle": "Auth/WaitlistForm",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    variant: \"default\",\n    size: \"md\",\n    locale: \"pt-BR\",\n  },"
        },
        {
          "name": "PillVariant",
          "description": "",
          "args": "{\n    variant: \"pill\",\n    size: \"md\",\n    socialProof:\n      \"🎉 Junte-se a mais de 1.200 desenvolvedores na lista de espera.\",\n  },"
        },
        {
          "name": "FloatingCard",
          "description": "",
          "args": "{\n    variant: \"floating\",\n    size: \"lg\",\n    socialProof:\n      \"🔒 Garantimos que seus dados não serão compartilhados com terceiros.\",\n  },"
        },
        {
          "name": "EnglishLocale",
          "description": "",
          "args": "{\n    locale: \"en-US\",\n    variant: \"pill\",\n  },"
        },
        {
          "name": "Disabled",
          "description": "",
          "args": "{\n    disabled: true,\n    variant: \"pill\",\n    socialProof: \"Inscrições temporariamente encerradas para a turma atual.\",\n  },"
        }
      ]
    },
    {
      "name": "ds-waterfall-chart",
      "description": "Waterfall chart for cumulative positive/negative value bridges.",
      "type": "registry:ui",
      "category": "ds",
      "importPath": "@/components/ds/waterfall-chart",
      "dependencies": [],
      "registryDependencies": [
        "chart",
        "skeleton",
        "card",
        "ui-i18n",
        "format-utils"
      ],
      "files": [
        "components/ds/waterfall-chart.tsx"
      ],
      "props": [
        {
          "name": "data",
          "required": true,
          "type": "WaterfallEntry[]"
        },
        {
          "name": "title",
          "required": false,
          "type": "string"
        },
        {
          "name": "subtitle",
          "required": false,
          "type": "string"
        },
        {
          "name": "footer",
          "required": false,
          "type": "React.ReactNode"
        },
        {
          "name": "height",
          "required": false,
          "type": "number"
        },
        {
          "name": "showGrid",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "showTooltip",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "valueFormatter",
          "required": false,
          "type": "(value: number) => string"
        },
        {
          "name": "format",
          "required": false,
          "type": "FormatPreset"
        },
        {
          "name": "decimals",
          "required": false,
          "type": "number"
        },
        {
          "name": "currency",
          "required": false,
          "type": "string"
        },
        {
          "name": "abbreviate",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        },
        {
          "name": "locale",
          "required": false,
          "type": "UILocale"
        }
      ],
      "storyTitle": "Charts/WaterfallChart",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    data: PNL_DATA,\n    title: \"P&L Waterfall\",\n    subtitle: \"Q3 2026 — income statement bridge\",\n    format: \"currency\",\n    currency: \"USD\",\n    abbreviate: true,\n    height: 360,\n  },"
        },
        {
          "name": "BudgetVariance",
          "description": "",
          "args": "{\n    data: [\n      { name: \"Budget\", value: 1200000, type: \"start\" as const },\n      { name: \"Extra Sales\", value: 85000, type: \"positive\" as const },\n      { name: \"Returns\", value: -23000, type: \"negative\" as const },\n      { name: \"New Costs\", value: -67000, type: \"negative\" as const },\n      { name: \"Savings\", value: 31000, type: \"positive\" as const },\n      { name: \"Actual\", value: 1226000, type: \"end\" as const },\n    ],\n    title: \"Budget Variance\",\n    subtitle: \"Planned vs Actual\",\n    format: \"currency\",\n    currency: \"BRL\",\n    abbreviate: true,\n    locale: \"pt-BR\",\n    height: 320,\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{\n    data: [],\n    title: \"P&L Waterfall\",\n    subtitle: \"Loading financial data…\",\n    loading: true,\n    height: 360,\n  },"
        },
        {
          "name": "EmptyData",
          "description": "",
          "args": "{\n    data: [],\n    title: \"Waterfall Chart\",\n    height: 320,\n  },"
        },
        {
          "name": "NoGrid",
          "description": "",
          "args": "{\n    data: PNL_DATA,\n    title: \"Clean P&L\",\n    showGrid: false,\n    format: \"currency\",\n    abbreviate: true,\n    height: 360,\n  },"
        }
      ]
    },
    {
      "name": "ds-wizard",
      "title": "Wizard",
      "description": "Wizard multi-step — ReUI Wizard 7.",
      "type": "registry:block",
      "category": "ds",
      "importPath": "@/components/ds/wizard",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "button",
        "progress",
        "skeleton"
      ],
      "files": [
        "components/ds/wizard.tsx"
      ],
      "props": [
        {
          "name": "steps",
          "required": true,
          "type": "WizardStep[]"
        },
        {
          "name": "currentId",
          "required": false,
          "type": "string"
        },
        {
          "name": "onStepChange",
          "required": false,
          "type": "(id: string) => void"
        },
        {
          "name": "loading",
          "required": false,
          "type": "boolean"
        }
      ],
      "storyTitle": "Onboarding/Wizard",
      "stories": [
        {
          "name": "Default",
          "description": "",
          "args": "{\n    steps: [\n      { id: \"1\", title: \"Account\", content: \"Form 1\" },\n      { id: \"2\", title: \"Details\", content: \"Form 2\" },\n    ],\n  },"
        },
        {
          "name": "Loading",
          "description": "",
          "args": "{ steps: [], loading: true }"
        }
      ]
    },
    {
      "name": "empty",
      "title": "Empty",
      "description": "A placeholder component for empty states with icon, title, description, and content slots.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/empty",
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/empty.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"icon\"",
          "options": [
            "default",
            "icon"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Empty",
      "stories": [
        {
          "name": "Default",
          "description": "Empty state with an inbox icon, title, and description prompting the user to create their first item.",
          "code": "<Empty>\n      <EmptyHeader>\n        <EmptyMedia variant=\"icon\">\n          <InboxIcon />\n        </EmptyMedia>\n        <EmptyTitle>No data yet</EmptyTitle>\n        <EmptyDescription>\n          Get started by creating your first item. It will appear here once\n          available.\n        </EmptyDescription>\n      </EmptyHeader>\n    </Empty>"
        },
        {
          "name": "WithContent",
          "description": "Empty state with an additional action link below the description for clearing filters or retrying.",
          "code": "<Empty>\n      <EmptyHeader>\n        <EmptyMedia variant=\"icon\">\n          <InboxIcon />\n        </EmptyMedia>\n        <EmptyTitle>No results found</EmptyTitle>\n        <EmptyDescription>\n          Try adjusting your search or filters to find what you are looking for.\n        </EmptyDescription>\n      </EmptyHeader>\n      <EmptyContent>\n        <button className=\"text-sm font-medium text-primary underline underline-offset-4 hover:text-primary/80\">\n          Clear Filters\n        </button>\n      </EmptyContent>\n    </Empty>"
        }
      ]
    },
    {
      "name": "field",
      "title": "Field",
      "description": "A form field wrapper with label, description, error messages, and horizontal/vertical orientation variants.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/field",
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "registryDependencies": [
        "label",
        "separator"
      ],
      "files": [
        "components/ui/field.tsx"
      ],
      "props": [
        {
          "name": "orientation",
          "required": false,
          "type": "\"vertical\" | \"horizontal\" | \"responsive\"",
          "options": [
            "vertical",
            "horizontal",
            "responsive"
          ],
          "default": "vertical"
        }
      ],
      "storyTitle": "Shadcn UI/Field",
      "stories": [
        {
          "name": "Default",
          "description": "Vertical field layout with a label, text input, and helper description text beneath the input.",
          "code": "<Field className=\"max-w-sm\">\n      <FieldLabel>Name</FieldLabel>\n      <FieldContent>\n        <Input placeholder=\"Enter your name\" />\n        <FieldDescription>Your full name as it appears on ID.</FieldDescription>\n      </FieldContent>\n    </Field>"
        },
        {
          "name": "Horizontal",
          "description": "Horizontal field orientation with the label positioned beside the input for inline form layouts.",
          "code": "<Field orientation=\"horizontal\" className=\"max-w-sm\">\n      <FieldLabel>Email</FieldLabel>\n      <FieldContent>\n        <Input type=\"email\" placeholder=\"you@example.com\" />\n      </FieldContent>\n    </Field>"
        },
        {
          "name": "WithError",
          "description": "Field displaying multiple validation errors with data-invalid state and aria-invalid on the input.",
          "code": "<Field className=\"max-w-sm\" data-invalid>\n      <FieldLabel>Password</FieldLabel>\n      <FieldContent>\n        <Input\n          type=\"password\"\n          defaultValue=\"abc\"\n          aria-invalid\n          aria-label=\"Password\"\n        />\n        <FieldError\n          errors={[\n            { message: \"Password must be at least 8 characters.\" },\n            { message: \"Password must contain a number.\" },\n          ]}\n        />\n      </FieldContent>\n    </Field>"
        },
        {
          "name": "FieldSetExample",
          "description": "Grouped fieldset with a legend title, separator between fields, and horizontal field layout.",
          "code": "<FieldSet className=\"max-w-md\">\n      <FieldLegend>Contact Information</FieldLegend>\n      <FieldGroup>\n        <Field orientation=\"horizontal\">\n          <FieldTitle>First Name</FieldTitle>\n          <FieldContent>\n            <Input placeholder=\"John\" />\n          </FieldContent>\n        </Field>\n        <FieldSeparator />\n        <Field orientation=\"horizontal\">\n          <FieldTitle>Last Name</FieldTitle>\n          <FieldContent>\n            <Input placeholder=\"Doe\" />\n          </FieldContent>\n        </Field>\n      </FieldGroup>\n    </FieldSet>"
        }
      ]
    },
    {
      "name": "format-utils",
      "title": "Format Utils",
      "description": "Shared formatting utilities including locale-aware number formatting via Intl.NumberFormat, value abbreviation (tri/bi/mi/mil, T/B/M/K), and format wrapper functions used by card-stats and chart components.",
      "type": "registry:lib",
      "category": "lib",
      "importPath": "@/lib/format-utils",
      "dependencies": [],
      "registryDependencies": [
        "ui-i18n"
      ],
      "files": [
        "lib/format-utils.ts"
      ]
    },
    {
      "name": "hover-card",
      "title": "Hover Card",
      "description": "A popover card that appears when hovering over a trigger element.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/hover-card",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/hover-card.tsx"
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Displays a profile card with avatar, name, role, and bio when hovering over the underlined trigger text.",
          "code": "<HoverCard>\n      <HoverCardTrigger asChild>\n        <span className=\"cursor-pointer text-sm font-medium underline underline-offset-4\">\n          Hover over me\n        </span>\n      </HoverCardTrigger>\n      <HoverCardContent className=\"w-80\">\n        <div className=\"flex items-start gap-3\">\n          <Avatar>\n            <AvatarImage src=\"https://github.com/example.png\" />\n            <AvatarFallback>JD</AvatarFallback>\n          </Avatar>\n          <div>\n            <p className=\"text-sm font-medium\">John Doe</p>\n            <p className=\"text-sm text-muted-foreground\">Software Engineer</p>\n            <p className=\"mt-2 text-xs text-muted-foreground\">\n              Building tools for the modern web.\n            </p>\n          </div>\n        </div>\n      </HoverCardContent>\n    </HoverCard>"
        }
      ]
    },
    {
      "name": "input",
      "title": "Input",
      "description": "A fundamental form text input element styling standard inputs such as text, passwords, emails, numbers, search bars, and files.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/input",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/input.tsx"
      ],
      "storyTitle": "Shadcn UI/Input",
      "props": [
        {
          "name": "type",
          "control": "select",
          "options": [
            "text",
            "password",
            "email",
            "number",
            "search",
            "tel",
            "url"
          ],
          "default": "text"
        },
        {
          "name": "disabled",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "placeholder",
          "control": "text",
          "default": ""
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Basic text input with a placeholder prompting the user to enter text.",
          "args": "{\n    placeholder: \"Enter text...\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Basic text input with a placeholder prompting the user to enter text.\",\n      },\n    },\n  },"
        },
        {
          "name": "Types",
          "description": "",
          "code": "<div className=\"flex w-full max-w-sm flex-col gap-4\">\n      <Input type=\"text\" placeholder=\"Text input\" aria-label=\"Text input\" />\n      <Input type=\"email\" placeholder=\"Email input\" aria-label=\"Email input\" />\n      <Input\n        type=\"password\"\n        placeholder=\"Password input\"\n        aria-label=\"Password input\"\n      />\n      <Input\n        type=\"number\"\n        placeholder=\"Number input\"\n        aria-label=\"Number input\"\n      />\n      <Input\n        type=\"search\"\n        placeholder=\"Search input\"\n        aria-label=\"Search input\"\n      />\n      <Input type=\"tel\" placeholder=\"Phone input\" aria-label=\"Phone input\" />\n      <Input type=\"url\" placeholder=\"URL input\" aria-label=\"URL input\" />\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "Input in a disabled state with a pre-filled value that cannot be modified.",
          "args": "{\n    disabled: true,\n    placeholder: \"Disabled input\",\n    value: \"Disabled value\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Input in a disabled state with a pre-filled value that cannot be modified.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithValue",
          "description": "",
          "args": "{\n    \"aria-label\": \"Filled input\",\n    value: \"Filled input value\",\n  },"
        },
        {
          "name": "Invalid",
          "description": "",
          "args": "{\n    \"aria-invalid\": true,\n    placeholder: \"Invalid input\",\n  },"
        },
        {
          "name": "File",
          "description": "",
          "args": "{\n    type: \"file\",\n    \"aria-label\": \"File input\",\n  },"
        }
      ]
    },
    {
      "name": "input-group",
      "title": "Input Group",
      "description": "An integrated form row that groups related inputs, text labels, prefix/suffix icons, keyboard shortcuts, and button actions.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/input-group",
      "dependencies": [
        "class-variance-authority",
        "cn"
      ],
      "registryDependencies": [
        "button",
        "input",
        "textarea"
      ],
      "files": [
        "components/ui/input-group.tsx"
      ],
      "props": [
        {
          "name": "align",
          "required": false,
          "type": "\"inline-start\" | \"inline-end\" | \"block-start\" | \"block-end\"",
          "options": [
            "inline-start",
            "inline-end",
            "block-start",
            "block-end"
          ],
          "default": "inline-start"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"xs\" | \"sm\" | \"icon-xs\" | \"icon-sm\"",
          "options": [
            "xs",
            "sm",
            "icon-xs",
            "icon-sm"
          ],
          "default": "xs"
        }
      ],
      "storyTitle": "Shadcn UI/InputGroup",
      "stories": [
        {
          "name": "Default",
          "description": "Basic input group wrapping a single input field without any addons or buttons attached.",
          "code": "<InputGroup>\n      <InputGroupInput placeholder=\"Enter text...\" />\n    </InputGroup>"
        },
        {
          "name": "WithAddon",
          "description": "",
          "code": "<div className=\"flex w-full max-w-sm flex-col gap-4\">\n      <InputGroup>\n        <InputGroupAddon>\n          <SearchIcon />\n        </InputGroupAddon>\n        <InputGroupInput placeholder=\"Search...\" />\n      </InputGroup>\n\n      <InputGroup>\n        <InputGroupInput placeholder=\"Email\" />\n        <InputGroupAddon align=\"inline-end\">\n          <MailIcon />\n        </InputGroupAddon>\n      </InputGroup>\n\n      <InputGroup>\n        <InputGroupAddon>\n          <UserIcon />\n        </InputGroupAddon>\n        <InputGroupInput placeholder=\"Username\" />\n        <InputGroupAddon align=\"inline-end\">@example.com</InputGroupAddon>\n      </InputGroup>\n    </div>"
        },
        {
          "name": "WithButton",
          "description": "",
          "code": "<div className=\"flex w-full max-w-sm flex-col gap-4\">\n      <InputGroup>\n        <InputGroupInput placeholder=\"Search...\" />\n        <InputGroupButton>\n          <SearchIcon data-icon=\"inline-start\" />\n          Search\n        </InputGroupButton>\n      </InputGroup>\n\n      <InputGroup>\n        <InputGroupButton aria-label=\"Search\">\n          <SearchIcon data-icon=\"inline-start\" />\n        </InputGroupButton>\n        <InputGroupInput placeholder=\"Icon only\" />\n      </InputGroup>\n\n      <InputGroup>\n        <InputGroupInput placeholder=\"Password\" type=\"password\" />\n        <InputGroupButton\n          variant=\"ghost\"\n          aria-label=\"Toggle password visibility\"\n        >\n          <EyeIcon />\n        </InputGroupButton>\n      </InputGroup>\n    </div>"
        },
        {
          "name": "WithText",
          "description": "",
          "code": "<div className=\"flex w-full max-w-sm flex-col gap-4\">\n      <InputGroup>\n        <InputGroupAddon>\n          <SearchIcon />\n        </InputGroupAddon>\n        <InputGroupInput placeholder=\"Search...\" />\n        <InputGroupText>Go</InputGroupText>\n      </InputGroup>\n\n      <InputGroup>\n        <InputGroupText>$</InputGroupText>\n        <InputGroupInput type=\"number\" placeholder=\"0.00\" />\n        <InputGroupText>.00</InputGroupText>\n      </InputGroup>\n    </div>"
        },
        {
          "name": "BlockAddon",
          "description": "",
          "code": "<InputGroup>\n      <InputGroupAddon align=\"block-start\">First Name</InputGroupAddon>\n      <InputGroupInput placeholder=\"John\" />\n      <InputGroupAddon align=\"block-end\">Last Name</InputGroupAddon>\n      <InputGroupInput placeholder=\"Doe\" />\n    </InputGroup>"
        },
        {
          "name": "Disabled",
          "description": "",
          "code": "<div className=\"flex w-full max-w-sm flex-col gap-4\">\n      <InputGroup>\n        <InputGroupAddon>\n          <SearchIcon />\n        </InputGroupAddon>\n        <InputGroupInput disabled placeholder=\"Disabled input\" />\n      </InputGroup>\n    </div>"
        }
      ]
    },
    {
      "name": "input-otp",
      "title": "Input Otp",
      "description": "A one-time password input with individual slot groups and separators.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/input-otp",
      "dependencies": [
        "cn",
        "input-otp",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/input-otp.tsx"
      ],
      "storyTitle": "Shadcn UI/Input OTP",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Six-character OTP input split into two groups of three slots separated by a visual divider.",
          "args": "{ maxLength: 6 } as any,\n  render: () => (\n    <InputOTP maxLength={6} aria-label=\"One-time password\">\n      <InputOTPGroup>\n        <InputOTPSlot index={0} />\n        <InputOTPSlot index={1} />\n        <InputOTPSlot index={2} />\n      </InputOTPGroup>\n      <InputOTPSeparator />\n      <InputOTPGroup>\n        <InputOTPSlot index={3} />\n        <InputOTPSlot index={4} />\n        <InputOTPSlot index={5} />\n      </InputOTPGroup>\n    </InputOTP>\n  ),",
          "code": "<InputOTP maxLength={6} aria-label=\"One-time password\">\n      <InputOTPGroup>\n        <InputOTPSlot index={0} />\n        <InputOTPSlot index={1} />\n        <InputOTPSlot index={2} />\n      </InputOTPGroup>\n      <InputOTPSeparator />\n      <InputOTPGroup>\n        <InputOTPSlot index={3} />\n        <InputOTPSlot index={4} />\n        <InputOTPSlot index={5} />\n      </InputOTPGroup>\n    </InputOTP>"
        },
        {
          "name": "FourDigits",
          "description": "",
          "args": "{ maxLength: 4 } as any,\n  render: () => (\n    <InputOTP maxLength={4} aria-label=\"One-time password\">\n      <InputOTPGroup>\n        <InputOTPSlot index={0} />\n        <InputOTPSlot index={1} />\n        <InputOTPSlot index={2} />\n        <InputOTPSlot index={3} />\n      </InputOTPGroup>\n    </InputOTP>\n  ),",
          "code": "<InputOTP maxLength={4} aria-label=\"One-time password\">\n      <InputOTPGroup>\n        <InputOTPSlot index={0} />\n        <InputOTPSlot index={1} />\n        <InputOTPSlot index={2} />\n        <InputOTPSlot index={3} />\n      </InputOTPGroup>\n    </InputOTP>"
        }
      ]
    },
    {
      "name": "item",
      "title": "Item",
      "description": "A list item component with media, content, title, description, actions, and size variants.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/item",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "separator"
      ],
      "files": [
        "components/ui/item.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"outline\" | \"muted\"",
          "options": [
            "default",
            "outline",
            "muted"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"default\" | \"sm\" | \"xs\"",
          "options": [
            "default",
            "sm",
            "xs"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Item",
      "stories": [
        {
          "name": "Default",
          "description": "List of two items with icon media, title, description, and a ghost action button.",
          "code": "<ItemGroup className=\"max-w-md\">\n      <Item role=\"listitem\">\n        <ItemMedia variant=\"icon\">\n          <StarIcon />\n        </ItemMedia>\n        <ItemContent>\n          <ItemTitle>Getting Started</ItemTitle>\n          <ItemDescription>\n            Learn the basics and set up your first project.\n          </ItemDescription>\n        </ItemContent>\n        <ItemActions>\n          <Button size=\"xs\" variant=\"ghost\">\n            Open\n          </Button>\n        </ItemActions>\n      </Item>\n      <ItemSeparator />\n      <Item role=\"listitem\">\n        <ItemMedia variant=\"icon\">\n          <StarIcon />\n        </ItemMedia>\n        <ItemContent>\n          <ItemTitle>Advanced Guide</ItemTitle>\n          <ItemDescription>\n            Deep dive into advanced features and configuration.\n          </ItemDescription>\n        </ItemContent>\n        <ItemActions>\n          <Button size=\"xs\" variant=\"ghost\">\n            Open\n          </Button>\n        </ItemActions>\n      </Item>\n    </ItemGroup>"
        },
        {
          "name": "Outline",
          "description": "",
          "args": "{\n    variant: \"outline\",\n  },\n  render: () => (\n    <ItemGroup className=\"max-w-md\">\n      <Item variant=\"outline\" role=\"listitem\">\n        <ItemContent>\n          <ItemTitle>Project Alpha</ItemTitle>\n          <ItemDescription>Last updated 2 days ago</ItemDescription>\n        </ItemContent>\n        <ItemActions>\n          <Button size=\"icon-xs\" variant=\"ghost\" aria-label=\"More options\">\n            <EllipsisVerticalIcon />\n          </Button>\n        </ItemActions>\n      </Item>\n      <Item variant=\"outline\" role=\"listitem\">\n        <ItemContent>\n          <ItemTitle>Project Beta</ItemTitle>\n          <ItemDescription>Last updated 5 days ago</ItemDescription>\n        </ItemContent>\n        <ItemActions>\n          <Button size=\"icon-xs\" variant=\"ghost\" aria-label=\"More options\">\n            <EllipsisVerticalIcon />\n          </Button>\n        </ItemActions>\n      </Item>\n    </ItemGroup>\n  ),",
          "code": "<ItemGroup className=\"max-w-md\">\n      <Item variant=\"outline\" role=\"listitem\">\n        <ItemContent>\n          <ItemTitle>Project Alpha</ItemTitle>\n          <ItemDescription>Last updated 2 days ago</ItemDescription>\n        </ItemContent>\n        <ItemActions>\n          <Button size=\"icon-xs\" variant=\"ghost\" aria-label=\"More options\">\n            <EllipsisVerticalIcon />\n          </Button>\n        </ItemActions>\n      </Item>\n      <Item variant=\"outline\" role=\"listitem\">\n        <ItemContent>\n          <ItemTitle>Project Beta</ItemTitle>\n          <ItemDescription>Last updated 5 days ago</ItemDescription>\n        </ItemContent>\n        <ItemActions>\n          <Button size=\"icon-xs\" variant=\"ghost\" aria-label=\"More options\">\n            <EllipsisVerticalIcon />\n          </Button>\n        </ItemActions>\n      </Item>\n    </ItemGroup>"
        },
        {
          "name": "WithHeader",
          "description": "",
          "code": "<ItemGroup className=\"max-w-md\">\n      <ItemHeader role=\"presentation\">\n        <ItemTitle>Projects</ItemTitle>\n      </ItemHeader>\n      <Item role=\"listitem\">\n        <ItemMedia variant=\"icon\">\n          <StarIcon />\n        </ItemMedia>\n        <ItemContent>\n          <ItemTitle>Design System</ItemTitle>\n          <ItemDescription>Component library and style guide.</ItemDescription>\n        </ItemContent>\n      </Item>\n      <ItemFooter role=\"presentation\">\n        <span className=\"text-xs text-muted-foreground\">3 items</span>\n      </ItemFooter>\n    </ItemGroup>"
        }
      ]
    },
    {
      "name": "kbd",
      "title": "Kbd",
      "description": "A keyboard key indicator for displaying keyboard shortcuts.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/kbd",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/kbd.tsx"
      ],
      "storyTitle": "Shadcn UI/Kbd",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Single keyboard shortcut ⌘K rendered as an inline kbd element with muted background styling.",
          "args": "{\n    children: \"⌘K\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Single keyboard shortcut ⌘K rendered as an inline kbd element with muted background styling.\",\n      },\n    },\n  },"
        },
        {
          "name": "Group",
          "description": "",
          "code": "<KbdGroup>\n      <Kbd>⌘</Kbd>\n      <span className=\"text-xs text-muted-foreground\">+</span>\n      <Kbd>Shift</Kbd>\n      <span className=\"text-xs text-muted-foreground\">+</span>\n      <Kbd>P</Kbd>\n    </KbdGroup>"
        },
        {
          "name": "SingleKeys",
          "description": "",
          "code": "<div className=\"flex flex-wrap gap-4\">\n      <Kbd>⌘K</Kbd>\n      <Kbd>⌘S</Kbd>\n      <Kbd>⌘⇧P</Kbd>\n      <Kbd>⌘⌫</Kbd>\n      <Kbd>Esc</Kbd>\n      <Kbd>⌥F4</Kbd>\n    </div>"
        }
      ]
    },
    {
      "name": "label",
      "title": "Label",
      "description": "A form label element built on Radix UI Label primitive.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/label",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/label.tsx"
      ],
      "storyTitle": "Shadcn UI/Label",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Form label associated with an email input field using htmlFor to demonstrate proper accessibility linking.",
          "code": "<div className=\"grid w-60 gap-2\">\n      <Label htmlFor=\"email\">Email</Label>\n      <Input id=\"email\" type=\"email\" placeholder=\"you@example.com\" />\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "",
          "code": "<div className=\"grid w-60 gap-2\">\n      <Label htmlFor=\"disabled-input\">Disabled Label</Label>\n      <Input id=\"disabled-input\" disabled placeholder=\"Cannot edit\" />\n    </div>"
        }
      ]
    },
    {
      "name": "marker",
      "title": "Marker",
      "description": "A status and pin marker indicator for chat and list items with support for variant, pin, and side-by-side layout.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/marker",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/marker.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"separator\" | \"border\"",
          "options": [
            "default",
            "separator",
            "border"
          ]
        }
      ],
      "storyTitle": "Shadcn UI/Marker",
      "stories": [
        {
          "name": "Default",
          "description": "Default marker with an information icon and a label indicating a status message.",
          "code": "<Marker>\n      <MarkerIcon>\n        <InfoIcon />\n      </MarkerIcon>\n      <MarkerContent>This is an informational marker</MarkerContent>\n    </Marker>"
        },
        {
          "name": "Variants",
          "description": "All three marker variants (default, separator, border) displayed side by side.",
          "code": "<div className=\"flex max-w-md flex-col gap-6\">\n      <Marker variant=\"default\">\n        <MarkerIcon>\n          <InfoIcon />\n        </MarkerIcon>\n        <MarkerContent>Default marker with icon</MarkerContent>\n      </Marker>\n      <Marker variant=\"separator\">\n        <MarkerContent>Separator variant</MarkerContent>\n      </Marker>\n      <Marker variant=\"border\">\n        <MarkerIcon>\n          <AlertTriangleIcon className=\"text-warning\" />\n        </MarkerIcon>\n        <MarkerContent>Border marker with warning</MarkerContent>\n      </Marker>\n    </div>"
        },
        {
          "name": "WithIcons",
          "description": "Markers with different semantic icons conveying various message types.",
          "code": "<div className=\"flex max-w-md flex-col gap-4\">\n      <Marker>\n        <MarkerIcon>\n          <InfoIcon />\n        </MarkerIcon>\n        <MarkerContent>Information message</MarkerContent>\n      </Marker>\n      <Marker>\n        <MarkerIcon>\n          <AlertTriangleIcon className=\"text-warning\" />\n        </MarkerIcon>\n        <MarkerContent>Warning message</MarkerContent>\n      </Marker>\n      <Marker>\n        <MarkerIcon>\n          <CheckCircleIcon className=\"text-success\" />\n        </MarkerIcon>\n        <MarkerContent>Success message</MarkerContent>\n      </Marker>\n    </div>"
        },
        {
          "name": "AsChild",
          "description": "Marker rendered as a clickable link using the asChild composition pattern.",
          "code": "<Marker asChild>\n      <a href=\"#\">\n        <MarkerIcon>\n          <InfoIcon />\n        </MarkerIcon>\n        <MarkerContent>Clickable marker link</MarkerContent>\n      </a>\n    </Marker>"
        },
        {
          "name": "SeparatorLabel",
          "description": "Marker with separator variant used as a section divider with centered text label.",
          "code": "<div className=\"flex max-w-md flex-col gap-3\">\n      <div className=\"text-sm text-foreground\">Previous section content</div>\n      <Marker variant=\"separator\">\n        <MarkerContent>Today</MarkerContent>\n      </Marker>\n      <div className=\"text-sm text-foreground\">\n        Today&apos;s section content\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "menubar",
      "title": "Menubar",
      "description": "A horizontal menu bar with dropdown menus, checkboxes, radio items, and submenus.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/menubar",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/menubar.tsx"
      ],
      "storyTitle": "Shadcn UI/Menubar",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Horizontal menubar with File, Edit, and View menus featuring items, keyboard shortcuts, a destructive item, checkbox items, and a submenu with radio group options.",
          "code": "<Menubar className=\"w-fit\">\n      <MenubarMenu>\n        <MenubarTrigger>File</MenubarTrigger>\n        <MenubarContent>\n          <MenubarItem>\n            New File\n            <MenubarShortcut>⌘N</MenubarShortcut>\n          </MenubarItem>\n          <MenubarItem>\n            Open\n            <MenubarShortcut>⌘O</MenubarShortcut>\n          </MenubarItem>\n          <MenubarSeparator />\n          <MenubarItem variant=\"destructive\">\n            Close\n            <MenubarShortcut>⌘W</MenubarShortcut>\n          </MenubarItem>\n        </MenubarContent>\n      </MenubarMenu>\n      <MenubarMenu>\n        <MenubarTrigger>Edit</MenubarTrigger>\n        <MenubarContent>\n          <MenubarItem>\n            Undo\n            <MenubarShortcut>⌘Z</MenubarShortcut>\n          </MenubarItem>\n          <MenubarItem>\n            Redo\n            <MenubarShortcut>⇧⌘Z</MenubarShortcut>\n          </MenubarItem>\n        </MenubarContent>\n      </MenubarMenu>\n      <MenubarMenu>\n        <MenubarTrigger>View</MenubarTrigger>\n        <MenubarContent>\n          <MenubarCheckboxItem checked>Show Sidebar</MenubarCheckboxItem>\n          <MenubarCheckboxItem>Show Toolbar</MenubarCheckboxItem>\n          <MenubarSeparator />\n          <MenubarSub>\n            <MenubarSubTrigger>Zoom</MenubarSubTrigger>\n            <MenubarSubContent>\n              <MenubarRadioGroup value=\"100\">\n                <MenubarRadioItem value=\"75\">75%</MenubarRadioItem>\n                <MenubarRadioItem value=\"100\">100%</MenubarRadioItem>\n                <MenubarRadioItem value=\"150\">150%</MenubarRadioItem>\n              </MenubarRadioGroup>\n            </MenubarSubContent>\n          </MenubarSub>\n        </MenubarContent>\n      </MenubarMenu>\n    </Menubar>"
        }
      ]
    },
    {
      "name": "message",
      "title": "Message",
      "description": "A chat message component with support for align (start/end), avatar, content, header, and footer slots. Composed of MessageGroup, MessageAvatar, MessageContent, MessageHeader, and MessageFooter sub-components.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/message",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/message.tsx"
      ],
      "storyTitle": "Shadcn UI/Message",
      "props": [
        {
          "name": "align",
          "control": "inline-radio",
          "options": [
            "start",
            "end"
          ],
          "default": "start"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Default start-aligned message with an avatar, sender name, and a chat bubble.",
          "code": "<Message>\n      <MessageAvatar>\n        <span className=\"text-xs font-medium text-muted-foreground\">JD</span>\n      </MessageAvatar>\n      <MessageContent>\n        <MessageHeader>John Doe</MessageHeader>\n        <Bubble variant=\"secondary\">\n          <BubbleContent>Hey, have you seen the latest updates?</BubbleContent>\n        </Bubble>\n        <MessageFooter>10:42 AM</MessageFooter>\n      </MessageContent>\n    </Message>"
        },
        {
          "name": "Alignment",
          "description": "Conversation layout showing start-aligned (incoming) and end-aligned (outgoing) messages.",
          "code": "<div className=\"flex max-w-lg flex-col gap-4\">\n      <Message align=\"start\">\n        <MessageAvatar>\n          <span className=\"text-xs font-medium text-muted-foreground\">AS</span>\n        </MessageAvatar>\n        <MessageContent>\n          <MessageHeader>Alice Silva</MessageHeader>\n          <Bubble variant=\"secondary\">\n            <BubbleContent>Hi! Are you free for a quick call?</BubbleContent>\n          </Bubble>\n          <MessageFooter>11:30 AM</MessageFooter>\n        </MessageContent>\n      </Message>\n      <Message align=\"end\">\n        <MessageContent>\n          <Bubble>\n            <BubbleContent>Sure, give me 5 minutes!</BubbleContent>\n          </Bubble>\n          <MessageFooter>11:31 AM</MessageFooter>\n        </MessageContent>\n      </Message>\n      <Message align=\"start\">\n        <MessageAvatar>\n          <span className=\"text-xs font-medium text-muted-foreground\">AS</span>\n        </MessageAvatar>\n        <MessageContent>\n          <MessageHeader>Alice Silva</MessageHeader>\n          <Bubble variant=\"secondary\">\n            <BubbleContent>\n              Great, I&apos;ll send you the meeting link.\n            </BubbleContent>\n          </Bubble>\n          <MessageFooter>11:31 AM</MessageFooter>\n        </MessageContent>\n      </Message>\n    </div>"
        },
        {
          "name": "Group",
          "description": "Consecutive messages from the same sender grouped together using MessageGroup.",
          "code": "<MessageGroup>\n      <Message align=\"start\">\n        <MessageAvatar>\n          <span className=\"text-xs font-medium text-muted-foreground\">MC</span>\n        </MessageAvatar>\n        <MessageContent>\n          <MessageHeader>Maria Costa</MessageHeader>\n          <Bubble variant=\"secondary\">\n            <BubbleContent>I&apos;ve reviewed the proposal.</BubbleContent>\n          </Bubble>\n          <Bubble variant=\"secondary\">\n            <BubbleContent>\n              Everything looks good, but we need to adjust the timeline.\n            </BubbleContent>\n          </Bubble>\n          <Bubble variant=\"secondary\">\n            <BubbleContent>Can we discuss this tomorrow?</BubbleContent>\n          </Bubble>\n          <MessageFooter>2:15 PM</MessageFooter>\n        </MessageContent>\n      </Message>\n    </MessageGroup>"
        },
        {
          "name": "WithBubbleVariants",
          "description": "Message combining different bubble variants within the same message content area.",
          "code": "<Message align=\"start\">\n      <MessageAvatar>\n        <span className=\"text-xs font-medium text-muted-foreground\">SK</span>\n      </MessageAvatar>\n      <MessageContent>\n        <MessageHeader>Support Team</MessageHeader>\n        <Bubble variant=\"secondary\">\n          <BubbleContent>\n            Here is the confirmation for your request:\n          </BubbleContent>\n        </Bubble>\n        <Bubble variant=\"outline\">\n          <BubbleContent>Ticket #1234 — Account Recovery</BubbleContent>\n        </Bubble>\n        <Bubble variant=\"destructive\">\n          <BubbleContent>\n            Please verify your identity within 24 hours.\n          </BubbleContent>\n        </Bubble>\n        <MessageFooter>3:00 PM · Urgent</MessageFooter>\n      </MessageContent>\n    </Message>"
        }
      ]
    },
    {
      "name": "message-scroller",
      "title": "Message Scroller",
      "description": "An auto-scrolling container for chat message lists with scroll-to-end/start buttons, visibility detection, and virtualized content support. Composed of MessageScrollerProvider, MessageScrollerViewport, MessageScrollerContent, MessageScrollerItem, and MessageScrollerButton sub-components.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/message-scroller",
      "dependencies": [
        "@shadcn/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ui/message-scroller.tsx"
      ],
      "storyTitle": "Shadcn UI/MessageScroller",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Message scroller with sample chat messages inside a fixed-height container. Scroll down to see the scroll-to-bottom button appear.",
          "code": "<MessageScrollerProvider>\n      <div className=\"h-[400px] w-full max-w-lg overflow-hidden rounded-lg border bg-background\">\n        <MessageScroller>\n          <MessageScrollerViewport>\n            <MessageScrollerContent>\n              {sampleMessages.map((msg, i) => (\n                <MessageScrollerItem\n                  key={i}\n                  scrollAnchor={i === sampleMessages.length - 1}\n                >\n                  <Message align={i % 2 === 0 ? \"start\" : \"end\"}>\n                    {i % 2 === 0 && (\n                      <MessageAvatar>\n                        <span className=\"text-xs font-medium text-muted-foreground\">\n                          {msg.initials}\n                        </span>\n                      </MessageAvatar>\n                    )}\n                    <MessageContent>\n                      {i % 2 === 0 && <MessageHeader>{msg.name}</MessageHeader>}\n                      <Bubble variant={i % 2 === 0 ? \"secondary\" : undefined}>\n                        <BubbleContent>{msg.text}</BubbleContent>\n                      </Bubble>\n                      <MessageFooter>{msg.time}</MessageFooter>\n                    </MessageContent>\n                  </Message>\n                </MessageScrollerItem>\n              ))}\n            </MessageScrollerContent>\n          </MessageScrollerViewport>\n          <MessageScrollerButton direction=\"end\" />\n        </MessageScroller>\n      </div>\n    </MessageScrollerProvider>"
        }
      ]
    },
    {
      "name": "native-select",
      "title": "Native Select",
      "description": "A styled native HTML select element with optgroup and option sub-components.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/native-select",
      "dependencies": [
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/native-select.tsx"
      ],
      "storyTitle": "Shadcn UI/Native Select",
      "props": [
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "sm",
            "default"
          ],
          "description": "Select height preset",
          "default": "default"
        },
        {
          "name": "disabled",
          "control": "boolean",
          "default": "false"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Native select element with three simple options using the default size preset and a chevron icon.",
          "code": "<NativeSelect defaultValue=\"option-1\" aria-label=\"Select option\">\n      <NativeSelectOption value=\"option-1\">Option 1</NativeSelectOption>\n      <NativeSelectOption value=\"option-2\">Option 2</NativeSelectOption>\n      <NativeSelectOption value=\"option-3\">Option 3</NativeSelectOption>\n    </NativeSelect>"
        },
        {
          "name": "Small",
          "description": "Compact native select using the small size preset for space-constrained layouts.",
          "code": "<NativeSelect size=\"sm\" defaultValue=\"option-1\" aria-label=\"Select option\">\n      <NativeSelectOption value=\"option-1\">Option 1</NativeSelectOption>\n      <NativeSelectOption value=\"option-2\">Option 2</NativeSelectOption>\n    </NativeSelect>"
        },
        {
          "name": "WithGroup",
          "description": "Native select with options organized into Fruits and Vegetables optgroups via NativeSelectOptGroup.",
          "code": "<NativeSelect defaultValue=\"apple\" aria-label=\"Select option\">\n      <NativeSelectOptGroup label=\"Fruits\">\n        <NativeSelectOption value=\"apple\">Apple</NativeSelectOption>\n        <NativeSelectOption value=\"banana\">Banana</NativeSelectOption>\n      </NativeSelectOptGroup>\n      <NativeSelectOptGroup label=\"Vegetables\">\n        <NativeSelectOption value=\"carrot\">Carrot</NativeSelectOption>\n        <NativeSelectOption value=\"broccoli\">Broccoli</NativeSelectOption>\n      </NativeSelectOptGroup>\n    </NativeSelect>"
        },
        {
          "name": "Disabled",
          "description": "Native select in a disabled state with a pre-selected value, preventing user interaction.",
          "code": "<NativeSelect disabled defaultValue=\"option-1\" aria-label=\"Select option\">\n      <NativeSelectOption value=\"option-1\">Option 1</NativeSelectOption>\n      <NativeSelectOption value=\"option-2\">Option 2</NativeSelectOption>\n    </NativeSelect>"
        }
      ]
    },
    {
      "name": "navigation-menu",
      "title": "Navigation Menu",
      "description": "A responsive navigation menu with trigger, content, viewport, and indicator sub-components.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/navigation-menu",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/navigation-menu.tsx"
      ],
      "storyTitle": "Shadcn UI/Navigation Menu",
      "props": [
        {
          "name": "viewport",
          "control": "boolean",
          "description": "Whether to render the animated viewport indicator for the active dropdown",
          "default": "true"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Navigation menu with two dropdown panels (Getting Started and Components) and a direct Documentation link, with the viewport indicator enabled.",
          "args": "{\n    viewport: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Navigation menu with two dropdown panels (Getting Started and Components) and a direct Documentation link, with the viewport indicator enabled.\",\n      },\n    },\n  },\n  render: (args) => (\n    <NavigationMenu {...args}>\n      <NavigationMenuList>\n        <NavigationMenuItem>\n          <NavigationMenuTrigger>Getting Started</NavigationMenuTrigger>\n          <NavigationMenuContent>\n            <ul className=\"grid w-80 gap-1 p-3 md:w-96 md:grid-cols-2 lg:w-[32rem]\">\n              <ListItem title=\"Installation\" href=\"#\">\n                How to install and set up the project\n              </ListItem>\n              <ListItem title=\"Quick Start\" href=\"#\">\n                Get up and running in minutes\n              </ListItem>\n              <ListItem title=\"Configuration\" href=\"#\">\n                Customize your setup\n              </ListItem>\n              <ListItem title=\"API Reference\" href=\"#\">\n                Complete API documentation\n              </ListItem>\n            </ul>\n          </NavigationMenuContent>\n        </NavigationMenuItem>\n        <NavigationMenuItem>\n          <NavigationMenuTrigger>Components</NavigationMenuTrigger>\n          <NavigationMenuContent>\n            <ul className=\"grid w-80 gap-1 p-3 md:w-96 md:grid-cols-2\">\n              <ListItem title=\"Button\" href=\"#\">\n                Interactive button control\n              </ListItem>\n              <ListItem title=\"Badge\" href=\"#\">\n                Visual indicators for status\n              </ListItem>\n              <ListItem title=\"Card\" href=\"#\">\n                Content containers\n              </ListItem>\n              <ListItem title=\"Dialog\" href=\"#\">\n                Modal overlay dialogs\n              </ListItem>\n            </ul>\n          </NavigationMenuContent>\n        </NavigationMenuItem>\n        <NavigationMenuItem>\n          <NavigationMenuLink asChild href=\"#\">\n            <a className=\"inline-flex h-9 w-max items-center justify-center rounded-3xl px-4.5 py-2.5 text-sm font-medium transition-all outline-none hover:bg-muted focus:bg-muted focus-visible:ring-3 focus-visible:ring-ring/30 focus-visible:outline-1\">\n              Documentation\n            </a>\n          </NavigationMenuLink>\n        </NavigationMenuItem>\n      </NavigationMenuList>\n    </NavigationMenu>\n  ),"
        },
        {
          "name": "NoViewport",
          "description": "",
          "args": "{\n    viewport: false,\n  },\n  render: (args) => (\n    <NavigationMenu {...args}>\n      <NavigationMenuList>\n        <NavigationMenuItem>\n          <NavigationMenuTrigger>Getting Started</NavigationMenuTrigger>\n          <NavigationMenuContent>\n            <ul className=\"grid w-80 gap-1 p-3\">\n              <ListItem title=\"Installation\" href=\"#\">\n                How to install and set up the project\n              </ListItem>\n              <ListItem title=\"Quick Start\" href=\"#\">\n                Get up and running in minutes\n              </ListItem>\n            </ul>\n          </NavigationMenuContent>\n        </NavigationMenuItem>\n        <NavigationMenuItem>\n          <NavigationMenuLink asChild href=\"#\">\n            <a className=\"inline-flex h-9 w-max items-center justify-center rounded-3xl px-4.5 py-2.5 text-sm font-medium transition-all outline-none hover:bg-muted focus:bg-muted focus-visible:ring-3 focus-visible:ring-ring/30 focus-visible:outline-1\">\n              Changelog\n            </a>\n          </NavigationMenuLink>\n        </NavigationMenuItem>\n      </NavigationMenuList>\n    </NavigationMenu>\n  ),"
        }
      ]
    },
    {
      "name": "pagination",
      "title": "Pagination",
      "description": "A semantic pagination component built with native <nav> and <ul> elements, prev/next links, and ellipsis.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/pagination",
      "dependencies": [
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ui/pagination.tsx"
      ],
      "storyTitle": "Shadcn UI/Pagination",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Pagination with five page links, page 2 marked as active, previous/next arrows, and an ellipsis indicator for truncated pages.",
          "code": "<Pagination>\n      <PaginationContent>\n        <PaginationItem>\n          <PaginationPrevious href=\"#\" />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">1</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\" isActive>\n            2\n          </PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">3</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationEllipsis />\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationLink href=\"#\">8</PaginationLink>\n        </PaginationItem>\n        <PaginationItem>\n          <PaginationNext href=\"#\" />\n        </PaginationItem>\n      </PaginationContent>\n    </Pagination>"
        },
        {
          "name": "Sizes",
          "description": "Two pagination examples demonstrating small and default page link sizes with custom previous/next labels.",
          "code": "<div className=\"flex flex-col gap-6\">\n      <Pagination>\n        <PaginationContent>\n          <PaginationItem>\n            <PaginationPrevious href=\"#\" text=\"Previous\" />\n          </PaginationItem>\n          <PaginationItem>\n            <PaginationLink href=\"#\" size=\"sm\">\n              1\n            </PaginationLink>\n          </PaginationItem>\n          <PaginationItem>\n            <PaginationLink href=\"#\" isActive size=\"sm\">\n              2\n            </PaginationLink>\n          </PaginationItem>\n          <PaginationItem>\n            <PaginationLink href=\"#\" size=\"sm\">\n              3\n            </PaginationLink>\n          </PaginationItem>\n          <PaginationItem>\n            <PaginationNext href=\"#\" text=\"Next\" />\n          </PaginationItem>\n        </PaginationContent>\n      </Pagination>\n      <Pagination>\n        <PaginationContent>\n          <PaginationItem>\n            <PaginationPrevious href=\"#\" text=\"Previous\" />\n          </PaginationItem>\n          <PaginationItem>\n            <PaginationLink href=\"#\" size=\"default\">\n              1\n            </PaginationLink>\n          </PaginationItem>\n          <PaginationItem>\n            <PaginationLink href=\"#\" isActive size=\"default\">\n              2\n            </PaginationLink>\n          </PaginationItem>\n          <PaginationItem>\n            <PaginationLink href=\"#\" size=\"default\">\n              3\n            </PaginationLink>\n          </PaginationItem>\n          <PaginationItem>\n            <PaginationNext href=\"#\" text=\"Next\" />\n          </PaginationItem>\n        </PaginationContent>\n      </Pagination>\n    </div>"
        }
      ]
    },
    {
      "name": "popover",
      "title": "Popover",
      "description": "A rich information bubble popover displaying contextual content triggered by focus/click events.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/popover",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/popover.tsx"
      ],
      "storyTitle": "Shadcn UI/Popover",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Popover with a header containing title and description, plus additional content below, triggered by an outline button.",
          "code": "<Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\">Open Popover</Button>\n      </PopoverTrigger>\n      <PopoverContent>\n        <PopoverHeader>\n          <PopoverTitle>Popover Title</PopoverTitle>\n          <PopoverDescription>\n            This is a popover description with some additional context.\n          </PopoverDescription>\n        </PopoverHeader>\n        <div className=\"mt-2\">\n          <p className=\"text-sm\">Popover content goes here.</p>\n        </div>\n      </PopoverContent>\n    </Popover>"
        },
        {
          "name": "AlignStart",
          "description": "",
          "code": "<Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\">Align Start</Button>\n      </PopoverTrigger>\n      <PopoverContent align=\"start\">\n        <PopoverTitle>Aligned Start</PopoverTitle>\n        <p className=\"text-sm text-muted-foreground\">\n          This popover is aligned to the start.\n        </p>\n      </PopoverContent>\n    </Popover>"
        },
        {
          "name": "AlignEnd",
          "description": "",
          "code": "<Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\">Align End</Button>\n      </PopoverTrigger>\n      <PopoverContent align=\"end\">\n        <PopoverTitle>Aligned End</PopoverTitle>\n        <p className=\"text-sm text-muted-foreground\">\n          This popover is aligned to the end.\n        </p>\n      </PopoverContent>\n    </Popover>"
        },
        {
          "name": "NoHeader",
          "description": "",
          "code": "<Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\">Simple Content</Button>\n      </PopoverTrigger>\n      <PopoverContent>\n        <div className=\"flex flex-col gap-2\">\n          <button className=\"text-sm hover:underline\">Dashboard</button>\n          <button className=\"text-sm hover:underline\">Settings</button>\n          <button className=\"text-sm hover:underline\">Logout</button>\n        </div>\n      </PopoverContent>\n    </Popover>"
        }
      ]
    },
    {
      "name": "progress",
      "title": "Progress",
      "description": "A simple progress bar indicator designed to show status completion values.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/progress",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/progress.tsx"
      ],
      "storyTitle": "Shadcn UI/Progress",
      "props": [
        {
          "name": "value",
          "description": "Progress value",
          "default": "0"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Determinate progress bar at 50% value with a filled track and rounded styling.",
          "args": "{\n    value: 50,\n    \"aria-label\": \"Progress: 50%\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Determinate progress bar at 50% value with a filled track and rounded styling.\",\n      },\n    },\n  },"
        },
        {
          "name": "States",
          "description": "",
          "code": "<div className=\"flex w-full max-w-md flex-col gap-4\">\n      <Progress value={20} aria-label=\"Progress: 20%\" />\n      <Progress value={50} aria-label=\"Progress: 50%\" />\n      <Progress value={80} aria-label=\"Progress: 80%\" />\n      <Progress value={100} aria-label=\"Progress: 100%\" />\n    </div>"
        },
        {
          "name": "Indeterminate",
          "description": "Progress bar with no set value, displaying an indeterminate animated pulse to indicate ongoing activity.",
          "code": "<div className=\"w-full max-w-md\">\n      <Progress value={undefined} aria-label=\"Loading progress\" />\n    </div>"
        }
      ]
    },
    {
      "name": "questionnaire",
      "title": "Questionnaire",
      "description": "A multi-step questionnaire with single-choice, multiple-choice, freeform, and skippable questions. Owns the ordered items, active item, answer state, validation, progress, and navigation. Composed of QuestionnaireItem, QuestionnaireProgress, QuestionnaireTitle, QuestionnaireDescription, QuestionnaireChoices, QuestionnaireChoice, QuestionnaireChoiceDescription, QuestionnaireInput, QuestionnaireError, QuestionnaireActions, QuestionnairePrevious, QuestionnaireSkip, QuestionnaireNext, and QuestionnaireSubmit sub-components.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/questionnaire",
      "dependencies": [
        "@shadcn/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ui/questionnaire.tsx"
      ],
      "storyTitle": "Shadcn UI/Questionnaire",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "A three-step questionnaire with single-choice questions, a progress counter, and full navigation actions.",
          "code": "<Questionnaire\n      className=\"mx-auto max-w-lg\"\n      items={freeformItems}\n      defaultItem=\"direction\"\n      onSubmit={handleSubmit}\n    >\n      <QuestionnaireProgress />\n      <SingleChoiceQuestions />\n      <QuestionnaireNavigation />\n    </Questionnaire>"
        },
        {
          "name": "MultipleChoice",
          "description": "A `multiple` item turns fixed choices into checkboxes, read back with `FormData.getAll()` on submit.",
          "code": "<Questionnaire\n      className=\"mx-auto max-w-lg\"\n      items={questionnaireItems.slice(1, 2)}\n      defaultItem=\"signals\"\n      onSubmit={handleSubmit}\n    >\n      <QuestionnaireProgress />\n      <QuestionnaireItem name=\"signals\" multiple>\n        <QuestionnaireTitle>\n          What should every progress update include?\n        </QuestionnaireTitle>\n        <QuestionnaireDescription>\n          Select every source that may affect the implementation.\n        </QuestionnaireDescription>\n        <QuestionnaireChoices>\n          <QuestionnaireChoice value=\"progress\">\n            <span className=\"font-medium\">Progress</span>\n            <QuestionnaireChoiceDescription>\n              Show how much of the work is done.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"decisions\">\n            <span className=\"font-medium\">Decisions</span>\n            <QuestionnaireChoiceDescription>\n              Summarize the choices made along the way.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"risks\">\n            <span className=\"font-medium\">Risks</span>\n            <QuestionnaireChoiceDescription>\n              Surface anything that might block delivery.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n        </QuestionnaireChoices>\n        <QuestionnaireError />\n      </QuestionnaireItem>\n      <QuestionnaireNavigation />\n    </Questionnaire>"
        },
        {
          "name": "Freeform",
          "description": "A required question combining fixed choices with a `QuestionnaireInput` freeform answer.",
          "code": "<Questionnaire\n      className=\"mx-auto max-w-lg\"\n      items={questionnaireItems.slice(0, 1)}\n      defaultItem=\"direction\"\n      onSubmit={handleSubmit}\n    >\n      <QuestionnaireProgress />\n      <QuestionnaireItem name=\"direction\" required>\n        <QuestionnaireTitle>What should we prototype next?</QuestionnaireTitle>\n        <QuestionnaireDescription>\n          Choose a direction or write your own.\n        </QuestionnaireDescription>\n        <QuestionnaireChoices>\n          <QuestionnaireChoice value=\"delegation\">\n            <span className=\"font-medium\">Sub-agent delegation</span>\n            <QuestionnaireChoiceDescription>\n              Show when work is delegated and what comes back.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"questions\">\n            <span className=\"font-medium\">Question prompts</span>\n            <QuestionnaireChoiceDescription>\n              Show choices while the agent waits for input.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n          <QuestionnaireInput\n            aria-label=\"Another direction\"\n            placeholder=\"Type another direction…\"\n          />\n        </QuestionnaireChoices>\n        <QuestionnaireError />\n      </QuestionnaireItem>\n      <QuestionnaireNavigation />\n    </Questionnaire>"
        },
        {
          "name": "WithSkip",
          "description": "An optional middle item with an explicit `QuestionnaireSkip` action so it can be intentionally left unanswered.",
          "code": "<Questionnaire\n      className=\"mx-auto max-w-lg\"\n      items={[\n        {\n          name: \"type\",\n          required: true,\n          choices: [\n            { value: \"feature\" },\n            { value: \"bugfix\" },\n            { value: \"refactor\" },\n          ],\n        },\n        {\n          name: \"constraints\",\n          choices: [{ value: \"deps\" }, { value: \"db\" }, { value: \"api\" }],\n        },\n        {\n          name: \"review\",\n          required: true,\n          choices: [{ value: \"tests\" }, { value: \"diff\" }, { value: \"both\" }],\n        },\n      ]}\n      defaultItem=\"type\"\n      onSubmit={handleSubmit}\n    >\n      <QuestionnaireProgress />\n      <QuestionnaireItem name=\"type\" required>\n        <QuestionnaireTitle>What kind of change is this?</QuestionnaireTitle>\n        <QuestionnaireDescription>\n          Choose the category that best describes the work.\n        </QuestionnaireDescription>\n        <QuestionnaireChoices>\n          <QuestionnaireChoice value=\"feature\">New feature</QuestionnaireChoice>\n          <QuestionnaireChoice value=\"bugfix\">Bug fix</QuestionnaireChoice>\n          <QuestionnaireChoice value=\"refactor\">Refactor</QuestionnaireChoice>\n        </QuestionnaireChoices>\n        <QuestionnaireError />\n      </QuestionnaireItem>\n      <QuestionnaireItem name=\"constraints\">\n        <QuestionnaireTitle>\n          Are there any implementation constraints?\n        </QuestionnaireTitle>\n        <QuestionnaireDescription>\n          Answer if needed, or intentionally skip this question.\n        </QuestionnaireDescription>\n        <QuestionnaireChoices>\n          <QuestionnaireChoice value=\"deps\">\n            Do not add dependencies\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"db\">\n            Do not change the database\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"api\">\n            Preserve the public API\n          </QuestionnaireChoice>\n        </QuestionnaireChoices>\n        <QuestionnaireError />\n      </QuestionnaireItem>\n      <QuestionnaireItem name=\"review\" required>\n        <QuestionnaireTitle>\n          How should the work be reviewed?\n        </QuestionnaireTitle>\n        <QuestionnaireDescription>\n          Choose the checks the agent should complete before handoff.\n        </QuestionnaireDescription>\n        <QuestionnaireChoices>\n          <QuestionnaireChoice value=\"tests\">\n            Run the test suite\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"diff\">\n            Review the final diff\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"both\">\n            Tests and diff review\n          </QuestionnaireChoice>\n        </QuestionnaireChoices>\n        <QuestionnaireError />\n      </QuestionnaireItem>\n      <QuestionnaireNavigation />\n    </Questionnaire>"
        },
        {
          "name": "Shortcuts",
          "description": "`shortcuts=\"letters\"` assigns a keyboard key to each enabled choice, surfaced as letter badges and navigable without a mouse.",
          "code": "<Questionnaire\n      className=\"mx-auto max-w-lg\"\n      items={questionnaireItems}\n      defaultItem=\"direction\"\n      shortcuts=\"letters\"\n      onSubmit={handleSubmit}\n    >\n      <QuestionnaireProgress />\n      <SingleChoiceQuestions />\n      <QuestionnaireNavigation />\n    </Questionnaire>"
        },
        {
          "name": "Error",
          "description": "A required item marked `invalid` with a custom `QuestionnaireError` message, shown until a valid answer is selected.",
          "code": "<Questionnaire\n      className=\"mx-auto max-w-lg\"\n      items={questionnaireItems.slice(0, 1)}\n      defaultItem=\"direction\"\n      onSubmit={handleSubmit}\n    >\n      <QuestionnaireProgress />\n      <QuestionnaireItem name=\"direction\" required invalid>\n        <QuestionnaireTitle>What should we prototype next?</QuestionnaireTitle>\n        <QuestionnaireDescription>\n          Choose a direction or write another answer.\n        </QuestionnaireDescription>\n        <QuestionnaireChoices>\n          <QuestionnaireChoice value=\"delegation\">\n            <span className=\"font-medium\">Sub-agent delegation</span>\n            <QuestionnaireChoiceDescription>\n              Show when work is delegated and what comes back.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"questions\">\n            <span className=\"font-medium\">Question prompts</span>\n            <QuestionnaireChoiceDescription>\n              Show choices while the agent waits for input.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"both\">\n            <span className=\"font-medium\">Both together</span>\n            <QuestionnaireChoiceDescription>\n              Explore one unified interaction pattern.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n        </QuestionnaireChoices>\n        <QuestionnaireError>\n          Please choose a project direction.\n        </QuestionnaireError>\n      </QuestionnaireItem>\n      <QuestionnaireNavigation />\n    </Questionnaire>"
        },
        {
          "name": "Disabled",
          "description": "Disabled choices and a disabled freeform input block interaction while preserving the visual layout.",
          "code": "<Questionnaire\n      className=\"mx-auto max-w-lg\"\n      items={disabledItems}\n      defaultItem=\"direction\"\n      onSubmit={handleSubmit}\n    >\n      <QuestionnaireProgress />\n      <QuestionnaireItem name=\"direction\" required>\n        <QuestionnaireTitle>What should we prototype next?</QuestionnaireTitle>\n        <QuestionnaireDescription>\n          Some options are not available right now.\n        </QuestionnaireDescription>\n        <QuestionnaireChoices>\n          <QuestionnaireChoice value=\"delegation\">\n            <span className=\"font-medium\">Sub-agent delegation</span>\n            <QuestionnaireChoiceDescription>\n              Show when work is delegated and what comes back.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n          <QuestionnaireChoice value=\"questions\" disabled>\n            <span className=\"font-medium\">Question prompts</span>\n            <QuestionnaireChoiceDescription>\n              Disabled while the prompt engine is offline.\n            </QuestionnaireChoiceDescription>\n          </QuestionnaireChoice>\n          <QuestionnaireInput\n            aria-label=\"Another direction\"\n            placeholder=\"Type another direction…\"\n            disabled\n          />\n        </QuestionnaireChoices>\n        <QuestionnaireError />\n      </QuestionnaireItem>\n      <QuestionnaireNavigation />\n    </Questionnaire>"
        },
        {
          "name": "CardComposition",
          "description": "Questionnaire composed with Card slots, rendering the title and description into the card header while keeping their semantic meaning.",
          "code": "<Questionnaire\n        className=\"mx-auto max-w-lg\"\n        items={questionnaireItems}\n        defaultItem=\"direction\"\n        shortcuts=\"numbers\"\n        onSubmit={handleSubmit}\n      >\n        <QuestionnaireItem\n          aria-labelledby={directionTitleId}\n          name=\"direction\"\n          required\n        >\n          <Card>\n            <CardHeader>\n              <QuestionnaireTitle id={directionTitleId} render={<CardTitle />}>\n                What should we prototype next?\n              </QuestionnaireTitle>\n              <QuestionnaireDescription render={<CardDescription />}>\n                Choose one direction or write another answer.\n              </QuestionnaireDescription>\n              <CardAction>\n                <QuestionnaireProgress />\n              </CardAction>\n            </CardHeader>\n            <CardContent>\n              <QuestionnaireChoices>\n                <QuestionnaireChoice value=\"delegation\">\n                  <span className=\"font-medium\">Sub-agent delegation</span>\n                  <QuestionnaireChoiceDescription>\n                    Show when work is delegated and what comes back.\n                  </QuestionnaireChoiceDescription>\n                </QuestionnaireChoice>\n                <QuestionnaireChoice value=\"questions\">\n                  <span className=\"font-medium\">Question prompts</span>\n                  <QuestionnaireChoiceDescription>\n                    Show choices while the agent waits for input.\n                  </QuestionnaireChoiceDescription>\n                </QuestionnaireChoice>\n                <QuestionnaireChoice value=\"both\">\n                  <span className=\"font-medium\">Both together</span>\n                  <QuestionnaireChoiceDescription>\n                    Explore one unified interaction pattern.\n                  </QuestionnaireChoiceDescription>\n                </QuestionnaireChoice>\n              </QuestionnaireChoices>\n              <QuestionnaireError />\n            </CardContent>\n          </Card>\n        </QuestionnaireItem>\n        <QuestionnaireItem\n          aria-labelledby={signalsTitleId}\n          name=\"signals\"\n          multiple\n        >\n          <Card>\n            <CardHeader>\n              <QuestionnaireTitle id={signalsTitleId} render={<CardTitle />}>\n                What should every progress update include?\n              </QuestionnaireTitle>\n              <QuestionnaireDescription render={<CardDescription />}>\n                Select all that apply, or skip this question.\n              </QuestionnaireDescription>\n              <CardAction>\n                <QuestionnaireProgress />\n              </CardAction>\n            </CardHeader>\n            <CardContent>\n              <QuestionnaireChoices>\n                <QuestionnaireChoice value=\"progress\">\n                  Progress\n                </QuestionnaireChoice>\n                <QuestionnaireChoice value=\"decisions\">\n                  Decisions\n                </QuestionnaireChoice>\n                <QuestionnaireChoice value=\"risks\">Risks</QuestionnaireChoice>\n              </QuestionnaireChoices>\n              <QuestionnaireError />\n            </CardContent>\n          </Card>\n        </QuestionnaireItem>\n        <QuestionnaireItem\n          aria-labelledby={timingTitleId}\n          name=\"timing\"\n          required\n        >\n          <Card>\n            <CardHeader>\n              <QuestionnaireTitle id={timingTitleId} render={<CardTitle />}>\n                When should this be revisited?\n              </QuestionnaireTitle>\n              <QuestionnaireDescription render={<CardDescription />}>\n                Choose when this should be revisited.\n              </QuestionnaireDescription>\n              <CardAction>\n                <QuestionnaireProgress />\n              </CardAction>\n            </CardHeader>\n            <CardContent>\n              <QuestionnaireChoices>\n                <QuestionnaireChoice value=\"week\">\n                  This week\n                </QuestionnaireChoice>\n                <QuestionnaireChoice value=\"cycle\">\n                  Next cycle\n                </QuestionnaireChoice>\n                <QuestionnaireChoice value=\"later\">\n                  Revisit later\n                </QuestionnaireChoice>\n              </QuestionnaireChoices>\n              <QuestionnaireError />\n            </CardContent>\n          </Card>\n        </QuestionnaireItem>\n        <QuestionnaireNavigation />\n      </Questionnaire>"
        }
      ]
    },
    {
      "name": "radio-group",
      "title": "Radio Group",
      "description": "A set of radio buttons for single-selection from a list of options.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/radio-group",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/radio-group.tsx"
      ],
      "storyTitle": "Shadcn UI/Radio Group",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Radio group with three options, the first selected by default, demonstrating standard single-selection behavior.",
          "code": "<RadioGroup defaultValue=\"option-1\">\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"option-1\" id=\"option-1\" />\n        <Label htmlFor=\"option-1\">Option 1</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"option-2\" id=\"option-2\" />\n        <Label htmlFor=\"option-2\">Option 2</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"option-3\" id=\"option-3\" />\n        <Label htmlFor=\"option-3\">Option 3</Label>\n      </div>\n    </RadioGroup>"
        },
        {
          "name": "Disabled",
          "description": "Radio group comparing an enabled option against a disabled option with muted label styling.",
          "code": "<RadioGroup defaultValue=\"option-1\">\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"option-1\" id=\"disabled-1\" />\n        <Label htmlFor=\"disabled-1\">Enabled</Label>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <RadioGroupItem value=\"option-2\" id=\"disabled-2\" disabled />\n        <Label htmlFor=\"disabled-2\" className=\"text-muted-foreground\">\n          Disabled\n        </Label>\n      </div>\n    </RadioGroup>"
        }
      ]
    },
    {
      "name": "resizable",
      "title": "Resizable",
      "description": "Resizable panel layouts with drag handles for adjustable split views.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/resizable",
      "dependencies": [
        "cn",
        "react-resizable-panels"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/resizable.tsx"
      ],
      "storyTitle": "Shadcn UI/Resizable",
      "props": [],
      "stories": [
        {
          "name": "Horizontal",
          "description": "Horizontal split-panel layout with two resizable panels and a visible drag handle.",
          "code": "<ResizablePanelGroup\n      orientation=\"horizontal\"\n      className=\"min-h-48 max-w-lg rounded-2xl border\"\n    >\n      <ResizablePanel defaultSize={50}>\n        <div className=\"flex h-full items-center justify-center p-4\">\n          <span className=\"text-sm text-muted-foreground\">Panel 1</span>\n        </div>\n      </ResizablePanel>\n      <ResizableHandle withHandle />\n      <ResizablePanel defaultSize={50}>\n        <div className=\"flex h-full items-center justify-center p-4\">\n          <span className=\"text-sm text-muted-foreground\">Panel 2</span>\n        </div>\n      </ResizablePanel>\n    </ResizablePanelGroup>"
        },
        {
          "name": "Vertical",
          "description": "",
          "code": "<ResizablePanelGroup\n      orientation=\"vertical\"\n      className=\"min-h-48 max-w-lg rounded-2xl border\"\n    >\n      <ResizablePanel defaultSize={50}>\n        <div className=\"flex h-full items-center justify-center p-4\">\n          <span className=\"text-sm text-muted-foreground\">Top</span>\n        </div>\n      </ResizablePanel>\n      <ResizableHandle withHandle />\n      <ResizablePanel defaultSize={50}>\n        <div className=\"flex h-full items-center justify-center p-4\">\n          <span className=\"text-sm text-muted-foreground\">Bottom</span>\n        </div>\n      </ResizablePanel>\n    </ResizablePanelGroup>"
        },
        {
          "name": "ThreePanels",
          "description": "",
          "code": "<ResizablePanelGroup\n      orientation=\"horizontal\"\n      className=\"min-h-48 max-w-2xl rounded-2xl border\"\n    >\n      <ResizablePanel defaultSize={25} minSize={15}>\n        <div className=\"flex h-full items-center justify-center p-4\">\n          <span className=\"text-sm text-muted-foreground\">Sidebar</span>\n        </div>\n      </ResizablePanel>\n      <ResizableHandle />\n      <ResizablePanel defaultSize={50}>\n        <div className=\"flex h-full items-center justify-center p-4\">\n          <span className=\"text-sm text-muted-foreground\">Content</span>\n        </div>\n      </ResizablePanel>\n      <ResizableHandle withHandle />\n      <ResizablePanel defaultSize={25} minSize={15}>\n        <div className=\"flex h-full items-center justify-center p-4\">\n          <span className=\"text-sm text-muted-foreground\">Details</span>\n        </div>\n      </ResizablePanel>\n    </ResizablePanelGroup>"
        }
      ]
    },
    {
      "name": "scroll-area",
      "title": "Scroll Area",
      "description": "A custom scroll wrapper that replaces browser scrollbars with cross-browser consistent, styling-flexible scroll rails.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/scroll-area",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/scroll-area.tsx"
      ],
      "storyTitle": "Shadcn UI/ScrollArea",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Custom scroll area with long lorem ipsum text, demonstrating custom scrollbar styling and keyboard focus support.",
          "code": "<ScrollArea className=\"h-40 w-full rounded-lg border p-4\">\n      <p>\n        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod\n        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim\n        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea\n        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate\n        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n        occaecat cupidatat non proident, sunt in culpa qui officia deserunt\n        mollit anim id est laborum.\n      </p>\n      <p>\n        Sed ut perspiciatis unde omnis iste natus error sit voluptatem\n        accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab\n        illo inventore veritatis et quasi architecto beatae vitae dicta sunt\n        explicabo.\n      </p>\n    </ScrollArea>"
        },
        {
          "name": "Horizontal",
          "description": "",
          "code": "<ScrollArea className=\"h-20 w-full rounded-lg border p-4\">\n      <div className=\"flex w-max gap-4\">\n        {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((i) => (\n          <div\n            key={i}\n            className=\"flex h-12 w-24 items-center justify-center rounded-md bg-muted\"\n          >\n            Item {i}\n          </div>\n        ))}\n      </div>\n    </ScrollArea>"
        },
        {
          "name": "Small",
          "description": "",
          "code": "<ScrollArea className=\"h-24 w-64 rounded-lg border p-4\">\n      <p>\n        Short content that might not overflow but shows the scroll area styling.\n      </p>\n    </ScrollArea>"
        },
        {
          "name": "LongContent",
          "description": "",
          "code": "<ScrollArea className=\"h-60 w-full max-w-sm rounded-lg border p-4\">\n      {Array.from({ length: 20 }, (_, i) => (\n        <p key={i} className=\"mb-2\">\n          Line {i + 1}: Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n        </p>\n      ))}\n    </ScrollArea>"
        }
      ]
    },
    {
      "name": "select",
      "title": "Select",
      "description": "A dropdown select component with groups, labels, scroll buttons, and item selection.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/select",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/select.tsx"
      ],
      "storyTitle": "Shadcn UI/Select",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Select dropdown with four fruit options and a placeholder, using the default trigger and content positioning.",
          "code": "<Select>\n      <SelectTrigger className=\"w-48\" aria-label=\"Select a fruit\">\n        <SelectValue placeholder=\"Select a fruit\" />\n      </SelectTrigger>\n      <SelectContent>\n        <SelectItem value=\"apple\">Apple</SelectItem>\n        <SelectItem value=\"banana\">Banana</SelectItem>\n        <SelectItem value=\"orange\">Orange</SelectItem>\n        <SelectItem value=\"grape\">Grape</SelectItem>\n      </SelectContent>\n    </Select>"
        },
        {
          "name": "Sizes",
          "description": "",
          "code": "<div className=\"flex items-center gap-4\">\n      <Select defaultValue=\"sm\">\n        <SelectTrigger size=\"sm\" className=\"w-40\" aria-label=\"Small select\">\n          <SelectValue />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"sm\">Small (sm)</SelectItem>\n          <SelectItem value=\"default\">Default</SelectItem>\n        </SelectContent>\n      </Select>\n      <Select defaultValue=\"default\">\n        <SelectTrigger\n          size=\"default\"\n          className=\"w-40\"\n          aria-label=\"Default select\"\n        >\n          <SelectValue />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectItem value=\"default\">Default</SelectItem>\n          <SelectItem value=\"sm\">Small (sm)</SelectItem>\n        </SelectContent>\n      </Select>\n    </div>"
        },
        {
          "name": "WithGroups",
          "description": "Select dropdown with options grouped into Fruits and Vegetables categories, separated by a divider.",
          "code": "<Select>\n      <SelectTrigger className=\"w-56\" aria-label=\"Select an option\">\n        <SelectValue placeholder=\"Select an option\" />\n      </SelectTrigger>\n      <SelectContent>\n        <SelectGroup>\n          <SelectLabel>Fruits</SelectLabel>\n          <SelectItem value=\"apple\">Apple</SelectItem>\n          <SelectItem value=\"banana\">Banana</SelectItem>\n          <SelectItem value=\"orange\">Orange</SelectItem>\n        </SelectGroup>\n        <SelectSeparator />\n        <SelectGroup>\n          <SelectLabel>Vegetables</SelectLabel>\n          <SelectItem value=\"carrot\">Carrot</SelectItem>\n          <SelectItem value=\"broccoli\">Broccoli</SelectItem>\n        </SelectGroup>\n      </SelectContent>\n    </Select>"
        },
        {
          "name": "PopperPosition",
          "description": "",
          "code": "<Select>\n      <SelectTrigger className=\"w-48\" aria-label=\"Popper position\">\n        <SelectValue placeholder=\"Popper position\" />\n      </SelectTrigger>\n      <SelectContent position=\"popper\">\n        <SelectItem value=\"1\">Option 1</SelectItem>\n        <SelectItem value=\"2\">Option 2</SelectItem>\n        <SelectItem value=\"3\">Option 3</SelectItem>\n      </SelectContent>\n    </Select>"
        }
      ]
    },
    {
      "name": "separator",
      "title": "Separator",
      "description": "A visual divider for separating content sections horizontally or vertically.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/separator",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/separator.tsx"
      ],
      "storyTitle": "Shadcn UI/Separator",
      "props": [
        {
          "name": "orientation",
          "control": "radio",
          "options": [
            "horizontal",
            "vertical"
          ],
          "description": "The axis along which the separator is rendered",
          "default": "horizontal"
        },
        {
          "name": "decorative",
          "control": "boolean",
          "description": "Whether the separator is purely decorative (not announced by screen readers)",
          "default": "true"
        }
      ],
      "stories": [
        {
          "name": "Horizontal",
          "description": "Horizontal divider separating two blocks of text to demonstrate visual content separation.",
          "args": "{\n    orientation: \"horizontal\",\n    decorative: true,\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Horizontal divider separating two blocks of text to demonstrate visual content separation.\",\n      },\n    },\n  },\n  render: (args) => (\n    <div className=\"flex flex-col gap-4\">\n      <p className=\"text-sm text-muted-foreground\">\n        Content above the separator\n      </p>\n      <Separator {...args} />\n      <p className=\"text-sm text-muted-foreground\">\n        Content below the separator\n      </p>\n    </div>\n  ),"
        },
        {
          "name": "Vertical",
          "description": "Vertical separator dividing three inline text labels in a flex row layout.",
          "code": "<div className=\"flex h-12 items-center gap-4\">\n      <span className=\"text-sm text-muted-foreground\">Left</span>\n      <Separator orientation=\"vertical\" />\n      <span className=\"text-sm text-muted-foreground\">Center</span>\n      <Separator orientation=\"vertical\" />\n      <span className=\"text-sm text-muted-foreground\">Right</span>\n    </div>"
        }
      ]
    },
    {
      "name": "sheet",
      "title": "Sheet",
      "description": "A slide-in panel (drawer) from any side of the screen with header, footer, and close button.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/sheet",
      "dependencies": [
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        "components/ui/sheet.tsx"
      ],
      "storyTitle": "Shadcn UI/Sheet",
      "props": [],
      "stories": [
        {
          "name": "Right",
          "description": "Slide-in panel from the right side with a profile editing form, header, footer, and close button.",
          "code": "<Sheet>\n      <SheetTrigger asChild>\n        <Button variant=\"outline\">Open Right Sheet</Button>\n      </SheetTrigger>\n      <SheetContent side=\"right\">\n        <SheetHeader>\n          <SheetTitle>Edit Profile</SheetTitle>\n          <SheetDescription>\n            Make changes to your profile here. Click save when you are done.\n          </SheetDescription>\n        </SheetHeader>\n        <div className=\"flex-1 p-6 pt-0\">\n          <p className=\"text-sm text-muted-foreground\">\n            Sheet content goes here. You can place any elements inside.\n          </p>\n        </div>\n        <SheetFooter>\n          <SheetClose asChild>\n            <Button variant=\"outline\">Cancel</Button>\n          </SheetClose>\n          <Button>Save Changes</Button>\n        </SheetFooter>\n      </SheetContent>\n    </Sheet>"
        },
        {
          "name": "Left",
          "description": "",
          "code": "<Sheet>\n      <SheetTrigger asChild>\n        <Button variant=\"outline\">Open Left Sheet</Button>\n      </SheetTrigger>\n      <SheetContent side=\"left\">\n        <SheetHeader>\n          <SheetTitle>Navigation</SheetTitle>\n          <SheetDescription>Browse through the sections.</SheetDescription>\n        </SheetHeader>\n        <div className=\"flex-1 p-6 pt-0\">\n          <nav className=\"flex flex-col gap-2\">\n            <Button variant=\"ghost\" className=\"justify-start\">\n              Dashboard\n            </Button>\n            <Button variant=\"ghost\" className=\"justify-start\">\n              Settings\n            </Button>\n            <Button variant=\"ghost\" className=\"justify-start\">\n              Profile\n            </Button>\n          </nav>\n        </div>\n      </SheetContent>\n    </Sheet>"
        },
        {
          "name": "Top",
          "description": "",
          "code": "<Sheet>\n      <SheetTrigger asChild>\n        <Button variant=\"outline\">Open Top Sheet</Button>\n      </SheetTrigger>\n      <SheetContent side=\"top\" className=\"h-48\">\n        <SheetHeader>\n          <SheetTitle>Notification</SheetTitle>\n          <SheetDescription>\n            This is a top slide-in notification panel.\n          </SheetDescription>\n        </SheetHeader>\n      </SheetContent>\n    </Sheet>"
        },
        {
          "name": "Bottom",
          "description": "",
          "code": "<Sheet>\n      <SheetTrigger asChild>\n        <Button variant=\"outline\">Open Bottom Sheet</Button>\n      </SheetTrigger>\n      <SheetContent side=\"bottom\" className=\"h-64\">\n        <SheetHeader>\n          <SheetTitle>Quick Actions</SheetTitle>\n          <SheetDescription>\n            Access frequently used actions from the bottom.\n          </SheetDescription>\n        </SheetHeader>\n        <div className=\"flex-1 p-6 pt-0\">\n          <div className=\"flex gap-2\">\n            <Button className=\"flex-1\">Action 1</Button>\n            <Button className=\"flex-1\" variant=\"outline\">\n              Action 2\n            </Button>\n          </div>\n        </div>\n      </SheetContent>\n    </Sheet>"
        },
        {
          "name": "WithoutCloseButton",
          "description": "",
          "code": "<Sheet>\n      <SheetTrigger asChild>\n        <Button variant=\"outline\">No Close Button</Button>\n      </SheetTrigger>\n      <SheetContent side=\"right\" showCloseButton={false}>\n        <SheetHeader>\n          <SheetTitle>Custom Close</SheetTitle>\n          <SheetDescription>\n            The default close button is hidden. Use a custom close mechanism.\n          </SheetDescription>\n        </SheetHeader>\n        <div className=\"flex-1 p-6 pt-0\">\n          <SheetClose asChild>\n            <Button variant=\"outline\" className=\"w-full\">\n              Close Manually\n            </Button>\n          </SheetClose>\n        </div>\n      </SheetContent>\n    </Sheet>"
        }
      ]
    },
    {
      "name": "sidebar",
      "title": "Sidebar",
      "description": "A responsive collapsible sidebar with menu, groups, tooltips, and mobile sheet support.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/sidebar",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui",
        "lucide-react"
      ],
      "registryDependencies": [
        "button",
        "input",
        "separator",
        "sheet",
        "skeleton",
        "tooltip"
      ],
      "files": [
        "components/ui/sidebar.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"outline\"",
          "options": [
            "default",
            "outline"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"default\" | \"sm\" | \"lg\"",
          "options": [
            "default",
            "sm",
            "lg"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Sidebar",
      "stories": [
        {
          "name": "Default",
          "description": "Full-featured sidebar with search input, grouped navigation menus, footer links, and a collapsible rail."
        }
      ]
    },
    {
      "name": "skeleton",
      "title": "Skeleton",
      "description": "A placeholder loading state component shaped as elements to outline UI containers during data fetching lifecycle phases.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/skeleton",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/skeleton.tsx"
      ],
      "storyTitle": "Shadcn UI/Skeleton",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Small rectangular skeleton placeholder with animate-pulse to indicate loading content.",
          "args": "{\n    className: \"h-4 w-20\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Small rectangular skeleton placeholder with animate-pulse to indicate loading content.\",\n      },\n    },\n  },"
        },
        {
          "name": "Variants",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <Skeleton className=\"h-4 w-20\" />\n      <Skeleton className=\"h-4 w-32\" />\n      <Skeleton className=\"h-4 w-24\" />\n    </div>"
        },
        {
          "name": "Card",
          "description": "",
          "code": "<div className=\"flex w-full max-w-sm flex-col gap-3 rounded-lg border p-4\">\n      <Skeleton className=\"h-6 w-3/4\" />\n      <Skeleton className=\"h-4 w-full\" />\n      <Skeleton className=\"h-4 w-2/3\" />\n    </div>"
        },
        {
          "name": "Avatar",
          "description": "",
          "code": "<div className=\"flex items-center gap-3\">\n      <Skeleton className=\"size-10 rounded-full\" />\n      <div className=\"flex flex-col gap-1\">\n        <Skeleton className=\"h-4 w-24\" />\n        <Skeleton className=\"h-3 w-16\" />\n      </div>\n    </div>"
        },
        {
          "name": "Image",
          "description": "",
          "code": "<Skeleton className=\"aspect-video w-full max-w-sm rounded-lg\" />"
        }
      ]
    },
    {
      "name": "slider",
      "title": "Slider",
      "description": "A range slider for numeric input with single or multiple thumb handles.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/slider",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/slider.tsx"
      ],
      "storyTitle": "Shadcn UI/Slider",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Single-thumb slider at value 50 within a 0–100 range for selecting one value.",
          "args": "{\n    defaultValue: [50],\n    max: 100,\n    min: 0,\n    \"aria-label\": \"Slider value\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Single-thumb slider at value 50 within a 0–100 range for selecting one value.\",\n      },\n    },\n  },"
        },
        {
          "name": "Range",
          "description": "Dual-thumb slider with values at 25 and 75 for selecting a range between two points.",
          "args": "{\n    defaultValue: [25, 75],\n    max: 100,\n    min: 0,\n    step: 1,\n    \"aria-label\": \"Range slider\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Dual-thumb slider with values at 25 and 75 for selecting a range between two points.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithSteps",
          "description": "",
          "args": "{\n    defaultValue: [2],\n    max: 10,\n    min: 0,\n    step: 2,\n    \"aria-label\": \"Slider with steps\",\n  },"
        },
        {
          "name": "Disabled",
          "description": "Single-thumb slider at value 40 in a disabled state, preventing user interaction.",
          "args": "{\n    defaultValue: [40],\n    max: 100,\n    min: 0,\n    disabled: true,\n    \"aria-label\": \"Disabled slider\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Single-thumb slider at value 40 in a disabled state, preventing user interaction.\",\n      },\n    },\n  },"
        }
      ]
    },
    {
      "name": "sonner",
      "title": "Sonner",
      "description": "A toast notification provider using the Sonner library with theme-aware styling.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/sonner",
      "dependencies": [
        "next-themes",
        "sonner",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/sonner.tsx"
      ],
      "storyTitle": "Shadcn UI/Sonner (Toaster)",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Toast system with buttons to trigger a basic text toast and a toast with an additional description message.",
          "code": "<>\n      <Toaster />\n      <div className=\"flex flex-wrap gap-2\">\n        <Button variant=\"outline\" onClick={() => toast(\"Hello, world!\")}>\n          Default Toast\n        </Button>\n        <Button\n          variant=\"outline\"\n          onClick={() =>\n            toast(\"Your changes have been saved.\", {\n              description: \"The operation completed successfully.\",\n            })\n          }\n        >\n          With Description\n        </Button>\n      </div>\n    </>"
        },
        {
          "name": "Variants",
          "description": "",
          "code": "<>\n      <Toaster />\n      <div className=\"flex flex-wrap gap-2\">\n        <Button onClick={() => toast.success(\"Data saved successfully\")}>\n          Success\n        </Button>\n        <Button\n          variant=\"outline\"\n          onClick={() => toast.info(\"You have 3 new messages\")}\n        >\n          Info\n        </Button>\n        <Button\n          variant=\"secondary\"\n          onClick={() => toast.warning(\"Disk space is running low\")}\n        >\n          Warning\n        </Button>\n        <Button\n          variant=\"destructive\"\n          onClick={() => toast.error(\"Something went wrong\")}\n        >\n          Error\n        </Button>\n      </div>\n    </>"
        },
        {
          "name": "Loading",
          "description": "",
          "code": "<>\n      <Toaster />\n      <Button\n        variant=\"outline\"\n        onClick={() => {\n          const id = toast.loading(\"Uploading file...\")\n          setTimeout(() => toast.success(\"Upload complete!\", { id }), 2000)\n        }}\n      >\n        Simulate Loading\n      </Button>\n    </>"
        },
        {
          "name": "Dismissable",
          "description": "",
          "code": "<>\n      <Toaster />\n      <div className=\"flex flex-wrap gap-2\">\n        <Button\n          variant=\"outline\"\n          onClick={() =>\n            toast(\"This will auto-dismiss\", {\n              duration: 3000,\n            })\n          }\n        >\n          3s Auto-dismiss\n        </Button>\n        <Button\n          variant=\"outline\"\n          onClick={() =>\n            toast(\"Sticky notification\", {\n              duration: Infinity,\n            })\n          }\n        >\n          Sticky (no dismiss)\n        </Button>\n      </div>\n    </>"
        }
      ]
    },
    {
      "name": "spinner",
      "title": "Spinner",
      "description": "An animated loader icon used to represent background processing, async submission delays, or loading data sequences.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/spinner",
      "dependencies": [
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/spinner.tsx"
      ],
      "storyTitle": "Shadcn UI/Spinner",
      "props": [
        {
          "name": "className",
          "control": "text"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Default-sized spinning loader icon inheriting color from the parent text."
        },
        {
          "name": "CustomSize",
          "description": "Spinner icons displayed at four different sizes (3, 4, 6, 8) to demonstrate size flexibility.",
          "code": "<div className=\"flex items-center gap-4\">\n      <Spinner className=\"size-3\" />\n      <Spinner className=\"size-4\" />\n      <Spinner className=\"size-6\" />\n      <Spinner className=\"size-8\" />\n    </div>"
        },
        {
          "name": "InContext",
          "description": "Spinner paired with contextual loading text labels to show typical inline usage.",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n        <Spinner />\n        Loading data…\n      </div>\n      <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n        <Spinner className=\"size-5\" />\n        Processing request…\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "switch",
      "title": "Switch",
      "description": "A toggle switch control for binary settings with size variants.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/switch",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/switch.tsx"
      ],
      "storyTitle": "Shadcn UI/Switch",
      "props": [
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "default",
            "sm"
          ],
          "description": "Switch size preset",
          "default": "default"
        },
        {
          "name": "disabled",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "defaultChecked",
          "control": "boolean",
          "default": "false"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Toggle switch in the default size preset, demonstrating the unchecked state.",
          "args": "{\n    size: \"default\",\n    \"aria-label\": \"Toggle switch\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Toggle switch in the default size preset, demonstrating the unchecked state.\",\n      },\n    },\n  },"
        },
        {
          "name": "Sizes",
          "description": "Two toggled-on switches comparing the small and default size presets side by side.",
          "code": "<div className=\"flex items-center gap-6\">\n      <Switch size=\"sm\" defaultChecked aria-label=\"Small switch\" />\n      <Switch size=\"default\" defaultChecked aria-label=\"Default switch\" />\n    </div>"
        },
        {
          "name": "States",
          "description": "",
          "code": "<div className=\"flex flex-col gap-4\">\n      <div className=\"flex items-center gap-4\">\n        <Switch aria-label=\"Unchecked switch\" />\n        <span className=\"text-sm text-muted-foreground\">Unchecked</span>\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <Switch defaultChecked aria-label=\"Checked switch\" />\n        <span className=\"text-sm text-muted-foreground\">Checked</span>\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <Switch disabled aria-label=\"Disabled unchecked switch\" />\n        <span className=\"text-sm text-muted-foreground\">\n          Disabled unchecked\n        </span>\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <Switch disabled defaultChecked aria-label=\"Disabled checked switch\" />\n        <span className=\"text-sm text-muted-foreground\">Disabled checked</span>\n      </div>\n    </div>"
        }
      ]
    },
    {
      "name": "table",
      "title": "Table",
      "description": "A responsive table component built using native HTML table elements styled with Tailwind CSS.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/table",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/table.tsx"
      ],
      "storyTitle": "Shadcn UI/Table",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Responsive table with header, body rows, and a caption displaying invoice data with right-aligned amounts.",
          "code": "<div className=\"w-full max-w-3xl rounded-md border\">\n      <Table>\n        <TableCaption>A list of your recent invoices.</TableCaption>\n        <TableHeader>\n          <TableRow>\n            <TableHead className=\"w-[100px]\">Invoice</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead>Method</TableHead>\n            <TableHead className=\"text-right\">Amount</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          {invoices.map((invoice) => (\n            <TableRow key={invoice.invoice}>\n              <TableCell className=\"font-medium\">{invoice.invoice}</TableCell>\n              <TableCell>{invoice.paymentStatus}</TableCell>\n              <TableCell>{invoice.paymentMethod}</TableCell>\n              <TableCell className=\"text-right\">\n                {invoice.totalAmount}\n              </TableCell>\n            </TableRow>\n          ))}\n        </TableBody>\n      </Table>\n    </div>"
        },
        {
          "name": "WithFooter",
          "description": "",
          "code": "<div className=\"w-full max-w-3xl rounded-md border\">\n      <Table>\n        <TableHeader>\n          <TableRow>\n            <TableHead className=\"w-[100px]\">Invoice</TableHead>\n            <TableHead>Status</TableHead>\n            <TableHead>Method</TableHead>\n            <TableHead className=\"text-right\">Amount</TableHead>\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          {invoices.map((invoice) => (\n            <TableRow key={invoice.invoice}>\n              <TableCell className=\"font-medium\">{invoice.invoice}</TableCell>\n              <TableCell>{invoice.paymentStatus}</TableCell>\n              <TableCell>{invoice.paymentMethod}</TableCell>\n              <TableCell className=\"text-right\">\n                {invoice.totalAmount}\n              </TableCell>\n            </TableRow>\n          ))}\n        </TableBody>\n        <TableFooter>\n          <TableRow>\n            <TableCell colSpan={3}>Total</TableCell>\n            <TableCell className=\"text-right\">$1,750.00</TableCell>\n          </TableRow>\n        </TableFooter>\n      </Table>\n    </div>"
        }
      ]
    },
    {
      "name": "tabs",
      "title": "Tabs",
      "description": "A tabbed interface with list, trigger, and content panels supporting default and line variants.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/tabs",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/tabs.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"line\"",
          "options": [
            "default",
            "line"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Tabs",
      "stories": [
        {
          "name": "Default",
          "description": "Horizontal tabs with three sections (Account, Password, Notifications) and corresponding content panels.",
          "code": "<Tabs defaultValue=\"tab-1\" className=\"w-full max-w-md\">\n      <TabsList>\n        <TabsTrigger value=\"tab-1\">Account</TabsTrigger>\n        <TabsTrigger value=\"tab-2\">Password</TabsTrigger>\n        <TabsTrigger value=\"tab-3\">Notifications</TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">Account settings content.</TabsContent>\n      <TabsContent value=\"tab-2\">Password settings content.</TabsContent>\n      <TabsContent value=\"tab-3\">Notification preferences.</TabsContent>\n    </Tabs>"
        },
        {
          "name": "Variants",
          "description": "",
          "code": "<div className=\"flex w-full max-w-md flex-col gap-8\">\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Default variant</p>\n        <Tabs defaultValue=\"tab-1\">\n          <TabsList variant=\"default\">\n            <TabsTrigger value=\"tab-1\">Tab 1</TabsTrigger>\n            <TabsTrigger value=\"tab-2\">Tab 2</TabsTrigger>\n            <TabsTrigger value=\"tab-3\">Tab 3</TabsTrigger>\n          </TabsList>\n          <TabsContent value=\"tab-1\">Content 1</TabsContent>\n          <TabsContent value=\"tab-2\">Content 2</TabsContent>\n          <TabsContent value=\"tab-3\">Content 3</TabsContent>\n        </Tabs>\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Line variant</p>\n        <Tabs defaultValue=\"tab-1\">\n          <TabsList variant=\"line\">\n            <TabsTrigger value=\"tab-1\">Tab 1</TabsTrigger>\n            <TabsTrigger value=\"tab-2\">Tab 2</TabsTrigger>\n            <TabsTrigger value=\"tab-3\">Tab 3</TabsTrigger>\n          </TabsList>\n          <TabsContent value=\"tab-1\">Content 1</TabsContent>\n          <TabsContent value=\"tab-2\">Content 2</TabsContent>\n          <TabsContent value=\"tab-3\">Content 3</TabsContent>\n        </Tabs>\n      </div>\n    </div>"
        },
        {
          "name": "Vertical",
          "description": "Tabs arranged vertically with the list on the left and content panels on the right.",
          "code": "<Tabs defaultValue=\"tab-1\" orientation=\"vertical\" className=\"max-w-sm\">\n      <TabsList>\n        <TabsTrigger value=\"tab-1\">Profile</TabsTrigger>\n        <TabsTrigger value=\"tab-2\">Security</TabsTrigger>\n        <TabsTrigger value=\"tab-3\">Billing</TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">Profile information.</TabsContent>\n      <TabsContent value=\"tab-2\">Security settings.</TabsContent>\n      <TabsContent value=\"tab-3\">Billing details.</TabsContent>\n    </Tabs>"
        },
        {
          "name": "Disabled",
          "description": "",
          "code": "<Tabs defaultValue=\"tab-1\" className=\"w-full max-w-md\">\n      <TabsList>\n        <TabsTrigger value=\"tab-1\">Active</TabsTrigger>\n        <TabsTrigger value=\"tab-2\" disabled>\n          Disabled\n        </TabsTrigger>\n        <TabsTrigger value=\"tab-3\">Available</TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab-1\">Active content</TabsContent>\n      <TabsContent value=\"tab-2\">Disabled content</TabsContent>\n      <TabsContent value=\"tab-3\">Available content</TabsContent>\n    </Tabs>"
        }
      ]
    },
    {
      "name": "textarea",
      "title": "Textarea",
      "description": "A multi-line text input field supporting dynamic sizing, transition glows, and custom invalid validation borders.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/textarea",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/textarea.tsx"
      ],
      "storyTitle": "Shadcn UI/Textarea",
      "props": [
        {
          "name": "disabled",
          "control": "boolean",
          "default": "false"
        },
        {
          "name": "placeholder",
          "control": "text",
          "default": ""
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Multi-line text input with a placeholder prompting the user to enter a message.",
          "args": "{\n    placeholder: \"Enter your message...\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Multi-line text input with a placeholder prompting the user to enter a message.\",\n      },\n    },\n  },"
        },
        {
          "name": "WithValue",
          "description": "",
          "args": "{\n    \"aria-label\": \"Message content\",\n    value: \"This is a pre-filled textarea with some content.\",\n  },"
        },
        {
          "name": "Disabled",
          "description": "Textarea in a disabled state with a placeholder indicating it cannot be edited.",
          "args": "{\n    disabled: true,\n    placeholder: \"Disabled textarea\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Textarea in a disabled state with a placeholder indicating it cannot be edited.\",\n      },\n    },\n  },"
        },
        {
          "name": "Invalid",
          "description": "Textarea in an invalid state with destructive border styling indicated by aria-invalid.",
          "args": "{\n    \"aria-invalid\": true,\n    placeholder: \"Invalid textarea\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Textarea in an invalid state with destructive border styling indicated by aria-invalid.\",\n      },\n    },\n  },"
        },
        {
          "name": "Rows",
          "description": "",
          "code": "<div className=\"flex w-full max-w-sm flex-col gap-4\">\n      <Textarea placeholder=\"Default rows\" aria-label=\"Default rows\" />\n      <Textarea rows={3} placeholder=\"3 rows\" aria-label=\"3 rows\" />\n      <Textarea rows={5} placeholder=\"5 rows\" aria-label=\"5 rows\" />\n      <Textarea rows={10} placeholder=\"10 rows\" aria-label=\"10 rows\" />\n    </div>"
        }
      ]
    },
    {
      "name": "toggle",
      "title": "Toggle",
      "description": "A two-state button for on/off toggling with variants and sizes.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/toggle",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/toggle.tsx"
      ],
      "props": [
        {
          "name": "variant",
          "required": false,
          "type": "\"default\" | \"outline\"",
          "options": [
            "default",
            "outline"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "required": false,
          "type": "\"default\" | \"sm\" | \"lg\"",
          "options": [
            "default",
            "sm",
            "lg"
          ],
          "default": "default"
        }
      ],
      "storyTitle": "Shadcn UI/Toggle",
      "stories": [
        {
          "name": "Default",
          "description": "Default variant toggle button in standard size with a text label.",
          "args": "{\n    children: \"Toggle\",\n    variant: \"default\",\n    size: \"default\",\n  },\n  parameters: {\n    docs: {\n      description: {\n        story:\n          \"Default variant toggle button in standard size with a text label.\",\n      },\n    },\n  },"
        },
        {
          "name": "Variants",
          "description": "Default and outline toggle variants displayed side by side for visual comparison.",
          "code": "<div className=\"flex items-center gap-4\">\n      <Toggle variant=\"default\" aria-label=\"Toggle default\">\n        Default\n      </Toggle>\n      <Toggle variant=\"outline\" aria-label=\"Toggle outline\">\n        Outline\n      </Toggle>\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "Toggle buttons in small, default, and large sizes to demonstrate the three size presets.",
          "code": "<div className=\"flex items-center gap-4\">\n      <Toggle size=\"sm\" aria-label=\"Small toggle\">\n        Small\n      </Toggle>\n      <Toggle size=\"default\" aria-label=\"Default toggle\">\n        Default\n      </Toggle>\n      <Toggle size=\"lg\" aria-label=\"Large toggle\">\n        Large\n      </Toggle>\n    </div>"
        },
        {
          "name": "WithIcons",
          "description": "",
          "code": "<div className=\"flex items-center gap-4\">\n      <Toggle aria-label=\"Toggle bold\">\n        <BoldIcon data-icon=\"inline-start\" />\n        Bold\n      </Toggle>\n      <Toggle aria-label=\"Toggle italic\">\n        <ItalicIcon data-icon=\"inline-start\" />\n        Italic\n      </Toggle>\n      <Toggle aria-label=\"Toggle underline\">\n        <UnderlineIcon data-icon=\"inline-start\" />\n        Underline\n      </Toggle>\n    </div>"
        },
        {
          "name": "Pressed",
          "description": "",
          "code": "<div className=\"flex items-center gap-4\">\n      <Toggle pressed aria-label=\"Toggle bold\">\n        <BoldIcon data-icon=\"inline-start\" />\n      </Toggle>\n      <Toggle pressed variant=\"outline\" aria-label=\"Toggle italic\">\n        <ItalicIcon data-icon=\"inline-start\" />\n      </Toggle>\n    </div>"
        },
        {
          "name": "Disabled",
          "description": "Toggle buttons in disabled state across default and outline variants, including a disabled pressed state.",
          "code": "<div className=\"flex items-center gap-4\">\n      <Toggle disabled variant=\"default\" aria-label=\"Disabled default\">\n        Disabled\n      </Toggle>\n      <Toggle disabled variant=\"outline\" aria-label=\"Disabled outline\">\n        Disabled\n      </Toggle>\n      <Toggle disabled pressed variant=\"outline\" aria-label=\"Disabled pressed\">\n        Disabled Pressed\n      </Toggle>\n    </div>"
        }
      ]
    },
    {
      "name": "toggle-group",
      "title": "Toggle Group",
      "description": "A group of toggle buttons for multi-selection with connected or separated styling.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/toggle-group",
      "dependencies": [
        "class-variance-authority",
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [
        "toggle"
      ],
      "files": [
        "components/ui/toggle-group.tsx"
      ],
      "storyTitle": "Shadcn UI/Toggle Group",
      "props": [
        {
          "name": "type",
          "control": "inline-radio",
          "options": [
            "single",
            "multiple"
          ],
          "description": "Selection behavior",
          "default": "single"
        },
        {
          "name": "orientation",
          "control": "inline-radio",
          "options": [
            "horizontal",
            "vertical"
          ],
          "default": "horizontal"
        },
        {
          "name": "spacing",
          "control": "number",
          "description": "Gap between items (0 = connected/segmented)",
          "default": "2"
        },
        {
          "name": "variant",
          "control": "inline-radio",
          "options": [
            "default",
            "outline"
          ],
          "default": "default"
        },
        {
          "name": "size",
          "control": "inline-radio",
          "options": [
            "default",
            "sm",
            "lg"
          ],
          "default": "default"
        }
      ],
      "stories": [
        {
          "name": "Default",
          "description": "Horizontal toggle group with multiple selection enabled and three formatting icon buttons.",
          "args": "{ type: \"multiple\" } as any,\n  render: () => (\n    <ToggleGroup type=\"multiple\">\n      <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n        <BoldIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n        <ItalicIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n        <UnderlineIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n    </ToggleGroup>\n  ),",
          "code": "<ToggleGroup type=\"multiple\">\n      <ToggleGroupItem value=\"bold\" aria-label=\"Toggle bold\">\n        <BoldIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"italic\" aria-label=\"Toggle italic\">\n        <ItalicIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"underline\" aria-label=\"Toggle underline\">\n        <UnderlineIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n    </ToggleGroup>"
        },
        {
          "name": "Variants",
          "description": "",
          "args": "{ type: \"multiple\" } as any,\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Default variant</p>\n        <ToggleGroup type=\"multiple\" variant=\"default\">\n          <ToggleGroupItem value=\"bold\" aria-label=\"Bold\">\n            <BoldIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"italic\" aria-label=\"Italic\">\n            <ItalicIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"underline\" aria-label=\"Underline\">\n            <UnderlineIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n        </ToggleGroup>\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Outline variant</p>\n        <ToggleGroup type=\"multiple\" variant=\"outline\">\n          <ToggleGroupItem value=\"bold\" aria-label=\"Bold\">\n            <BoldIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"italic\" aria-label=\"Italic\">\n            <ItalicIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"underline\" aria-label=\"Underline\">\n            <UnderlineIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n        </ToggleGroup>\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Default variant</p>\n        <ToggleGroup type=\"multiple\" variant=\"default\">\n          <ToggleGroupItem value=\"bold\" aria-label=\"Bold\">\n            <BoldIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"italic\" aria-label=\"Italic\">\n            <ItalicIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"underline\" aria-label=\"Underline\">\n            <UnderlineIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n        </ToggleGroup>\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Outline variant</p>\n        <ToggleGroup type=\"multiple\" variant=\"outline\">\n          <ToggleGroupItem value=\"bold\" aria-label=\"Bold\">\n            <BoldIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"italic\" aria-label=\"Italic\">\n            <ItalicIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"underline\" aria-label=\"Underline\">\n            <UnderlineIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n        </ToggleGroup>\n      </div>\n    </div>"
        },
        {
          "name": "Sizes",
          "description": "Toggle groups in small and large sizes demonstrating the size presets with alignment icons.",
          "args": "{ type: \"multiple\" } as any,\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Small</p>\n        <ToggleGroup type=\"multiple\" size=\"sm\">\n          <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n            <AlignLeftIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n            <AlignCenterIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n            <AlignRightIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n        </ToggleGroup>\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Large</p>\n        <ToggleGroup type=\"multiple\" size=\"lg\">\n          <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n            <AlignLeftIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n            <AlignCenterIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n            <AlignRightIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n        </ToggleGroup>\n      </div>\n    </div>\n  ),",
          "code": "<div className=\"flex flex-col gap-6\">\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Small</p>\n        <ToggleGroup type=\"multiple\" size=\"sm\">\n          <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n            <AlignLeftIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n            <AlignCenterIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n            <AlignRightIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n        </ToggleGroup>\n      </div>\n      <div>\n        <p className=\"mb-2 text-sm text-muted-foreground\">Large</p>\n        <ToggleGroup type=\"multiple\" size=\"lg\">\n          <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n            <AlignLeftIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n            <AlignCenterIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n          <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n            <AlignRightIcon data-icon=\"inline-start\" />\n          </ToggleGroupItem>\n        </ToggleGroup>\n      </div>\n    </div>"
        },
        {
          "name": "Segmented",
          "description": "",
          "args": "{ type: \"single\" } as any,\n  render: () => (\n    <ToggleGroup type=\"single\" variant=\"outline\" spacing={0}>\n      <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n        <AlignLeftIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n        <AlignCenterIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n        <AlignRightIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n    </ToggleGroup>\n  ),",
          "code": "<ToggleGroup type=\"single\" variant=\"outline\" spacing={0}>\n      <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n        <AlignLeftIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n        <AlignCenterIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n        <AlignRightIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n    </ToggleGroup>"
        },
        {
          "name": "Vertical",
          "description": "Toggle group arranged vertically with multiple selection for formatting options.",
          "args": "{ type: \"multiple\" } as any,\n  render: () => (\n    <ToggleGroup type=\"multiple\" orientation=\"vertical\">\n      <ToggleGroupItem value=\"bold\" aria-label=\"Bold\">\n        <BoldIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"italic\" aria-label=\"Italic\">\n        <ItalicIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"underline\" aria-label=\"Underline\">\n        <UnderlineIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n    </ToggleGroup>\n  ),",
          "code": "<ToggleGroup type=\"multiple\" orientation=\"vertical\">\n      <ToggleGroupItem value=\"bold\" aria-label=\"Bold\">\n        <BoldIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"italic\" aria-label=\"Italic\">\n        <ItalicIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"underline\" aria-label=\"Underline\">\n        <UnderlineIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n    </ToggleGroup>"
        },
        {
          "name": "Single",
          "description": "",
          "args": "{ type: \"single\" } as any,\n  render: () => (\n    <ToggleGroup type=\"single\" defaultValue=\"center\">\n      <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n        <AlignLeftIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n        <AlignCenterIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n        <AlignRightIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n    </ToggleGroup>\n  ),",
          "code": "<ToggleGroup type=\"single\" defaultValue=\"center\">\n      <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n        <AlignLeftIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n        <AlignCenterIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n        <AlignRightIcon data-icon=\"inline-start\" />\n      </ToggleGroupItem>\n    </ToggleGroup>"
        }
      ]
    },
    {
      "name": "tooltip",
      "title": "Tooltip",
      "description": "A lightweight popup hint displaying auxiliary text descriptions when a cursor hovers over or focus lands on trigger targets.",
      "type": "registry:ui",
      "category": "ui",
      "importPath": "@/components/ui/tooltip",
      "dependencies": [
        "cn",
        "radix-ui"
      ],
      "registryDependencies": [],
      "files": [
        "components/ui/tooltip.tsx"
      ],
      "storyTitle": "Shadcn UI/Tooltip",
      "props": [],
      "stories": [
        {
          "name": "Default",
          "description": "Basic tooltip displaying 'Add to library' when hovering over the trigger button.",
          "code": "<TooltipProvider>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\">Hover me</Button>\n        </TooltipTrigger>\n        <TooltipContent>\n          <p>Add to library</p>\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>"
        },
        {
          "name": "Sides",
          "description": "",
          "code": "<TooltipProvider>\n      <div className=\"flex gap-4\">\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <Button variant=\"outline\">Top</Button>\n          </TooltipTrigger>\n          <TooltipContent side=\"top\">\n            <p>Tooltip on top</p>\n          </TooltipContent>\n        </Tooltip>\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <Button variant=\"outline\">Right</Button>\n          </TooltipTrigger>\n          <TooltipContent side=\"right\">\n            <p>Tooltip on right</p>\n          </TooltipContent>\n        </Tooltip>\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <Button variant=\"outline\">Bottom</Button>\n          </TooltipTrigger>\n          <TooltipContent side=\"bottom\">\n            <p>Tooltip on bottom</p>\n          </TooltipContent>\n        </Tooltip>\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <Button variant=\"outline\">Left</Button>\n          </TooltipTrigger>\n          <TooltipContent side=\"left\">\n            <p>Tooltip on left</p>\n          </TooltipContent>\n        </Tooltip>\n      </div>\n    </TooltipProvider>"
        },
        {
          "name": "Delay",
          "description": "",
          "code": "<TooltipProvider delayDuration={700}>\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button variant=\"outline\">700ms delay</Button>\n        </TooltipTrigger>\n        <TooltipContent>\n          <p>Delayed tooltip</p>\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>"
        }
      ]
    },
    {
      "name": "ui-i18n",
      "title": "UI i18n",
      "description": "Shared locale-based i18n dictionary with en-US, pt-PR, es-ES, and fr-FR support for UI components.",
      "type": "registry:lib",
      "category": "lib",
      "importPath": "@/lib/ui-i18n",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        "lib/ui-i18n.ts"
      ]
    }
  ]
}