{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "citations",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/registry/ui/citations.tsx",
      "content": "\"use client\";\n\nimport { PreviewCard } from \"@base-ui/react/preview-card\";\nimport { cn } from \"@/lib/utils\";\n\nexport type Source = {\n  title: string;\n  url: string;\n  snippet?: string;\n};\n\nfunction hostname(url: string) {\n  try {\n    return new URL(url).hostname.replace(/^www\\./, \"\");\n  } catch {\n    return url;\n  }\n}\n\n/** Inline numbered marker, e.g. [1], with a hover preview of the source. */\nexport function CitationMarker({\n  index,\n  source,\n}: {\n  index: number;\n  source: Source;\n}) {\n  return (\n    <PreviewCard.Root>\n      <PreviewCard.Trigger\n        href={source.url}\n        target=\"_blank\"\n        rel=\"noreferrer\"\n        aria-label={`Source ${index}: ${source.title}`}\n        className=\"mx-0.5 inline-flex h-4 min-w-4 -translate-y-px items-center justify-center rounded-sm border bg-muted/60 px-1 align-middle font-mono text-[10px] text-muted-foreground no-underline transition-colors hover:border-transparent hover:bg-primary hover:text-primary-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n      >\n        {index}\n      </PreviewCard.Trigger>\n      <PreviewCard.Portal>\n        <PreviewCard.Positioner sideOffset={8}>\n          <PreviewCard.Popup className=\"z-50 w-72 rounded border bg-background p-3 text-sm shadow-lg transition-opacity data-[ending-style]:opacity-0 data-[starting-style]:opacity-0\">\n            <div className=\"font-mono text-[11px] text-muted-foreground\">{hostname(source.url)}</div>\n            <div className=\"mt-0.5 font-medium leading-snug\">{source.title}</div>\n            {source.snippet && (\n              <p className=\"mt-1.5 line-clamp-3 text-xs leading-relaxed text-muted-foreground\">\n                {source.snippet}\n              </p>\n            )}\n          </PreviewCard.Popup>\n        </PreviewCard.Positioner>\n      </PreviewCard.Portal>\n    </PreviewCard.Root>\n  );\n}\n\n/** Footer list of all sources used in a response. */\nexport function Sources({\n  sources,\n  className,\n}: {\n  sources: Source[];\n  className?: string;\n}) {\n  if (!sources.length) return null;\n  return (\n    <ol className={cn(\"flex flex-wrap gap-2\", className)} aria-label=\"Sources\">\n      {sources.map((s, i) => (\n        <li key={s.url}>\n          <a\n            href={s.url}\n            target=\"_blank\"\n            rel=\"noreferrer\"\n            className=\"flex items-center gap-1.5 rounded-sm border px-2 py-1 text-xs text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n          >\n            <span className=\"font-mono text-foreground\">{i + 1}</span>\n            <span className=\"max-w-40 truncate font-mono\">{hostname(s.url)}</span>\n          </a>\n        </li>\n      ))}\n    </ol>\n  );\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}