{
  "slug": "dotted-accordion",
  "name": "Dotted Accordion",
  "description": "Rectangular architectural accordion with contiguous flush items and continuous dotted crosshair guidelines exceeding bounds with smooth gradient masks.",
  "summary": "A technical accordion with zero-radius rectangular geometry, no gap between items, and projecting boundary guidelines. On selection, the active item's boundaries turn into dotted grid lines that extend past both axes and fade out through linear-gradient CSS masks. Content opens with a bezier height tween.",
  "category": "accordion",
  "tags": [
    "accordion",
    "dotted",
    "grid",
    "crosshair",
    "blueprint",
    "technical",
    "mask",
    "fade",
    "interactive"
  ],
  "dependencies": [
    "clsx",
    "tailwind-merge",
    "motion"
  ],
  "version": "1.0.0",
  "createdDate": "2026-09-22",
  "updatedDate": "2026-09-22",
  "interactive": true,
  "supportsColor": false,
  "highlights": [
    "Zero-radius crisp rectangular geometry with zero gap between points",
    "Continuous dotted boundary guidelines that project outward on both horizontal and vertical axes",
    "Bilateral gradient mask effect fading extended guidelines smoothly to transparent",
    "Active item selection illuminates bounding crosshairs with animated opacity transitions",
    "Drawer height and opacity animation synchronized with the guideline reveal",
    "Monospace technical index prefixes and zero-radius square morphing indicators"
  ],
  "anatomy": [
    "<DottedAccordion> (Root container with projecting vertical and horizontal dotted framing guides)",
    "<button> (Zero-radius trigger header housing monospace index prefix, title, and indicator)",
    "<motion.div> (Expanding drawer rendering the description text)"
  ],
  "physics": {
    "engine": "Motion Tweens & CSS Gradient Masks",
    "description": "Bezier height tween combined with CSS mask-image linear gradients on the guidelines.",
    "parameters": [
      {
        "label": "Height Transition",
        "value": "320ms open / 250ms close [0.16, 1, 0.3, 1]"
      },
      {
        "label": "Guideline Extension",
        "value": "48px past boundary (fixed)"
      },
      {
        "label": "Mask Falloff",
        "value": "extensionLength px linear-gradient ramp (48px default)"
      },
      {
        "label": "Line Style",
        "value": "border-dotted, zinc-900/70 (light) / white/70 (dark)"
      },
      {
        "label": "Corner Radius",
        "value": "0px (rounded-none)"
      },
      {
        "label": "Compositing",
        "value": "transform + mask"
      }
    ]
  },
  "accessibility": {
    "role": "region",
    "aria": "Triggers are buttons with aria-expanded. Each open panel is a role=\"region\" labelled by its trigger and referenced by aria-controls.",
    "reducedMotion": "With prefers-reduced-motion, height, opacity and indicator transitions become instant.",
    "keyboard": [
      {
        "key": "Tab",
        "description": "Navigate between accordion item triggers."
      },
      {
        "key": "Enter / Space",
        "description": "Expand or collapse the focused accordion item."
      }
    ]
  },
  "guidelines": {
    "recommended": [
      "Technical developer consoles, terminal settings, and telemetry dashboards",
      "CAD, engineering, and architectural product feature presentations",
      "Developer tools requiring precision grid alignment and crosshair aesthetics"
    ],
    "bestPractices": [
      "Provide sufficient container padding (px-8 or px-12) so extended guidelines fade out naturally",
      "Use technical monospace tags or prefixes to reinforce the architectural grid aesthetic",
      "Reduced-motion fallbacks apply automatically from the OS setting; no configuration needed"
    ]
  },
  "props": [
    {
      "name": "items",
      "type": "DottedAccordionItem[]",
      "description": "Array of items containing title, description, and optional tag strings.",
      "required": true
    },
    {
      "name": "defaultIndex",
      "type": "number | null",
      "defaultValue": "0",
      "description": "Index of the item that should be open by default on mount."
    },
    {
      "name": "collapsible",
      "type": "boolean",
      "defaultValue": "true",
      "description": "Whether clicking an active item closes it."
    },
    {
      "name": "extensionLength",
      "type": "number",
      "defaultValue": "48",
      "description": "Distance in pixels that dotted guidelines project outward beyond the accordion boundary."
    },
    {
      "name": "closeOnClickOutside",
      "type": "boolean",
      "defaultValue": "true",
      "description": "Whether clicking outside the accordion automatically closes any open items."
    },
    {
      "name": "onToggle",
      "type": "(index: number | null) => void",
      "description": "Called with the index of the newly opened item, or null when every item is closed."
    }
  ],
  "usage": "import { DottedAccordion } from \"@/components/ui/dotted-accordion\";\n\nconst items = [\n  { title: \"Installation\", description: \"Add the component with the CLI or copy the source.\" },\n  { title: \"Theming\", description: \"Colors follow your Tailwind light and dark tokens.\" },\n];\n\nexport function DottedAccordionDemo() {\n  return <DottedAccordion items={items} />;\n}",
  "files": [
    {
      "name": "dotted-accordion.tsx",
      "path": "registry/ui/dotted-accordion.tsx",
      "code": "\"use client\";\n\nimport React, {\n  useState,\n  useRef,\n  useEffect,\n  useMemo,\n  forwardRef,\n  useId,\n  useImperativeHandle,\n} from \"react\";\nimport { motion, AnimatePresence, useReducedMotion } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface DottedAccordionItem {\n  title: string;\n  description: string;\n}\n\nexport interface DottedAccordionProps extends Omit<\n  React.HTMLAttributes<HTMLDivElement>,\n  \"onToggle\"\n> {\n  items: DottedAccordionItem[];\n  defaultIndex?: number | null;\n  collapsible?: boolean;\n  extensionLength?: number;\n  closeOnClickOutside?: boolean;\n  onToggle?: (index: number | null) => void;\n}\n\nexport const DottedAccordion = forwardRef<HTMLDivElement, DottedAccordionProps>(\n  (\n    {\n      items,\n      className,\n      defaultIndex = 0,\n      collapsible = true,\n      extensionLength = 48,\n      closeOnClickOutside = true,\n      onToggle,\n      ...props\n    },\n    ref,\n  ) => {\n    const [activeIndex, setActiveIndex] = useState<number | null>(defaultIndex);\n    const innerRef = useRef<HTMLDivElement>(null);\n    const prefersReducedMotion = useReducedMotion();\n    const baseId = useId();\n\n    useImperativeHandle(ref, () => innerRef.current as HTMLDivElement);\n\n    useEffect(() => {\n      if (!closeOnClickOutside) return;\n\n      const handleClickOutside = (event: MouseEvent) => {\n        if (\n          innerRef.current &&\n          !innerRef.current.contains(event.target as Node)\n        ) {\n          setActiveIndex(null);\n          onToggle?.(null);\n        }\n      };\n\n      document.addEventListener(\"mousedown\", handleClickOutside);\n      return () =>\n        document.removeEventListener(\"mousedown\", handleClickOutside);\n    }, [closeOnClickOutside, onToggle]);\n\n    const toggleAccordion = (index: number) => {\n      const nextIndex =\n        activeIndex === index ? (collapsible ? null : index) : index;\n      setActiveIndex(nextIndex);\n      onToggle?.(nextIndex);\n    };\n\n    const horizontalMaskStyle = useMemo(\n      () => ({\n        WebkitMaskImage: `linear-gradient(to right, transparent, black ${extensionLength}px, black calc(100% - ${extensionLength}px), transparent)`,\n        maskImage: `linear-gradient(to right, transparent, black ${extensionLength}px, black calc(100% - ${extensionLength}px), transparent)`,\n      }),\n      [extensionLength],\n    );\n\n    const verticalMaskStyle = useMemo(\n      () => ({\n        WebkitMaskImage: `linear-gradient(to bottom, transparent, black ${extensionLength}px, black calc(100% - ${extensionLength}px), transparent)`,\n        maskImage: `linear-gradient(to bottom, transparent, black ${extensionLength}px, black calc(100% - ${extensionLength}px), transparent)`,\n      }),\n      [extensionLength],\n    );\n\n    return (\n      <div className=\"@container/accordion relative w-full overflow-clip select-none\">\n        <div\n          ref={innerRef}\n          className={cn(\n            \"relative mx-auto my-6 w-[calc(100%-2rem)] @lg/accordion:my-12 @lg/accordion:w-[calc(100%-7rem)] max-w-xl rounded-none border border-zinc-200 bg-white dark:border-white/10 dark:bg-black\",\n            className,\n          )}\n          {...props}\n        >\n          <div className=\"flex flex-col gap-0 rounded-none divide-y divide-zinc-200 dark:divide-white/10 relative z-10\">\n            {items.map((item, index) => {\n              const isOpen = activeIndex === index;\n              const triggerId = `${baseId}-trigger-${index}`;\n              const panelId = `${baseId}-panel-${index}`;\n\n              return (\n                <div\n                  key={index}\n                  className={cn(\n                    \"relative rounded-none transition-colors duration-200\",\n                    isOpen\n                      ? \"bg-zinc-50 dark:bg-[#111116]\"\n                      : \"bg-white hover:bg-zinc-50/70 dark:bg-[#0a0a0c] dark:hover:bg-[#0f0f13]\",\n                  )}\n                >\n                  <AnimatePresence>\n                    {isOpen && (\n                      <>\n                        <motion.div\n                          initial={{ opacity: 0 }}\n                          animate={{ opacity: 1 }}\n                          exit={{ opacity: 0 }}\n                          transition={{ duration: 0.2 }}\n                          className=\"absolute top-0 -left-12 -right-12 h-0 border-t border-dotted border-zinc-900/70 dark:border-white/70 pointer-events-none z-20\"\n                          style={horizontalMaskStyle}\n                        />\n                        <motion.div\n                          initial={{ opacity: 0 }}\n                          animate={{ opacity: 1 }}\n                          exit={{ opacity: 0 }}\n                          transition={{ duration: 0.2 }}\n                          className=\"absolute bottom-0 -left-12 -right-12 h-0 border-b border-dotted border-zinc-900/70 dark:border-white/70 pointer-events-none z-20\"\n                          style={horizontalMaskStyle}\n                        />\n                        <motion.div\n                          initial={{ opacity: 0 }}\n                          animate={{ opacity: 1 }}\n                          exit={{ opacity: 0 }}\n                          transition={{ duration: 0.2 }}\n                          className=\"absolute left-0 -top-12 -bottom-12 w-0 border-l border-dotted border-zinc-900/70 dark:border-white/70 pointer-events-none z-20\"\n                          style={verticalMaskStyle}\n                        />\n                        <motion.div\n                          initial={{ opacity: 0 }}\n                          animate={{ opacity: 1 }}\n                          exit={{ opacity: 0 }}\n                          transition={{ duration: 0.2 }}\n                          className=\"absolute right-0 -top-12 -bottom-12 w-0 border-r border-dotted border-zinc-900/70 dark:border-white/70 pointer-events-none z-20\"\n                          style={verticalMaskStyle}\n                        />\n                      </>\n                    )}\n                  </AnimatePresence>\n\n                  <button\n                    type=\"button\"\n                    id={triggerId}\n                    aria-expanded={isOpen}\n                    aria-controls={isOpen ? panelId : undefined}\n                    onClick={() => toggleAccordion(index)}\n                    className=\"group flex w-full cursor-pointer items-center justify-between px-3 @lg/accordion:px-5 py-4 text-left rounded-none transition-colors outline-none focus-visible:ring-1 focus-visible:ring-foreground/30 dark:focus-visible:ring-white/30\"\n                  >\n                    <div className=\"flex items-center gap-2 @lg/accordion:gap-3.5 min-w-0 flex-1\">\n                      <span className=\"font-mono text-xs text-zinc-400 group-hover:text-zinc-600 dark:text-zinc-500 dark:group-hover:text-zinc-400 transition-colors shrink-0 w-5\">\n                        {String(index + 1).padStart(2, \"0\")}\n                      </span>\n                      <span\n                        className={cn(\n                          \"text-sm font-medium tracking-tight transition-colors duration-200 whitespace-normal break-words\",\n                          isOpen\n                            ? \"text-zinc-950 dark:text-white\"\n                            : \"text-zinc-700 group-hover:text-zinc-950 dark:text-zinc-300 dark:group-hover:text-white\",\n                        )}\n                      >\n                        {item.title}\n                      </span>\n                    </div>\n\n                    <div className=\"relative flex items-center justify-center w-5 h-5 text-zinc-400 group-hover:text-zinc-700 dark:text-zinc-500 dark:group-hover:text-zinc-200 transition-colors shrink-0 ml-3\">\n                      <motion.span\n                        className=\"absolute h-[1.5px] w-3 bg-current rounded-none\"\n                        animate={{ rotate: isOpen ? 180 : 0 }}\n                        transition={\n                          prefersReducedMotion\n                            ? { duration: 0 }\n                            : { type: \"spring\", stiffness: 320, damping: 24 }\n                        }\n                      />\n                      <motion.span\n                        className=\"absolute w-[1.5px] h-3 bg-current rounded-none\"\n                        animate={{\n                          scaleY: isOpen ? 0 : 1,\n                          opacity: isOpen ? 0 : 1,\n                          rotate: isOpen ? 90 : 0,\n                        }}\n                        transition={\n                          prefersReducedMotion\n                            ? { duration: 0 }\n                            : { type: \"spring\", stiffness: 320, damping: 24 }\n                        }\n                      />\n                    </div>\n                  </button>\n\n                  <AnimatePresence initial={false}>\n                    {isOpen && (\n                      <motion.div\n                        initial={{ height: 0, opacity: 0 }}\n                        animate={{\n                          height: \"auto\",\n                          opacity: 1,\n                          transition: prefersReducedMotion\n                            ? { duration: 0 }\n                            : {\n                                height: {\n                                  duration: 0.32,\n                                  ease: [0.16, 1, 0.3, 1],\n                                },\n                                opacity: {\n                                  duration: 0.22,\n                                  ease: \"easeOut\",\n                                },\n                              },\n                        }}\n                        exit={{\n                          height: 0,\n                          opacity: 0,\n                          transition: prefersReducedMotion\n                            ? { duration: 0 }\n                            : {\n                                height: {\n                                  duration: 0.25,\n                                  ease: [0.16, 1, 0.3, 1],\n                                },\n                                opacity: {\n                                  duration: 0.15,\n                                  ease: \"easeIn\",\n                                },\n                              },\n                        }}\n                        id={panelId}\n                        role=\"region\"\n                        aria-labelledby={triggerId}\n                        className=\"overflow-hidden rounded-none\"\n                      >\n                        <div\n                          className=\"cursor-pointer pl-10 @lg/accordion:pl-13.5 pr-3 @lg/accordion:pr-5 pb-5 pt-0.5 text-sm leading-relaxed text-zinc-600 dark:text-zinc-400 font-light\"\n                          onClick={() => toggleAccordion(index)}\n                        >\n                          {item.description}\n                        </div>\n                      </motion.div>\n                    )}\n                  </AnimatePresence>\n                </div>\n              );\n            })}\n          </div>\n        </div>\n      </div>\n    );\n  },\n);\n\nDottedAccordion.displayName = \"DottedAccordion\";\n\nexport default DottedAccordion;\n",
      "content": "\"use client\";\n\nimport React, {\n  useState,\n  useRef,\n  useEffect,\n  useMemo,\n  forwardRef,\n  useId,\n  useImperativeHandle,\n} from \"react\";\nimport { motion, AnimatePresence, useReducedMotion } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface DottedAccordionItem {\n  title: string;\n  description: string;\n}\n\nexport interface DottedAccordionProps extends Omit<\n  React.HTMLAttributes<HTMLDivElement>,\n  \"onToggle\"\n> {\n  items: DottedAccordionItem[];\n  defaultIndex?: number | null;\n  collapsible?: boolean;\n  extensionLength?: number;\n  closeOnClickOutside?: boolean;\n  onToggle?: (index: number | null) => void;\n}\n\nexport const DottedAccordion = forwardRef<HTMLDivElement, DottedAccordionProps>(\n  (\n    {\n      items,\n      className,\n      defaultIndex = 0,\n      collapsible = true,\n      extensionLength = 48,\n      closeOnClickOutside = true,\n      onToggle,\n      ...props\n    },\n    ref,\n  ) => {\n    const [activeIndex, setActiveIndex] = useState<number | null>(defaultIndex);\n    const innerRef = useRef<HTMLDivElement>(null);\n    const prefersReducedMotion = useReducedMotion();\n    const baseId = useId();\n\n    useImperativeHandle(ref, () => innerRef.current as HTMLDivElement);\n\n    useEffect(() => {\n      if (!closeOnClickOutside) return;\n\n      const handleClickOutside = (event: MouseEvent) => {\n        if (\n          innerRef.current &&\n          !innerRef.current.contains(event.target as Node)\n        ) {\n          setActiveIndex(null);\n          onToggle?.(null);\n        }\n      };\n\n      document.addEventListener(\"mousedown\", handleClickOutside);\n      return () =>\n        document.removeEventListener(\"mousedown\", handleClickOutside);\n    }, [closeOnClickOutside, onToggle]);\n\n    const toggleAccordion = (index: number) => {\n      const nextIndex =\n        activeIndex === index ? (collapsible ? null : index) : index;\n      setActiveIndex(nextIndex);\n      onToggle?.(nextIndex);\n    };\n\n    const horizontalMaskStyle = useMemo(\n      () => ({\n        WebkitMaskImage: `linear-gradient(to right, transparent, black ${extensionLength}px, black calc(100% - ${extensionLength}px), transparent)`,\n        maskImage: `linear-gradient(to right, transparent, black ${extensionLength}px, black calc(100% - ${extensionLength}px), transparent)`,\n      }),\n      [extensionLength],\n    );\n\n    const verticalMaskStyle = useMemo(\n      () => ({\n        WebkitMaskImage: `linear-gradient(to bottom, transparent, black ${extensionLength}px, black calc(100% - ${extensionLength}px), transparent)`,\n        maskImage: `linear-gradient(to bottom, transparent, black ${extensionLength}px, black calc(100% - ${extensionLength}px), transparent)`,\n      }),\n      [extensionLength],\n    );\n\n    return (\n      <div className=\"@container/accordion relative w-full overflow-clip select-none\">\n        <div\n          ref={innerRef}\n          className={cn(\n            \"relative mx-auto my-6 w-[calc(100%-2rem)] @lg/accordion:my-12 @lg/accordion:w-[calc(100%-7rem)] max-w-xl rounded-none border border-zinc-200 bg-white dark:border-white/10 dark:bg-black\",\n            className,\n          )}\n          {...props}\n        >\n          <div className=\"flex flex-col gap-0 rounded-none divide-y divide-zinc-200 dark:divide-white/10 relative z-10\">\n            {items.map((item, index) => {\n              const isOpen = activeIndex === index;\n              const triggerId = `${baseId}-trigger-${index}`;\n              const panelId = `${baseId}-panel-${index}`;\n\n              return (\n                <div\n                  key={index}\n                  className={cn(\n                    \"relative rounded-none transition-colors duration-200\",\n                    isOpen\n                      ? \"bg-zinc-50 dark:bg-[#111116]\"\n                      : \"bg-white hover:bg-zinc-50/70 dark:bg-[#0a0a0c] dark:hover:bg-[#0f0f13]\",\n                  )}\n                >\n                  <AnimatePresence>\n                    {isOpen && (\n                      <>\n                        <motion.div\n                          initial={{ opacity: 0 }}\n                          animate={{ opacity: 1 }}\n                          exit={{ opacity: 0 }}\n                          transition={{ duration: 0.2 }}\n                          className=\"absolute top-0 -left-12 -right-12 h-0 border-t border-dotted border-zinc-900/70 dark:border-white/70 pointer-events-none z-20\"\n                          style={horizontalMaskStyle}\n                        />\n                        <motion.div\n                          initial={{ opacity: 0 }}\n                          animate={{ opacity: 1 }}\n                          exit={{ opacity: 0 }}\n                          transition={{ duration: 0.2 }}\n                          className=\"absolute bottom-0 -left-12 -right-12 h-0 border-b border-dotted border-zinc-900/70 dark:border-white/70 pointer-events-none z-20\"\n                          style={horizontalMaskStyle}\n                        />\n                        <motion.div\n                          initial={{ opacity: 0 }}\n                          animate={{ opacity: 1 }}\n                          exit={{ opacity: 0 }}\n                          transition={{ duration: 0.2 }}\n                          className=\"absolute left-0 -top-12 -bottom-12 w-0 border-l border-dotted border-zinc-900/70 dark:border-white/70 pointer-events-none z-20\"\n                          style={verticalMaskStyle}\n                        />\n                        <motion.div\n                          initial={{ opacity: 0 }}\n                          animate={{ opacity: 1 }}\n                          exit={{ opacity: 0 }}\n                          transition={{ duration: 0.2 }}\n                          className=\"absolute right-0 -top-12 -bottom-12 w-0 border-r border-dotted border-zinc-900/70 dark:border-white/70 pointer-events-none z-20\"\n                          style={verticalMaskStyle}\n                        />\n                      </>\n                    )}\n                  </AnimatePresence>\n\n                  <button\n                    type=\"button\"\n                    id={triggerId}\n                    aria-expanded={isOpen}\n                    aria-controls={isOpen ? panelId : undefined}\n                    onClick={() => toggleAccordion(index)}\n                    className=\"group flex w-full cursor-pointer items-center justify-between px-3 @lg/accordion:px-5 py-4 text-left rounded-none transition-colors outline-none focus-visible:ring-1 focus-visible:ring-foreground/30 dark:focus-visible:ring-white/30\"\n                  >\n                    <div className=\"flex items-center gap-2 @lg/accordion:gap-3.5 min-w-0 flex-1\">\n                      <span className=\"font-mono text-xs text-zinc-400 group-hover:text-zinc-600 dark:text-zinc-500 dark:group-hover:text-zinc-400 transition-colors shrink-0 w-5\">\n                        {String(index + 1).padStart(2, \"0\")}\n                      </span>\n                      <span\n                        className={cn(\n                          \"text-sm font-medium tracking-tight transition-colors duration-200 whitespace-normal break-words\",\n                          isOpen\n                            ? \"text-zinc-950 dark:text-white\"\n                            : \"text-zinc-700 group-hover:text-zinc-950 dark:text-zinc-300 dark:group-hover:text-white\",\n                        )}\n                      >\n                        {item.title}\n                      </span>\n                    </div>\n\n                    <div className=\"relative flex items-center justify-center w-5 h-5 text-zinc-400 group-hover:text-zinc-700 dark:text-zinc-500 dark:group-hover:text-zinc-200 transition-colors shrink-0 ml-3\">\n                      <motion.span\n                        className=\"absolute h-[1.5px] w-3 bg-current rounded-none\"\n                        animate={{ rotate: isOpen ? 180 : 0 }}\n                        transition={\n                          prefersReducedMotion\n                            ? { duration: 0 }\n                            : { type: \"spring\", stiffness: 320, damping: 24 }\n                        }\n                      />\n                      <motion.span\n                        className=\"absolute w-[1.5px] h-3 bg-current rounded-none\"\n                        animate={{\n                          scaleY: isOpen ? 0 : 1,\n                          opacity: isOpen ? 0 : 1,\n                          rotate: isOpen ? 90 : 0,\n                        }}\n                        transition={\n                          prefersReducedMotion\n                            ? { duration: 0 }\n                            : { type: \"spring\", stiffness: 320, damping: 24 }\n                        }\n                      />\n                    </div>\n                  </button>\n\n                  <AnimatePresence initial={false}>\n                    {isOpen && (\n                      <motion.div\n                        initial={{ height: 0, opacity: 0 }}\n                        animate={{\n                          height: \"auto\",\n                          opacity: 1,\n                          transition: prefersReducedMotion\n                            ? { duration: 0 }\n                            : {\n                                height: {\n                                  duration: 0.32,\n                                  ease: [0.16, 1, 0.3, 1],\n                                },\n                                opacity: {\n                                  duration: 0.22,\n                                  ease: \"easeOut\",\n                                },\n                              },\n                        }}\n                        exit={{\n                          height: 0,\n                          opacity: 0,\n                          transition: prefersReducedMotion\n                            ? { duration: 0 }\n                            : {\n                                height: {\n                                  duration: 0.25,\n                                  ease: [0.16, 1, 0.3, 1],\n                                },\n                                opacity: {\n                                  duration: 0.15,\n                                  ease: \"easeIn\",\n                                },\n                              },\n                        }}\n                        id={panelId}\n                        role=\"region\"\n                        aria-labelledby={triggerId}\n                        className=\"overflow-hidden rounded-none\"\n                      >\n                        <div\n                          className=\"cursor-pointer pl-10 @lg/accordion:pl-13.5 pr-3 @lg/accordion:pr-5 pb-5 pt-0.5 text-sm leading-relaxed text-zinc-600 dark:text-zinc-400 font-light\"\n                          onClick={() => toggleAccordion(index)}\n                        >\n                          {item.description}\n                        </div>\n                      </motion.div>\n                    )}\n                  </AnimatePresence>\n                </div>\n              );\n            })}\n          </div>\n        </div>\n      </div>\n    );\n  },\n);\n\nDottedAccordion.displayName = \"DottedAccordion\";\n\nexport default DottedAccordion;\n",
      "type": "registry:ui",
      "target": "@ui/dotted-accordion.tsx"
    }
  ],
  "type": "registry:ui",
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "title": "Dotted Accordion"
}
