{
  "name": "vizcn",
  "shelf": "https://vibecoding.tech/vizcn",
  "skins": [
    {
      "key": "core",
      "class": null,
      "note": "default skin — light tokens on :root, dark polarity via .dark on the app root"
    },
    {
      "key": "terminal",
      "class": ".vz-terminal",
      "note": "dense terminal register (#111 surface, amber controls); dark-only — wrap the chart subtree"
    },
    {
      "key": "paper",
      "class": ".vz-paper",
      "note": "print/editorial register (white paper, hard ink rules); light-only — wrap the chart subtree"
    }
  ],
  "forms": [
    {
      "name": "bench-matrix",
      "install": "https://vibecoding.tech/vizcn/r/bench-matrix.json",
      "question": "How do these models compare across many benchmarks at once?",
      "family": "matrix",
      "whenToUse": "Comparing a handful of models across many named benchmarks in one glance, especially when one model is the protagonist.",
      "antiUse": "Trends over time or more than ~6 models — use a time-series form or a ranking board instead of a wide table.",
      "client": true,
      "props": "models (id, label, vendor?, color?, hero? — hero color must be a 6-digit hex, tint is built by hex+alpha concat), groups (label + rows {bench, note?, values: (number|null)[], decimals?}), meta?, footnote?, decimals?=1, benchColLabel?='benchmark'",
      "example": "'use client'\n\nimport { seriesColor } from '../../lib/palette'\nimport { BenchMatrix, type BenchMatrixGroup, type BenchMatrixModel } from \"@/components/vizcn/bench-matrix\"\n\nconst models: BenchMatrixModel[] = [\n  { id: 'atlas', label: 'Atlas 2 (max)', vendor: 'Meridian', color: seriesColor(0), hero: true },\n  { id: 'nova', label: 'Nova Pro', vendor: 'Helix Labs' },\n  { id: 'orion', label: 'Orion 1.5', vendor: 'Vantage' },\n  { id: 'vega', label: 'Vega Ultra', vendor: 'Helix Labs' },\n]\n\nconst groups: BenchMatrixGroup[] = [\n  {\n    label: 'reasoning',\n    rows: [\n      {\n        bench: 'ReasonEval',\n        note: 'graduate-level multi-step reasoning, no tools',\n        values: [88.4, 86.1, 84.9, 87.2],\n      },\n      {\n        bench: 'PuzzleBench Hard',\n        note: 'constraint puzzles, pass@1',\n        values: [71.3, 69.8, 64.2, 70.5],\n      },\n      {\n        bench: 'LongContext QA',\n        note: 'needle retrieval over 1M-token inputs',\n        values: [92.6, 90.1, null, 91.4],\n      },\n    ],\n  },\n  {\n    label: 'coding',\n    rows: [\n      {\n        bench: 'RepoPatch Verified',\n        note: 'real repository bug fixes, end-to-end',\n        values: [74.8, 72.3, 70.6, 73.1],\n      },\n      {\n        bench: 'CodeGolf Elite',\n        note: 'competitive programming, percentile',\n        values: [61.2, 63.7, 58.4, 60.9],\n      },\n    ],\n  },\n  {\n    label: 'agentic',\n    rows: [\n      {\n        bench: 'AgentOps Suite',\n        note: 'multi-step tool use across 40 tasks',\n        values: [67.5, 62.8, 59.3, 65.0],\n      },\n      {\n        bench: 'BrowserQuest',\n        note: 'autonomous web navigation, success rate',\n        values: [54.1, 51.6, 47.2, 53.8],\n      },\n    ],\n  },\n]\n\nexport default function BenchMatrixDemo() {\n  return (\n    <BenchMatrix\n      models={models}\n      groups={groups}\n      meta=\"7 benchmarks · snapshot Jul 9, 2026\"\n      footnote=\"Scores as reported by each vendor; dash = not published. Higher is better.\"\n    />\n  )\n}\n"
    },
    {
      "name": "bubble-field",
      "install": "https://vibecoding.tech/vizcn/r/bubble-field.json",
      "question": "How is the pool scattered across two axes?",
      "family": "distribution",
      "whenToUse": "Showing how a pool of entities spreads across two quantitative axes with size and category as secondary encodings.",
      "antiUse": "Few points with runs per entity and an efficiency story — use frontier-board; exact value reading — use a table.",
      "client": false,
      "props": "points: {x, y, size, category, label?}[]; categories: {key, label, color?}[]; xLabel; yLabel; xLog?; yLog?; width?; height?",
      "example": "import { BubbleField } from \"@/components/vizcn/bubble-field\"\n\nexport default function BubbleFieldDemo() {\n  return (\n    <BubbleField\n      xLabel=\"GitHub stars\"\n      yLabel=\"Files in default branch\"\n      xLog\n      yLog\n      categories={[\n        { key: 'typescript', label: 'TypeScript' },\n        { key: 'go', label: 'Go' },\n        { key: 'python', label: 'Python' },\n        { key: 'javascript', label: 'JavaScript' },\n        { key: 'rust', label: 'Rust' },\n      ]}\n      points={[\n        { label: 'ts-router', x: 90000, y: 2100, size: 520, category: 'typescript' },\n        { label: 'signal-kit', x: 54000, y: 860, size: 310, category: 'typescript' },\n        { label: 'canvas-core', x: 27000, y: 3900, size: 470, category: 'typescript' },\n        { label: 'typed-shell', x: 11800, y: 620, size: 180, category: 'typescript' },\n        { label: 'node-ledger', x: 4300, y: 1280, size: 140, category: 'typescript' },\n        { label: 'form-wire', x: 1300, y: 240, size: 64, category: 'typescript' },\n        { label: 'go-proxy', x: 76000, y: 940, size: 280, category: 'go' },\n        { label: 'cluster-watch', x: 31000, y: 1800, size: 250, category: 'go' },\n        { label: 'tiny-store', x: 9200, y: 310, size: 120, category: 'go' },\n        { label: 'queue-lab', x: 2800, y: 520, size: 96, category: 'go' },\n        { label: 'packet-view', x: 700, y: 110, size: 42, category: 'go' },\n        { label: 'py-agent', x: 68000, y: 7200, size: 610, category: 'python' },\n        { label: 'data-craft', x: 42000, y: 3400, size: 430, category: 'python' },\n        { label: 'prompt-eval', x: 15000, y: 890, size: 210, category: 'python' },\n        { label: 'task-bench', x: 5200, y: 2700, size: 240, category: 'python' },\n        { label: 'micro-orbit', x: 600, y: 160, size: 50, category: 'python' },\n        { label: 'js-bundler', x: 47000, y: 1300, size: 260, category: 'javascript' },\n        { label: 'web-hook', x: 19000, y: 430, size: 130, category: 'javascript' },\n        { label: 'dom-scan', x: 3600, y: 760, size: 98, category: 'javascript' },\n        { label: 'fetch-lite', x: 900, y: 80, size: 38, category: 'javascript' },\n        { label: 'rust-cache', x: 61000, y: 960, size: 300, category: 'rust' },\n        { label: 'safe-term', x: 22000, y: 4100, size: 350, category: 'rust' },\n        { label: 'byte-index', x: 6800, y: 1500, size: 160, category: 'rust' },\n        { label: 'mini-wasm', x: 1700, y: 190, size: 70, category: 'rust' },\n      ]}\n    />\n  )\n}\n"
    },
    {
      "name": "delta-bars",
      "install": "https://vibecoding.tech/vizcn/r/delta-bars.json",
      "question": "Who is ahead today, and by how much?",
      "family": "time-series",
      "whenToUse": "Tracking the day-by-day lead between exactly two rivals where the sign and streaks of the gap matter more than absolute volumes (head-to-head races, A/B momentum).",
      "antiUse": "Not for more than 2 rivals or for absolute magnitudes — use race lines or stacked forms instead.",
      "client": true,
      "props": "a, b: {label, color?, values: (number|null)[]} (colors default to seriesColor(0)/seriesColor(1)); xLabels?: {frac, text}[]",
      "example": "import { DeltaBars, type DeltaSeries } from \"@/components/vizcn/delta-bars\"\n\n/**\n * Demo: daily request volume for two rival models over 30 days.\n * Deterministic synthetic waves: Atlas trends up and takes the lead\n * mid-month; one reporting gap (null on both) shows the missing-day hole.\n */\n\nconst N = 30\n\nfunction wave(i: number, base: number, trend: number, amp: number, phase: number): number {\n  return Math.round(\n    base + i * trend + amp * Math.sin(i / 3.1 + phase) + amp * 0.5 * Math.sin(i / 1.6 + phase * 2)\n  )\n}\n\nconst ATLAS: DeltaSeries = {\n  label: 'Atlas',\n  values: Array.from({ length: N }, (_, i) => (i === 17 ? null : wave(i, 480_000, 9_500, 90_000, 0.4))),\n}\n\nconst NOVA: DeltaSeries = {\n  label: 'Nova',\n  values: Array.from({ length: N }, (_, i) => (i === 17 ? null : wave(i, 590_000, 1_500, 80_000, 2.3))),\n}\n\nconst X_LABELS = [\n  { frac: 0.02, text: 'Jun 1' },\n  { frac: 0.34, text: 'Jun 11' },\n  { frac: 0.67, text: 'Jun 21' },\n  { frac: 0.98, text: 'Jun 30' },\n]\n\nexport default function DeltaBarsDemo() {\n  return (\n    <div className=\"mx-auto max-w-4xl p-6\">\n      <DeltaBars a={ATLAS} b={NOVA} xLabels={X_LABELS} />\n    </div>\n  )\n}\n"
    },
    {
      "name": "dumbbell-range",
      "install": "https://vibecoding.tech/vizcn/r/dumbbell-range.json",
      "question": "How far apart are the two values per row, and who sits where?",
      "family": "ranking/comparison",
      "whenToUse": "Comparing a two-point range across a handful of named entities where both endpoints and the gap matter (price min/max, input/output cost, before/after scores).",
      "antiUse": "Not for more than 2 points per row (use a range strip or box plot) and not for time series — use lines.",
      "client": true,
      "props": "rows: {label, lo, hi, highlight?}[]; maxValue?; unit? (default \"$\"); formatValue?; loLabel?/hiLabel? (legend, default \"lo\"/\"hi\"); caption?; loColor? (default seriesColor(0)); hiColor? (default seriesColor(5)); highlightColor? (default seriesColor(1))",
      "example": "import { DumbbellRange } from \"@/components/vizcn/dumbbell-range\"\n\nexport default function DumbbellRangeDemo() {\n  return (\n    <div className=\"mx-auto w-full max-w-[560px]\">\n      <p className=\"mb-4 text-[13px] font-semibold text-[var(--vz-ink,#111)]\">\n        API pricing · input / output, Jun 2026\n      </p>\n      <DumbbellRange\n        loLabel=\"input\"\n        hiLabel=\"output\"\n        caption=\"$ per 1M tokens\"\n        rows={[\n          { label: 'Atlas 4', lo: 15, hi: 75, highlight: true },\n          { label: 'Nova Max', lo: 10, hi: 40 },\n          { label: 'Orion Pro', lo: 5, hi: 25 },\n          { label: 'Vega 2', lo: 2.5, hi: 10 },\n          { label: 'Lumen', lo: 0.5, hi: 4 },\n        ]}\n      />\n    </div>\n  )\n}\n"
    },
    {
      "name": "dune-flow",
      "install": "https://vibecoding.tech/vizcn/r/dune-flow.json",
      "question": "What made up the flow over time, and when were the waves?",
      "family": "time-series",
      "whenToUse": "Daily composition of a volume stream (issues by priority, requests by tier) where the trend shape matters more than exact per-day spikes.",
      "antiUse": "When readers must read exact values off the chart — the B-spline deliberately does not pass through the data points (raw values live only in the tooltip).",
      "client": true,
      "props": "days: ISO 'YYYY-MM-DD'[] (min 4); series: { label, color?, values: (number|null)[] }[] stacked bottom-up; yLabel?: string",
      "example": "'use client'\n\nimport { RAMP } from '../../lib/palette'\nimport { DuneAreaChart } from \"@/components/vizcn/dune-flow\"\n\n/**\n * Demo: open evaluation tasks by priority over six weeks — an ORDINAL\n * series (Low → Medium → High), so it uses the single-hue RAMP instead of\n * categorical hues. Data is deterministic (smooth waves, no randomness).\n */\n\nconst N = 42\nconst START = Date.UTC(2026, 0, 5) // 2026-01-05\nconst DAY_MS = 86_400_000\n\nconst days = Array.from({ length: N }, (_, i) =>\n  new Date(START + i * DAY_MS).toISOString().slice(0, 10)\n)\n\nconst wave = (i: number, base: number, amp: number, period: number, phase: number) =>\n  Math.round(base + amp * Math.sin((i / period) * Math.PI * 2 + phase) + (amp / 3) * Math.sin(i / 2.7 + phase))\n\nconst low = Array.from({ length: N }, (_, i) => wave(i, 34, 12, 21, 0.4))\nconst medium = Array.from({ length: N }, (_, i) => wave(i, 22, 9, 17, 2.1))\nconst high = Array.from({ length: N }, (_, i) => Math.max(0, wave(i, 10, 8, 14, 4.2)))\n\nexport default function DuneFlowDemo() {\n  return (\n    <DuneAreaChart\n      days={days}\n      series={[\n        { label: 'Low', color: RAMP[0], values: low },\n        { label: 'Medium', color: RAMP[1], values: medium },\n        { label: 'High', color: RAMP[2], values: high },\n      ]}\n      yLabel=\"Open evaluation tasks by priority\"\n    />\n  )\n}\n"
    },
    {
      "name": "frontier-board",
      "install": "https://vibecoding.tech/vizcn/r/frontier-board.json",
      "question": "Which model delivers the most score per dollar (or token), and at what effort level?",
      "family": "ranking",
      "whenToUse": "Comparing models on a quality-vs-cost tradeoff when each model has multiple runs (effort levels / modes) that form a frontier.",
      "antiUse": "Needs >=2 runs per model to draw frontier lines; single-point-per-model data reads better as rank-bars.",
      "client": true,
      "props": "title, versions[] (datasets of models with runs), metrics[] (X-axis toggles with tickPrefix/Suffix), yMax/yTickSuffix, xAscending (two axis genres: default false = inverted, cheaper right, efficient corner up-right; true = conventional ascending, expensive right, efficient corner up-left), subjectId highlight, UI label strings",
      "example": "import { FrontierBoard } from \"@/components/vizcn/frontier-board\"\nimport type { FrontierModel, FrontierRun } from \"@/components/vizcn/frontier-board\"\n\n// vendor identity colors (color follows the entity): a vivid set that\n// holds on both light and dark surfaces\nconst FAMILY_COLOR = {\n  atlas: '#E8734A',\n  nova: '#10A37F',\n  orion: '#4285F4',\n  vega: '#D946EF',\n  quasar: '#5B6EE1',\n} as const\n\n/**\n * Demo: fictional models with real-leaderboard density — 10 models across\n * five fictional vendors, effort-level runs (minimal→max), two dataset\n * versions, labeled defaults. Values mirror the density of real coding\n * leaderboards; every name is invented. Deterministic data.\n */\n\nconst fr = (\n  variant: string | undefined,\n  cost: number,\n  score: number,\n  extra?: Partial<FrontierRun>,\n): FrontierRun => {\n  const { x, ...rest } = extra ?? {}\n  return {\n    variant,\n    score,\n    std: 2,\n    x: {\n      cost,\n      tokens: Math.round(cost * 6.8 + score * 0.4),\n      steps: Math.round(cost * 2.2 + 14),\n      ...x,\n    },\n    ...rest,\n  }\n}\n\nconst V11: FrontierModel[] = [\n  {\n    id: 'atlas-4',\n    color: FAMILY_COLOR.atlas,\n    badge: 'M',\n    runs: [\n      fr('max', 21.63, 70.4, { std: 4, x: { tokens: 119, steps: 88 } }),\n      fr('high', 13.4, 70, { labeled: true, isDefault: true, labelDx: -14, labelDy: 44 }),\n      fr('medium', 9.3, 68.7),\n      fr('low', 6.2, 65.3),\n      fr('minimal', 3.7, 59.6),\n    ],\n  },\n  {\n    id: 'atlas-3.5',\n    color: FAMILY_COLOR.atlas,\n    badge: 'M',\n    runs: [\n      fr('max', 13.22, 59.1, { x: { tokens: 135, steps: 120 } }),\n      fr('xhigh', 8.0, 54.3),\n      fr('high', 4.3, 51.7, { labeled: true, isDefault: true, labelDx: 6, labelDy: 42 }),\n      fr('medium', 3.5, 48.6),\n      fr('low', 2.7, 40.8),\n    ],\n  },\n  {\n    id: 'atlas-3',\n    color: FAMILY_COLOR.atlas,\n    badge: 'M',\n    runs: [\n      fr('max', 26.4, 54, {\n        labeled: true,\n        isDefault: true,\n        std: 4,\n        x: { tokens: 214, steps: 268 },\n      }),\n      fr('xhigh', 11.9, 49.7),\n      fr('high', 8.3, 48.3),\n      fr('medium', 4.4, 39.9),\n      fr('low', 2.3, 30.5),\n    ],\n  },\n  {\n    id: 'atlas-2',\n    color: FAMILY_COLOR.atlas,\n    badge: 'M',\n    runs: [fr('high', 5.52, 30.2, { labeled: true, std: 4, x: { tokens: 76, steps: 134 } })],\n  },\n  {\n    id: 'nova-5',\n    color: FAMILY_COLOR.nova,\n    badge: 'H',\n    runs: [\n      fr('xhigh', 7.23, 67.1, { std: 6, x: { tokens: 46, steps: 82 } }),\n      fr('high', 4.9, 64.4),\n      fr('medium', 2.6, 53.9, { labeled: true }),\n      fr('low', 1.2, 27.2),\n    ],\n  },\n  {\n    id: 'nova-4',\n    color: FAMILY_COLOR.nova,\n    badge: 'H',\n    runs: [fr('xhigh', 5.65, 51.7, { labeled: true, labelDx: 16, labelDy: 20, x: { tokens: 71, steps: 70 } })],\n  },\n  {\n    id: 'orion-72b',\n    color: FAMILY_COLOR.orion,\n    badge: 'V',\n    runs: [\n      fr('max', 3.92, 43.7, { labeled: true, isDefault: true, x: { tokens: 78, steps: 129 } }),\n      fr('high', 2.9, 36.3),\n    ],\n  },\n  {\n    id: 'vega-flash',\n    color: FAMILY_COLOR.vega,\n    badge: 'S',\n    runs: [fr('medium', 7.34, 37.2, { labeled: true, x: { tokens: 276, steps: 86 } })],\n  },\n  {\n    id: 'vega-pro',\n    color: FAMILY_COLOR.vega,\n    badge: 'S',\n    runs: [fr('high', 9.48, 11.8, { labeled: true, labelDx: 14, x: { tokens: 196, steps: 81 } })],\n  },\n  {\n    id: 'quasar-coder',\n    color: FAMILY_COLOR.quasar,\n    badge: 'Q',\n    runs: [\n      fr(undefined, 2.82, 30.7, {\n        labeled: true,\n        labelDx: -6,\n        labelDy: -24,\n        std: 1,\n        x: { tokens: 59, steps: 149 },\n      }),\n    ],\n  },\n]\n\n/** v1 — the previous snapshot: a notch lower and cheaper, two models fewer. */\nconst V1: FrontierModel[] = V11.filter(\n  (m) => m.id !== 'orion-72b' && m.id !== 'quasar-coder',\n).map((m) => ({\n  ...m,\n  runs: m.runs.map((run) => ({\n    ...run,\n    score: Math.round((run.score - 4.5) * 10) / 10,\n    x: {\n      cost: Math.round(run.x.cost * 92) / 100,\n      tokens: Math.round(run.x.tokens * 0.92),\n      steps: Math.round(run.x.steps * 0.92),\n    },\n  })),\n}))\n\nconst VERSIONS = [\n  { key: 'v1.1', label: 'v1.1', models: V11 },\n  { key: 'v1', label: 'v1', models: V1 },\n]\n\nconst METRICS = [\n  { key: 'cost', label: 'Price', axisLabel: 'Avg cost per task', tickPrefix: '$' },\n  { key: 'tokens', label: 'Output tokens', axisLabel: 'Avg output tokens per task, k', tickSuffix: 'k' },\n  { key: 'steps', label: 'Agent steps', axisLabel: 'Avg agent steps per task' },\n]\n\n/** Primary: ascending X axis (Artificial Analysis genre). */\nexport default function FrontierBoardDemo() {\n  return (\n    <FrontierBoard\n      title=\"Agentic coding score\"\n      versions={VERSIONS}\n      metrics={METRICS}\n      yMax={80}\n      meta=\"113 tasks · updated Jul 1, 2026\"\n      xAscending\n    />\n  )\n}\n\n/** Second axis genre: inverted X (DeepSWE style — cheaper to the right). */\nexport function InvertedDemo() {\n  return (\n    <FrontierBoard\n      title=\"Agentic coding score\"\n      versions={VERSIONS}\n      metrics={METRICS}\n      yMax={80}\n      meta=\"113 tasks · updated Jul 1, 2026\"\n    />\n  )\n}\n"
    },
    {
      "name": "heat-strip",
      "install": "https://vibecoding.tech/vizcn/r/heat-strip.json",
      "question": "Is this thing alive — how did its activity move over the last year?",
      "family": "time-series",
      "whenToUse": "Liveness at a glance over a long window of weekly counts (repo activity, releases, posts) where the shape and recency matter more than exact values.",
      "antiUse": "Not for exact value reading or short ranges (<12 weeks) — use a column chart instead.",
      "client": true,
      "props": "weeks: number[] (weekly counts, oldest first, newest last); color? (default var(--vz-good,#059669))",
      "example": "import { HeatStrip } from \"@/components/vizcn/heat-strip\"\n\n// 52 weekly counts, oldest first — a project ramping up over the year\n// with a mid-year lull and a strong recent stretch. Deterministic.\nconst WEEKS = [\n  12, 18, 9, 22, 31, 27, 14, 8, 19, 25, 33, 41, 38, 29, 17, 11, 6, 3, 8, 15, 24, 36, 44, 52, 47,\n  39, 31, 26, 34, 42, 55, 61, 58, 49, 37, 28, 21, 16, 23, 35, 46, 57, 63, 71, 68, 54, 43, 39, 48,\n  59, 66, 62,\n]\n\nexport default function HeatStripDemo() {\n  return (\n    <div className=\"mx-auto w-full max-w-[560px]\">\n      <p className=\"mb-4 text-[13px] font-semibold text-[var(--vz-ink,#111)]\">\n        Atlas SDK · a year of weekly activity\n      </p>\n      <HeatStrip weeks={WEEKS} />\n    </div>\n  )\n}\n"
    },
    {
      "name": "leaderboard-bars",
      "install": "https://vibecoding.tech/vizcn/r/leaderboard-bars.json",
      "question": "Who clears the bar, with what spread, and at what cost?",
      "family": "ranking",
      "whenToUse": "Benchmark leaderboards where run-to-run spread (±std) and secondary costs (price/tokens/time) matter alongside the score; reference rows out of competition.",
      "antiUse": "Single-metric rankings without spread or metric columns — use rank-bars; past ~12 rows the board outgrows a screen and labels stop scanning — use leaderboard-table.",
      "client": false,
      "props": "rows: {label, sub? (per-row note), value, std?, valueLabel?, color? (entity identity; default neutral), metrics?, offside?, offsideTag?}[]; columns?; barLabel?; rowLabel?; max?; unit?; ticks?",
      "example": "import { LeaderboardBars } from \"@/components/vizcn/leaderboard-bars\"\n\nexport default function LeaderboardBarsDemo() {\n  return (\n    <LeaderboardBars\n      rowLabel=\"configuration\"\n      barLabel=\"pass@1\"\n      columns={['cost', 'tokens', 'min']}\n      rows={[\n        {\n          label: 'Opus 4.8',\n          sub: 'Claude Code',\n          value: 78.7,\n          std: 6.1,\n          metrics: ['$3.12', '33k', '13'],\n          color: '#E8734A',\n        },\n        {\n          label: 'Sonnet 5',\n          sub: 'Claude Code',\n          value: 74.7,\n          std: 2.3,\n          metrics: ['$2.42', '29k', '13'],\n          color: '#E8734A',\n        },\n        {\n          label: 'GPT-5.5',\n          sub: 'Codex',\n          value: 66.7,\n          std: 4.6,\n          metrics: ['$2.34', '16k', '12'],\n          color: '#10A37F',\n        },\n        {\n          label: 'Haiku 4.5',\n          sub: 'Claude Code',\n          value: 53.3,\n          std: 4.6,\n          metrics: ['$0.57', '18k', '10'],\n          color: '#E8734A',\n        },\n        {\n          label: 'Fable 5',\n          value: 85,\n          valueLabel: '85% · 17/20',\n          offside: true,\n          offsideTag: 'OFF THE BOARD',\n        },\n      ]}\n    />\n  )\n}\n"
    },
    {
      "name": "leaderboard-table",
      "install": "https://vibecoding.tech/vizcn/r/leaderboard-table.json",
      "question": "Who leads on score, with what confidence spread, and what does that score cost?",
      "family": "ranking",
      "whenToUse": "Benchmark leaderboards where score alone is not enough: each run carries a spread (std) and economy metrics, and models have multiple effort levels worth comparing.",
      "antiUse": "Wide-figure genre (min-width ~700px) — not for narrow containers or mobile cards; for a single metric without spread or economy columns, rank-bars is lighter.",
      "client": true,
      "props": "versions: {key, label, models: {id, color?, badge?, logoUrl?, runs: {variant?, score, std?, x}[]}[]}[] (same rail as frontier-board); columns: {key, label, prefix?, suffix?, decimals?}[]; meta?; footnote?; xMax?; scoreSuffix/scoreLabel/modelColLabel/bestLabel/allRunsLabel/modelsLabel/allLabel UI strings",
      "example": "import { LeaderboardBars } from \"@/components/vizcn/leaderboard-table\"\nimport type { LeaderboardModel, LeaderboardRun } from \"@/components/vizcn/leaderboard-table\"\n\n// vendor identity colors (color follows the entity): a vivid set that\n// holds on both light and dark surfaces — same rail as frontier-board\nconst FAMILY_COLOR = {\n  atlas: '#E8734A',\n  nova: '#10A37F',\n  orion: '#4285F4',\n  vega: '#D946EF',\n  quasar: '#5B6EE1',\n} as const\n\n/**\n * Demo: fictional models with real-leaderboard density — the same data\n * rail as the frontier-board demo (one dataset feeds both forms). Every\n * name is invented; values mirror real coding-leaderboard density.\n */\n\nconst lr = (\n  variant: string | undefined,\n  cost: number,\n  score: number,\n  extra?: Partial<LeaderboardRun>,\n): LeaderboardRun => {\n  const { x, ...rest } = extra ?? {}\n  return {\n    variant,\n    score,\n    std: 2,\n    x: {\n      cost,\n      tokens: Math.round(cost * 6.8 + score * 0.4),\n      steps: Math.round(cost * 2.2 + 14),\n      ...x,\n    },\n    ...rest,\n  }\n}\n\nconst V11: LeaderboardModel[] = [\n  {\n    id: 'atlas-4',\n    color: FAMILY_COLOR.atlas,\n    badge: 'M',\n    runs: [\n      lr('max', 21.63, 70.4, { std: 4, x: { tokens: 119, steps: 88 } }),\n      lr('high', 13.4, 70),\n      lr('medium', 9.3, 68.7),\n      lr('low', 6.2, 65.3),\n      lr('minimal', 3.7, 59.6),\n    ],\n  },\n  {\n    id: 'atlas-3.5',\n    color: FAMILY_COLOR.atlas,\n    badge: 'M',\n    runs: [\n      lr('max', 13.22, 59.1, { x: { tokens: 135, steps: 120 } }),\n      lr('xhigh', 8.0, 54.3),\n      lr('high', 4.3, 51.7),\n      lr('medium', 3.5, 48.6),\n      lr('low', 2.7, 40.8),\n    ],\n  },\n  {\n    id: 'atlas-3',\n    color: FAMILY_COLOR.atlas,\n    badge: 'M',\n    runs: [\n      lr('max', 26.4, 54, { std: 4, x: { tokens: 214, steps: 268 } }),\n      lr('xhigh', 11.9, 49.7),\n      lr('high', 8.3, 48.3),\n      lr('medium', 4.4, 39.9),\n      lr('low', 2.3, 30.5),\n    ],\n  },\n  {\n    id: 'atlas-2',\n    color: FAMILY_COLOR.atlas,\n    badge: 'M',\n    runs: [lr('high', 5.52, 30.2, { std: 4, x: { tokens: 76, steps: 134 } })],\n  },\n  {\n    id: 'nova-5',\n    color: FAMILY_COLOR.nova,\n    badge: 'H',\n    runs: [\n      lr('xhigh', 7.23, 67.1, { std: 6, x: { tokens: 46, steps: 82 } }),\n      lr('high', 4.9, 64.4),\n      lr('medium', 2.6, 53.9),\n      lr('low', 1.2, 27.2),\n    ],\n  },\n  {\n    id: 'nova-4',\n    color: FAMILY_COLOR.nova,\n    badge: 'H',\n    runs: [lr('xhigh', 5.65, 51.7, { x: { tokens: 71, steps: 70 } })],\n  },\n  {\n    id: 'orion-72b',\n    color: FAMILY_COLOR.orion,\n    badge: 'V',\n    runs: [\n      lr('max', 3.92, 43.7, { x: { tokens: 78, steps: 129 } }),\n      lr('high', 2.9, 36.3),\n    ],\n  },\n  {\n    id: 'vega-flash',\n    color: FAMILY_COLOR.vega,\n    badge: 'S',\n    runs: [lr('medium', 7.34, 37.2, { x: { tokens: 276, steps: 86 } })],\n  },\n  {\n    id: 'vega-pro',\n    color: FAMILY_COLOR.vega,\n    badge: 'S',\n    runs: [lr('high', 9.48, 11.8, { x: { tokens: 196, steps: 81 } })],\n  },\n  {\n    id: 'quasar-coder',\n    color: FAMILY_COLOR.quasar,\n    badge: 'Q',\n    runs: [lr(undefined, 2.82, 30.7, { std: 1, x: { tokens: 59, steps: 149 } })],\n  },\n]\n\n/** v1 — the previous snapshot: a notch lower and cheaper, two models fewer. */\nconst V1: LeaderboardModel[] = V11.filter(\n  (m) => m.id !== 'orion-72b' && m.id !== 'quasar-coder',\n).map((m) => ({\n  ...m,\n  runs: m.runs.map((run) => ({\n    ...run,\n    score: Math.round((run.score - 4.5) * 10) / 10,\n    x: {\n      cost: Math.round(run.x.cost * 92) / 100,\n      tokens: Math.round(run.x.tokens * 0.92),\n      steps: Math.round(run.x.steps * 0.92),\n    },\n  })),\n}))\n\nexport default function LeaderboardTableDemo() {\n  return (\n    <LeaderboardBars\n      meta=\"113 tasks · updated Jul 1, 2026\"\n      footnote=\"All runs executed on the same harness with a 100-step budget; cost is the average per solved task. Fictional models, deterministic demo data.\"\n      versions={[\n        { key: 'v1.1', label: 'v1.1', models: V11 },\n        { key: 'v1', label: 'v1', models: V1 },\n      ]}\n      columns={[\n        { key: 'cost', label: 'cost', prefix: '$', decimals: 2 },\n        { key: 'tokens', label: 'tokens', suffix: 'k' },\n        { key: 'steps', label: 'steps' },\n      ]}\n    />\n  )\n}\n"
    },
    {
      "name": "paired-bars",
      "install": "https://vibecoding.tech/vizcn/r/paired-bars.json",
      "question": "How do two measurements of the same subjects compare?",
      "family": "comparison",
      "whenToUse": "The same subjects measured two ways (two harnesses, two environments, two setups, plan vs fact) where per-subject deltas matter.",
      "antiUse": "More than two measurements per subject — use a table or bench-matrix; two rivals over time — use delta-bars.",
      "client": false,
      "props": "groups: {label, color?, a: {label, value, valueLabel?}, b: {label, value, valueLabel?}}[]; max?; unit?; ticks?; barLabel?",
      "example": "import { PairedBars } from \"@/components/vizcn/paired-bars\"\n\nexport default function PairedBarsDemo() {\n  return (\n    <PairedBars\n      barLabel=\"pass rate\"\n      unit=\"%\"\n      max={60}\n      ticks={[0, 20, 40, 60]}\n      groups={[\n        {\n          label: 'claude-opus-4.7',\n          color: '#E8734A',\n          a: { label: 'mini-swe-agent', value: 50 },\n          b: { label: 'Claude Code', value: 40 },\n        },\n        {\n          label: 'gpt-5.5',\n          color: '#10A37F',\n          a: { label: 'mini-swe-agent', value: 40 },\n          b: { label: 'Codex CLI', value: 40 },\n        },\n        {\n          label: 'gemini-3.1-pro',\n          color: '#4285F4',\n          a: { label: 'mini-swe-agent', value: 40 },\n          b: { label: 'Gemini CLI', value: 20 },\n        },\n      ]}\n    />\n  )\n}\n"
    },
    {
      "name": "rank-bars",
      "install": "https://vibecoding.tech/vizcn/r/rank-bars.json",
      "question": "Who leads this ranking, and by how much?",
      "family": "ranking",
      "whenToUse": "Comparing one metric across a handful of named entities where order and gaps matter (leaderboards, price ladders).",
      "antiUse": "Not for time series, part-to-whole composition, or more than ~10 rows — use a table or sparklines instead.",
      "client": true,
      "props": "items: {label, value, valueLabel?, sub?, highlight?, color?}[]; maxValue?; unit?; highlightColor? (default seriesColor(0))",
      "example": "import { RankBarChart } from \"@/components/vizcn/rank-bars\"\n\nexport default function RankBarsDemo() {\n  return (\n    <div className=\"mx-auto w-full max-w-[560px]\">\n      <p className=\"mb-4 text-[13px] font-semibold text-[var(--vz-ink,#111)]\">\n        Coding benchmark · pass rate, Jun 2026\n      </p>\n      <RankBarChart\n        unit=\"%\"\n        items={[\n          { label: 'Atlas 4', sub: 'Meridian', value: 74.2, highlight: true },\n          { label: 'Nova Max', sub: 'Helix Labs', value: 68.9 },\n          { label: 'Orion Pro', sub: 'Vantage', value: 63.5 },\n          { label: 'Vega 2', sub: 'Meridian', value: 57.1 },\n          { label: 'Lumen', sub: 'Helix Labs', value: 44.8 },\n        ]}\n      />\n    </div>\n  )\n}\n"
    },
    {
      "name": "rank-slope",
      "install": "https://vibecoding.tech/vizcn/r/rank-slope.json",
      "question": "How does the ranking reorder between two contexts?",
      "family": "ranking",
      "whenToUse": "Re-ranking between exactly two contexts (two benchmarks, two dates, before/after) where crossings and spread change are the message.",
      "antiUse": "More than two contexts — use lines; when only the gap per item matters — use dumbbell-range.",
      "client": false,
      "props": "left: string; right: string; items: {label, from, to, color?}[]; unit?='%'; height?",
      "example": "import { RankSlope } from \"@/components/vizcn/rank-slope\"\n\nexport default function RankSlopeDemo() {\n  return (\n    <RankSlope\n      left=\"SWE-Bench Pro\"\n      right=\"DeepSWE\"\n      unit=\"%\"\n      items={[\n        { label: 'claude-opus-4.7', from: 64, to: 54, color: '#E8734A' },\n        { label: 'gpt-5.5', from: 59, to: 70, color: '#10A37F' },\n        { label: 'gpt-5.4', from: 58, to: 56, color: '#10A37F' },\n        { label: 'claude-sonnet-4.6', from: 54, to: 32, color: '#E8734A' },\n        { label: 'gpt-5.4-mini', from: 54, to: 24, color: '#10A37F' },\n        { label: 'gemini-3.1-pro', from: 46, to: 10, color: '#4285F4' },\n        { label: 'claude-haiku-4.5', from: 39, to: 0, color: '#E8734A' },\n        { label: 'gemini-3-flash', from: 35, to: 5, color: '#4285F4' },\n      ]}\n    />\n  )\n}\n"
    },
    {
      "name": "share-strip",
      "install": "https://vibecoding.tech/vizcn/r/share-strip.json",
      "question": "What makes up the whole, in one strip?",
      "family": "composition",
      "whenToUse": "Flat part-to-whole composition of a handful of categories where the single-strip proportion is the message.",
      "antiUse": "Hierarchies or many small categories — use treemap; comparing composition across subjects — use verdict-stack.",
      "client": false,
      "props": "parts: {label, value, color?}[]; title?; unit?",
      "example": "import { ShareStrip } from \"@/components/vizcn/share-strip\"\n\nexport default function ShareStripDemo() {\n  return (\n    <ShareStrip\n      title=\"Language distribution\"\n      parts={[\n        { label: 'Typescript', value: 35 },\n        { label: 'Go', value: 34 },\n        { label: 'Python', value: 34 },\n        { label: 'Javascript', value: 5 },\n        { label: 'Rust', value: 5 },\n      ]}\n    />\n  )\n}\n"
    },
    {
      "name": "stacked-activity",
      "install": "https://vibecoding.tech/vizcn/r/stacked-activity.json",
      "question": "What makes up each day's volume, and how does it breathe day to day?",
      "family": "time-series",
      "whenToUse": "Daily volume split into 2-4 additive parts over weeks of data, where per-day composition matters as much as the trend.",
      "antiUse": "Comparing exact values of individual segments across days (inner segments have no common baseline) or fewer than 5 days.",
      "client": true,
      "props": "days: ISO date strings; segments: {key,label,color,values[]} bottom-up; unit?; note?; partialLast?; partialNote?",
      "example": "'use client'\n\nimport { seriesColor } from '../../lib/palette'\nimport { StackedActivityBars, type StackSegment } from \"@/components/vizcn/stacked-activity\"\n\n/**\n * Demo: 28 days of token traffic for the fictional model \"Atlas\" —\n * deterministic waves (no randomness), stacked as prompt / completion /\n * reasoning tokens. The last day is partial and hatched.\n */\n\nconst N = 28\n\nfunction isoDays(startIso: string, count: number): string[] {\n  const d = new Date(`${startIso}T00:00:00Z`)\n  const out: string[] = []\n  for (let i = 0; i < count; i++) {\n    out.push(d.toISOString().slice(0, 10))\n    d.setUTCDate(d.getUTCDate() + 1)\n  }\n  return out\n}\n\nconst days = isoDays('2025-06-01', N)\n\nconst wave = (i: number, base: number, a1: number, a2: number) =>\n  Math.round((base + a1 * Math.sin(i / 3.1) + a2 * Math.sin(i / 1.4 + 1.7) + i * 0.06) * 100) / 100\n\nconst prompt = days.map((_, i) => wave(i, 5.8, 1.6, 0.7))\nconst completion = days.map((_, i) => wave(i, 2.4, 0.8, 0.4))\nconst reasoning = days.map((_, i) => wave(i, 1.1, 0.5, 0.25))\n\n// last day is in progress — scale it down to look partial\nconst partial = (vs: number[]) => vs.map((v, i) => (i === N - 1 ? Math.round(v * 42) / 100 : v))\n\nconst segments: StackSegment[] = [\n  { key: 'prompt', label: 'Prompt', color: seriesColor(0), values: partial(prompt) },\n  { key: 'completion', label: 'Completion', color: seriesColor(1), values: partial(completion) },\n  { key: 'reasoning', label: 'Reasoning', color: seriesColor(2), values: partial(reasoning) },\n]\n\nexport default function StackedActivityDemo() {\n  return (\n    <StackedActivityBars\n      days={days}\n      segments={segments}\n      unit=\"B\"\n      note=\"Daily token volume for Atlas by request part. Hover a day to pin it in the legend.\"\n      partialLast\n      partialNote=\"partial day\"\n    />\n  )\n}\n"
    },
    {
      "name": "treemap",
      "install": "https://vibecoding.tech/vizcn/r/treemap.json",
      "question": "How is the whole split up, and who dominates?",
      "family": "composition",
      "whenToUse": "Showing one full field at a glance where a few players clearly dominate — market share, install base, budget split — with roughly 5-15 items.",
      "antiUse": "Not for close values (areas are hard to compare precisely) or deep hierarchies (flat only) — use rank bars or a nested treemap library instead.",
      "client": true,
      "props": "items: {label, value, valueLabel?, sub?, href?, iconUrl?, badge?, color?, muted?}[]; rows? (default 2); rowHeight? (default 96); defaultColor? (default seriesColor(0))",
      "example": "import { seriesColor } from '../../lib/palette'\nimport { Treemap } from \"@/components/vizcn/treemap\"\n\nconst VENDOR = {\n  meridian: seriesColor(0),\n  helix: seriesColor(1),\n  vantage: seriesColor(2),\n}\n\nexport default function TreemapDemo() {\n  return (\n    <div className=\"mx-auto max-w-[640px]\">\n      <p className=\"mb-2 text-[13px] font-bold text-[var(--vz-ink,#111)]\">Assistant usage share, Jun 2026</p>\n      <Treemap\n        rows={2}\n        rowHeight={104}\n        items={[\n          {\n            label: 'Atlas',\n            value: 34,\n            valueLabel: '34%',\n            sub: 'Meridian',\n            badge: 'npm 12.4M/wk',\n            color: VENDOR.meridian,\n          },\n          {\n            label: 'Nova',\n            value: 26,\n            valueLabel: '26%',\n            sub: 'Helix Labs',\n            badge: 'npm 8.1M/wk',\n            color: VENDOR.helix,\n          },\n          {\n            label: 'Orion',\n            value: 18,\n            valueLabel: '18%',\n            sub: 'Vantage',\n            badge: 'npm 4.9M/wk',\n            color: VENDOR.vantage,\n          },\n          {\n            label: 'Vega',\n            value: 12,\n            valueLabel: '12%',\n            sub: 'Meridian',\n            color: VENDOR.meridian,\n          },\n          {\n            label: 'Lumen',\n            value: 7,\n            valueLabel: '7%',\n            sub: 'Helix Labs',\n            color: VENDOR.helix,\n          },\n          { label: 'Others', value: 3, valueLabel: '3%', sub: 'long tail', muted: true },\n        ]}\n      />\n      <p className=\"mt-2 text-[10.5px] font-medium uppercase tracking-[0.08em] text-[var(--vz-muted,#8A8A8A)]\">\n        area = share of total · color = vendor · brighter = bigger\n      </p>\n    </div>\n  )\n}\n"
    },
    {
      "name": "value-columns",
      "install": "https://vibecoding.tech/vizcn/r/value-columns.json",
      "question": "How do these few values stack up side by side?",
      "family": "ranking",
      "whenToUse": "Comparing one magnitude across a handful of named entities where side-by-side height reads instantly (tariffs, prices, counters).",
      "antiUse": "Not for many items (>8) or time series — use rank bars or lines instead.",
      "client": true,
      "props": "items: {label, value, valueLabel?, sub?, highlight?, color?}[]; height? (default 180); maxValue?; highlightColor? (default seriesColor(0))",
      "example": "import { ColumnChart } from \"@/components/vizcn/value-columns\"\nimport { seriesColor } from '../../lib/palette'\n\nexport default function ValueColumnsDemo() {\n  return (\n    <div className=\"mx-auto w-full max-w-[560px]\">\n      <p className=\"mb-4 text-[13px] font-semibold text-[var(--vz-ink,#111)]\">\n        Pro plan price · $/month, Jun 2026\n      </p>\n      {/* color follows the entity: each vendor's column wears its color */}\n      <ColumnChart\n        items={[\n          { label: 'Atlas 4', sub: 'Meridian', value: 20, valueLabel: '$20', highlight: true },\n          { label: 'Nova Max', sub: 'Helix Labs', value: 30, valueLabel: '$30', color: seriesColor(1) },\n          { label: 'Orion Pro', sub: 'Vantage', value: 25, valueLabel: '$25', color: seriesColor(2) },\n          { label: 'Vega 2', sub: 'Stellar', value: 15, valueLabel: '$15', color: seriesColor(3) },\n          { label: 'Lumen', sub: 'Helix Labs', value: 10, valueLabel: '$10', color: seriesColor(4) },\n        ]}\n      />\n    </div>\n  )\n}\n"
    },
    {
      "name": "verdict-stack",
      "install": "https://vibecoding.tech/vizcn/r/verdict-stack.json",
      "question": "What do each subject's outcomes consist of?",
      "family": "composition",
      "whenToUse": "Comparing the composition of outcomes or verdicts across subjects with a shared taxonomy (failure modes, ticket categories).",
      "antiUse": "Reading exact segment values (no common baseline) — use a table; time series — use stacked-activity.",
      "client": true,
      "props": "subjects: {label, n, counts: Record<string, number>}[]; taxonomy: {group: string, tags: {key, label, color?}[]}[]",
      "example": "import { VerdictStack } from \"@/components/vizcn/verdict-stack\"\n\n// Rounded fictional reconstruction of the donor figure.\nexport default function VerdictStackDemo() {\n  return (\n    <VerdictStack\n      taxonomy={[\n        // Verdict semantics over neutral palette: pass green; failure severity\n        // ramp amber → red → maroon; verifier artifacts grey; cheated ink-black.\n        { group: 'PASS', tags: [{ key: 'legitimate', label: 'legitimate', color: '#1a7f37' }] },\n        {\n          group: 'FAIL',\n          tags: [\n            { key: 'missed_requirement', label: 'missed requirement', color: '#d97706' },\n            { key: 'wrong_logic', label: 'wrong logic', color: '#c41e1e' },\n            { key: 'regression', label: 'regression', color: '#7f1d1d' },\n          ],\n        },\n        {\n          group: 'VERIFIER',\n          tags: [\n            { key: 'test_mismatch', label: 'test mismatch', color: '#9c9c9c' },\n            { key: 'cheated', label: 'cheated', color: '#111111' },\n          ],\n        },\n      ]}\n      subjects={[\n        {\n          label: 'gpt-5.5',\n          n: 90,\n          counts: {\n            legitimate: 60,\n            missed_requirement: 18,\n            wrong_logic: 6,\n            regression: 3,\n            test_mismatch: 3,\n            cheated: 0,\n          },\n        },\n        {\n          label: 'claude-opus-4.7',\n          n: 90,\n          counts: {\n            legitimate: 44,\n            missed_requirement: 30,\n            wrong_logic: 6,\n            regression: 4,\n            test_mismatch: 2,\n            cheated: 4,\n          },\n        },\n        {\n          label: 'gpt-5.4',\n          n: 90,\n          counts: {\n            legitimate: 42,\n            missed_requirement: 32,\n            wrong_logic: 8,\n            regression: 4,\n            test_mismatch: 4,\n            cheated: 0,\n          },\n        },\n        {\n          label: 'claude-sonnet-4.6',\n          n: 80,\n          counts: {\n            legitimate: 24,\n            missed_requirement: 38,\n            wrong_logic: 8,\n            regression: 4,\n            test_mismatch: 4,\n            cheated: 2,\n          },\n        },\n        {\n          label: 'gemini-3.1-pro',\n          n: 83,\n          counts: {\n            legitimate: 8,\n            missed_requirement: 40,\n            wrong_logic: 16,\n            regression: 8,\n            test_mismatch: 9,\n            cheated: 2,\n          },\n        },\n        {\n          label: 'claude-haiku-4.5',\n          n: 90,\n          counts: {\n            legitimate: 0,\n            missed_requirement: 52,\n            wrong_logic: 20,\n            regression: 8,\n            test_mismatch: 8,\n            cheated: 2,\n          },\n        },\n      ]}\n    />\n  )\n}\n"
    }
  ]
}