{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "chart",
  "type": "registry:ui",
  "title": "Chart",
  "description": "Recharts container used by every Wingtics chart. Colors inherit --chart-1…5 from the host theme.",
  "dependencies": [
    "recharts@2.15.4",
    "d3-scale@4.0.2",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "packages/react/src/lib/cn.ts",
      "type": "registry:lib",
      "target": "@lib/cn.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]): string {\n  return twMerge(clsx(inputs));\n}\n"
    },
    {
      "path": "packages/react/src/charts/chart.tsx",
      "type": "registry:ui",
      "target": "@ui/chart.tsx",
      "content": "import { type CSSProperties, type ReactElement, useId } from \"react\";\nimport { scaleSymlog } from \"d3-scale\";\nimport { ResponsiveContainer } from \"recharts\";\nimport { cn } from \"../lib/cn.js\";\nimport type { AxisScale } from \"./variants.js\";\n\nexport type ChartConfig = Record<\n  string,\n  {\n    label?: string;\n    color?: string;\n  }\n>;\n\n/**\n * Pinned locale on purpose. Bare `toLocaleString()` follows the runtime's\n * locale, so Node renders `4279` where the browser renders `4,279` and React\n * throws a hydration mismatch on every server-rendered number.\n */\nconst NUMBER_FORMAT = new Intl.NumberFormat(\"en-US\", { maximumFractionDigits: 2 });\n\n/**\n * Fractions are kept rather than rounded away. A pie slice sized from 1.5 that\n * prints \"2\" is a label disagreeing with its own geometry, and metrics like\n * bounce rate are routinely fractional. Integers still print as integers.\n */\nexport function formatNumber(value: number): string {\n  return Number.isFinite(value) ? NUMBER_FORMAT.format(value) : \"—\";\n}\n\nexport const PALETTE = [\n  \"var(--ak-chart-1, var(--chart-1))\",\n  \"var(--ak-chart-2, var(--chart-2))\",\n  \"var(--ak-chart-3, var(--chart-3))\",\n  \"var(--ak-chart-4, var(--chart-4))\",\n  \"var(--ak-chart-5, var(--chart-5))\",\n];\n\n/**\n * Resolve the public scale option to something recharts can consume.\n * Recharts assigns the final domain and range, so symlog needs a fresh scale.\n */\nexport function rechartsScale(scale: AxisScale): \"log\" | ReturnType<typeof scaleSymlog> {\n  return scale === \"symlog\" ? scaleSymlog() : \"log\";\n}\n\nexport function numericAxisDomain(scale: Exclude<AxisScale, \"linear\">): [number | \"auto\", \"auto\"] {\n  return scale === \"log\" ? [1, \"auto\"] : [\"auto\", \"auto\"];\n}\n\n/** Config for a multi-series chart, one palette colour per key. */\nexport function seriesConfig(keys: string[], config?: ChartConfig): ChartConfig {\n  const out: ChartConfig = {};\n  keys.forEach((key, index) => {\n    out[key] = {\n      label: config?.[key]?.label ?? key,\n      color: config?.[key]?.color ?? PALETTE[index % PALETTE.length],\n    };\n  });\n  return out;\n}\n\nexport function ChartContainer({\n  className,\n  config,\n  children,\n}: {\n  className?: string;\n  config: ChartConfig;\n  children: ReactElement;\n}) {\n  const id = useId().replace(/:/g, \"\");\n  const vars: Record<string, string> = {};\n  for (const [key, item] of Object.entries(config)) {\n    if (item.color) vars[`--color-${key}`] = item.color;\n  }\n\n  return (\n    <div\n      data-chart={id}\n      className={cn(\"ak-rechart flex h-[220px] w-full justify-center text-xs\", className)}\n      style={vars as CSSProperties}\n    >\n      <ResponsiveContainer width=\"100%\" height=\"100%\">\n        {children}\n      </ResponsiveContainer>\n    </div>\n  );\n}\n\n/**\n * Multi-series tooltip. A stacked chart is unreadable with a single value, so\n * every series in the hovered slot gets a row, plus a total when it means\n * something (it does for stacked, not for grouped).\n */\nexport function ChartTooltipRows({\n  label,\n  rows,\n  total,\n}: {\n  label?: string;\n  rows: { name: string; value: number; color: string }[];\n  total?: boolean;\n}) {\n  if (!rows.length) return null;\n  const sum = rows.reduce((acc, row) => acc + row.value, 0);\n  return (\n    <div className=\"rounded-lg border border-[color:var(--ak-border)] bg-[color:var(--ak-surface)] px-2.5 py-1.5 text-xs shadow-md\">\n      {label ? <p className=\"mb-1 text-[color:var(--ak-muted)]\">{label}</p> : null}\n      <ul className=\"ak-legend\">\n        {rows.map((row) => (\n          <li key={row.name}>\n            {/* Swatch and name are one unit — left them separate and\n                space-between strands the dot at the far edge. */}\n            <span className=\"ak-legend-name\">\n              <i style={{ background: row.color }} />\n              {row.name}\n            </span>\n            <strong>{formatNumber(row.value)}</strong>\n          </li>\n        ))}\n        {total && rows.length > 1 ? (\n          <li className=\"ak-legend-total\">\n            <span>Total</span>\n            <strong>{formatNumber(sum)}</strong>\n          </li>\n        ) : null}\n      </ul>\n    </div>\n  );\n}\n\n/** Series legend for the multi-series variants, totalled over the whole range. */\nexport function ChartLegend({\n  keys,\n  config,\n  data,\n}: {\n  keys: string[];\n  config: ChartConfig;\n  data: Record<string, string | number>[];\n}) {\n  return (\n    // Row layout, not the stacked list: this legend sits under a full-width\n    // chart, where the list's space-between would strand each value at the far\n    // edge of the card.\n    <ul className=\"ak-legend ak-legend-row\">\n      {keys.map((key) => (\n        <li key={key}>\n          <i style={{ background: config[key]?.color }} />\n          <span>{config[key]?.label ?? key}</span>\n          <strong>{formatNumber(data.reduce((acc, row) => acc + Number(row[key] ?? 0), 0))}</strong>\n        </li>\n      ))}\n    </ul>\n  );\n}\n\nexport function ChartTooltipBox({\n  label,\n  value,\n  name,\n}: {\n  label?: string;\n  value?: string | number;\n  name?: string;\n}) {\n  if (value == null) return null;\n  return (\n    <div className=\"rounded-lg border border-[color:var(--ak-border)] bg-[color:var(--ak-surface)] px-2.5 py-1.5 text-xs shadow-md\">\n      {label ? <p className=\"mb-1 text-[color:var(--ak-muted)]\">{label}</p> : null}\n      <p className=\"font-medium text-[color:var(--ak-text)]\">\n        {name ? `${name}: ` : null}\n        {typeof value === \"number\" ? formatNumber(value) : value}\n      </p>\n    </div>\n  );\n}\n"
    },
    {
      "path": "packages/react/src/charts/variants.ts",
      "type": "registry:lib",
      "target": "@lib/chart-variants.ts",
      "content": "export const AREA_CHART_VARIANTS = [\n  \"gradient\",\n  \"linear\",\n  \"natural\",\n  \"step\",\n  \"dots\",\n  \"spark\",\n  \"dither\",\n  \"glow\",\n  \"hatched\",\n  \"bars\",\n  \"solid\",\n  \"stacked\",\n  \"stream\",\n  \"band\",\n  \"ridge\",\n  \"riso\",\n  \"screentone\",\n  \"grain\",\n] as const;\nexport type AreaChartVariant = (typeof AREA_CHART_VARIANTS)[number];\n\n/** Variants that draw one band per key in `dataKeys` instead of a single series. */\nexport const AREA_MULTI_VARIANTS: readonly AreaChartVariant[] = [\"stacked\", \"stream\", \"ridge\"];\n\nexport const LINE_CHART_VARIANTS = [\n  \"monotone\",\n  \"linear\",\n  \"step\",\n  \"dashed\",\n  \"dots\",\n  \"dither\",\n  \"glow\",\n  \"ping\",\n  \"rainbow\",\n  \"values\",\n  \"focus\",\n  \"anomaly\",\n  \"riso\",\n  \"forecast\",\n  \"dual\",\n] as const;\nexport type LineChartVariant = (typeof LINE_CHART_VARIANTS)[number];\n\nexport const BAR_CHART_VARIANTS = [\n  \"vertical\",\n  \"horizontal\",\n  \"rounded\",\n  \"hatched\",\n  \"dither\",\n  \"glow\",\n  \"gradient\",\n  \"duotone\",\n  \"grouped\",\n  \"stacked\",\n  \"stacked-100\",\n  \"diverging\",\n  \"editorial\",\n  \"bullet\",\n] as const;\nexport type BarChartVariant = (typeof BAR_CHART_VARIANTS)[number];\n\n/** Variants that draw one line per key in `dataKeys` instead of a single series. */\nexport const LINE_MULTI_VARIANTS: readonly LineChartVariant[] = [\"focus\", \"dual\"];\n\n/** Variants that draw one bar per key in `dataKeys` instead of a single series. */\nexport const BAR_MULTI_VARIANTS: readonly BarChartVariant[] = [\"grouped\", \"stacked\", \"stacked-100\"];\n\nexport const PIE_CHART_VARIANTS = [\n  \"donut\",\n  \"pie\",\n  \"legend\",\n  \"dither\",\n  \"rounded\",\n  \"radial\",\n  \"glow\",\n  \"half\",\n  \"callout\",\n] as const;\nexport type PieChartVariant = (typeof PIE_CHART_VARIANTS)[number];\n\nexport const METRIC_CARD_VARIANTS = [\n  \"default\",\n  \"spark\",\n  \"compact\",\n  \"hero\",\n  \"bleed\",\n  \"histogram\",\n] as const;\nexport type MetricCardVariant = (typeof METRIC_CARD_VARIANTS)[number];\n\nexport const BAR_LIST_VARIANTS = [\"bar\", \"compact\", \"table\", \"inset\", \"dual\"] as const;\nexport type BarListVariant = (typeof BAR_LIST_VARIANTS)[number];\n\nexport const FUNNEL_CHART_VARIANTS = [\"tape\", \"steps\", \"vertical\", \"flow\"] as const;\nexport type FunnelChartVariant = (typeof FUNNEL_CHART_VARIANTS)[number];\n\nexport const RADAR_CHART_VARIANTS = [\"stroke\", \"fill\", \"glow\", \"dither\", \"polygon\"] as const;\nexport type RadarChartVariant = (typeof RADAR_CHART_VARIANTS)[number];\n\nexport const GAUGE_CHART_VARIANTS = [\"arc\", \"ring\", \"tick\", \"score\"] as const;\nexport type GaugeChartVariant = (typeof GAUGE_CHART_VARIANTS)[number];\n\nexport const COMPOSED_CHART_VARIANTS = [\"combo\", \"highlight\", \"overlay\"] as const;\nexport type ComposedChartVariant = (typeof COMPOSED_CHART_VARIANTS)[number];\n\nexport const SCATTER_CHART_VARIANTS = [\"dots\", \"bubble\", \"glow\", \"field\"] as const;\nexport type ScatterChartVariant = (typeof SCATTER_CHART_VARIANTS)[number];\n\nexport const SANKEY_CHART_VARIANTS = [\"flow\", \"gradient\", \"dither\"] as const;\nexport type SankeyChartVariant = (typeof SANKEY_CHART_VARIANTS)[number];\n\nexport const CANDLESTICK_CHART_VARIANTS = [\"ohlc\", \"hollow\", \"wick\", \"volume\"] as const;\nexport type CandlestickChartVariant = (typeof CANDLESTICK_CHART_VARIANTS)[number];\n\nexport const CHOROPLETH_CHART_VARIANTS = [\"tiles\", \"heat\", \"dither\"] as const;\nexport type ChoroplethChartVariant = (typeof CHOROPLETH_CHART_VARIANTS)[number];\n\nexport const LIVE_LINE_CHART_VARIANTS = [\"stream\", \"glow\", \"dashed\"] as const;\nexport type LiveLineChartVariant = (typeof LIVE_LINE_CHART_VARIANTS)[number];\n\nexport const RING_CHART_VARIANTS = [\"stack\", \"nested\", \"track\"] as const;\nexport type RingChartVariant = (typeof RING_CHART_VARIANTS)[number];\n\nexport const HEATMAP_CHART_VARIANTS = [\"calendar\", \"matrix\", \"dither\", \"month\"] as const;\nexport type HeatmapChartVariant = (typeof HEATMAP_CHART_VARIANTS)[number];\n\nexport const SUNBURST_CHART_VARIANTS = [\"nest\", \"burst\"] as const;\nexport type SunburstChartVariant = (typeof SUNBURST_CHART_VARIANTS)[number];\n\nexport const PROFIT_LOSS_CHART_VARIANTS = [\"fill\", \"stroke\", \"bars\"] as const;\nexport type ProfitLossChartVariant = (typeof PROFIT_LOSS_CHART_VARIANTS)[number];\n\nexport const HORIZON_CHART_VARIANTS = [\"bands\", \"mirror\"] as const;\nexport type HorizonChartVariant = (typeof HORIZON_CHART_VARIANTS)[number];\n\nexport const COHORT_GRID_VARIANTS = [\"triangle\", \"counts\"] as const;\nexport type CohortGridVariant = (typeof COHORT_GRID_VARIANTS)[number];\n\nexport const BUMP_CHART_VARIANTS = [\"ribbon\", \"line\"] as const;\nexport type BumpChartVariant = (typeof BUMP_CHART_VARIANTS)[number];\n\nexport const WATERFALL_CHART_VARIANTS = [\"bridge\", \"bars\"] as const;\nexport type WaterfallChartVariant = (typeof WATERFALL_CHART_VARIANTS)[number];\n\nexport const SHARE_BAND_VARIANTS = [\"segments\", \"legend\"] as const;\nexport type ShareBandVariant = (typeof SHARE_BAND_VARIANTS)[number];\n\nexport const SLOPE_CHART_VARIANTS = [\"paired\", \"change\"] as const;\nexport type SlopeChartVariant = (typeof SLOPE_CHART_VARIANTS)[number];\n\nexport const TREEMAP_CHART_VARIANTS = [\"heat\", \"diverging\"] as const;\nexport type TreemapChartVariant = (typeof TREEMAP_CHART_VARIANTS)[number];\n\nexport type ChartDatum = Record<string, string | number>;\n\nexport interface SankeyNode {\n  name: string;\n}\n\nexport interface SankeyLink {\n  source: number;\n  target: number;\n  value: number;\n}\n\n/** Structurally matches @wingtics/core's provider-agnostic candle type. */\nexport interface CandleDatum {\n  date: string;\n  open: number;\n  high: number;\n  low: number;\n  close: number;\n  /** Traded volume for the period. Optional for price-only legacy rows. */\n  volume?: number;\n}\n\nexport interface SunburstNode {\n  label: string;\n  value: number;\n  children?: SunburstNode[];\n}\n\nexport const BREAKDOWN_CARD_VARIANTS = [\"bars\", \"split\", \"plain\", \"heat\"] as const;\nexport type BreakdownCardVariant = (typeof BREAKDOWN_CARD_VARIANTS)[number];\n\nexport const QUOTA_BAR_VARIANTS = [\"bar\", \"segments\", \"steps\", \"compact\"] as const;\nexport type QuotaBarVariant = (typeof QUOTA_BAR_VARIANTS)[number];\n\nexport const MARIMEKKO_VARIANTS = [\"mosaic\", \"labels\", \"outline\", \"heat\"] as const;\nexport type MarimekkoVariant = (typeof MARIMEKKO_VARIANTS)[number];\n\nexport const SPARK_TABLE_VARIANTS = [\"sparkline\", \"bars\", \"area\", \"plain\"] as const;\nexport type SparkTableVariant = (typeof SPARK_TABLE_VARIANTS)[number];\n\nexport const TIMELINE_VARIANTS = [\"rail\", \"alternating\", \"stacked\", \"dots\"] as const;\nexport type TimelineVariant = (typeof TIMELINE_VARIANTS)[number];\n\nexport const STRIP_CHART_VARIANTS = [\"ticks\", \"barcode\", \"dots\", \"density\"] as const;\nexport type StripChartVariant = (typeof STRIP_CHART_VARIANTS)[number];\n\nexport const RADIAL_TIME_VARIANTS = [\"rings\", \"dots\", \"bands\"] as const;\nexport type RadialTimeVariant = (typeof RADIAL_TIME_VARIANTS)[number];\n\nexport const GLOBE_CHART_VARIANTS = [\"spin\", \"drag\", \"focus\", \"arcs\", \"still\"] as const;\nexport type GlobeChartVariant = (typeof GLOBE_CHART_VARIANTS)[number];\n\nexport const METRIC_TABS_VARIANTS = [\"cards\", \"strip\", \"segmented\", \"stacked\"] as const;\nexport type MetricTabsVariant = (typeof METRIC_TABS_VARIANTS)[number];\n\nexport const EMPTY_STATE_VARIANTS = [\"panel\", \"dashed\", \"inline\", \"compact\"] as const;\nexport type EmptyStateVariant = (typeof EMPTY_STATE_VARIANTS)[number];\n\n/**\n * Axis scale.\n *\n * `symlog` is backed by a custom d3 scale because recharts' named ScaleType\n * union does not include it. A log axis cannot represent zero, so the charts\n * pin its floor to 1 rather than letting a zero point disappear silently.\n */\nexport const AXIS_SCALES = [\"linear\", \"log\", \"symlog\"] as const;\nexport type AxisScale = (typeof AXIS_SCALES)[number];\n"
    },
    {
      "path": "packages/react/src/charts/patterns.tsx",
      "type": "registry:ui",
      "target": "@ui/patterns.tsx",
      "content": "import { formatNumber } from \"./chart.js\";\nexport function DitherDots({ id, color }: { id: string; color: string }) {\n  return (\n    <pattern id={id} patternUnits=\"userSpaceOnUse\" width=\"6\" height=\"6\">\n      <circle cx=\"1.4\" cy=\"1.4\" r=\"1\" fill={color} />\n      <circle cx=\"4.6\" cy=\"4.6\" r=\"0.85\" fill={color} />\n    </pattern>\n  );\n}\n\nexport function HatchPattern({ id, color }: { id: string; color: string }) {\n  return (\n    <pattern id={id} patternUnits=\"userSpaceOnUse\" width=\"7\" height=\"7\">\n      <path d=\"M-1 8L8 -1\" stroke={color} strokeWidth=\"1.35\" />\n    </pattern>\n  );\n}\n\nexport function BarStripePattern({ id, color }: { id: string; color: string }) {\n  return (\n    <pattern id={id} patternUnits=\"userSpaceOnUse\" width=\"6\" height=\"8\">\n      <rect width=\"2.4\" height=\"8\" fill={color} />\n    </pattern>\n  );\n}\n\nexport function GlowFilter({ id }: { id: string }) {\n  return (\n    <filter id={id} x=\"-30%\" y=\"-30%\" width=\"160%\" height=\"160%\">\n      <feGaussianBlur stdDeviation=\"3.2\" result=\"blur\" />\n      <feColorMatrix\n        in=\"blur\"\n        type=\"matrix\"\n        values=\"1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 0.5 0\"\n        result=\"glow\"\n      />\n      <feMerge>\n        <feMergeNode in=\"glow\" />\n        <feMergeNode in=\"SourceGraphic\" />\n      </feMerge>\n    </filter>\n  );\n}\n\nexport function RainbowGradient({ id }: { id: string }) {\n  return (\n    <linearGradient id={id} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\">\n      <stop offset=\"0%\" stopColor=\"var(--ak-chart-1, var(--chart-1, #2563eb))\" />\n      <stop offset=\"35%\" stopColor=\"var(--ak-chart-2, var(--chart-2, #0f9f6e))\" />\n      <stop offset=\"70%\" stopColor=\"var(--ak-chart-3, var(--chart-3, #f59e0b))\" />\n      <stop offset=\"100%\" stopColor=\"var(--ak-chart-5, var(--chart-5, #ef4444))\" />\n    </linearGradient>\n  );\n}\n\nexport function FadeGradient({\n  id,\n  color,\n  start = 0.95,\n  end = 0.18,\n}: {\n  id: string;\n  color: string;\n  start?: number;\n  end?: number;\n}) {\n  return (\n    <linearGradient id={id} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n      <stop offset=\"0%\" stopColor={color} stopOpacity={start} />\n      <stop offset=\"100%\" stopColor={color} stopOpacity={end} />\n    </linearGradient>\n  );\n}\n\nexport function DuotoneGradient({ id, color }: { id: string; color: string }) {\n  return (\n    <linearGradient id={id} x1=\"0\" y1=\"1\" x2=\"0\" y2=\"0\">\n      <stop offset=\"0%\" stopColor={color} />\n      <stop offset=\"52%\" stopColor={color} />\n      <stop offset=\"52%\" stopColor={color} stopOpacity=\"0.36\" />\n      <stop offset=\"100%\" stopColor={color} stopOpacity=\"0.36\" />\n    </linearGradient>\n  );\n}\n\nexport function PingDot({\n  cx,\n  cy,\n  color,\n  last,\n}: {\n  cx?: number;\n  cy?: number;\n  color: string;\n  last?: boolean;\n}) {\n  if (cx == null || cy == null) return null;\n  return (\n    <g>\n      {last ? (\n        <>\n          <circle className=\"ak-ping\" cx={cx} cy={cy} r={9} fill={color} />\n          <circle className=\"ak-ping ak-ping-delay\" cx={cx} cy={cy} r={9} fill={color} />\n        </>\n      ) : null}\n      <circle cx={cx} cy={cy} r={3} fill={color} stroke=\"var(--ak-surface)\" strokeWidth={1.5} />\n    </g>\n  );\n}\n\nexport function ValueDot({\n  cx,\n  cy,\n  value,\n  color,\n  show,\n}: {\n  cx?: number;\n  cy?: number;\n  value?: string | number;\n  color: string;\n  show?: boolean;\n}) {\n  if (cx == null || cy == null) return null;\n  const label = typeof value === \"number\" ? formatNumber(value) : String(value ?? \"\");\n  return (\n    <g>\n      <circle cx={cx} cy={cy} r={2.5} fill={color} />\n      {show ? (\n        <text x={cx} y={cy - 8} textAnchor=\"middle\" className=\"ak-value-dot\">\n          {label}\n        </text>\n      ) : null}\n    </g>\n  );\n}\n\n/**\n * Halftone dot screen. Density carries the value, so it still reads when the\n * chart is printed, photocopied, or seen by someone who cannot separate the\n * palette's hues.\n */\nexport function ScreentonePattern({\n  id,\n  color,\n  density = 0.5,\n}: {\n  id: string;\n  color: string;\n  /** 0–1. Drives dot radius, which is what a halftone screen actually varies. */\n  density?: number;\n}) {\n  const r = 0.6 + Math.min(1, Math.max(0, density)) * 2.1;\n  return (\n    <pattern id={id} patternUnits=\"userSpaceOnUse\" width=\"7\" height=\"7\">\n      <circle cx=\"1.75\" cy=\"1.75\" r={r} fill={color} />\n      <circle cx=\"5.25\" cy=\"5.25\" r={r} fill={color} />\n    </pattern>\n  );\n}\n\n/**\n * Misregistered two-colour risograph: the same shape printed twice, slightly\n * out of alignment. The offset is the whole effect — a riso print that lines\n * up perfectly just looks like flat ink.\n */\nexport function RisoFilter({ id, offset = 2 }: { id: string; offset?: number }) {\n  return (\n    <filter id={id} x=\"-10%\" y=\"-10%\" width=\"120%\" height=\"120%\">\n      <feOffset dx={-offset} dy={offset * 0.6} result=\"shifted\" />\n      <feColorMatrix\n        in=\"shifted\"\n        type=\"matrix\"\n        values=\"0.9 0 0 0 0  0 0.4 0 0 0  0 0 0.5 0 0  0 0 0 0.55 0\"\n        result=\"ink\"\n      />\n      <feMerge>\n        <feMergeNode in=\"ink\" />\n        <feMergeNode in=\"SourceGraphic\" />\n      </feMerge>\n    </filter>\n  );\n}\n\n/** Fine film grain over a fill. Subtle by design: texture, not noise. */\nexport function GrainFilter({ id, amount = 0.42 }: { id: string; amount?: number }) {\n  return (\n    <filter id={id} x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n      <feTurbulence type=\"fractalNoise\" baseFrequency=\"0.9\" numOctaves=\"3\" result=\"noise\" />\n      <feColorMatrix in=\"noise\" type=\"saturate\" values=\"0\" result=\"grey\" />\n      <feComponentTransfer in=\"grey\" result=\"soft\">\n        <feFuncA type=\"linear\" slope={amount} intercept=\"0\" />\n      </feComponentTransfer>\n      <feBlend in=\"SourceGraphic\" in2=\"soft\" mode=\"multiply\" result=\"grained\" />\n      {/* Clipped back to the source shape. A filter paints its whole region,\n          so without this the noise covers the plot area as a grey rectangle\n          rather than texturing the fill. */}\n      <feComposite in=\"grained\" in2=\"SourceGraphic\" operator=\"in\" />\n    </filter>\n  );\n}\n"
    }
  ],
  "docs": "Map --chart-1…--chart-5 in your CSS. Charts do not ship a color theme.",
  "categories": [
    "analytics",
    "charts"
  ]
}
