{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "code-comparison",
  "type": "registry:ui",
  "title": "Code comparison",
  "description": "Binds implementation differences and rendered output inside one switchable comparison surface.",
  "dependencies": [
    "motion"
  ],
  "categories": [
    "cards-media"
  ],
  "docs": "https://motion-lexicon.pages.dev/en/components/code-comparison/",
  "meta": {
    "engines": [
      "motion"
    ],
    "runtimeCost": "medium",
    "signature": "Selected difference updates code and preview together",
    "sceneFamily": "product-mono",
    "motionRole": "ui",
    "primaryState": "Side-by-side code and result comparison",
    "assetProvenance": "self-contained"
  },
  "files": [
    {
      "path": "src/registry/components/code-comparison.tsx",
      "type": "registry:ui",
      "target": "components/motion-lexicon/code-comparison.tsx",
      "content": "\"use client\";\n\nimport { useId, useState, type ReactNode } from \"react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\n\nexport type CodeComparisonItem = { id: string; label: string; code: string; preview: ReactNode; description?: string; meta?: string };\nexport type CodeComparisonProps = { items: readonly CodeComparisonItem[]; label?: string; defaultId?: string; onChange?: (item: CodeComparisonItem, index: number) => void; className?: string };\n\nexport function CodeComparison({ items, label = \"Code comparison\", defaultId, onChange, className = \"\" }: CodeComparisonProps) {\n  const baseId = useId();\n  const [selectedId, setSelectedId] = useState(defaultId ?? items[0]?.id ?? \"\");\n  const selectedIndex = Math.max(0, items.findIndex((item) => item.id === selectedId));\n  const selected = items[selectedIndex];\n  const reduced = useReducedMotion() === true;\n  if (!selected) return null;\n  const select = (index: number) => { const item = items[index]; if (!item) return; setSelectedId(item.id); onChange?.(item, index); };\n  return <section aria-label={label} className={`w-full overflow-hidden rounded-[20px] border border-[#d8d8e9]/15 bg-[#111217] p-3 shadow-[0_24px_54px_-36px_rgba(0,0,0,.9)] ${className}`}><div className=\"mb-3 flex items-end justify-between gap-3 px-1\"><div><span className=\"font-mono text-[9px] tracking-[.16em] text-[#b9c7e9]/60\">IMPLEMENTATION NOTE</span><h3 className=\"mt-1 text-[15px] font-medium tracking-[-.03em] text-[#f2f4ff]\">{label}</h3></div>{selected.meta ? <span className=\"font-mono text-[8px] tracking-[.13em] text-[#b9c7e9]/60\">{selected.meta}</span> : null}</div><div role=\"tablist\" aria-label={label} className=\"mb-3 grid grid-cols-2 gap-1 rounded-xl border border-white/10 bg-white/[0.04] p-1\">{items.map((item, index) => <button key={item.id} id={`${baseId}-${item.id}-tab`} type=\"button\" role=\"tab\" aria-selected={index === selectedIndex} aria-controls={`${baseId}-${item.id}-panel`} tabIndex={index === selectedIndex ? 0 : -1} onClick={() => select(index)} onKeyDown={(event) => { if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") { event.preventDefault(); select((index + (event.key === \"ArrowLeft\" ? -1 : 1) + items.length) % items.length); } }} className={`min-h-11 rounded-[9px] px-3 text-[11px] font-medium outline-none focus-visible:ring-2 focus-visible:ring-[#9cc5ff] ${index === selectedIndex ? \"bg-[#e8edff] text-[#1a2131]\" : \"text-[#cfd9f6]/70 hover:bg-white/[0.07]\"}`}>{item.label}</button>)}</div><div id={`${baseId}-${selected.id}-panel`} role=\"tabpanel\" aria-labelledby={`${baseId}-${selected.id}-tab`} className=\"grid overflow-hidden rounded-[14px] border border-white/10 bg-[#181b24] md:grid-cols-[minmax(0,1.12fr)_minmax(170px,.88fr)]\"><div className=\"min-h-[220px] overflow-auto border-b border-white/10 bg-[#0b0d12] p-4 md:border-b-0 md:border-r\"><AnimatePresence mode=\"wait\" initial={false}><motion.pre key={selected.id} initial={reduced ? false : { opacity: 0, y: 5 }} animate={{ opacity: 1, y: 0 }} exit={reduced ? { opacity: 0 } : { opacity: 0, y: -5 }} transition={reduced ? { duration: 0 } : { duration: 0.2 }} className=\"whitespace-pre-wrap break-words font-mono text-[10px] leading-[1.75] text-[#cfe5ff]\"><code>{selected.code}</code></motion.pre></AnimatePresence></div><div className=\"relative min-h-[220px] overflow-hidden bg-[radial-gradient(circle_at_76%_20%,rgba(111,166,255,.26),transparent_32%),#1b202a]\"><AnimatePresence mode=\"wait\" initial={false}><motion.div key={selected.id} initial={reduced ? false : { opacity: 0, scale: 0.97 }} animate={{ opacity: 1, scale: 1 }} exit={reduced ? { opacity: 0 } : { opacity: 0, scale: 1.03 }} transition={reduced ? { duration: 0 } : { duration: 0.25 }} className=\"absolute inset-0\">{selected.preview}</motion.div></AnimatePresence><div className=\"pointer-events-none absolute inset-x-3 bottom-3 rounded-xl border border-white/15 bg-[#0e1118]/72 p-2.5 backdrop-blur-sm\"><strong className=\"block text-[11px] font-medium text-[#ecf3ff]\">{selected.label}</strong>{selected.description ? <span className=\"mt-1 block text-[10px] leading-relaxed text-[#c6d3ee]/68\">{selected.description}</span> : null}</div></div></div></section>;\n}\n"
    }
  ]
}
