{
  "name": "apple-activity-card",
  "type": "registry:component",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "type": "registry:component",
      "content": "\"use client\";\n\n/**\n * @author: @kokonutui\n * @description: Apple Activity Card\n * @version: 1.0.0\n * @date: 2025-06-26\n * @license: MIT\n * @website: https://kokonutui.com\n * @github: https://github.com/kokonut-labs/kokonutui\n */\n\nimport { motion } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ActivityData {\n  label: string;\n  value: number;\n  color: string;\n  size: number;\n  current: number;\n  target: number;\n  unit: string;\n}\n\ninterface CircleProgressProps {\n  data: ActivityData;\n  index: number;\n}\n\nconst activities: ActivityData[] = [\n  {\n    label: \"MOVE\",\n    value: 85,\n    color: \"#FF2D55\",\n    size: 200,\n    current: 479,\n    target: 800,\n    unit: \"CAL\",\n  },\n  {\n    label: \"EXERCISE\",\n    value: 60,\n    color: \"#A3F900\",\n    size: 160,\n    current: 24,\n    target: 30,\n    unit: \"MIN\",\n  },\n  {\n    label: \"STAND\",\n    value: 30,\n    color: \"#04C7DD\",\n    size: 120,\n    current: 6,\n    target: 12,\n    unit: \"HR\",\n  },\n];\n\nconst CircleProgress = ({ data, index }: CircleProgressProps) => {\n  const strokeWidth = 16;\n  const radius = (data.size - strokeWidth) / 2;\n  const circumference = radius * 2 * Math.PI;\n  const progress = ((100 - data.value) / 100) * circumference;\n\n  const gradientId = `gradient-${data.label.toLowerCase()}`;\n  const gradientUrl = `url(#${gradientId})`;\n\n  return (\n    <motion.div\n      animate={{ opacity: 1, scale: 1 }}\n      className=\"absolute inset-0 flex items-center justify-center\"\n      initial={{ opacity: 0, scale: 0.8 }}\n      transition={{ duration: 0.8, delay: index * 0.2, ease: \"easeOut\" }}\n    >\n      <div className=\"relative\">\n        <svg\n          aria-label={`${data.label} Activity Progress - ${data.value}%`}\n          className=\"-rotate-90 transform\"\n          height={data.size}\n          viewBox={`0 0 ${data.size} ${data.size}`}\n          width={data.size}\n        >\n          <title>{`${data.label} Activity Progress - ${data.value}%`}</title>\n\n          <defs>\n            <linearGradient id={gradientId} x1=\"0%\" x2=\"100%\" y1=\"0%\" y2=\"100%\">\n              <stop\n                offset=\"0%\"\n                style={{\n                  stopColor: data.color,\n                  stopOpacity: 1,\n                }}\n              />\n              <stop\n                offset=\"100%\"\n                style={{\n                  stopColor:\n                    data.color === \"#FF2D55\"\n                      ? \"#FF6B8B\"\n                      : data.color === \"#A3F900\"\n                        ? \"#C5FF4D\"\n                        : \"#4DDFED\",\n                  stopOpacity: 1,\n                }}\n              />\n            </linearGradient>\n          </defs>\n\n          <circle\n            className=\"text-zinc-200/50 dark:text-zinc-800/50\"\n            cx={data.size / 2}\n            cy={data.size / 2}\n            fill=\"none\"\n            r={radius}\n            stroke=\"currentColor\"\n            strokeWidth={strokeWidth}\n          />\n\n          <motion.circle\n            animate={{ strokeDashoffset: progress }}\n            cx={data.size / 2}\n            cy={data.size / 2}\n            fill=\"none\"\n            initial={{ strokeDashoffset: circumference }}\n            r={radius}\n            stroke={gradientUrl}\n            strokeDasharray={circumference}\n            strokeLinecap=\"round\"\n            strokeWidth={strokeWidth}\n            style={{\n              filter: \"drop-shadow(0 0 6px rgba(0,0,0,0.15))\",\n            }}\n            transition={{\n              duration: 1.8,\n              delay: index * 0.2,\n              ease: \"easeInOut\",\n            }}\n          />\n        </svg>\n      </div>\n    </motion.div>\n  );\n};\n\nconst DetailedActivityInfo = () => {\n  return (\n    <motion.div\n      animate={{ opacity: 1, x: 0 }}\n      className=\"ml-8 flex flex-col gap-6\"\n      initial={{ opacity: 0, x: 20 }}\n      transition={{ duration: 0.5, delay: 0.3 }}\n    >\n      {activities.map((activity) => (\n        <motion.div className=\"flex flex-col\" key={activity.label}>\n          <span className=\"font-medium text-sm text-zinc-600 dark:text-zinc-400\">\n            {activity.label}\n          </span>\n          <span\n            className=\"font-semibold text-2xl\"\n            style={{ color: activity.color }}\n          >\n            {activity.current}/{activity.target}\n            <span className=\"ml-1 text-base text-zinc-600 dark:text-zinc-400\">\n              {activity.unit}\n            </span>\n          </span>\n        </motion.div>\n      ))}\n    </motion.div>\n  );\n};\n\nexport default function AppleActivityCard({\n  title = \"Activity Rings\",\n  className,\n}: {\n  title?: string;\n  className?: string;\n}) {\n  return (\n    <div\n      className={cn(\n        \"relative mx-auto w-full max-w-3xl rounded-3xl p-8\",\n        \"text-zinc-900 dark:text-white\",\n        className\n      )}\n    >\n      <div className=\"flex flex-col items-center gap-8\">\n        <motion.h2\n          animate={{ opacity: 1, y: 0 }}\n          className=\"font-medium text-2xl text-zinc-900 dark:text-white\"\n          initial={{ opacity: 0, y: -20 }}\n          transition={{ duration: 0.5 }}\n        >\n          {title}\n        </motion.h2>\n\n        <div className=\"flex items-center\">\n          <div className=\"relative h-[180px] w-[180px]\">\n            {activities.map((activity, index) => (\n              <CircleProgress\n                data={activity}\n                index={index}\n                key={activity.label}\n              />\n            ))}\n          </div>\n          <DetailedActivityInfo />\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "path": "/components/kokonutui/apple-activity-card.tsx",
      "target": "components/kokonutui/apple-activity-card.tsx"
    }
  ]
}