{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "stripe-bg-guides",
  "type": "registry:ui",
  "description": "Stripe-style background guides component with animated patterns and effects",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "registry/default/ui/stripe-bg-guides.tsx",
      "content": "\"use client\"\n\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\"\nimport { AnimatePresence, motion } from \"motion/react\"\n\ntype AnimationDirection = \"top-to-bottom\" | \"bottom-to-top\" | \"both\" | \"random\"\ntype AnimationEasing = \"linear\" | \"easeIn\" | \"easeOut\" | \"easeInOut\" | \"spring\"\n\ninterface AnimatedBackgroundGuidesProps {\n  columnCount?: number\n  className?: string\n  solidLines?: number[]\n  animated?: boolean\n  animationDuration?: number\n  animationDelay?: number\n  glowColor?: string\n  glowSize?: string\n  glowOpacity?: number\n  randomize?: boolean\n  randomInterval?: number\n  direction?: AnimationDirection\n  easing?: AnimationEasing\n  responsive?: boolean\n  minColumnWidth?: string\n  maxActiveColumns?: number\n  darkMode?: boolean\n  contained?: boolean\n}\n\nconst easingFunctions = {\n  linear: [0, 0, 1, 1] as const,\n  easeIn: [0.42, 0, 1, 1] as const,\n  easeOut: [0, 0, 0.58, 1] as const,\n  easeInOut: [0.42, 0, 0.58, 1] as const,\n  spring: [0.175, 0.885, 0.32, 1.275] as const,\n}\n\nexport function StripeBgGuides({\n  columnCount = 4,\n  className = \"\",\n  solidLines = [],\n  animated = true,\n  animationDuration = 62,\n  animationDelay = 0.8,\n  glowColor = \"hsl(var(--accent))\",\n  //   glowColor = \"#D2F583\",\n  glowSize = \"10vh\",\n  glowOpacity = 0.4,\n  randomize = true,\n  randomInterval = 9000,\n  direction = \"both\",\n  easing = \"spring\",\n  responsive = false,\n  minColumnWidth = \"4rem\",\n  maxActiveColumns = 3,\n  darkMode = false,\n  contained = false,\n}: AnimatedBackgroundGuidesProps) {\n  const [windowWidth, setWindowWidth] = useState(\n    typeof window !== \"undefined\" ? window.innerWidth : 0\n  )\n\n  const columns = useMemo(() => {\n    const count = responsive\n      ? Math.max(Math.floor(windowWidth / parseInt(minColumnWidth)), 1)\n      : columnCount\n    return [...Array(count)]\n  }, [columnCount, responsive, windowWidth, minColumnWidth])\n\n  const [activeColumns, setActiveColumns] = useState<boolean[]>(\n    columns.map(() => true)\n  )\n\n  const getRandomColumns = useCallback(() => {\n    const newActiveColumns = columns.map(() => Math.random() < 0.5)\n    const activeCount = newActiveColumns.filter(Boolean).length\n    if (activeCount > maxActiveColumns) {\n      const indicesToDeactivate = newActiveColumns\n        .map((isActive, index) => (isActive ? index : -1))\n        .filter((index) => index !== -1)\n        .sort(() => Math.random() - 0.5)\n        .slice(0, activeCount - maxActiveColumns)\n      indicesToDeactivate.forEach((index) => {\n        newActiveColumns[index] = false\n      })\n    }\n    return newActiveColumns\n  }, [columns, maxActiveColumns])\n\n  useEffect(() => {\n    const handleResize = () => setWindowWidth(window.innerWidth)\n    if (typeof window !== \"undefined\") {\n      window.addEventListener(\"resize\", handleResize)\n      return () => window.removeEventListener(\"resize\", handleResize)\n    }\n  }, [])\n\n  useEffect(() => {\n    setActiveColumns(columns.map(() => true))\n  }, [columns])\n\n  useEffect(() => {\n    if (randomize && animated) {\n      const intervalId = setInterval(() => {\n        setActiveColumns(getRandomColumns())\n      }, randomInterval)\n      return () => clearInterval(intervalId)\n    } else {\n      setActiveColumns(columns.map(() => true))\n    }\n  }, [randomize, animated, randomInterval, getRandomColumns, columns])\n\n  const getAnimationVariants = useCallback(() => {\n    const variants = {\n      \"top-to-bottom\": {\n        initial: { top: \"-100%\" },\n        animate: { top: \"100%\" },\n      },\n      \"bottom-to-top\": {\n        initial: { top: \"100%\" },\n        animate: { top: \"-100%\" },\n      },\n      both: {\n        initial: { top: \"100%\" },\n        animate: { top: [\"-100%\", \"100%\"] },\n      },\n      random: {\n        initial: () => ({ top: Math.random() < 0.5 ? \"-100%\" : \"100%\" }),\n        animate: () => ({ top: Math.random() < 0.5 ? \"-100%\" : \"100%\" }),\n      },\n    }\n    return variants[direction] || variants[\"top-to-bottom\"]\n  }, [direction])\n\n  const animationVariants = useMemo(\n    () => getAnimationVariants(),\n    [getAnimationVariants]\n  )\n\n  const lineColors = useMemo(() => {\n    return {\n      solid: darkMode ? \"hsl(233 14% 13%)\" : \"hsl(233 14.1% 96.1%)\",\n      dashed: darkMode ? \"hsl(233 14% 20%)\" : \"hsl(233 14% 93%)\",\n    }\n  }, [darkMode])\n\n  return (\n    <div\n      className={`pointer-events-none ${\n        contained ? \"absolute inset-0\" : \"fixed inset-0\"\n      } ${className}`}\n      aria-hidden=\"true\"\n      style={{ zIndex: contained ? 0 : -1 }}\n    >\n      <div className=\"z-0 h-full w-full px-4 sm:px-6 lg:px-24\">\n        <div\n          className=\"mx-auto h-full w-full\"\n          style={{\n            display: \"grid\",\n            gridTemplateColumns: responsive\n              ? `repeat(auto-fit, minmax(${minColumnWidth}, 1fr))`\n              : `repeat(${columnCount}, minmax(0, 1fr))`,\n            gap: \"2rem\",\n          }}\n        >\n          {columns.map((_, index) => (\n            <div key={index} className=\"relative h-full\">\n              <div\n                className={`absolute inset-y-0 ${\n                  index === 0\n                    ? \"left-0\"\n                    : index === columns.length - 1\n                      ? \"right-0\"\n                      : \"left-1/2\"\n                } w-px ${\n                  solidLines.includes(index + 1)\n                    ? \"bg-gray-300\"\n                    : \"bg-gradient-to-b\"\n                } overflow-hidden`}\n                style={\n                  solidLines.includes(index + 1)\n                    ? { background: lineColors.solid }\n                    : {\n                        backgroundImage: `linear-gradient(to bottom, ${lineColors.dashed} 50%, transparent 50%)`,\n                        backgroundSize: \"1px 8px\",\n                      }\n                }\n              >\n                <AnimatePresence>\n                  {animated && activeColumns[index] && (\n                    <motion.div\n                      key={`glow-${index}`}\n                      className=\"absolute w-full\"\n                      style={{\n                        height: glowSize,\n                        background: `linear-gradient(to bottom, transparent, ${glowColor}, ${\n                          darkMode ? \"black\" : \"white\"\n                        })`,\n                        opacity: glowOpacity,\n                      }}\n                      initial={\n                        typeof animationVariants.initial === \"function\"\n                          ? animationVariants.initial()\n                          : animationVariants.initial\n                      }\n                      animate={\n                        typeof animationVariants.animate === \"function\"\n                          ? animationVariants.animate()\n                          : animationVariants.animate\n                      }\n                      exit={\n                        typeof animationVariants.initial === \"function\"\n                          ? animationVariants.initial()\n                          : animationVariants.initial\n                      }\n                      transition={{\n                        duration: animationDuration,\n                        repeat: Infinity,\n                        ease: easingFunctions[easing],\n                        delay: index * animationDelay,\n                      }}\n                    />\n                  )}\n                </AnimatePresence>\n              </div>\n            </div>\n          ))}\n        </div>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:ui"
    }
  ]
}