{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "corsair",
  "homepage": "https://github.com/KevinGirelli/corsair-ui",
  "items": [
    {
      "name": "theme",
      "title": "Theme",
      "description": "Corsair colour, radius and base styles for light and dark mode. Every component relies on these variables; override --primary, --primary-foreground and --ring to apply your brand.",
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "colors": {
                "background": "color-mix(in oklab, var(--background) calc(<alpha-value> * 100%), transparent)",
                "foreground": "color-mix(in oklab, var(--foreground) calc(<alpha-value> * 100%), transparent)",
                "card": {
                  "DEFAULT": "color-mix(in oklab, var(--card) calc(<alpha-value> * 100%), transparent)",
                  "foreground": "color-mix(in oklab, var(--card-foreground) calc(<alpha-value> * 100%), transparent)"
                },
                "popover": {
                  "DEFAULT": "color-mix(in oklab, var(--popover) calc(<alpha-value> * 100%), transparent)",
                  "foreground": "color-mix(in oklab, var(--popover-foreground) calc(<alpha-value> * 100%), transparent)"
                },
                "primary": {
                  "DEFAULT": "color-mix(in oklab, var(--primary) calc(<alpha-value> * 100%), transparent)",
                  "foreground": "color-mix(in oklab, var(--primary-foreground) calc(<alpha-value> * 100%), transparent)"
                },
                "secondary": {
                  "DEFAULT": "color-mix(in oklab, var(--secondary) calc(<alpha-value> * 100%), transparent)",
                  "foreground": "color-mix(in oklab, var(--secondary-foreground) calc(<alpha-value> * 100%), transparent)"
                },
                "muted": {
                  "DEFAULT": "color-mix(in oklab, var(--muted) calc(<alpha-value> * 100%), transparent)",
                  "foreground": "color-mix(in oklab, var(--muted-foreground) calc(<alpha-value> * 100%), transparent)"
                },
                "accent": {
                  "DEFAULT": "color-mix(in oklab, var(--accent) calc(<alpha-value> * 100%), transparent)",
                  "foreground": "color-mix(in oklab, var(--accent-foreground) calc(<alpha-value> * 100%), transparent)"
                },
                "destructive": {
                  "DEFAULT": "color-mix(in oklab, var(--destructive) calc(<alpha-value> * 100%), transparent)",
                  "foreground": "color-mix(in oklab, var(--destructive-foreground) calc(<alpha-value> * 100%), transparent)"
                },
                "success": "color-mix(in oklab, var(--success) calc(<alpha-value> * 100%), transparent)",
                "warning": "color-mix(in oklab, var(--warning) calc(<alpha-value> * 100%), transparent)",
                "border": "color-mix(in oklab, var(--border) calc(<alpha-value> * 100%), transparent)",
                "input": "color-mix(in oklab, var(--input) calc(<alpha-value> * 100%), transparent)",
                "field": "color-mix(in oklab, var(--field) calc(<alpha-value> * 100%), transparent)",
                "ring": "color-mix(in oklab, var(--ring) calc(<alpha-value> * 100%), transparent)"
              },
              "borderRadius": {
                "sm": "max(0px, calc(var(--radius) - 4px))",
                "md": "max(0px, calc(var(--radius) - 2px))",
                "lg": "var(--radius)",
                "xl": "calc(var(--radius) + 4px)"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "color-background": "var(--background)",
          "color-foreground": "var(--foreground)",
          "color-card": "var(--card)",
          "color-card-foreground": "var(--card-foreground)",
          "color-popover": "var(--popover)",
          "color-popover-foreground": "var(--popover-foreground)",
          "color-primary": "var(--primary)",
          "color-primary-foreground": "var(--primary-foreground)",
          "color-secondary": "var(--secondary)",
          "color-secondary-foreground": "var(--secondary-foreground)",
          "color-muted": "var(--muted)",
          "color-muted-foreground": "var(--muted-foreground)",
          "color-accent": "var(--accent)",
          "color-accent-foreground": "var(--accent-foreground)",
          "color-destructive": "var(--destructive)",
          "color-destructive-foreground": "var(--destructive-foreground)",
          "color-success": "var(--success)",
          "color-warning": "var(--warning)",
          "color-border": "var(--border)",
          "color-input": "var(--input)",
          "color-field": "var(--field)",
          "color-ring": "var(--ring)",
          "radius-sm": "max(0px, calc(var(--radius) - 4px))",
          "radius-md": "max(0px, calc(var(--radius) - 2px))",
          "radius-lg": "var(--radius)",
          "radius-xl": "calc(var(--radius) + 4px)"
        },
        "light": {
          "radius": "0.625rem",
          "background": "#ffffff",
          "foreground": "#0a0a0a",
          "card": "#ffffff",
          "card-foreground": "#0a0a0a",
          "popover": "#ffffff",
          "popover-foreground": "#0a0a0a",
          "primary": "#171717",
          "primary-foreground": "#fafafa",
          "secondary": "#f5f5f5",
          "secondary-foreground": "#171717",
          "muted": "#f5f5f5",
          "muted-foreground": "#6f6f6f",
          "accent": "#f5f5f5",
          "accent-foreground": "#171717",
          "destructive": "#dc2626",
          "destructive-foreground": "#ffffff",
          "success": "#16a34a",
          "warning": "#d97706",
          "border": "#e5e5e5",
          "input": "#e5e5e5",
          "field": "#ffffff",
          "ring": "#737373"
        },
        "dark": {
          "background": "#0a0a0a",
          "foreground": "#fafafa",
          "card": "#171717",
          "card-foreground": "#fafafa",
          "popover": "#171717",
          "popover-foreground": "#fafafa",
          "primary": "#fafafa",
          "primary-foreground": "#171717",
          "secondary": "#262626",
          "secondary-foreground": "#fafafa",
          "muted": "#262626",
          "muted-foreground": "#a3a3a3",
          "accent": "#262626",
          "accent-foreground": "#fafafa",
          "destructive": "#ef4444",
          "destructive-foreground": "#0a0a0a",
          "success": "#4ade80",
          "warning": "#fbbf24",
          "border": "rgb(255 255 255 / 0.1)",
          "input": "rgb(255 255 255 / 0.15)",
          "field": "rgb(255 255 255 / 0.05)",
          "ring": "#737373"
        }
      },
      "css": {
        "@layer base": {
          "*": {
            "@apply border-border outline-ring/50": {}
          },
          "body": {
            "@apply bg-background text-foreground": {}
          }
        }
      },
      "type": "registry:theme"
    },
    {
      "name": "theme-blue",
      "title": "Theme: Blue",
      "description": "The Corsair theme on a slate base with a blue primary. Installs the theme first, then sets its colours and radius; every text pair meets WCAG AA.",
      "registryDependencies": [
        "@corsair-ui/theme"
      ],
      "cssVars": {
        "light": {
          "radius": "0.625rem",
          "background": "#ffffff",
          "foreground": "#020617",
          "card": "#ffffff",
          "card-foreground": "#020617",
          "popover": "#ffffff",
          "popover-foreground": "#020617",
          "primary": "#2563eb",
          "primary-foreground": "#f8fafc",
          "secondary": "#f1f5f9",
          "secondary-foreground": "#0f172a",
          "muted": "#f1f5f9",
          "muted-foreground": "#607086",
          "accent": "#f1f5f9",
          "accent-foreground": "#0f172a",
          "destructive": "#dc2626",
          "destructive-foreground": "#ffffff",
          "success": "#16a34a",
          "warning": "#d97706",
          "border": "#e2e8f0",
          "input": "#e2e8f0",
          "field": "#ffffff",
          "ring": "#2563eb"
        },
        "dark": {
          "background": "#020617",
          "foreground": "#f8fafc",
          "card": "#0f172a",
          "card-foreground": "#f8fafc",
          "popover": "#0f172a",
          "popover-foreground": "#f8fafc",
          "primary": "#3b82f6",
          "primary-foreground": "#020617",
          "secondary": "#1e293b",
          "secondary-foreground": "#f8fafc",
          "muted": "#1e293b",
          "muted-foreground": "#94a3b8",
          "accent": "#1e293b",
          "accent-foreground": "#f8fafc",
          "destructive": "#ef4444",
          "destructive-foreground": "#0a0a0a",
          "success": "#4ade80",
          "warning": "#fbbf24",
          "border": "rgb(255 255 255 / 0.1)",
          "input": "rgb(255 255 255 / 0.15)",
          "field": "rgb(255 255 255 / 0.05)",
          "ring": "#3b82f6"
        }
      },
      "type": "registry:theme"
    },
    {
      "name": "theme-violet",
      "title": "Theme: Violet",
      "description": "The Corsair theme on a zinc base with a violet primary. Installs the theme first, then sets its colours and radius; every text pair meets WCAG AA.",
      "registryDependencies": [
        "@corsair-ui/theme"
      ],
      "cssVars": {
        "light": {
          "radius": "0.75rem",
          "background": "#ffffff",
          "foreground": "#09090b",
          "card": "#ffffff",
          "card-foreground": "#09090b",
          "popover": "#ffffff",
          "popover-foreground": "#09090b",
          "primary": "#7c3aed",
          "primary-foreground": "#fafafa",
          "secondary": "#f4f4f5",
          "secondary-foreground": "#18181b",
          "muted": "#f4f4f5",
          "muted-foreground": "#6d6d76",
          "accent": "#f4f4f5",
          "accent-foreground": "#18181b",
          "destructive": "#dc2626",
          "destructive-foreground": "#ffffff",
          "success": "#16a34a",
          "warning": "#d97706",
          "border": "#e4e4e7",
          "input": "#e4e4e7",
          "field": "#ffffff",
          "ring": "#7c3aed"
        },
        "dark": {
          "background": "#09090b",
          "foreground": "#fafafa",
          "card": "#18181b",
          "card-foreground": "#fafafa",
          "popover": "#18181b",
          "popover-foreground": "#fafafa",
          "primary": "#8b5cf6",
          "primary-foreground": "#09090b",
          "secondary": "#27272a",
          "secondary-foreground": "#fafafa",
          "muted": "#27272a",
          "muted-foreground": "#a1a1aa",
          "accent": "#27272a",
          "accent-foreground": "#fafafa",
          "destructive": "#ef4444",
          "destructive-foreground": "#0a0a0a",
          "success": "#4ade80",
          "warning": "#fbbf24",
          "border": "rgb(255 255 255 / 0.1)",
          "input": "rgb(255 255 255 / 0.15)",
          "field": "rgb(255 255 255 / 0.05)",
          "ring": "#8b5cf6"
        }
      },
      "type": "registry:theme"
    },
    {
      "name": "theme-rose",
      "title": "Theme: Rose",
      "description": "The Corsair theme on a stone base with a rose primary. Installs the theme first, then sets its colours and radius; every text pair meets WCAG AA.",
      "registryDependencies": [
        "@corsair-ui/theme"
      ],
      "cssVars": {
        "light": {
          "radius": "0.5rem",
          "background": "#ffffff",
          "foreground": "#0c0a09",
          "card": "#ffffff",
          "card-foreground": "#0c0a09",
          "popover": "#ffffff",
          "popover-foreground": "#0c0a09",
          "primary": "#be123c",
          "primary-foreground": "#fafaf9",
          "secondary": "#f5f5f4",
          "secondary-foreground": "#1c1917",
          "muted": "#f5f5f4",
          "muted-foreground": "#746d68",
          "accent": "#f5f5f4",
          "accent-foreground": "#1c1917",
          "destructive": "#dc2626",
          "destructive-foreground": "#ffffff",
          "success": "#16a34a",
          "warning": "#d97706",
          "border": "#e7e5e4",
          "input": "#e7e5e4",
          "field": "#ffffff",
          "ring": "#be123c"
        },
        "dark": {
          "background": "#0c0a09",
          "foreground": "#fafaf9",
          "card": "#1c1917",
          "card-foreground": "#fafaf9",
          "popover": "#1c1917",
          "popover-foreground": "#fafaf9",
          "primary": "#f43f5e",
          "primary-foreground": "#0c0a09",
          "secondary": "#292524",
          "secondary-foreground": "#fafaf9",
          "muted": "#292524",
          "muted-foreground": "#a8a29e",
          "accent": "#292524",
          "accent-foreground": "#fafaf9",
          "destructive": "#ef4444",
          "destructive-foreground": "#0a0a0a",
          "success": "#4ade80",
          "warning": "#fbbf24",
          "border": "rgb(255 255 255 / 0.1)",
          "input": "rgb(255 255 255 / 0.15)",
          "field": "rgb(255 255 255 / 0.05)",
          "ring": "#f43f5e"
        }
      },
      "type": "registry:theme"
    },
    {
      "name": "theme-emerald",
      "title": "Theme: Emerald",
      "description": "The Corsair theme on a zinc base with an emerald primary. Installs the theme first, then sets its colours and radius; every text pair meets WCAG AA.",
      "registryDependencies": [
        "@corsair-ui/theme"
      ],
      "cssVars": {
        "light": {
          "radius": "0.625rem",
          "background": "#ffffff",
          "foreground": "#09090b",
          "card": "#ffffff",
          "card-foreground": "#09090b",
          "popover": "#ffffff",
          "popover-foreground": "#09090b",
          "primary": "#047857",
          "primary-foreground": "#fafafa",
          "secondary": "#f4f4f5",
          "secondary-foreground": "#18181b",
          "muted": "#f4f4f5",
          "muted-foreground": "#6d6d76",
          "accent": "#f4f4f5",
          "accent-foreground": "#18181b",
          "destructive": "#dc2626",
          "destructive-foreground": "#ffffff",
          "success": "#16a34a",
          "warning": "#d97706",
          "border": "#e4e4e7",
          "input": "#e4e4e7",
          "field": "#ffffff",
          "ring": "#047857"
        },
        "dark": {
          "background": "#09090b",
          "foreground": "#fafafa",
          "card": "#18181b",
          "card-foreground": "#fafafa",
          "popover": "#18181b",
          "popover-foreground": "#fafafa",
          "primary": "#10b981",
          "primary-foreground": "#09090b",
          "secondary": "#27272a",
          "secondary-foreground": "#fafafa",
          "muted": "#27272a",
          "muted-foreground": "#a1a1aa",
          "accent": "#27272a",
          "accent-foreground": "#fafafa",
          "destructive": "#ef4444",
          "destructive-foreground": "#0a0a0a",
          "success": "#4ade80",
          "warning": "#fbbf24",
          "border": "rgb(255 255 255 / 0.1)",
          "input": "rgb(255 255 255 / 0.15)",
          "field": "rgb(255 255 255 / 0.05)",
          "ring": "#10b981"
        }
      },
      "type": "registry:theme"
    },
    {
      "name": "theme-amber",
      "title": "Theme: Amber",
      "description": "The Corsair theme on a stone base with an amber primary and square corners. Installs the theme first, then sets its colours and radius; every text pair meets WCAG AA.",
      "registryDependencies": [
        "@corsair-ui/theme"
      ],
      "cssVars": {
        "light": {
          "radius": "0rem",
          "background": "#ffffff",
          "foreground": "#0c0a09",
          "card": "#ffffff",
          "card-foreground": "#0c0a09",
          "popover": "#ffffff",
          "popover-foreground": "#0c0a09",
          "primary": "#f59e0b",
          "primary-foreground": "#0c0a09",
          "secondary": "#f5f5f4",
          "secondary-foreground": "#1c1917",
          "muted": "#f5f5f4",
          "muted-foreground": "#746d68",
          "accent": "#f5f5f4",
          "accent-foreground": "#1c1917",
          "destructive": "#dc2626",
          "destructive-foreground": "#ffffff",
          "success": "#16a34a",
          "warning": "#d97706",
          "border": "#e7e5e4",
          "input": "#e7e5e4",
          "field": "#ffffff",
          "ring": "#f59e0b"
        },
        "dark": {
          "background": "#0c0a09",
          "foreground": "#fafaf9",
          "card": "#1c1917",
          "card-foreground": "#fafaf9",
          "popover": "#1c1917",
          "popover-foreground": "#fafaf9",
          "primary": "#f59e0b",
          "primary-foreground": "#0c0a09",
          "secondary": "#292524",
          "secondary-foreground": "#fafaf9",
          "muted": "#292524",
          "muted-foreground": "#a8a29e",
          "accent": "#292524",
          "accent-foreground": "#fafaf9",
          "destructive": "#ef4444",
          "destructive-foreground": "#0a0a0a",
          "success": "#4ade80",
          "warning": "#fbbf24",
          "border": "rgb(255 255 255 / 0.1)",
          "input": "rgb(255 255 255 / 0.15)",
          "field": "rgb(255 255 255 / 0.05)",
          "ring": "#f59e0b"
        }
      },
      "type": "registry:theme"
    },
    {
      "name": "utils",
      "title": "Utils",
      "description": "The cn() helper: merges class names and resolves conflicting Tailwind utilities.",
      "dependencies": [
        "clsx",
        "tailwind-merge"
      ],
      "files": [
        {
          "path": "registry/default/lib/utils.ts",
          "type": "registry:lib"
        }
      ],
      "type": "registry:lib"
    },
    {
      "name": "spotify-track",
      "title": "getSpotifyTrack",
      "description": "Title, artist, cover and preview clip for a Spotify link, read on the server from the public embed page.",
      "dependencies": [
        "spotify-url-info@^3.3.3"
      ],
      "files": [
        {
          "path": "registry/default/lib/spotify-track.ts",
          "type": "registry:lib"
        }
      ],
      "type": "registry:lib"
    },
    {
      "name": "story-export",
      "title": "Story Export",
      "description": "Turns stories into images for Instagram, WhatsApp and TikTok: renderStoryPng() draws JSX to a 1080 × 1920 PNG in the browser with Satori, shareStory() opens the share sheet with it, plus downloadStory(), loadFont() and the safe area the apps draw over.",
      "dependencies": [
        "satori@^0.47.1"
      ],
      "files": [
        {
          "path": "registry/default/lib/story-export.ts",
          "type": "registry:lib"
        }
      ],
      "docs": "Next.js and webpack load Satori's layout engine by themselves. With Vite, call setStoryWasm() first with the URL of satori/layout.wasm (import wasm from \"satori/layout.wasm?url\").",
      "type": "registry:lib"
    },
    {
      "name": "use-media-query",
      "title": "useMediaQuery",
      "description": "Subscribes to a CSS media query. SSR-safe: renders a fallback on the server and hydrates without a mismatch.",
      "files": [
        {
          "path": "registry/default/hooks/use-media-query.ts",
          "type": "registry:hook"
        }
      ],
      "type": "registry:hook"
    },
    {
      "name": "use-in-view",
      "title": "useInView",
      "description": "Whether an element is in the viewport, from IntersectionObserver, with once, margin and amount options.",
      "files": [
        {
          "path": "registry/default/hooks/use-in-view.ts",
          "type": "registry:hook"
        }
      ],
      "type": "registry:hook"
    },
    {
      "name": "use-entrance",
      "title": "useEntrance",
      "description": "When a one-shot entrance runs: on first paint, or once in view, without hiding server-rendered content that is already on screen.",
      "registryDependencies": [
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/hooks/use-entrance.ts",
          "type": "registry:hook"
        }
      ],
      "type": "registry:hook"
    },
    {
      "name": "use-scroll-spy",
      "title": "useScrollSpy",
      "description": "The id of the section on screen, for a table of contents, from one IntersectionObserver. SSR-safe, keeps the last section between two.",
      "files": [
        {
          "path": "registry/default/hooks/use-scroll-spy.ts",
          "type": "registry:hook"
        }
      ],
      "type": "registry:hook"
    },
    {
      "name": "button",
      "title": "Button",
      "description": "Triggers an action. Variants default, secondary, outline, ghost, destructive and link; sizes sm, default, lg and three square icon sizes. Supports asChild and a loading state.",
      "dependencies": [
        "@radix-ui/react-slot",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/button.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "spinner",
      "title": "Spinner",
      "description": "Animated status indicator for work in progress, announced as Loading.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/spinner.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "badge",
      "title": "Badge",
      "description": "Short status or metadata label. Solid, secondary and outline styles, plus success, warning and destructive statuses shown as a coloured dot.",
      "dependencies": [
        "@radix-ui/react-slot",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/badge.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "label",
      "title": "Label",
      "description": "Accessible name for a form control.",
      "dependencies": [
        "@radix-ui/react-label"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/label.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "input",
      "title": "Input",
      "description": "Single-line text control. Its error state comes from aria-invalid, so any form library can drive it.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/input.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "textarea",
      "title": "Textarea",
      "description": "Multi-line text control with the same states as Input.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/textarea.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "input-group",
      "title": "Input Group",
      "description": "An input with icons, text or buttons attached on either side.",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/input"
      ],
      "files": [
        {
          "path": "registry/default/ui/input-group.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "field",
      "title": "Field",
      "description": "Layout for a control with its label, description and error, plus fieldset and group helpers. Independent of any form library.",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/label"
      ],
      "files": [
        {
          "path": "registry/default/ui/field.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "form",
      "title": "Form Field (react-hook-form)",
      "description": "FormField: a react-hook-form Controller laid out with Field, with the id, label and ARIA wiring done for you.",
      "dependencies": [
        "react-hook-form@^7.89.0"
      ],
      "registryDependencies": [
        "@corsair-ui/field"
      ],
      "files": [
        {
          "path": "registry/default/ui/form.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "checkbox",
      "title": "Checkbox",
      "description": "Checkbox with checked, unchecked and indeterminate states.",
      "dependencies": [
        "@radix-ui/react-checkbox",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/checkbox.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "radio-group",
      "title": "Radio Group",
      "description": "A set of options where exactly one can be selected.",
      "dependencies": [
        "@radix-ui/react-radio-group",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/radio-group.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "switch",
      "title": "Switch",
      "description": "On/off control for settings that apply immediately.",
      "dependencies": [
        "@radix-ui/react-switch"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/switch.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "select",
      "title": "Select",
      "description": "Pick one option from a list, with groups, labels and separators.",
      "dependencies": [
        "@radix-ui/react-select",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/select.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "separator",
      "title": "Separator",
      "description": "Horizontal or vertical divider.",
      "dependencies": [
        "@radix-ui/react-separator"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/separator.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "card",
      "title": "Card",
      "description": "Container with header, title, description, action, content and footer parts.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/card.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "flip-card",
      "title": "Flip Card",
      "description": "A card with two faces that turns over in 3D on hover, from a trigger, or from a prop.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/flip-card.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "creative"
      ],
      "type": "registry:ui"
    },
    {
      "name": "stamp",
      "title": "Stamp",
      "description": "A rubber stamp that slams onto the page: it starts large and transparent and lands rotated with a small overshoot.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/stamp.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "stamp": {
                  "from": {
                    "opacity": "0",
                    "transform": "rotate(var(--stamp-rotate, -8deg)) scale(var(--stamp-from, 1.6))"
                  },
                  "70%": {
                    "opacity": "1",
                    "transform": "rotate(var(--stamp-rotate, -8deg)) scale(0.96)"
                  },
                  "to": {
                    "opacity": "1",
                    "transform": "rotate(var(--stamp-rotate, -8deg)) scale(1)"
                  }
                }
              },
              "animation": {
                "stamp": "stamp 320ms cubic-bezier(0.2, 0.8, 0.2, 1) both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-stamp": "stamp 320ms cubic-bezier(0.2, 0.8, 0.2, 1) both"
        }
      },
      "css": {
        "@keyframes stamp": {
          "from": {
            "opacity": "0",
            "transform": "rotate(var(--stamp-rotate, -8deg)) scale(var(--stamp-from, 1.6))"
          },
          "70%": {
            "opacity": "1",
            "transform": "rotate(var(--stamp-rotate, -8deg)) scale(0.96)"
          },
          "to": {
            "opacity": "1",
            "transform": "rotate(var(--stamp-rotate, -8deg)) scale(1)"
          }
        }
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "alert",
      "title": "Alert",
      "description": "Callout for important messages on a neutral surface; default, success, warning and destructive tones colour the icon.",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/alert.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "skeleton",
      "title": "Skeleton",
      "description": "Placeholder shape shown while content loads.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/skeleton.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "popover",
      "title": "Popover",
      "description": "Floating panel anchored to a trigger, with header, title and description parts.",
      "dependencies": [
        "@radix-ui/react-popover"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/popover.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "command",
      "title": "Command",
      "description": "Searchable list navigated with the arrow keys; the base for comboboxes and command menus.",
      "dependencies": [
        "cmdk@^1.1.1",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/command.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "calendar",
      "title": "Calendar",
      "description": "Month grid for picking a date, several dates or a range, with dropdown captions and week numbers. Built on DayPicker.",
      "dependencies": [
        "@daypicker/react@^10.0.1",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/ui/calendar.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "date-picker",
      "title": "Date Picker",
      "description": "DatePicker and DateRangePicker: a calendar in a popover behind a button that shows the chosen date or range.",
      "dependencies": [
        "@daypicker/react@^10.0.1",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/calendar",
        "@corsair-ui/popover"
      ],
      "files": [
        {
          "path": "registry/default/ui/date-picker.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "combobox",
      "title": "Combobox",
      "description": "A select with a search box, for long lists of options.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/command",
        "@corsair-ui/popover"
      ],
      "files": [
        {
          "path": "registry/default/ui/combobox.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "input-otp",
      "title": "Input OTP",
      "description": "One-time code input drawn as separate slots, with paste and autofill support.",
      "dependencies": [
        "input-otp@^1.5.0",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/input-otp.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "caret-blink": {
                  "0%, 70%, 100%": {
                    "opacity": "1"
                  },
                  "20%, 50%": {
                    "opacity": "0"
                  }
                }
              },
              "animation": {
                "caret-blink": "caret-blink 1.25s ease-out infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-caret-blink": "caret-blink 1.25s ease-out infinite"
        }
      },
      "css": {
        "@keyframes caret-blink": {
          "0%, 70%, 100%": {
            "opacity": "1"
          },
          "20%, 50%": {
            "opacity": "0"
          }
        }
      },
      "type": "registry:ui"
    },
    {
      "name": "slider",
      "title": "Slider",
      "description": "Pick a number or a range by dragging or with the arrow keys, horizontal or vertical.",
      "dependencies": [
        "@radix-ui/react-slider"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/slider.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "toggle",
      "title": "Toggle",
      "description": "A button that stays pressed, in default and outline variants and three sizes.",
      "dependencies": [
        "@radix-ui/react-toggle",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/toggle.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "toggle-group",
      "title": "Toggle Group",
      "description": "A set of toggles with single or multiple selection, joined or spaced apart.",
      "dependencies": [
        "@radix-ui/react-toggle-group",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/toggle"
      ],
      "files": [
        {
          "path": "registry/default/ui/toggle-group.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "segmented-control",
      "title": "Segmented Control",
      "description": "A switch between two or more options with one thumb that slides to the active one, in three sizes. Never empty.",
      "dependencies": [
        "@radix-ui/react-toggle-group",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/segmented-control.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "number-input",
      "title": "Number Input",
      "description": "Number field with decrement and increment buttons, min, max and step, following the spinbutton keyboard pattern.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/input-group"
      ],
      "files": [
        {
          "path": "registry/default/ui/number-input.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "password-input",
      "title": "Password Input",
      "description": "Password field with a button that shows what was typed.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/input-group"
      ],
      "files": [
        {
          "path": "registry/default/ui/password-input.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "tooltip",
      "title": "Tooltip",
      "description": "A short label shown on hover and keyboard focus.",
      "dependencies": [
        "@radix-ui/react-tooltip"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/tooltip.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "reveal",
      "title": "Reveal",
      "description": "Fades and moves content into place when it scrolls into view, alone or staggered in a group. Visible without JavaScript.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/reveal.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "text-reveal",
      "title": "Text Reveal",
      "description": "Reveals text word by word, when it comes into view or tied to the scroll position.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/text-reveal.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "text-reveal": {
                  "from": {
                    "opacity": "var(--text-reveal-dim, 0.15)"
                  },
                  "to": {
                    "opacity": "1"
                  }
                }
              },
              "animation": {
                "text-reveal": "text-reveal linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-text-reveal": "text-reveal linear both"
        }
      },
      "css": {
        "@keyframes text-reveal": {
          "from": {
            "opacity": "var(--text-reveal-dim, 0.15)"
          },
          "to": {
            "opacity": "1"
          }
        }
      },
      "categories": [
        "motion",
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "magnetic",
      "title": "Magnetic",
      "description": "Pulls its content toward the mouse while hovered and springs it back on leave.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/magnetic.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "parallax",
      "title": "Parallax",
      "description": "Drifts content at a different speed from the page as it scrolls past, with CSS scroll-driven animations and no JavaScript.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/parallax.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "parallax": {
                  "from": {
                    "transform": "translate3d(0, var(--parallax-offset, 0px), 0)"
                  },
                  "to": {
                    "transform": "translate3d(0, calc(var(--parallax-offset, 0px) * -1), 0)"
                  }
                }
              },
              "animation": {
                "parallax": "parallax linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-parallax": "parallax linear both"
        }
      },
      "css": {
        "@keyframes parallax": {
          "from": {
            "transform": "translate3d(0, var(--parallax-offset, 0px), 0)"
          },
          "to": {
            "transform": "translate3d(0, calc(var(--parallax-offset, 0px) * -1), 0)"
          }
        }
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "tilt-scroll",
      "title": "Tilt Scroll",
      "description": "Content that starts tilted back in perspective and straightens as you scroll, with CSS scroll-driven animations and no JavaScript.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/tilt-scroll.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "tilt-scroll": {
                  "from": {
                    "transform": "perspective(var(--tilt-scroll-perspective, 1200px)) rotateX(var(--tilt-scroll-angle, 20deg)) scale(var(--tilt-scroll-scale, 0.9))"
                  },
                  "to": {
                    "transform": "perspective(var(--tilt-scroll-perspective, 1200px)) rotateX(0deg) scale(1)"
                  }
                }
              },
              "animation": {
                "tilt-scroll": "tilt-scroll linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-tilt-scroll": "tilt-scroll linear both"
        }
      },
      "css": {
        "@keyframes tilt-scroll": {
          "from": {
            "transform": "perspective(var(--tilt-scroll-perspective, 1200px)) rotateX(var(--tilt-scroll-angle, 20deg)) scale(var(--tilt-scroll-scale, 0.9))"
          },
          "to": {
            "transform": "perspective(var(--tilt-scroll-perspective, 1200px)) rotateX(0deg) scale(1)"
          }
        }
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "spotlight",
      "title": "Spotlight",
      "description": "A soft light that follows the pointer across a surface and along its edge.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/spotlight.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "creative"
      ],
      "type": "registry:ui"
    },
    {
      "name": "animated-border",
      "title": "Animated Border",
      "description": "A border with a light travelling around it, paused off screen.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/animated-border.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "creative"
      ],
      "type": "registry:ui"
    },
    {
      "name": "aurora",
      "title": "Aurora",
      "description": "Slow, soft light drifting behind its content, from three radial gradients.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/aurora.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "aurora": {
                  "0%, 100%": {
                    "transform": "translate3d(0, 0, 0) rotate(0deg) scale(1)"
                  },
                  "33%": {
                    "transform": "translate3d(8%, 6%, 0) rotate(12deg) scale(1.08)"
                  },
                  "66%": {
                    "transform": "translate3d(-6%, 10%, 0) rotate(-8deg) scale(0.96)"
                  }
                }
              },
              "animation": {
                "aurora": "aurora 20s ease-in-out infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-aurora": "aurora 20s ease-in-out infinite"
        }
      },
      "css": {
        "@keyframes aurora": {
          "0%, 100%": {
            "transform": "translate3d(0, 0, 0) rotate(0deg) scale(1)"
          },
          "33%": {
            "transform": "translate3d(8%, 6%, 0) rotate(12deg) scale(1.08)"
          },
          "66%": {
            "transform": "translate3d(-6%, 10%, 0) rotate(-8deg) scale(0.96)"
          }
        }
      },
      "categories": [
        "creative",
        "background"
      ],
      "type": "registry:ui"
    },
    {
      "name": "signature",
      "title": "Signature",
      "description": "Draws SVG strokes as if by hand, with optional ink filling in behind the pen, on view or with the scroll.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/signature.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "signature-draw": {
                  "from": {
                    "stroke-dashoffset": "1.01"
                  },
                  "to": {
                    "stroke-dashoffset": "0"
                  }
                }
              },
              "animation": {
                "signature-draw": "signature-draw linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-signature-draw": "signature-draw linear both"
        }
      },
      "css": {
        "@keyframes signature-draw": {
          "from": {
            "stroke-dashoffset": "1.01"
          },
          "to": {
            "stroke-dashoffset": "0"
          }
        }
      },
      "categories": [
        "creative"
      ],
      "type": "registry:ui"
    },
    {
      "name": "path-beam",
      "title": "Path Beam",
      "description": "A beam of light travelling along the paths of a flow diagram, one after another, on view, with the scroll or from your own progress.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/path-beam.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "path-beam": {
                  "from": {
                    "stroke-dashoffset": "var(--path-beam-length, 0.2)"
                  },
                  "to": {
                    "stroke-dashoffset": "-1"
                  }
                },
                "path-beam-progress": {
                  "from": {
                    "--path-beam-progress": "0"
                  },
                  "to": {
                    "--path-beam-progress": "1"
                  }
                }
              },
              "animation": {
                "path-beam": "path-beam 1.2s ease-in-out both",
                "path-beam-progress": "path-beam-progress linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-path-beam": "path-beam 1.2s ease-in-out both",
          "animate-path-beam-progress": "path-beam-progress linear both"
        }
      },
      "css": {
        "@keyframes path-beam": {
          "from": {
            "stroke-dashoffset": "var(--path-beam-length, 0.2)"
          },
          "to": {
            "stroke-dashoffset": "-1"
          }
        },
        "@keyframes path-beam-progress": {
          "from": {
            "--path-beam-progress": "0"
          },
          "to": {
            "--path-beam-progress": "1"
          }
        }
      },
      "categories": [
        "creative"
      ],
      "type": "registry:ui"
    },
    {
      "name": "copy-button",
      "title": "Copy Button",
      "description": "An icon button that copies a value and swaps to a check mark, announcing it to screen readers.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/ui/copy-button.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "dash-button",
      "title": "Dash Button",
      "description": "A pill button whose fill gives way to a dashed outline that marches on hover.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/ui/dash-button.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "dash-march": {
                  "to": {
                    "stroke-dashoffset": "-8"
                  }
                }
              },
              "animation": {
                "dash-march": "dash-march 0.8s linear infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-dash-march": "dash-march 0.8s linear infinite"
        }
      },
      "css": {
        "@keyframes dash-march": {
          "to": {
            "stroke-dashoffset": "-8"
          }
        }
      },
      "type": "registry:ui"
    },
    {
      "name": "color-swatches",
      "title": "Color Swatches",
      "description": "Pick one colour from a row of swatches: a radio group with arrow keys and form support.",
      "dependencies": [
        "@radix-ui/react-radio-group"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/color-swatches.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "bars-spinner",
      "title": "Bars Spinner",
      "description": "Twelve bars around a hub fading in turn, announced as Loading. No JavaScript.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/bars-spinner.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "bars-spinner": {
                  "0%": {
                    "opacity": "1"
                  },
                  "100%": {
                    "opacity": "0.2"
                  }
                }
              },
              "animation": {
                "bars-spinner": "bars-spinner 1s linear infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-bars-spinner": "bars-spinner 1s linear infinite"
        }
      },
      "css": {
        "@keyframes bars-spinner": {
          "0%": {
            "opacity": "1"
          },
          "100%": {
            "opacity": "0.2"
          }
        }
      },
      "type": "registry:ui"
    },
    {
      "name": "shimmer-text",
      "title": "Shimmer Text",
      "description": "A band of light sweeping across text now and then, paused off screen.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/shimmer-text.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "shimmer-text": {
                  "from": {
                    "background-position-x": "var(--shimmer-text-from)"
                  },
                  "to": {
                    "background-position-x": "var(--shimmer-text-to)"
                  }
                }
              },
              "animation": {
                "shimmer-text": "shimmer-text 3s linear infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-shimmer-text": "shimmer-text 3s linear infinite"
        }
      },
      "css": {
        "@keyframes shimmer-text": {
          "from": {
            "background-position-x": "var(--shimmer-text-from)"
          },
          "to": {
            "background-position-x": "var(--shimmer-text-to)"
          }
        }
      },
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "blur-text",
      "title": "Blur Text",
      "description": "Text that comes into focus one character at a time, and can blur back out.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/blur-text.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "blur-text": {
                  "from": {
                    "opacity": "0",
                    "filter": "blur(10px)",
                    "transform": "translate3d(0, 0.3em, 0)"
                  }
                },
                "blur-text-out": {
                  "to": {
                    "opacity": "0",
                    "filter": "blur(10px)",
                    "transform": "translate3d(0, 0.3em, 0)"
                  }
                }
              },
              "animation": {
                "blur-text": "blur-text 600ms cubic-bezier(0.22, 1, 0.36, 1) both",
                "blur-text-out": "blur-text-out 420ms cubic-bezier(0.55, 0, 1, 0.45) both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-blur-text": "blur-text 600ms cubic-bezier(0.22, 1, 0.36, 1) both",
          "animate-blur-text-out": "blur-text-out 420ms cubic-bezier(0.55, 0, 1, 0.45) both"
        }
      },
      "css": {
        "@keyframes blur-text": {
          "from": {
            "opacity": "0",
            "filter": "blur(10px)",
            "transform": "translate3d(0, 0.3em, 0)"
          }
        },
        "@keyframes blur-text-out": {
          "to": {
            "opacity": "0",
            "filter": "blur(10px)",
            "transform": "translate3d(0, 0.3em, 0)"
          }
        }
      },
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "slide-text",
      "title": "Slide Text",
      "description": "Words, characters or lines rising into place from below their own baseline.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/slide-text.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "slide-text": {
                  "from": {
                    "transform": "translate3d(0, calc(100% + 0.2em), 0)"
                  }
                }
              },
              "animation": {
                "slide-text": "slide-text 650ms cubic-bezier(0.3, 0.9, 0.2, 1) both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-slide-text": "slide-text 650ms cubic-bezier(0.3, 0.9, 0.2, 1) both"
        }
      },
      "css": {
        "@keyframes slide-text": {
          "from": {
            "transform": "translate3d(0, calc(100% + 0.2em), 0)"
          }
        }
      },
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "flip-text",
      "title": "Flip Text",
      "description": "Kinetic type in 3D: characters or words turning into place around their horizontal axis, one after another.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/flip-text.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "flip-text": {
                  "from": {
                    "opacity": "0",
                    "transform": "perspective(var(--flip-text-perspective, 600px)) rotateX(var(--flip-text-angle, -90deg))"
                  },
                  "to": {
                    "transform": "perspective(var(--flip-text-perspective, 600px)) rotateX(0deg)"
                  }
                }
              },
              "animation": {
                "flip-text": "flip-text 800ms cubic-bezier(0.2, 0.8, 0.2, 1) both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-flip-text": "flip-text 800ms cubic-bezier(0.2, 0.8, 0.2, 1) both"
        }
      },
      "css": {
        "@keyframes flip-text": {
          "from": {
            "opacity": "0",
            "transform": "perspective(var(--flip-text-perspective, 600px)) rotateX(var(--flip-text-angle, -90deg))"
          },
          "to": {
            "transform": "perspective(var(--flip-text-perspective, 600px)) rotateX(0deg)"
          }
        }
      },
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "split-flap",
      "title": "Split Flap",
      "description": "A split-flap board: when the value changes, only the characters that changed flip, like a departure board.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/split-flap.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "split-flap-top": {
                  "from": {
                    "transform": "perspective(var(--split-flap-perspective, 400px)) rotateX(0deg)"
                  },
                  "to": {
                    "transform": "perspective(var(--split-flap-perspective, 400px)) rotateX(-90deg)"
                  }
                },
                "split-flap-bottom": {
                  "from": {
                    "transform": "perspective(var(--split-flap-perspective, 400px)) rotateX(90deg)"
                  },
                  "to": {
                    "transform": "perspective(var(--split-flap-perspective, 400px)) rotateX(0deg)"
                  }
                }
              },
              "animation": {
                "split-flap-top": "split-flap-top 150ms ease-in both",
                "split-flap-bottom": "split-flap-bottom 150ms ease-out both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-split-flap-top": "split-flap-top 150ms ease-in both",
          "animate-split-flap-bottom": "split-flap-bottom 150ms ease-out both"
        }
      },
      "css": {
        "@keyframes split-flap-top": {
          "from": {
            "transform": "perspective(var(--split-flap-perspective, 400px)) rotateX(0deg)"
          },
          "to": {
            "transform": "perspective(var(--split-flap-perspective, 400px)) rotateX(-90deg)"
          }
        },
        "@keyframes split-flap-bottom": {
          "from": {
            "transform": "perspective(var(--split-flap-perspective, 400px)) rotateX(90deg)"
          },
          "to": {
            "transform": "perspective(var(--split-flap-perspective, 400px)) rotateX(0deg)"
          }
        }
      },
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "dissolve-text",
      "title": "Dissolve Text",
      "description": "Words or characters surfacing at scattered moments, the same on server and client.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/dissolve-text.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "dissolve-text": {
                  "from": {
                    "opacity": "0"
                  }
                }
              },
              "animation": {
                "dissolve-text": "dissolve-text 1000ms cubic-bezier(0.25, 0.8, 0.3, 1) both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-dissolve-text": "dissolve-text 1000ms cubic-bezier(0.25, 0.8, 0.3, 1) both"
        }
      },
      "css": {
        "@keyframes dissolve-text": {
          "from": {
            "opacity": "0"
          }
        }
      },
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "highlight-text",
      "title": "Highlight Text",
      "description": "A marker that slides in behind a phrase, or a hand-drawn line drawn under it.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/highlight-text.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "highlight-text": {
                  "from": {
                    "transform": "var(--highlight-text-from)"
                  }
                },
                "highlight-text-draw": {
                  "from": {
                    "stroke-dashoffset": "1.01"
                  },
                  "to": {
                    "stroke-dashoffset": "0"
                  }
                }
              },
              "animation": {
                "highlight-text": "highlight-text 600ms cubic-bezier(0.22, 1, 0.36, 1) both",
                "highlight-text-draw": "highlight-text-draw 600ms cubic-bezier(0.65, 0, 0.35, 1) both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-highlight-text": "highlight-text 600ms cubic-bezier(0.22, 1, 0.36, 1) both",
          "animate-highlight-text-draw": "highlight-text-draw 600ms cubic-bezier(0.65, 0, 0.35, 1) both"
        }
      },
      "css": {
        "@keyframes highlight-text": {
          "from": {
            "transform": "var(--highlight-text-from)"
          }
        },
        "@keyframes highlight-text-draw": {
          "from": {
            "stroke-dashoffset": "1.01"
          },
          "to": {
            "stroke-dashoffset": "0"
          }
        }
      },
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "scramble-text",
      "title": "Scramble Text",
      "description": "Text that decodes itself: noise sweeps across, then each character locks in.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/scramble-text.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "wave-text",
      "title": "Wave Text",
      "description": "Bands of colour washing through text like a swell, on one CSS animation.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/wave-text.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "wave-text": {
                  "from": {
                    "--wave-text-offset": "-25"
                  },
                  "to": {
                    "--wave-text-offset": "200"
                  }
                }
              },
              "animation": {
                "wave-text": "wave-text 3.75s linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-wave-text": "wave-text 3.75s linear both"
        }
      },
      "css": {
        "@keyframes wave-text": {
          "from": {
            "--wave-text-offset": "-25"
          },
          "to": {
            "--wave-text-offset": "200"
          }
        }
      },
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "text-signature",
      "title": "Text Signature",
      "description": "Writes any text in any font as a signature: outlines drawn by the pen, then inked.",
      "dependencies": [
        "opentype.js@^2.0.0"
      ],
      "devDependencies": [
        "@types/opentype.js@^1.3.10"
      ],
      "registryDependencies": [
        "@corsair-ui/signature"
      ],
      "files": [
        {
          "path": "registry/default/ui/text-signature.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "marquee",
      "title": "Marquee",
      "description": "Content scrolling in a seamless loop, pausing on focus and off screen, and draggable by the pointer.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/marquee.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "marquee-x": {
                  "to": {
                    "transform": "translate3d(calc(-100% / var(--marquee-copies)), 0, 0)"
                  }
                },
                "marquee-y": {
                  "to": {
                    "transform": "translate3d(0, calc(-100% / var(--marquee-copies)), 0)"
                  }
                }
              },
              "animation": {
                "marquee-x": "marquee-x 20s linear infinite",
                "marquee-y": "marquee-y 20s linear infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-marquee-x": "marquee-x 20s linear infinite",
          "animate-marquee-y": "marquee-y 20s linear infinite"
        }
      },
      "css": {
        "@keyframes marquee-x": {
          "to": {
            "transform": "translate3d(calc(-100% / var(--marquee-copies)), 0, 0)"
          }
        },
        "@keyframes marquee-y": {
          "to": {
            "transform": "translate3d(0, calc(-100% / var(--marquee-copies)), 0)"
          }
        }
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "line-chart",
      "title": "Line Chart",
      "description": "One series as a line, with a cursor that snaps to points; a slider for keyboards and screen readers.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/line-chart.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "qr-code",
      "title": "QR Code",
      "description": "A crisp SVG QR code in dots, rounded or square modules. Renders on the server, and can draw itself in.",
      "dependencies": [
        "qrcode@^1.5.4"
      ],
      "devDependencies": [
        "@types/qrcode@^1.5.6"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/qr-code.tsx",
          "type": "registry:ui"
        },
        {
          "path": "registry/default/ui/qr-code-reveal.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "qr-code-reveal": {
                  "from": {
                    "transform": "scale(0)"
                  },
                  "to": {
                    "transform": "scale(1)"
                  }
                }
              },
              "animation": {
                "qr-code-reveal": "qr-code-reveal 800ms cubic-bezier(0.16, 1, 0.3, 1) both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-qr-code-reveal": "qr-code-reveal 800ms cubic-bezier(0.16, 1, 0.3, 1) both"
        }
      },
      "css": {
        "@keyframes qr-code-reveal": {
          "from": {
            "transform": "scale(0)"
          },
          "to": {
            "transform": "scale(1)"
          }
        }
      },
      "type": "registry:ui"
    },
    {
      "name": "tweet-card",
      "title": "Tweet Card",
      "description": "A post from X in your theme, with no embed script: a card, a server component that fetches by id, and a client one.",
      "dependencies": [
        "react-tweet@^3.3.1",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/tweet-card.tsx",
          "type": "registry:ui"
        },
        {
          "path": "registry/default/ui/tweet.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "spotify-card",
      "title": "Spotify Card",
      "description": "A track card with cover art, a link to Spotify and a preview clip that spins a record while it plays.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/spotify-track"
      ],
      "files": [
        {
          "path": "registry/default/ui/spotify-card.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "light-rays",
      "title": "Light Rays",
      "description": "Soft beams of light falling from above, from a small WebGL2 shader.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/light-rays.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "background"
      ],
      "type": "registry:ui"
    },
    {
      "name": "warp-gradient",
      "title": "Warp Gradient",
      "description": "A liquid field of colour carried along by layered noise, from one WebGL2 shader.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/warp-gradient.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "background"
      ],
      "type": "registry:ui"
    },
    {
      "name": "dialog",
      "title": "Dialog",
      "description": "Modal window centred over the page, with a focus trap, overlay, close button, header, footer, title and description parts.",
      "dependencies": [
        "@radix-ui/react-dialog",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/dialog.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "alert-dialog",
      "title": "Alert Dialog",
      "description": "Modal that asks the user to confirm or cancel before an action, with action and cancel buttons.",
      "dependencies": [
        "@radix-ui/react-alert-dialog"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/ui/alert-dialog.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "sheet",
      "title": "Sheet",
      "description": "Dialog that slides in from any edge of the screen, for menus, filters and side panels.",
      "dependencies": [
        "@radix-ui/react-dialog",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/sheet.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "toast",
      "title": "Toast",
      "description": "Brief notifications shown with a toast() call and a Toaster mounted once, with variants, an optional action, swipe to dismiss and screen reader announcements.",
      "dependencies": [
        "@radix-ui/react-toast",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/toast.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "nav-link",
      "title": "Nav Link",
      "description": "A navigation link that marks the current page with aria-current and data-active. Supports asChild for router links.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/nav-link.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "site-header",
      "title": "Site Header",
      "description": "A sticky page header with brand, navigation, actions and a sheet menu for small screens, flagging data-scrolled once the page scrolls.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/sheet",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/site-header.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "dock",
      "title": "Dock",
      "description": "A floating bar of icon links pinned to the bottom or top of the viewport, with tooltips and an optional reveal after scrolling.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/tooltip",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/dock.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "tabs",
      "title": "Tabs",
      "description": "Sections of content shown one at a time, with a segmented or underlined tab list, horizontal or vertical.",
      "dependencies": [
        "@radix-ui/react-tabs",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/tabs.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "avatar",
      "title": "Avatar",
      "description": "A round picture of a person with a fallback while it loads or when it fails, in three sizes, plus an overlapping group.",
      "dependencies": [
        "@radix-ui/react-avatar",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/avatar.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "rating",
      "title": "Rating",
      "description": "Stars for giving a score as a radio group, or for showing one read-only with fractional fills.",
      "dependencies": [
        "@radix-ui/react-radio-group",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/rating.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "wave-rating",
      "title": "Wave Rating",
      "description": "The rating, animated: sweeping a finger, pen or mouse across the stars lifts them in a wave that crests under the pointer, a tip shows the score, and letting go pops the chosen star. Same props and radio group as rating.",
      "dependencies": [
        "@radix-ui/react-radio-group"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/rating",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/wave-rating.tsx",
          "type": "registry:ui"
        }
      ],
      "meta": {
        "variantOf": "rating"
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "stat",
      "title": "Stat",
      "description": "Key figures as a description list: label, value and a caption with an optional trend arrow.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/stat.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "number-ticker",
      "title": "Number Ticker",
      "description": "A number that counts up to its value when it comes into view, formatted for the locale.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/number-ticker.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "code-block",
      "title": "Code Block",
      "description": "A block of code with an optional caption, a language label and a copy button.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/copy-button"
      ],
      "files": [
        {
          "path": "registry/default/ui/code-block.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "corner-frame",
      "title": "Corner Frame",
      "description": "A box with bracket marks on its corners, in any size, thickness, colour and inset.",
      "dependencies": [
        "@radix-ui/react-slot"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/corner-frame.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "phone-frame",
      "title": "Phone Frame",
      "description": "A generic phone drawn in CSS around a screenshot or any content, with an island, a notch or no cut-out, that scales with its width.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/phone-frame.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "creative"
      ],
      "type": "registry:ui"
    },
    {
      "name": "browser-frame",
      "title": "Browser Frame",
      "description": "A browser window drawn in CSS around a page or a screenshot, with window dots, an address field and optional actions.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/browser-frame.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "creative"
      ],
      "type": "registry:ui"
    },
    {
      "name": "youtube-embed",
      "title": "YouTube Embed",
      "description": "A YouTube video that costs one poster image until it is played, with player controls through its ref.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/youtube-embed.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "carousel",
      "title": "Carousel",
      "description": "Slides on a native scroll-snap track, with keyboard steps, previous and next buttons, dots and an optional coverflow look.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/ui/carousel.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "preloader",
      "title": "Preloader",
      "description": "A full-screen cover that counts to 100 on first load, waits for your content to be ready, then fades out.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/preloader.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "custom-cursor",
      "title": "Custom Cursor",
      "description": "A dot and a trailing ring that follow a mouse pointer, growing over interactive elements and showing labels.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/custom-cursor.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "scroll-progress",
      "title": "Scroll Progress",
      "description": "A reading progress bar that fills as the page scrolls, with CSS scroll-driven animations and no JavaScript.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/scroll-progress.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "scroll-progress": {
                  "from": {
                    "transform": "scaleX(0)"
                  },
                  "to": {
                    "transform": "scaleX(1)"
                  }
                }
              },
              "animation": {
                "scroll-progress": "scroll-progress linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-scroll-progress": "scroll-progress linear both"
        }
      },
      "css": {
        "@keyframes scroll-progress": {
          "from": {
            "transform": "scaleX(0)"
          },
          "to": {
            "transform": "scaleX(1)"
          }
        }
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "scroll-background",
      "title": "Scroll Background",
      "description": "A background that blends from one colour to the next as you scroll, with CSS scroll-driven animations and no JavaScript.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/scroll-background.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "scroll-background": {
                  "from": {
                    "opacity": "0"
                  },
                  "to": {
                    "opacity": "1"
                  }
                }
              },
              "animation": {
                "scroll-background": "scroll-background linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-scroll-background": "scroll-background linear both"
        }
      },
      "css": {
        "@keyframes scroll-background": {
          "from": {
            "opacity": "0"
          },
          "to": {
            "opacity": "1"
          }
        }
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "scroll-scene",
      "title": "Scroll Scene",
      "description": "A scrollytelling scene: a stage pinned beside steps, crossfading to the slide of the step on screen, with a 0 to 1 scroll progress variable for scrubbing.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-scroll-spy"
      ],
      "files": [
        {
          "path": "registry/default/ui/scroll-scene.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "scroll-scene-progress": {
                  "from": {
                    "--scroll-scene-progress": "0"
                  },
                  "to": {
                    "--scroll-scene-progress": "1"
                  }
                }
              },
              "animation": {
                "scroll-scene-progress": "scroll-scene-progress linear both"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-scroll-scene-progress": "scroll-scene-progress linear both"
        }
      },
      "css": {
        "@keyframes scroll-scene-progress": {
          "from": {
            "--scroll-scene-progress": "0"
          },
          "to": {
            "--scroll-scene-progress": "1"
          }
        }
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "wipe-transition",
      "title": "Wipe Transition",
      "description": "Switches content behind a band that sweeps across it, swapping while covered, with a crossfade for phones and reduced motion.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/wipe-transition.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "smooth-scroll",
      "title": "Smooth Scroll",
      "description": "Smooth wheel and trackpad scrolling for the page, off with reduced motion, with a scrollTo hook that works either way.",
      "dependencies": [
        "lenis@^1.3.26"
      ],
      "registryDependencies": [
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/smooth-scroll.tsx",
          "type": "registry:ui"
        }
      ],
      "css": {
        "html.lenis, html.lenis body": {
          "height": "auto"
        },
        ".lenis:not(.lenis-autoToggle).lenis-stopped": {
          "overflow": "clip"
        },
        ".lenis [data-lenis-prevent], .lenis [data-lenis-prevent-wheel], .lenis [data-lenis-prevent-touch], .lenis [data-lenis-prevent-vertical], .lenis [data-lenis-prevent-horizontal]": {
          "overscroll-behavior": "contain"
        },
        ".lenis.lenis-smooth iframe": {
          "pointer-events": "none"
        },
        ".lenis.lenis-autoToggle": {
          "transition-property": "overflow",
          "transition-duration": "1ms",
          "transition-behavior": "allow-discrete"
        }
      },
      "categories": [
        "motion"
      ],
      "type": "registry:ui"
    },
    {
      "name": "grain",
      "title": "Grain",
      "description": "Film grain over a surface, from a tile of SVG noise, with an optional stepped jitter.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/grain.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "grain": {
                  "0%, 100%": {
                    "transform": "translate3d(0, 0, 0)"
                  },
                  "10%": {
                    "transform": "translate3d(-5%, -10%, 0)"
                  },
                  "20%": {
                    "transform": "translate3d(-15%, 5%, 0)"
                  },
                  "30%": {
                    "transform": "translate3d(7%, -15%, 0)"
                  },
                  "40%": {
                    "transform": "translate3d(-5%, 15%, 0)"
                  },
                  "50%": {
                    "transform": "translate3d(-15%, 10%, 0)"
                  },
                  "60%": {
                    "transform": "translate3d(15%, 0, 0)"
                  },
                  "70%": {
                    "transform": "translate3d(0, 10%, 0)"
                  },
                  "80%": {
                    "transform": "translate3d(3%, 15%, 0)"
                  },
                  "90%": {
                    "transform": "translate3d(-10%, 10%, 0)"
                  }
                }
              },
              "animation": {
                "grain": "grain 0.8s steps(1) infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-grain": "grain 0.8s steps(1) infinite"
        }
      },
      "css": {
        "@keyframes grain": {
          "0%, 100%": {
            "transform": "translate3d(0, 0, 0)"
          },
          "10%": {
            "transform": "translate3d(-5%, -10%, 0)"
          },
          "20%": {
            "transform": "translate3d(-15%, 5%, 0)"
          },
          "30%": {
            "transform": "translate3d(7%, -15%, 0)"
          },
          "40%": {
            "transform": "translate3d(-5%, 15%, 0)"
          },
          "50%": {
            "transform": "translate3d(-15%, 10%, 0)"
          },
          "60%": {
            "transform": "translate3d(15%, 0, 0)"
          },
          "70%": {
            "transform": "translate3d(0, 10%, 0)"
          },
          "80%": {
            "transform": "translate3d(3%, 15%, 0)"
          },
          "90%": {
            "transform": "translate3d(-10%, 10%, 0)"
          }
        }
      },
      "categories": [
        "creative",
        "background"
      ],
      "type": "registry:ui"
    },
    {
      "name": "hover-reveal",
      "title": "Hover Reveal",
      "description": "A second layer seen through a soft circle that follows the pointer.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/hover-reveal.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "creative"
      ],
      "type": "registry:ui"
    },
    {
      "name": "particles",
      "title": "Particles",
      "description": "Dots drifting slowly across a surface, laid out from a seed and moved with CSS alone.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/particles.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "particles-up": {
                  "0%": {
                    "transform": "translate3d(0, 0, 0)",
                    "opacity": "0"
                  },
                  "15%, 85%": {
                    "opacity": "var(--particles-opacity, 1)"
                  },
                  "100%": {
                    "transform": "translate3d(var(--particles-drift, 0), -100%, 0)",
                    "opacity": "0"
                  }
                },
                "particles-down": {
                  "0%": {
                    "transform": "translate3d(0, 0, 0)",
                    "opacity": "0"
                  },
                  "15%, 85%": {
                    "opacity": "var(--particles-opacity, 1)"
                  },
                  "100%": {
                    "transform": "translate3d(var(--particles-drift, 0), 100%, 0)",
                    "opacity": "0"
                  }
                }
              },
              "animation": {
                "particles-up": "particles-up 14s linear infinite",
                "particles-down": "particles-down 14s linear infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-particles-up": "particles-up 14s linear infinite",
          "animate-particles-down": "particles-down 14s linear infinite"
        }
      },
      "css": {
        "@keyframes particles-up": {
          "0%": {
            "transform": "translate3d(0, 0, 0)",
            "opacity": "0"
          },
          "15%, 85%": {
            "opacity": "var(--particles-opacity, 1)"
          },
          "100%": {
            "transform": "translate3d(var(--particles-drift, 0), -100%, 0)",
            "opacity": "0"
          }
        },
        "@keyframes particles-down": {
          "0%": {
            "transform": "translate3d(0, 0, 0)",
            "opacity": "0"
          },
          "15%, 85%": {
            "opacity": "var(--particles-opacity, 1)"
          },
          "100%": {
            "transform": "translate3d(var(--particles-drift, 0), 100%, 0)",
            "opacity": "0"
          }
        }
      },
      "categories": [
        "motion",
        "background"
      ],
      "type": "registry:ui"
    },
    {
      "name": "topography",
      "title": "Topography",
      "description": "Contour lines like a topographic map over slowly shifting terrain, from one WebGL2 shader.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-in-view"
      ],
      "files": [
        {
          "path": "registry/default/ui/topography.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "creative",
        "background"
      ],
      "type": "registry:ui"
    },
    {
      "name": "roll-text",
      "title": "Roll Text",
      "description": "Characters that roll up to a copy of themselves on hover or keyboard focus.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/roll-text.tsx",
          "type": "registry:ui"
        }
      ],
      "categories": [
        "text"
      ],
      "type": "registry:ui"
    },
    {
      "name": "dropdown-menu",
      "title": "Dropdown Menu",
      "description": "A menu of actions and options that opens from a button, with checkbox and radio items, labels, shortcuts and submenus.",
      "dependencies": [
        "@radix-ui/react-dropdown-menu",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/dropdown-menu.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "context-menu",
      "title": "Context Menu",
      "description": "A menu of actions for an area of the page that opens on right click or long press, with checkbox and radio items, labels, shortcuts and submenus.",
      "dependencies": [
        "@radix-ui/react-context-menu",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/context-menu.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "navigation-menu",
      "title": "Navigation Menu",
      "description": "Site navigation with links and triggers that open panels of links in a shared, animated viewport.",
      "dependencies": [
        "@radix-ui/react-navigation-menu",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/navigation-menu.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "hover-card",
      "title": "Hover Card",
      "description": "A preview card that appears while a link is hovered or focused, for supplementary content.",
      "dependencies": [
        "@radix-ui/react-hover-card"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/hover-card.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "accordion",
      "title": "Accordion",
      "description": "Stacked sections that open and close under their headings, one or several at a time, with a height animation.",
      "dependencies": [
        "@radix-ui/react-accordion",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/accordion.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "accordion-open": {
                  "from": {
                    "height": "0"
                  },
                  "to": {
                    "height": "var(--radix-accordion-content-height)"
                  }
                },
                "accordion-close": {
                  "from": {
                    "height": "var(--radix-accordion-content-height)"
                  },
                  "to": {
                    "height": "0"
                  }
                }
              },
              "animation": {
                "accordion-open": "accordion-open 0.2s ease-out",
                "accordion-close": "accordion-close 0.2s ease-out"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-accordion-open": "accordion-open 0.2s ease-out",
          "animate-accordion-close": "accordion-close 0.2s ease-out"
        }
      },
      "css": {
        "@keyframes accordion-open": {
          "from": {
            "height": "0"
          },
          "to": {
            "height": "var(--radix-accordion-content-height)"
          }
        },
        "@keyframes accordion-close": {
          "from": {
            "height": "var(--radix-accordion-content-height)"
          },
          "to": {
            "height": "0"
          }
        }
      },
      "type": "registry:ui"
    },
    {
      "name": "collapsible",
      "title": "Collapsible",
      "description": "A region that a trigger button shows and hides, with a height animation.",
      "dependencies": [
        "@radix-ui/react-collapsible"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/collapsible.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "collapsible-open": {
                  "from": {
                    "height": "0"
                  },
                  "to": {
                    "height": "var(--radix-collapsible-content-height)"
                  }
                },
                "collapsible-close": {
                  "from": {
                    "height": "var(--radix-collapsible-content-height)"
                  },
                  "to": {
                    "height": "0"
                  }
                }
              },
              "animation": {
                "collapsible-open": "collapsible-open 0.2s ease-out",
                "collapsible-close": "collapsible-close 0.2s ease-out"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-collapsible-open": "collapsible-open 0.2s ease-out",
          "animate-collapsible-close": "collapsible-close 0.2s ease-out"
        }
      },
      "css": {
        "@keyframes collapsible-open": {
          "from": {
            "height": "0"
          },
          "to": {
            "height": "var(--radix-collapsible-content-height)"
          }
        },
        "@keyframes collapsible-close": {
          "from": {
            "height": "var(--radix-collapsible-content-height)"
          },
          "to": {
            "height": "0"
          }
        }
      },
      "type": "registry:ui"
    },
    {
      "name": "progress",
      "title": "Progress",
      "description": "A progress bar for tasks with a known amount, or an indeterminate one when the amount is unknown.",
      "dependencies": [
        "@radix-ui/react-progress"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/progress.tsx",
          "type": "registry:ui"
        }
      ],
      "tailwind": {
        "config": {
          "theme": {
            "extend": {
              "keyframes": {
                "progress-indeterminate": {
                  "from": {
                    "transform": "translateX(-100%)"
                  },
                  "to": {
                    "transform": "translateX(250%)"
                  }
                }
              },
              "animation": {
                "progress-indeterminate": "progress-indeterminate 1.5s ease-in-out infinite"
              }
            }
          }
        }
      },
      "cssVars": {
        "theme": {
          "animate-progress-indeterminate": "progress-indeterminate 1.5s ease-in-out infinite"
        }
      },
      "css": {
        "@keyframes progress-indeterminate": {
          "from": {
            "transform": "translateX(-100%)"
          },
          "to": {
            "transform": "translateX(250%)"
          }
        }
      },
      "type": "registry:ui"
    },
    {
      "name": "scroll-area",
      "title": "Scroll Area",
      "description": "A scrolling box with thin themed scrollbars that keeps native scrolling.",
      "dependencies": [
        "@radix-ui/react-scroll-area"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/scroll-area.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "breadcrumb",
      "title": "Breadcrumb",
      "description": "The trail of links from the top of a site to the current page, with separators and an ellipsis.",
      "dependencies": [
        "@radix-ui/react-slot",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/breadcrumb.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "pagination",
      "title": "Pagination",
      "description": "Page links with previous and next, an ellipsis, and a helper that works out which page numbers to show.",
      "dependencies": [
        "@radix-ui/react-slot",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/ui/pagination.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "table",
      "title": "Table",
      "description": "A data table on native table elements, with a scroll container, selected rows and sortable column headers.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/table.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "sidebar",
      "title": "Sidebar",
      "description": "An application sidebar that collapses to icons or off canvas on desktop and opens as a sheet on mobile, with a keyboard shortcut.",
      "dependencies": [
        "@radix-ui/react-slot",
        "class-variance-authority",
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/separator",
        "@corsair-ui/sheet",
        "@corsair-ui/tooltip",
        "@corsair-ui/use-media-query"
      ],
      "files": [
        {
          "path": "registry/default/ui/sidebar.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "drawer",
      "title": "Drawer",
      "description": "A bottom sheet dialog for phones that can also be dragged down to close.",
      "dependencies": [
        "@radix-ui/react-dialog"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/drawer.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "data-table",
      "title": "Data Table",
      "description": "A table with sortable headers, a text filter, pagination and row selection, built on TanStack Table v9.",
      "dependencies": [
        "@tanstack/react-table@^9.2.4"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/table",
        "@corsair-ui/pagination",
        "@corsair-ui/checkbox",
        "@corsair-ui/input"
      ],
      "files": [
        {
          "path": "registry/default/ui/data-table.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "dropzone",
      "title": "Dropzone",
      "description": "A file drop area on a native file input that checks type, size and count, and lists the chosen files.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/ui/dropzone.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "kbd",
      "title": "Kbd",
      "description": "A key or key combination shown as a small keycap, alone or in a group.",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/kbd.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "empty-state",
      "title": "Empty State",
      "description": "What a list, table or page shows when it has nothing in it yet, with an icon, title, description and actions.",
      "dependencies": [
        "class-variance-authority"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/empty-state.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "stepper",
      "title": "Stepper",
      "description": "The steps of a multi-step flow with complete, current and upcoming states, horizontal or vertical.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/stepper.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "timeline",
      "title": "Timeline",
      "description": "A vertical list of events with a coloured dot for each status and a line joining them.",
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/timeline.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "resizable",
      "title": "Resizable",
      "description": "Panels resized by dragging or with the keyboard, side by side or stacked.",
      "dependencies": [
        "lucide-react",
        "react-resizable-panels@^4.14.1"
      ],
      "registryDependencies": [
        "@corsair-ui/utils"
      ],
      "files": [
        {
          "path": "registry/default/ui/resizable.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "bar-chart",
      "title": "Bar Chart",
      "description": "One series as vertical or horizontal bars that grow in on first view, with a keyboard slider over the bars.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/bar-chart.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "area-chart",
      "title": "Area Chart",
      "description": "One or more series as gradient-filled areas, stacked or overlapping, with a legend and a keyboard slider over the points.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/area-chart.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "donut-chart",
      "title": "Donut Chart",
      "description": "Parts of a whole as a ring with the total in the middle and a keyboard-navigable legend of values and shares.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-entrance"
      ],
      "files": [
        {
          "path": "registry/default/ui/donut-chart.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "story-frame",
      "title": "Story Frame",
      "description": "A 9:16 story preview that is the exported PNG itself, with Share (the phone's share sheet, Instagram included), Download and Copy link, and the safe area the apps draw over.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/story-export"
      ],
      "files": [
        {
          "path": "registry/default/ui/story-frame.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "story",
      "title": "Story",
      "description": "A 1080 × 1920 story put together from parts (header, eyebrow, title, grid of tiles, list of rows, highlight, image, call to action), laid out inside the safe area, with themes, patterns and a background photo. Drawn by Satori: render it with story-frame or renderStoryPng().",
      "registryDependencies": [
        "@corsair-ui/story-export"
      ],
      "files": [
        {
          "path": "registry/default/ui/story.tsx",
          "type": "registry:ui"
        }
      ],
      "type": "registry:ui"
    },
    {
      "name": "hero",
      "title": "Hero",
      "description": "The opening section of a landing page with an eyebrow, a title, a description, actions and an optional media slot.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/badge",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/hero.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "feature-grid",
      "title": "Feature Grid",
      "description": "A grid of features with an icon, a title and a description under a centred section header.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/card"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/feature-grid.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "stats",
      "title": "Stats",
      "description": "A row of key figures that count up when they scroll into view, under a centred section header.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/stat",
        "@corsair-ui/number-ticker"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/stats.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "logo-cloud",
      "title": "Logo Cloud",
      "description": "Customer or partner logos in a grid or a scrolling marquee under a small title.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/marquee"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/logo-cloud.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "cta",
      "title": "Call to Action",
      "description": "A closing band with a title, a description and one or two actions.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/cta.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "pricing",
      "title": "Pricing",
      "description": "A pricing section with plan cards, a featured plan and an optional monthly or yearly billing switch.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/badge",
        "@corsair-ui/button",
        "@corsair-ui/card",
        "@corsair-ui/toggle-group"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/pricing.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "faq",
      "title": "FAQ",
      "description": "A frequently asked questions section with a header and the answers in an accordion, split or stacked.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/accordion"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/faq.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "testimonials",
      "title": "Testimonials",
      "description": "A section of customer quotes with names, roles and avatars, in a masonry or grid layout.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/avatar",
        "@corsair-ui/card"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/testimonials.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "contact-form",
      "title": "Contact Form",
      "description": "A contact section with a header, contact details and a validated message form that reports pending, success and error states.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/card",
        "@corsair-ui/field",
        "@corsair-ui/input",
        "@corsair-ui/textarea"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/contact-form.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "newsletter",
      "title": "Newsletter",
      "description": "A compact sign-up band with an inline email form that reports pending, success and error states.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/input"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/newsletter.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "site-footer",
      "title": "Site Footer",
      "description": "A page footer with a brand, link columns in a navigation landmark, a copyright line and optional social icon links.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/separator"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/site-footer.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "login-form",
      "title": "Login Form",
      "description": "A centred sign-in card with email and password fields, a remember-me checkbox, optional sign-in providers and pending, success and error states.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/card",
        "@corsair-ui/checkbox",
        "@corsair-ui/field",
        "@corsair-ui/input",
        "@corsair-ui/password-input",
        "@corsair-ui/separator"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/login-form.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "signup-form",
      "title": "Signup Form",
      "description": "A centred sign-up card with name, email and password fields, a required terms checkbox, optional sign-up providers and pending, success and error states.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button",
        "@corsair-ui/card",
        "@corsair-ui/checkbox",
        "@corsair-ui/field",
        "@corsair-ui/input",
        "@corsair-ui/password-input",
        "@corsair-ui/separator"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/signup-form.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "not-found",
      "title": "Not Found",
      "description": "A 404 page section with a large decorative error code, a page heading, a description, an optional search slot and actions.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/button"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/not-found.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "dashboard",
      "title": "Dashboard",
      "description": "An application page with a collapsible sidebar, a header, stat cards, a line chart and a recent-activity table.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/avatar",
        "@corsair-ui/badge",
        "@corsair-ui/button",
        "@corsair-ui/card",
        "@corsair-ui/data-table",
        "@corsair-ui/line-chart",
        "@corsair-ui/separator",
        "@corsair-ui/sidebar",
        "@corsair-ui/stat"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/dashboard.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    },
    {
      "name": "settings",
      "title": "Settings",
      "description": "An account settings page with tabs for a profile form, a password change and delete-account dialog, and notification switches.",
      "registryDependencies": [
        "@corsair-ui/utils",
        "@corsair-ui/use-media-query",
        "@corsair-ui/alert-dialog",
        "@corsair-ui/avatar",
        "@corsair-ui/button",
        "@corsair-ui/card",
        "@corsair-ui/field",
        "@corsair-ui/input",
        "@corsair-ui/password-input",
        "@corsair-ui/switch",
        "@corsair-ui/tabs",
        "@corsair-ui/textarea"
      ],
      "files": [
        {
          "path": "registry/default/components/blocks/settings.tsx",
          "type": "registry:component"
        }
      ],
      "type": "registry:block"
    }
  ]
}