{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "figure",
  "type": "registry:component",
  "title": "Figure",
  "description": "Figure plate with run-in caption, plus an editorial table with small-caps heads and hairline rules.",
  "dependencies": [],
  "registryDependencies": [
    "https://mocoui.site/r/tokens.json"
  ],
  "files": [
    {
      "path": "registry/figure/figure.tsx",
      "type": "registry:component",
      "target": "components/moco/figure.tsx",
      "content": "import * as React from \"react\";\nimport \"./figure.css\";\n\nexport type FigurePlateProps = {\n  children: React.ReactNode;\n  /** Bold run-in phrase. Include its own full stop. */\n  lead: string;\n  caption: React.ReactNode;\n  id?: string;\n  /** Break out of a centred prose column to a wider measure. */\n  wide?: boolean;\n};\n\n/**\n * A figure plate with a run-in caption. The caption sits outside the plate\n * and always opens with a bold run-in phrase — consistency is the point.\n */\nexport function FigurePlate({ children, lead, caption, id, wide = true }: FigurePlateProps) {\n  return (\n    <figure id={id} className={`moco-plate-wrap${wide ? \" moco-breakout\" : \"\"}`}>\n      <div className=\"moco-plate\">{children}</div>\n      <figcaption className=\"moco-cap\">\n        <b className=\"moco-lead-in\">{lead}</b> {caption}\n      </figcaption>\n    </figure>\n  );\n}\n\nexport type EdTableProps = {\n  head: { label: string; numeric?: boolean }[];\n  rows: React.ReactNode[][];\n  /** Optional totals row, set off by a heavier rule. */\n  summary?: React.ReactNode[];\n  /** Bold run-in phrase for the caption. Include its own full stop. */\n  lead: string;\n  caption: React.ReactNode;\n  /** Index of the row to emphasise. */\n  bestIndex?: number;\n};\n\n/** Editorial table: caption below, small-caps heads, hairline rules, no zebra. */\nexport function EdTable({ head, rows, summary, lead, caption, bestIndex }: EdTableProps) {\n  return (\n    <table className=\"moco-ed\">\n      <thead>\n        <tr>\n          {head.map((h) => (\n            <th key={h.label} className={h.numeric ? \"moco-n\" : undefined} scope=\"col\">\n              {h.label}\n            </th>\n          ))}\n        </tr>\n      </thead>\n      <tbody>\n        {rows.map((r, i) => (\n          <tr key={i} data-best={i === bestIndex ? \"true\" : undefined}>\n            {r.map((c, j) => (\n              <td key={j} className={head[j]?.numeric ? \"moco-n\" : undefined}>\n                {c}\n              </td>\n            ))}\n          </tr>\n        ))}\n        {summary ? (\n          <tr className=\"moco-summary\">\n            {summary.map((c, j) => (\n              <td key={j} className={head[j]?.numeric ? \"moco-n\" : undefined}>\n                {c}\n              </td>\n            ))}\n          </tr>\n        ) : null}\n      </tbody>\n      <caption>\n        <b className=\"moco-lead-in\">{lead}</b> {caption}\n      </caption>\n    </table>\n  );\n}\n"
    },
    {
      "path": "registry/figure/figure.css",
      "type": "registry:file",
      "target": "components/moco/figure.css",
      "content": "/* margin-block, not the shorthand — `.moco-breakout` owns margin-left. */\n.moco-plate-wrap {\n  margin-block: 3rem;\n}\n\n/* Break out of a centred prose column. Override --moco-figure-wide to tune. */\n.moco-breakout {\n  width: min(var(--moco-figure-wide, 1080px), calc(100vw - 3rem));\n  margin-left: 50%;\n  transform: translateX(-50%);\n}\n\n@media (max-width: 560px) {\n  .moco-breakout {\n    width: calc(100vw - 2.5rem);\n  }\n}\n\n.moco-plate {\n  position: relative;\n  background: var(--moco-panel);\n  border-radius: 2px;\n  padding: 2rem 1.75rem;\n  overflow-x: auto;\n  overflow-y: hidden;\n  background-image: radial-gradient(120% 90% at 50% 0%, rgba(0, 0, 0, 0.028), transparent 70%);\n}\n\n.moco-plate::-webkit-scrollbar {\n  height: 6px;\n}\n.moco-plate::-webkit-scrollbar-thumb {\n  background: var(--moco-line);\n  border-radius: 3px;\n}\n\n@media (max-width: 720px) {\n  .moco-plate {\n    padding: 1.25rem 1rem;\n    -webkit-mask-image: linear-gradient(to right, #000 93%, transparent 100%);\n    mask-image: linear-gradient(to right, #000 93%, transparent 100%);\n  }\n}\n\nfigcaption.moco-cap {\n  display: block;\n  margin-top: 0.9rem;\n  font-size: 14.5px;\n  line-height: 1.6;\n  color: var(--moco-muted);\n  max-width: 680px;\n  font-family: var(--moco-serif);\n  font-variant-numeric: normal;\n  letter-spacing: 0;\n}\n\n/* The run-in phrase stays mono — it's a label, and the contrast against the\n   serif explanation is what makes captions scannable. */\nfigcaption.moco-cap .moco-lead-in,\ntable.moco-ed caption .moco-lead-in {\n  font-family: var(--moco-mono);\n  font-size: 0.88em;\n  color: var(--moco-ink);\n  font-weight: 500;\n}\n\ntable.moco-ed {\n  width: 100%;\n  border-collapse: collapse;\n  font-size: 13px;\n}\n\ntable.moco-ed caption {\n  caption-side: bottom;\n  text-align: left;\n  margin-top: 0.9rem;\n  font-size: 13.5px;\n  line-height: 1.6;\n  color: var(--moco-muted);\n  font-family: var(--moco-serif);\n  font-variant-numeric: normal;\n  letter-spacing: 0;\n}\n\ntable.moco-ed th {\n  font-weight: 400;\n  font-size: 10.5px;\n  letter-spacing: 0.09em;\n  text-transform: uppercase;\n  color: var(--moco-faint);\n  text-align: left;\n  padding: 0 0.75rem 0.6rem 0;\n  border-bottom: 1px solid var(--moco-line);\n  white-space: nowrap;\n}\n\ntable.moco-ed td {\n  padding: 0.55rem 0.75rem 0.55rem 0;\n  border-bottom: 1px solid var(--moco-line);\n  color: var(--moco-body);\n}\n\ntable.moco-ed th.moco-n,\ntable.moco-ed td.moco-n {\n  text-align: right;\n  font-variant-numeric: tabular-nums;\n  padding-right: 0;\n  white-space: nowrap;\n}\n\ntable.moco-ed tr[data-best=\"true\"] td {\n  color: var(--moco-ink);\n  font-weight: 700;\n}\n\ntable.moco-ed tr.moco-summary td {\n  border-top: 1px solid var(--moco-muted);\n  border-bottom: none;\n  color: var(--moco-ink);\n  padding-top: 0.75rem;\n}\n"
    }
  ],
  "docs": "import { FigurePlate, EdTable } from \"./figure\";\n\nexport default function FigureDemo() {\n  return (\n    <>\n      <FigurePlate\n        wide={false}\n        lead=\"Latency falls with cache depth.\"\n        caption=\"Each bar is the median of 1,000 runs against the same prefix.\"\n      >\n        <svg viewBox=\"0 0 240 80\" width=\"240\" height=\"80\" role=\"img\" aria-label=\"Three bars falling in height\">\n          <rect x=\"20\" y=\"10\" width=\"40\" height=\"60\" fill=\"var(--moco-accent)\" />\n          <rect x=\"100\" y=\"30\" width=\"40\" height=\"40\" fill=\"var(--moco-accent)\" />\n          <rect x=\"180\" y=\"50\" width=\"40\" height=\"20\" fill=\"var(--moco-accent)\" />\n        </svg>\n      </FigurePlate>\n\n      <EdTable\n        head={[{ label: \"Strategy\" }, { label: \"$/month\", numeric: true }, { label: \"vs. baseline\", numeric: true }]}\n        rows={[\n          [\"No caching\", \"$1,284\", \"1.00×\"],\n          [\"5-minute TTL\", \"$212\", \"6.06×\"],\n          [\"1-hour TTL\", \"$318\", \"4.04×\"],\n        ]}\n        summary={[\"Best\", \"$212\", \"6.06×\"]}\n        bestIndex={1}\n        lead=\"The short TTL wins.\"\n        caption=\"Steady traffic keeps the cache warm, so the cheaper write premium dominates.\"\n      />\n    </>\n  );\n}\n",
  "meta": {
    "tags": [
      "figure",
      "caption",
      "table",
      "layout"
    ]
  }
}