{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "gradient-mesh",
  "title": "Gradient Mesh",
  "author": "WebberUI",
  "description": "網格漸層背景：四到五個柔和 radial-gradient 色點以 transform 緩慢漂移交織成流動 mesh。",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/webber/gradient-mesh.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\n/** 預設柔和多彩配色：粉 → 紫 → 藍 → 翠 → 琥珀，深淺底皆耐看 */\nconst DEFAULT_COLORS = [\"#f472b6\", \"#a78bfa\", \"#60a5fa\", \"#34d399\", \"#fbbf24\"];\n\ninterface MeshConfig {\n  /** 初始定位與尺寸——只負責擺位，位移一律交給 transform */\n  className: string;\n  /** 漂移幅度（px），x / y 各自往返，`repeatType: \"mirror\"` 在原點與此值間擺盪 */\n  drift: { x: number; y: number };\n  /** x 軸漂移週期（秒） */\n  durationX: number;\n  /** y 軸漂移週期（秒），刻意與 durationX 錯開，讓色點走出弧形軌跡 */\n  durationY: number;\n}\n\n/** 五個色點鋪成 mesh：四角 + 中央，各自不同週期，永不同步 */\nconst MESH_POINTS: MeshConfig[] = [\n  {\n    className: \"left-[-10%] top-[-15%] h-[70%] w-[55%]\",\n    drift: { x: 50, y: 40 },\n    durationX: 15,\n    durationY: 21,\n  },\n  {\n    className: \"right-[-12%] top-[-12%] h-[75%] w-[55%]\",\n    drift: { x: -55, y: 45 },\n    durationX: 19,\n    durationY: 14,\n  },\n  {\n    className: \"left-[22%] top-[20%] h-[70%] w-[55%]\",\n    drift: { x: 45, y: -40 },\n    durationX: 22,\n    durationY: 17,\n  },\n  {\n    className: \"left-[-8%] bottom-[-18%] h-[70%] w-[55%]\",\n    drift: { x: 55, y: -35 },\n    durationX: 13,\n    durationY: 20,\n  },\n  {\n    className: \"right-[-10%] bottom-[-20%] h-[75%] w-[60%]\",\n    drift: { x: -50, y: -45 },\n    durationX: 18,\n    durationY: 12,\n  },\n];\n\ninterface MeshPointProps {\n  config: MeshConfig;\n  color: string;\n  isStatic: boolean;\n  /** 漂移倍速：週期除以此值，越大越快 */\n  speed: number;\n}\n\nfunction MeshPoint({ config, color, isStatic, speed }: MeshPointProps) {\n  return (\n    <motion.div\n      className={cn(\"absolute rounded-full blur-3xl\", config.className)}\n      style={{\n        background: `radial-gradient(circle at center, ${color} 0%, transparent 70%)`,\n      }}\n      animate={isStatic ? { x: 0, y: 0 } : { x: config.drift.x, y: config.drift.y }}\n      transition={\n        isStatic\n          ? { duration: 0 }\n          : {\n              x: {\n                duration: config.durationX / speed,\n                repeat: Infinity,\n                repeatType: \"mirror\",\n                ease: \"easeInOut\",\n              },\n              y: {\n                duration: config.durationY / speed,\n                repeat: Infinity,\n                repeatType: \"mirror\",\n                ease: \"easeInOut\",\n              },\n            }\n      }\n    />\n  );\n}\n\ninterface GradientMeshProps {\n  /** mesh 色點顏色，依序對應各色點；預設柔和多彩配色 */\n  colors?: string[];\n  /** 漂移倍速，1 為基準，數值越大流動越快 */\n  speed?: number;\n  /** 前景內容，疊在 mesh 之上；佈局（如置中、高度）直接寫在 `className` */\n  children?: React.ReactNode;\n  className?: string;\n}\n\nexport function GradientMesh({\n  colors = DEFAULT_COLORS,\n  speed = 1,\n  children,\n  className,\n}: GradientMeshProps) {\n  const reducedMotion = useReducedMotion();\n  // 首次渲染必須與 SSR 輸出一致，掛載後才依 reduced-motion 切換靜態版\n  const [mounted, setMounted] = React.useState(false);\n  React.useEffect(() => setMounted(true), []);\n  const isStatic = Boolean(mounted && reducedMotion);\n\n  // 避免除以 0 或負值造成 Infinity / 反向週期\n  const safeSpeed = speed > 0 ? speed : 1;\n\n  return (\n    <div\n      className={cn(\n        \"relative isolate overflow-hidden bg-neutral-50 dark:bg-neutral-950\",\n        className,\n      )}\n    >\n      <div aria-hidden className=\"pointer-events-none absolute inset-0 -z-10\">\n        {MESH_POINTS.map((point, i) => (\n          <MeshPoint\n            key={i}\n            config={point}\n            color={colors[i % colors.length] ?? DEFAULT_COLORS[i]}\n            isStatic={isStatic}\n            speed={safeSpeed}\n          />\n        ))}\n      </div>\n      {children}\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "background"
  ],
  "type": "registry:ui"
}