{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "area-chart-card",
  "title": "Area Chart",
  "description": "Stacked, overlapping, or 100% area series with a count-up headline and period control.",
  "dependencies": [
    "recharts@^3.10.1"
  ],
  "registryDependencies": [
    "https://components.exe.xyz/r/chart-card.json"
  ],
  "files": [
    {
      "path": "src/components/charts/area-chart-card.tsx",
      "content": "import { useState } from \"react\"\nimport {\n  Area,\n  AreaChart,\n  CartesianGrid,\n  ResponsiveContainer,\n  Tooltip,\n  XAxis,\n  YAxis,\n} from \"recharts\"\n\nimport {\n  ChartCard,\n  ChartPlot,\n  ChartTiles,\n  PlotTooltip,\n  axisTick,\n  chartColor,\n  formatNumber,\n  useActiveRange,\n  usePrefersReducedMotion,\n} from \"@/components/charts/chart-card\"\n\nexport type AreaChartRow = Record<string, string | number>\nexport type AreaChartSeries = { key: string; label: string; color?: string }\n\nconst DEFAULT_DATA: AreaChartRow[] = [\n  { label: \"Jan\", organic: 3200, referral: 1600, paid: 1100 },\n  { label: \"Feb\", organic: 3400, referral: 1700, paid: 1200 },\n  { label: \"Mar\", organic: 3800, referral: 1900, paid: 1400 },\n  { label: \"Apr\", organic: 4000, referral: 2000, paid: 1450 },\n  { label: \"May\", organic: 4200, referral: 2100, paid: 1500 },\n  { label: \"Jun\", organic: 4400, referral: 2200, paid: 1600 },\n  { label: \"Jul\", organic: 4600, referral: 2300, paid: 1650 },\n  { label: \"Aug\", organic: 4500, referral: 2400, paid: 1700 },\n  { label: \"Sep\", organic: 4300, referral: 2200, paid: 1550 },\n  { label: \"Oct\", organic: 4100, referral: 2100, paid: 1500 },\n  { label: \"Nov\", organic: 4700, referral: 2500, paid: 1800 },\n  { label: \"Dec\", organic: 5300, referral: 2900, paid: 1850 },\n]\n\nconst DEFAULT_SERIES: AreaChartSeries[] = [\n  { key: \"organic\", label: \"Organic\" },\n  { key: \"referral\", label: \"Referral\" },\n  { key: \"paid\", label: \"Paid\" },\n]\n\nexport function AreaChartCard({\n  title = \"Visitors\",\n  variant = \"stacked\",\n  shape = \"smooth\",\n  data,\n  series = DEFAULT_SERIES,\n  headline,\n  delta = 8.2,\n  range,\n  ranges,\n  tiles = true,\n}: {\n  title?: string\n  variant?: \"stacked\" | \"overlap\" | \"percent\"\n  shape?: \"smooth\" | \"sharp\"\n  data?: AreaChartRow[]\n  series?: AreaChartSeries[]\n  headline?: number\n  delta?: number\n  range?: string\n  ranges?: {\n    id: string\n    label: string\n    data: AreaChartRow[]\n    delta?: number\n    headline?: number\n  }[]\n  tiles?: boolean\n}) {\n  const reduced = usePrefersReducedMotion()\n  const { id, setId, active } = useActiveRange(ranges, range)\n  const plotData = active?.data ?? data ?? DEFAULT_DATA\n  const plotDelta = active?.delta ?? delta\n  const [activeKey, setActiveKey] = useState<string | null>(null)\n\n  const totals = series.map((item) => ({\n    ...item,\n    total: plotData.reduce((sum, row) => {\n      const value = row[item.key]\n      return sum + (typeof value === \"number\" ? value : 0)\n    }, 0),\n    color: chartColor(\n      series.findIndex((s) => s.key === item.key),\n      item.color\n    ),\n  }))\n  const plotHeadline =\n    active?.headline ?? headline ?? totals.reduce((sum, s) => sum + s.total, 0)\n\n  const stacked = variant !== \"overlap\"\n  const curve = shape === \"sharp\" ? \"linear\" : \"monotone\"\n\n  const summary = `${title} ${formatNumber(plotHeadline)}, ${series\n    .map((item, i) => `${item.label} ${formatNumber(totals[i]?.total ?? 0)}`)\n    .join(\", \")}`\n\n  return (\n    <ChartCard\n      title={title}\n      headline={plotHeadline}\n      delta={plotDelta}\n      period={ranges ? undefined : \"This year\"}\n      ranges={ranges}\n      range={id}\n      onRangeChange={setId}\n      summary={summary}\n      tiles={\n        tiles ? (\n          <ChartTiles\n            activeId={activeKey}\n            onActiveChange={setActiveKey}\n            items={totals.map((item) => ({\n              id: item.key,\n              label: item.label,\n              value: formatNumber(item.total),\n              color: item.color,\n            }))}\n          />\n        ) : undefined\n      }\n    >\n      <ChartPlot height={220} summary={summary}>\n        <ResponsiveContainer width=\"100%\" height=\"100%\">\n          <AreaChart\n            data={plotData}\n            stackOffset={variant === \"percent\" ? \"expand\" : \"none\"}\n            margin={{ top: 8, right: 8, left: 0, bottom: 0 }}\n          >\n            <CartesianGrid\n              vertical={false}\n              stroke=\"var(--border)\"\n              strokeDasharray=\"1 4\"\n            />\n            <XAxis\n              dataKey=\"label\"\n              tick={axisTick}\n              tickLine={false}\n              axisLine={{ stroke: \"var(--border)\" }}\n              interval={0}\n            />\n            <YAxis\n              tick={axisTick}\n              tickLine={false}\n              axisLine={false}\n              width={40}\n              tickFormatter={\n                variant === \"percent\"\n                  ? (value: number) => `${Math.round(value * 100)}%`\n                  : (value: number) =>\n                      value >= 1000\n                        ? `${Math.round(value / 100) / 10}k`\n                        : String(value)\n              }\n            />\n            <Tooltip\n              cursor={{ stroke: \"var(--ring)\", strokeWidth: 1 }}\n              content={<PlotTooltip />}\n            />\n            {series.map((item, index) => {\n              const color = chartColor(index, item.color)\n              const dimmed = activeKey != null && activeKey !== item.key\n              return (\n                <Area\n                  key={item.key}\n                  type={curve}\n                  dataKey={item.key}\n                  name={item.label}\n                  stackId={stacked ? \"s\" : undefined}\n                  stroke={color}\n                  fill={color}\n                  fillOpacity={\n                    dimmed ? 0.08 : variant === \"overlap\" ? 0.28 : 0.78\n                  }\n                  strokeWidth={1.5}\n                  strokeOpacity={dimmed ? 0.25 : 1}\n                  isAnimationActive={!reduced}\n                />\n              )\n            })}\n          </AreaChart>\n        </ResponsiveContainer>\n      </ChartPlot>\n    </ChartCard>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:block"
}