{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "carousel",
  "title": "Carousel",
  "description": "Slides travel on a spring and the active dot stretches into a bar.",
  "dependencies": [
    "@ui-sdk/core@0.1.0-beta.2",
    "@ui-sdk/react@0.1.0-beta.2"
  ],
  "registryDependencies": [
    "@keyframery/motion"
  ],
  "files": [
    {
      "path": "registry/components/keyframery/primitives/carousel.tsx",
      "content": "\"use client\"\n\n/* Animated drop-in for `@ui-sdk/react/carousel`: same parts, same props. Swap the import and keep your code.\n   This file adds motion only. Colours, radii, shadows and spacing stay yours. */\n\nimport {\n  CarouselIndicator as CarouselIndicatorPart,\n  CarouselItem as CarouselItemPart,\n  CarouselNext as CarouselNextPart,\n  CarouselPlayToggle as CarouselPlayTogglePart,\n  CarouselPrevious as CarouselPreviousPart,\n} from \"@ui-sdk/react/carousel\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport * from \"@ui-sdk/react/carousel\"\n\n/* Direction: the slides travel by native scrolling. On top of that, a slide that leaves the\n   current page sinks back (scale 0.9, a 2px blur) and dims, and the arriving one grows into\n   place on a spring. The scale goes on the slide's content, not the slide, so the scroll range\n   stays exact (a scaled slide would shorten it). */\nfunction CarouselItem({ className, ...props }: React.ComponentProps<typeof CarouselItemPart>) {\n  return (\n    <CarouselItemPart\n      className={cn(\n        \"transition-opacity duration-[calc(460ms*var(--kf-speed,1))] ease-house\",\n        \"*:transition-[scale,filter] *:duration-[calc(520ms*var(--kf-speed,1))] *:ease-spring\",\n        \"not-data-active:opacity-40 not-data-active:*:scale-[0.9] not-data-active:*:blur-[2px]\",\n        \"motion-reduce:transition-none! motion-reduce:*:transition-none\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* Press: the key dips and springs back on release. */\nconst press =\n  \"[transition:scale_calc(220ms*var(--kf-speed,1))_var(--ease-pop),opacity_calc(150ms*var(--kf-speed,1)),background-color_calc(150ms*var(--kf-speed,1)),box-shadow_calc(150ms*var(--kf-speed,1)),color_calc(150ms*var(--kf-speed,1))] not-data-disabled:active:scale-[0.9] motion-reduce:transition-none!\"\n\nfunction CarouselPrevious({ className, ...props }: React.ComponentProps<typeof CarouselPreviousPart>) {\n  return <CarouselPreviousPart className={cn(press, className)} {...props} />\n}\n\nfunction CarouselNext({ className, ...props }: React.ComponentProps<typeof CarouselNextPart>) {\n  return <CarouselNextPart className={cn(press, className)} {...props} />\n}\n\nfunction CarouselPlayToggle({ className, ...props }: React.ComponentProps<typeof CarouselPlayTogglePart>) {\n  return <CarouselPlayTogglePart className={cn(press, className)} {...props} />\n}\n\n/* The current indicator widens on a spring, so it overshoots a touch and settles, while the one\n   it left shrinks back. Give it its width in your styles (for example data-selected:w-5). */\nfunction CarouselIndicator({ className, ...props }: React.ComponentProps<typeof CarouselIndicatorPart>) {\n  return (\n    <CarouselIndicatorPart\n      className={cn(\n        \"[transition:width_calc(560ms*var(--kf-speed,1))_var(--ease-spring),height_calc(560ms*var(--kf-speed,1))_var(--ease-spring),background-color_calc(200ms*var(--kf-speed,1)),scale_calc(220ms*var(--kf-speed,1))_var(--ease-pop)] active:scale-[0.8]\",\n        \"motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { CarouselIndicator, CarouselItem, CarouselNext, CarouselPlayToggle, CarouselPrevious }\n",
      "type": "registry:component",
      "target": "components/keyframery/primitives/carousel.tsx"
    },
    {
      "path": "registry/components/keyframery/carousel.tsx",
      "content": "\"use client\"\n\n/* Styled carousel: the animated primitive plus the Keyframery look. */\n\nimport {\n  Carousel as CarouselRoot,\n  CarouselContent as CarouselContentPart,\n  CarouselIndicator as CarouselIndicatorPart,\n  CarouselIndicatorGroup as CarouselIndicatorGroupPart,\n  CarouselItem as CarouselItemPart,\n  CarouselNext as CarouselNextPart,\n  CarouselPlayToggle as CarouselPlayTogglePart,\n  CarouselPrevious as CarouselPreviousPart,\n  CarouselViewport as CarouselViewportPart,\n} from \"@/components/keyframery/primitives/carousel\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Carousel({ className, ...props }: React.ComponentProps<typeof CarouselRoot>) {\n  return <CarouselRoot className={cn(\"relative flex flex-col gap-3\", className)} {...props} />\n}\n\n/* The scrolling window. UI SDK writes its overflow and snapping inline; the scrollbar is hidden. */\nfunction CarouselViewport({\n  className,\n  ...props\n}: React.ComponentProps<typeof CarouselViewportPart>) {\n  return (\n    <CarouselViewportPart\n      className={cn(\n        \"rounded-[14px] outline-none [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\",\n        \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n        \"data-dragging:cursor-grabbing\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CarouselContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof CarouselContentPart>) {\n  return (\n    <CarouselContentPart\n      className={cn(\"flex gap-3 data-[orientation=vertical]:flex-col\", className)}\n      {...props}\n    />\n  )\n}\n\n/* One slide to a view. The leaving slide sinks back and dims (from the primitive). */\nfunction CarouselItem({ className, ...props }: React.ComponentProps<typeof CarouselItemPart>) {\n  return <CarouselItemPart className={cn(\"min-w-0 shrink-0 grow-0 basis-full\", className)} {...props} />\n}\n\n/* Round keys. At the ends they stay focusable but quiet down. */\nconst roundKey = [\n  \"inline-grid size-8 shrink-0 cursor-pointer place-items-center rounded-full bg-background text-foreground outline-none select-none [&_svg]:size-4\",\n  \"shadow-[0_0_0_1px_rgb(0_0_0/0.06),0_1px_1px_rgb(0_0_0/0.05),0_3px_6px_-2px_rgb(0_0_0/0.1)]\",\n  \"dark:bg-accent dark:shadow-[0_0_0_1px_rgb(255_255_255/0.07),inset_0_1px_0_rgb(255_255_255/0.08),0_2px_6px_-1px_rgb(0_0_0/0.6)]\",\n  \"not-data-disabled:hover:bg-[color-mix(in_oklab,var(--background),var(--foreground)_3%)] dark:not-data-disabled:hover:bg-[color-mix(in_oklab,var(--accent),var(--foreground)_7%)]\",\n  \"not-data-disabled:hover:shadow-[0_0_0_1px_rgb(0_0_0/0.1),0_1px_1px_rgb(0_0_0/0.05),0_4px_8px_-2px_rgb(0_0_0/0.12)]\",\n  \"dark:not-data-disabled:hover:shadow-[0_0_0_1px_rgb(255_255_255/0.12),inset_0_1px_0_rgb(255_255_255/0.1),0_2px_6px_-1px_rgb(0_0_0/0.6)]\",\n  \"not-data-disabled:active:shadow-[0_0_0_1px_rgb(0_0_0/0.1),0_1px_1px_rgb(0_0_0/0.04),0_1px_2px_-1px_rgb(0_0_0/0.06)]\",\n  \"dark:not-data-disabled:active:shadow-[0_0_0_1px_rgb(255_255_255/0.09),inset_0_1px_0_rgb(255_255_255/0.04),0_1px_2px_-1px_rgb(0_0_0/0.6)]\",\n  \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n  \"data-disabled:cursor-not-allowed data-disabled:opacity-40\",\n]\n\nfunction Chevron({ d }: { d: string }) {\n  return (\n    <svg\n      aria-hidden\n      viewBox=\"0 0 16 16\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"1.5\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n    >\n      <path d={d} />\n    </svg>\n  )\n}\n\nfunction CarouselPrevious({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CarouselPreviousPart>) {\n  return (\n    <CarouselPreviousPart aria-label=\"Previous slide\" className={cn(roundKey, className)} {...props}>\n      {children ?? <Chevron d=\"m10 4-4 4 4 4\" />}\n    </CarouselPreviousPart>\n  )\n}\n\nfunction CarouselNext({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CarouselNextPart>) {\n  return (\n    <CarouselNextPart aria-label=\"Next slide\" className={cn(roundKey, className)} {...props}>\n      {children ?? <Chevron d=\"m6 4 4 4-4 4\" />}\n    </CarouselNextPart>\n  )\n}\n\nfunction CarouselPlayToggle({\n  className,\n  ...props\n}: React.ComponentProps<typeof CarouselPlayTogglePart>) {\n  return <CarouselPlayTogglePart className={cn(roundKey, className)} {...props} />\n}\n\n/* The dots sit in a small pill well. */\nfunction CarouselIndicatorGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof CarouselIndicatorGroupPart>) {\n  return (\n    <CarouselIndicatorGroupPart\n      className={cn(\n        \"inline-flex h-5 w-fit items-center gap-1 rounded-full bg-muted px-1.5\",\n        \"shadow-[inset_0_1px_2px_rgb(0_0_0/0.07),inset_0_0_0_1px_rgb(0_0_0/0.035)]\",\n        \"dark:shadow-[inset_0_1px_2px_rgb(0_0_0/0.5),inset_0_0_0_1px_rgb(255_255_255/0.04)]\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* The current dot is a short bar; it widens on a spring (from the primitive). */\nfunction CarouselIndicator({\n  className,\n  ...props\n}: React.ComponentProps<typeof CarouselIndicatorPart>) {\n  return (\n    <CarouselIndicatorPart\n      className={cn(\n        \"relative h-1.5 w-1.5 cursor-pointer rounded-full bg-foreground/20 outline-none\",\n        \"hover:bg-foreground/45 data-selected:w-5 data-selected:bg-foreground\",\n        /* A larger hit area than the dot itself. */\n        \"after:absolute after:-inset-x-0.5 after:-inset-y-2\",\n        \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-muted\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* A hairline that follows --carousel-progress on every frame of the scroll. */\nfunction CarouselProgress({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      aria-hidden\n      data-slot=\"carousel-progress\"\n      className={cn(\"h-0.5 w-full overflow-hidden rounded-full bg-foreground/10\", className)}\n      {...props}\n    >\n      <div className=\"h-full w-full origin-left scale-x-(--carousel-progress) rounded-full bg-foreground/70 rtl:origin-right\" />\n    </div>\n  )\n}\n\nexport {\n  Carousel,\n  CarouselContent,\n  CarouselIndicator,\n  CarouselIndicatorGroup,\n  CarouselItem,\n  CarouselNext,\n  CarouselPlayToggle,\n  CarouselPrevious,\n  CarouselProgress,\n  CarouselViewport,\n}\n",
      "type": "registry:component",
      "target": "components/keyframery/carousel.tsx"
    }
  ],
  "type": "registry:component"
}