{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "curcuit-board",
  "type": "registry:block",
  "title": "Curcuit board",
  "description": "Curcuit board",
  "files": [
    {
      "path": "components/usages/curcuitboardusage.tsx",
      "content": "import { CircuitBoard } from \"@/registry/open-source/curcuit-board\"\r\nimport { Cpu, HardDrive, Database, Cloud, Server, Shield, } from \"lucide-react\"\r\n\r\nexport default function Usage() {\r\n    return (\r\n        <div>\r\n\r\n            <CircuitBoard\r\n                nodes={[\r\n                    { id: \"cpu\", x: 100, y: 100, label: \"CPU\", icon: <Cpu className=\"w-4 h-4\" /> },\r\n                    { id: \"ram\", x: 250, y: 100, label: \"RAM\", icon: <HardDrive className=\"w-4 h-4\" /> },\r\n                    { id: \"storage\", x: 400, y: 100, label: \"Storage\", icon: <Database className=\"w-4 h-4\" /> },\r\n                ]}\r\n                connections={[\r\n                    { from: \"cpu\", to: \"ram\", bidirectional: true },\r\n                    { from: \"ram\", to: \"storage\", bidirectional: true },\r\n                ]}\r\n                width={500}\r\n                height={200}\r\n                showGrid={false}\r\n            />\r\n            <CircuitBoard\r\n                nodes={[\r\n                    { id: \"start\", x: 80, y: 150, label: \"Cloud\", icon: <Cloud className=\"w-4 h-4\" /> },\r\n                    { id: \"process\", x: 250, y: 80, label: \"Server\", icon: <Server className=\"w-4 h-4\" /> },\r\n                    { id: \"validate\", x: 250, y: 220, label: \"Validate\", icon: <Shield className=\"w-4 h-4\" /> },\r\n                    { id: \"end\", x: 420, y: 150, label: \"Database\", icon: <Database className=\"w-4 h-4\" /> },\r\n                ]}\r\n                connections={[\r\n                    { from: \"start\", to: \"process\", animated: true },\r\n                    { from: \"start\", to: \"validate\", animated: true },\r\n                    { from: \"process\", to: \"end\", animated: true },\r\n                    { from: \"validate\", to: \"end\", animated: true },\r\n                ]}\r\n                width={500}\r\n                height={300}\r\n            />\r\n        </div>\r\n    )\r\n}",
      "type": "registry:block",
      "target": "~/example.tsx"
    },
    {
      "path": "components/usages/curcuitboardusage.tsx",
      "content": "import { CircuitBoard } from \"@/registry/open-source/curcuit-board\"\r\nimport { Cpu, HardDrive, Database, Cloud, Server, Shield, } from \"lucide-react\"\r\n\r\nexport default function Usage() {\r\n    return (\r\n        <div>\r\n\r\n            <CircuitBoard\r\n                nodes={[\r\n                    { id: \"cpu\", x: 100, y: 100, label: \"CPU\", icon: <Cpu className=\"w-4 h-4\" /> },\r\n                    { id: \"ram\", x: 250, y: 100, label: \"RAM\", icon: <HardDrive className=\"w-4 h-4\" /> },\r\n                    { id: \"storage\", x: 400, y: 100, label: \"Storage\", icon: <Database className=\"w-4 h-4\" /> },\r\n                ]}\r\n                connections={[\r\n                    { from: \"cpu\", to: \"ram\", bidirectional: true },\r\n                    { from: \"ram\", to: \"storage\", bidirectional: true },\r\n                ]}\r\n                width={500}\r\n                height={200}\r\n                showGrid={false}\r\n            />\r\n            <CircuitBoard\r\n                nodes={[\r\n                    { id: \"start\", x: 80, y: 150, label: \"Cloud\", icon: <Cloud className=\"w-4 h-4\" /> },\r\n                    { id: \"process\", x: 250, y: 80, label: \"Server\", icon: <Server className=\"w-4 h-4\" /> },\r\n                    { id: \"validate\", x: 250, y: 220, label: \"Validate\", icon: <Shield className=\"w-4 h-4\" /> },\r\n                    { id: \"end\", x: 420, y: 150, label: \"Database\", icon: <Database className=\"w-4 h-4\" /> },\r\n                ]}\r\n                connections={[\r\n                    { from: \"start\", to: \"process\", animated: true },\r\n                    { from: \"start\", to: \"validate\", animated: true },\r\n                    { from: \"process\", to: \"end\", animated: true },\r\n                    { from: \"validate\", to: \"end\", animated: true },\r\n                ]}\r\n                width={500}\r\n                height={300}\r\n            />\r\n        </div>\r\n    )\r\n}",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/curcuit-board.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { motion } from \"framer-motion\"\nimport { cn } from \"../utilities/cn\"\n\n// Credit:\n// https://www.componentry.fun/docs/components/circuit-board\n\ninterface CircuitNode {\n    id: string\n    x: number\n    y: number\n    label?: string\n    icon?: React.ReactNode\n    status?: \"active\" | \"inactive\" | \"processing\" | \"error\"\n    size?: \"sm\" | \"md\" | \"lg\"\n}\n\ninterface CircuitConnection {\n    from: string\n    to: string\n    animated?: boolean\n    bidirectional?: boolean\n    color?: string\n    pulseColor?: string\n}\n\ninterface CircuitBoardProps extends React.HTMLAttributes<HTMLDivElement> {\n    nodes: CircuitNode[]\n    connections: CircuitConnection[]\n    width?: number\n    height?: number\n    gridSize?: number\n    showGrid?: boolean\n    gridColor?: string\n    traceColor?: string\n    pulseColor?: string\n    nodeColor?: string\n    pulseSpeed?: number\n    traceWidth?: number\n    /** Force a specific theme variant. Defaults to auto-detect from system. */\n    variant?: \"light\" | \"dark\" | \"auto\"\n}\n\nfunction CircuitBoard({\n    nodes,\n    connections,\n    width = 600,\n    height = 400,\n    gridSize = 20,\n    showGrid = true,\n    gridColor,\n    traceColor,\n    pulseColor,\n    nodeColor,\n    pulseSpeed = 2,\n    traceWidth = 2,\n    variant = \"auto\",\n    className,\n    ...props\n}: CircuitBoardProps) {\n    // Theme-aware color defaults\n    const [isDark, setIsDark] = React.useState(true)\n\n    React.useEffect(() => {\n        if (variant !== \"auto\") {\n            setIsDark(variant === \"dark\")\n            return\n        }\n\n        // Check for dark class on html/body\n        const checkTheme = () => {\n            const isDarkMode = document.documentElement.classList.contains(\"dark\") ||\n                document.body.classList.contains(\"dark\")\n            setIsDark(isDarkMode)\n        }\n\n        checkTheme()\n\n        // Listen for changes\n        const observer = new MutationObserver(checkTheme)\n        observer.observe(document.documentElement, { attributes: true, attributeFilter: [\"class\"] })\n        observer.observe(document.body, { attributes: true, attributeFilter: [\"class\"] })\n\n        const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\")\n        mediaQuery.addEventListener(\"change\", checkTheme)\n\n        return () => {\n            observer.disconnect()\n            mediaQuery.removeEventListener(\"change\", checkTheme)\n        }\n    }, [variant])\n\n    // Compute theme-aware colors\n    const computedGridColor = gridColor || (isDark ? \"rgba(163, 163, 163, 0.08)\" : \"rgba(64, 64, 64, 0.12)\")\n    const computedTraceColor = traceColor || (isDark ? \"rgba(163, 163, 163, 0.25)\" : \"rgba(64, 64, 64, 0.35)\")\n    const computedPulseColor = pulseColor || (isDark ? \"rgba(163, 163, 163, 0.6)\" : \"rgba(64, 64, 64, 0.7)\")\n    const computedNodeColor = nodeColor || (isDark ? \"rgba(163, 163, 163, 0.5)\" : \"rgba(64, 64, 64, 0.6)\")\n    const nodeMap = React.useMemo(() => {\n        return new Map(nodes.map((node) => [node.id, node]))\n    }, [nodes])\n\n    const getNodeSize = React.useCallback((size?: CircuitNode[\"size\"]) => {\n        switch (size) {\n            case \"sm\":\n                return 24\n            case \"lg\":\n                return 48\n            default:\n                return 36\n        }\n    }, [])\n\n    const calculatePath = React.useCallback(\n        (from: CircuitNode, to: CircuitNode): string => {\n            const fromSize = getNodeSize(from.size) / 2 + 4\n            const toSize = getNodeSize(to.size) / 2 + 4\n\n            const dx = to.x - from.x\n            const dy = to.y - from.y\n\n            // Calculate start and end points offset from node centers\n            let startX = from.x\n            let startY = from.y\n            let endX = to.x\n            let endY = to.y\n\n            // Create circuit-like paths with right angles\n            if (Math.abs(dx) > Math.abs(dy)) {\n                // Horizontal first, then vertical\n                startX = from.x + (dx > 0 ? fromSize : -fromSize)\n                endX = to.x + (dx > 0 ? -toSize : toSize)\n                const midX = from.x + dx / 2\n                return `M ${startX} ${startY} H ${midX} V ${endY} H ${endX}`\n            } else {\n                // Vertical first, then horizontal\n                startY = from.y + (dy > 0 ? fromSize : -fromSize)\n                endY = to.y + (dy > 0 ? -toSize : toSize)\n                const midY = from.y + dy / 2\n                return `M ${startX} ${startY} V ${midY} H ${endX} V ${endY}`\n            }\n        },\n        [getNodeSize]\n    )\n\n    const getStatusColor = (status?: CircuitNode[\"status\"]) => {\n        if (isDark) {\n            switch (status) {\n                case \"active\":\n                    return \"rgba(163, 163, 163, 0.7)\"\n                case \"processing\":\n                    return \"rgba(163, 163, 163, 0.5)\"\n                case \"error\":\n                    return \"rgba(120, 113, 108, 0.6)\"\n                default:\n                    return computedNodeColor\n            }\n        } else {\n            switch (status) {\n                case \"active\":\n                    return \"rgba(64, 64, 64, 0.8)\"\n                case \"processing\":\n                    return \"rgba(64, 64, 64, 0.6)\"\n                case \"error\":\n                    return \"rgba(180, 83, 83, 0.7)\"\n                default:\n                    return computedNodeColor\n            }\n        }\n    }\n\n    return (\n        <div\n            className={cn(\n                \"relative overflow-hidden\",\n                className\n            )}\n            style={{ width, height }}\n            {...props}\n        >\n            <svg\n                width={width}\n                height={height}\n                className=\"absolute inset-0\"\n                style={{ overflow: \"visible\" }}\n            >\n                <defs>\n                    {/* Glow filter for the pulse effect */}\n                    <filter id=\"glow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n                        <feGaussianBlur stdDeviation=\"3\" result=\"coloredBlur\" />\n                        <feMerge>\n                            <feMergeNode in=\"coloredBlur\" />\n                            <feMergeNode in=\"SourceGraphic\" />\n                        </feMerge>\n                    </filter>\n\n                    {/* Grid pattern */}\n                    {showGrid && (\n                        <pattern\n                            id=\"circuitGrid\"\n                            width={gridSize}\n                            height={gridSize}\n                            patternUnits=\"userSpaceOnUse\"\n                        >\n                            <circle cx={gridSize / 2} cy={gridSize / 2} r=\"0.5\" fill={computedGridColor} />\n                        </pattern>\n                    )}\n\n                    {/* Animated gradient for electricity effect */}\n                    {connections.map((conn, i) => (\n                        <linearGradient\n                            key={`gradient-${i}`}\n                            id={`electricGradient-${i}`}\n                            gradientUnits=\"userSpaceOnUse\"\n                        >\n                            <stop offset=\"0%\" stopColor=\"transparent\" />\n                            <stop offset=\"40%\" stopColor=\"transparent\" />\n                            <stop offset=\"50%\" stopColor={conn.pulseColor || computedPulseColor} />\n                            <stop offset=\"60%\" stopColor=\"transparent\" />\n                            <stop offset=\"100%\" stopColor=\"transparent\" />\n                        </linearGradient>\n                    ))}\n                </defs>\n\n                {/* Grid background */}\n                {showGrid && (\n                    <rect width={width} height={height} fill=\"url(#circuitGrid)\" />\n                )}\n\n                {/* Connection traces */}\n                {connections.map((conn, i) => {\n                    const fromNode = nodeMap.get(conn.from)\n                    const toNode = nodeMap.get(conn.to)\n                    if (!fromNode || !toNode) return null\n\n                    const path = calculatePath(fromNode, toNode)\n                    const pathLength = 500 // Approximate path length for animation\n\n                    return (\n                        <g key={`connection-${i}`}>\n                            {/* Base trace */}\n                            <motion.path\n                                d={path}\n                                fill=\"none\"\n                                stroke={conn.color || computedTraceColor}\n                                strokeWidth={traceWidth}\n                                strokeLinecap=\"round\"\n                                strokeLinejoin=\"round\"\n                                initial={{ pathLength: 0 }}\n                                animate={{ pathLength: 1 }}\n                                transition={{ duration: 1, delay: i * 0.2 }}\n                            />\n\n                            {/* Animated electricity pulse */}\n                            {conn.animated !== false && (\n                                <motion.path\n                                    d={path}\n                                    fill=\"none\"\n                                    stroke={conn.pulseColor || computedPulseColor}\n                                    strokeWidth={traceWidth + 2}\n                                    strokeLinecap=\"round\"\n                                    strokeLinejoin=\"round\"\n                                    filter=\"url(#glow)\"\n                                    strokeDasharray={`${pathLength * 0.1} ${pathLength * 0.9}`}\n                                    initial={{ strokeDashoffset: pathLength }}\n                                    animate={{ strokeDashoffset: -pathLength }}\n                                    transition={{\n                                        duration: pulseSpeed,\n                                        repeat: Infinity,\n                                        ease: \"linear\",\n                                        delay: i * 0.3,\n                                    }}\n                                />\n                            )}\n\n                            {/* Bidirectional pulse */}\n                            {conn.bidirectional && (\n                                <motion.path\n                                    d={path}\n                                    fill=\"none\"\n                                    stroke={conn.pulseColor || computedPulseColor}\n                                    strokeWidth={traceWidth + 2}\n                                    strokeLinecap=\"round\"\n                                    strokeLinejoin=\"round\"\n                                    filter=\"url(#glow)\"\n                                    strokeDasharray={`${pathLength * 0.1} ${pathLength * 0.9}`}\n                                    initial={{ strokeDashoffset: -pathLength }}\n                                    animate={{ strokeDashoffset: pathLength }}\n                                    transition={{\n                                        duration: pulseSpeed,\n                                        repeat: Infinity,\n                                        ease: \"linear\",\n                                        delay: i * 0.3 + pulseSpeed / 2,\n                                    }}\n                                />\n                            )}\n\n\n                        </g>\n                    )\n                })}\n            </svg>\n\n            {/* Nodes */}\n            {nodes.map((node, i) => {\n                const size = getNodeSize(node.size)\n                const statusColor = getStatusColor(node.status)\n\n                return (\n                    <motion.div\n                        key={node.id}\n                        className=\"absolute flex items-center justify-center\"\n                        style={{\n                            left: node.x - size / 2,\n                            top: node.y - size / 2,\n                            width: size,\n                            height: size,\n                        }}\n                        initial={{ scale: 0, opacity: 0 }}\n                        animate={{ scale: 1, opacity: 1 }}\n                        transition={{ delay: i * 0.1 + 0.5, type: \"spring\" }}\n                    >\n                        {/* Node background with pulse */}\n                        <motion.div\n                            className=\"absolute inset-0 rounded-lg\"\n                            style={{ backgroundColor: statusColor }}\n                            animate={\n                                node.status === \"processing\"\n                                    ? { opacity: [0.2, 0.5, 0.2] }\n                                    : { opacity: 0.2 }\n                            }\n                            transition={\n                                node.status === \"processing\"\n                                    ? { duration: 1.5, repeat: Infinity }\n                                    : {}\n                            }\n                        />\n\n                        {/* Node border */}\n                        <div\n                            className=\"absolute inset-0 rounded-lg border-2\"\n                            style={{ borderColor: statusColor }}\n                        />\n\n                        {/* Inner glow for active nodes */}\n                        {node.status === \"active\" && (\n                            <motion.div\n                                className=\"absolute inset-0 rounded-lg\"\n                                style={{\n                                    boxShadow: `0 0 20px ${statusColor}40, inset 0 0 10px ${statusColor}20`,\n                                }}\n                                animate={{ opacity: [0.5, 1, 0.5] }}\n                                transition={{ duration: 2, repeat: Infinity }}\n                            />\n                        )}\n\n                        {/* Node content */}\n                        <div className=\"relative z-10 flex flex-col items-center justify-center\">\n                            {node.icon && (\n                                <div style={{ color: statusColor }}>{node.icon}</div>\n                            )}\n                        </div>\n\n                        {/* Label */}\n                        {node.label && (\n                            <div\n                                className=\"absolute -bottom-6 left-1/2 -translate-x-1/2 whitespace-nowrap text-xs font-medium\"\n                                style={{ color: statusColor }}\n                            >\n                                {node.label}\n                            </div>\n                        )}\n                    </motion.div>\n                )\n            })}\n        </div>\n    )\n}\n\n// Pre-built circuit patterns\ninterface CircuitPatternProps extends Omit<CircuitBoardProps, \"nodes\" | \"connections\"> {\n    pattern: \"data-flow\" | \"network\" | \"processor\" | \"tree\"\n}\n\nfunction CircuitPattern({ pattern, ...props }: CircuitPatternProps) {\n    const patterns = {\n        \"data-flow\": {\n            nodes: [\n                { id: \"input\", x: 50, y: 200, label: \"Input\", status: \"active\" as const },\n                { id: \"process1\", x: 200, y: 100, label: \"Process\", status: \"processing\" as const },\n                { id: \"process2\", x: 200, y: 300, label: \"Validate\", status: \"active\" as const },\n                { id: \"merge\", x: 400, y: 200, label: \"Merge\", status: \"active\" as const },\n                { id: \"output\", x: 550, y: 200, label: \"Output\", status: \"active\" as const },\n            ],\n            connections: [\n                { from: \"input\", to: \"process1\", animated: true },\n                { from: \"input\", to: \"process2\", animated: true },\n                { from: \"process1\", to: \"merge\", animated: true },\n                { from: \"process2\", to: \"merge\", animated: true },\n                { from: \"merge\", to: \"output\", animated: true },\n            ],\n        },\n        network: {\n            nodes: [\n                { id: \"server\", x: 300, y: 80, label: \"Server\", status: \"active\" as const, size: \"lg\" as const },\n                { id: \"client1\", x: 100, y: 200, label: \"Client 1\", status: \"active\" as const },\n                { id: \"client2\", x: 300, y: 250, label: \"Client 2\", status: \"processing\" as const },\n                { id: \"client3\", x: 500, y: 200, label: \"Client 3\", status: \"active\" as const },\n                { id: \"db\", x: 300, y: 350, label: \"Database\", status: \"active\" as const },\n            ],\n            connections: [\n                { from: \"server\", to: \"client1\", bidirectional: true },\n                { from: \"server\", to: \"client2\", bidirectional: true },\n                { from: \"server\", to: \"client3\", bidirectional: true },\n                { from: \"server\", to: \"db\", bidirectional: true },\n            ],\n        },\n        processor: {\n            nodes: [\n                { id: \"alu\", x: 300, y: 200, label: \"ALU\", status: \"processing\" as const, size: \"lg\" as const },\n                { id: \"reg1\", x: 150, y: 100, label: \"R1\", status: \"active\" as const, size: \"sm\" as const },\n                { id: \"reg2\", x: 150, y: 200, label: \"R2\", status: \"active\" as const, size: \"sm\" as const },\n                { id: \"reg3\", x: 150, y: 300, label: \"R3\", status: \"active\" as const, size: \"sm\" as const },\n                { id: \"cache\", x: 450, y: 200, label: \"Cache\", status: \"active\" as const },\n                { id: \"out\", x: 550, y: 200, label: \"Out\", status: \"active\" as const, size: \"sm\" as const },\n            ],\n            connections: [\n                { from: \"reg1\", to: \"alu\", animated: true },\n                { from: \"reg2\", to: \"alu\", animated: true },\n                { from: \"reg3\", to: \"alu\", animated: true },\n                { from: \"alu\", to: \"cache\", animated: true },\n                { from: \"cache\", to: \"out\", animated: true },\n            ],\n        },\n        tree: {\n            nodes: [\n                { id: \"root\", x: 300, y: 50, label: \"Root\", status: \"active\" as const },\n                { id: \"l1\", x: 150, y: 150, label: \"L1\", status: \"active\" as const },\n                { id: \"r1\", x: 450, y: 150, label: \"R1\", status: \"processing\" as const },\n                { id: \"l1l\", x: 80, y: 280, label: \"L1L\", status: \"active\" as const, size: \"sm\" as const },\n                { id: \"l1r\", x: 220, y: 280, label: \"L1R\", status: \"active\" as const, size: \"sm\" as const },\n                { id: \"r1l\", x: 380, y: 280, label: \"R1L\", status: \"error\" as const, size: \"sm\" as const },\n                { id: \"r1r\", x: 520, y: 280, label: \"R1R\", status: \"active\" as const, size: \"sm\" as const },\n            ],\n            connections: [\n                { from: \"root\", to: \"l1\", animated: true },\n                { from: \"root\", to: \"r1\", animated: true },\n                { from: \"l1\", to: \"l1l\", animated: true },\n                { from: \"l1\", to: \"l1r\", animated: true },\n                { from: \"r1\", to: \"r1l\", animated: true },\n                { from: \"r1\", to: \"r1r\", animated: true },\n            ],\n        },\n    }\n\n    const selectedPattern = patterns[pattern]\n    return <CircuitBoard nodes={selectedPattern.nodes} connections={selectedPattern.connections} {...props} />\n}\n\n// Interactive circuit node for building custom circuits\ninterface CircuitNodeComponentProps {\n    status?: \"active\" | \"inactive\" | \"processing\" | \"error\"\n    size?: \"sm\" | \"md\" | \"lg\"\n    glowColor?: string\n    children?: React.ReactNode\n    className?: string\n    onClick?: () => void\n}\n\nfunction CircuitNode({\n    status = \"inactive\",\n    size = \"md\",\n    glowColor,\n    children,\n    className,\n    onClick,\n}: CircuitNodeComponentProps) {\n    const [isDark, setIsDark] = React.useState(true)\n\n    React.useEffect(() => {\n        const checkTheme = () => {\n            const isDarkMode = document.documentElement.classList.contains(\"dark\") ||\n                document.body.classList.contains(\"dark\")\n            setIsDark(isDarkMode)\n        }\n\n        checkTheme()\n\n        const observer = new MutationObserver(checkTheme)\n        observer.observe(document.documentElement, { attributes: true, attributeFilter: [\"class\"] })\n        observer.observe(document.body, { attributes: true, attributeFilter: [\"class\"] })\n\n        const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\")\n        mediaQuery.addEventListener(\"change\", checkTheme)\n\n        return () => {\n            observer.disconnect()\n            mediaQuery.removeEventListener(\"change\", checkTheme)\n        }\n    }, [])\n\n    const sizeClasses = {\n        sm: \"w-8 h-8\",\n        md: \"w-12 h-12\",\n        lg: \"w-16 h-16\",\n    }\n\n    const statusColors = isDark\n        ? {\n            active: \"rgba(163, 163, 163, 0.7)\",\n            inactive: \"rgba(115, 115, 115, 0.4)\",\n            processing: \"rgba(163, 163, 163, 0.5)\",\n            error: \"rgba(120, 113, 108, 0.6)\",\n        }\n        : {\n            active: \"rgba(64, 64, 64, 0.8)\",\n            inactive: \"rgba(100, 100, 100, 0.5)\",\n            processing: \"rgba(64, 64, 64, 0.6)\",\n            error: \"rgba(180, 83, 83, 0.7)\",\n        }\n\n    const color = glowColor || statusColors[status]\n\n    return (\n        <motion.div\n            className={cn(\n                \"relative flex items-center justify-center rounded-lg border\",\n                isDark ? \"bg-neutral-900/50\" : \"bg-neutral-200/60\",\n                sizeClasses[size],\n                className\n            )}\n            style={{ borderColor: color }}\n            whileHover={{ scale: 1.1 }}\n            whileTap={{ scale: 0.95 }}\n            onClick={onClick}\n        >\n            {/* Pulse animation for processing state */}\n            {status === \"processing\" && (\n                <motion.div\n                    className=\"absolute inset-0 rounded-lg\"\n                    style={{ backgroundColor: color }}\n                    animate={{ opacity: [0.1, 0.3, 0.1] }}\n                    transition={{ duration: 1.5, repeat: Infinity }}\n                />\n            )}\n\n            {/* Active glow */}\n            {status === \"active\" && (\n                <div\n                    className=\"absolute inset-0 rounded-lg\"\n                    style={{\n                        boxShadow: `0 0 20px ${color}60, 0 0 40px ${color}30`,\n                    }}\n                />\n            )}\n\n            {/* Error pulse */}\n            {status === \"error\" && (\n                <motion.div\n                    className=\"absolute inset-0 rounded-lg\"\n                    style={{ boxShadow: `0 0 20px ${color}80` }}\n                    animate={{ opacity: [0.5, 1, 0.5] }}\n                    transition={{ duration: 0.5, repeat: Infinity }}\n                />\n            )}\n\n            <div className=\"relative z-10\" style={{ color }}>\n                {children}\n            </div>\n        </motion.div>\n    )\n}\n\n// Animated trace line component for custom layouts\ninterface CircuitTraceProps {\n    path: string\n    animated?: boolean\n    color?: string\n    pulseColor?: string\n    width?: number\n    pulseSpeed?: number\n}\n\nfunction CircuitTrace({\n    path,\n    animated = true,\n    color,\n    pulseColor,\n    width = 2,\n    pulseSpeed = 2,\n}: CircuitTraceProps) {\n    const [isDark, setIsDark] = React.useState(true)\n\n    React.useEffect(() => {\n        const checkTheme = () => {\n            const isDarkMode = document.documentElement.classList.contains(\"dark\") ||\n                document.body.classList.contains(\"dark\")\n            setIsDark(isDarkMode)\n        }\n\n        checkTheme()\n\n        const observer = new MutationObserver(checkTheme)\n        observer.observe(document.documentElement, { attributes: true, attributeFilter: [\"class\"] })\n        observer.observe(document.body, { attributes: true, attributeFilter: [\"class\"] })\n\n        const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\")\n        mediaQuery.addEventListener(\"change\", checkTheme)\n\n        return () => {\n            observer.disconnect()\n            mediaQuery.removeEventListener(\"change\", checkTheme)\n        }\n    }, [])\n\n    const computedColor = color || (isDark ? \"rgba(163, 163, 163, 0.25)\" : \"rgba(64, 64, 64, 0.35)\")\n    const computedPulseColor = pulseColor || (isDark ? \"rgba(163, 163, 163, 0.6)\" : \"rgba(64, 64, 64, 0.7)\")\n    const pathLength = 500\n\n    return (\n        <svg className=\"absolute inset-0 overflow-visible pointer-events-none\">\n            <defs>\n                <filter id=\"traceGlow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n                    <feGaussianBlur stdDeviation=\"3\" result=\"coloredBlur\" />\n                    <feMerge>\n                        <feMergeNode in=\"coloredBlur\" />\n                        <feMergeNode in=\"SourceGraphic\" />\n                    </feMerge>\n                </filter>\n            </defs>\n\n            {/* Base trace */}\n            <motion.path\n                d={path}\n                fill=\"none\"\n                stroke={computedColor}\n                strokeWidth={width}\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                initial={{ pathLength: 0 }}\n                animate={{ pathLength: 1 }}\n                transition={{ duration: 1 }}\n            />\n\n            {/* Animated pulse */}\n            {animated && (\n                <motion.path\n                    d={path}\n                    fill=\"none\"\n                    stroke={computedPulseColor}\n                    strokeWidth={width + 2}\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    filter=\"url(#traceGlow)\"\n                    strokeDasharray={`${pathLength * 0.1} ${pathLength * 0.9}`}\n                    initial={{ strokeDashoffset: pathLength }}\n                    animate={{ strokeDashoffset: -pathLength }}\n                    transition={{\n                        duration: pulseSpeed,\n                        repeat: Infinity,\n                        ease: \"linear\",\n                    }}\n                />\n            )}\n        </svg>\n    )\n}\n\nexport {\n    CircuitBoard,\n    CircuitPattern,\n    CircuitNode,\n    CircuitTrace,\n    type CircuitNode as CircuitNodeType,\n    type CircuitConnection,\n    type CircuitBoardProps,\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/utilities/cn.ts",
      "content": "import { ClassValue, clsx } from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n\treturn twMerge(clsx(inputs));\r\n}\r\n",
      "type": "registry:ui"
    }
  ]
}