{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mod-popup",
  "title": "Mod popup",
  "description": "The armor-mod inspect flyout — the in-game mod tooltip, the mod counterpart to PlugPopup.",
  "dependencies": [
    "@engram/core"
  ],
  "registryDependencies": [
    "@engram/bungie-image",
    "@engram/cn",
    "@engram/panel",
    "@engram/tokens"
  ],
  "files": [
    {
      "path": "src/components/mod-popup.tsx",
      "content": "import type { ModPopupProps as ModData, ModStat } from \"@engram/core\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.js\";\nimport { BungieImage } from \"./bungie-image.js\";\nimport { Panel } from \"./panel.js\";\n\nexport interface ModPopupProps extends ModData {\n  /** Action buttons (e.g. an Equip / Insert button). */\n  footer?: ReactNode;\n  className?: string;\n}\n\n// The in-game armor energy-cost glyph (the \"hammer\") is a UI-font symbol, not a\n// manifest icon — Bungie's \"Any Energy Type Cost\" stat icon is blank. We draw it\n// so the cost reads like the game; consumers can override via `energyIcon`.\nfunction EnergyHammer() {\n  return (\n    <svg\n      viewBox=\"0 0 24 24\"\n      aria-hidden\n      className=\"size-4 shrink-0 text-engram-muted\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth={2}\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n    >\n      <title>Energy cost</title>\n      <path d=\"m15 12-8.373 8.373a1 1 0 1 1-3-3L12 9\" />\n      <path d=\"m18 15 4-4\" />\n      <path d=\"m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172V7l-2.26-2.26a6 6 0 0 0-4.202-1.756L9 2.96l.92.82A6.18 6.18 0 0 1 12 8.4V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5\" />\n    </svg>\n  );\n}\n\nfunction StatRow({ stat }: { stat: ModStat }) {\n  const positive = stat.value >= 0;\n  return (\n    <div className=\"flex items-center gap-2.5 text-[13px]\">\n      {stat.icon ? (\n        <BungieImage\n          src={stat.icon}\n          aria-hidden\n          className=\"size-4 shrink-0 object-contain opacity-80\"\n        />\n      ) : (\n        <span aria-hidden className=\"size-4 shrink-0\" />\n      )}\n      <span className=\"text-engram-fg\">\n        {positive ? \"+\" : \"\"}\n        {stat.value} {stat.name}\n      </span>\n      <span\n        aria-hidden\n        className={cn(\n          \"text-[10px]\",\n          positive ? \"text-engram-good\" : \"text-engram-bad\",\n        )}\n      >\n        {positive ? \"▲\" : \"▼\"}\n      </span>\n    </div>\n  );\n}\n\n/**\n * The armor-mod inspect flyout — the in-game mod tooltip, the mod counterpart to\n * {@link PlugPopup}. A neutral (non-element) header with the mod name + category\n * (\"{slot} Armor Mod\"), an energy-cost readout, any stat bonuses (e.g. +10\n * Super), the effect description beside the mod icon, and an optional ⓘ info\n * note (stacking / diminishing returns). Presentational only — pairs with\n * {@link ItemHoverCard} like the other inspect popups.\n */\nexport function ModPopup({\n  name,\n  subtitle,\n  energyCost,\n  energyIcon,\n  icon,\n  stats,\n  description,\n  note,\n  footer,\n  className,\n}: ModPopupProps) {\n  return (\n    <Panel\n      tone=\"glass\"\n      className={cn(\n        \"flex w-[320px] max-w-full flex-col border border-engram-border-strong\",\n        className,\n      )}\n    >\n      <header\n        className=\"flex flex-col justify-center px-4 py-3\"\n        style={{\n          backgroundImage:\n            \"linear-gradient(180deg, var(--engram-raised-2) 0%, var(--engram-raised) 100%)\",\n        }}\n      >\n        <h3 className=\"break-words font-engram-display font-bold text-2xl text-engram-fg uppercase leading-[1.04] tracking-tight\">\n          {name}\n        </h3>\n        {subtitle ? (\n          <p className=\"mt-0.5 text-[13px] text-engram-muted\">{subtitle}</p>\n        ) : null}\n      </header>\n\n      <div className=\"flex flex-col gap-3 px-4 py-3.5\">\n        {energyCost != null ? (\n          <div className=\"flex items-center gap-2.5\">\n            {energyIcon ? (\n              <BungieImage\n                src={energyIcon}\n                aria-hidden\n                className=\"size-4 shrink-0 object-contain opacity-90\"\n              />\n            ) : (\n              <EnergyHammer />\n            )}\n            <span className=\"font-engram-display font-bold text-engram-fg text-lg tabular-nums leading-none\">\n              {energyCost}\n            </span>\n            <span className=\"font-engram-display text-engram-muted text-xs uppercase tracking-[0.08em]\">\n              Energy Cost\n            </span>\n          </div>\n        ) : null}\n\n        {stats && stats.length > 0 ? (\n          <div className=\"flex flex-col gap-1.5 border-engram-border border-t pt-3\">\n            {stats.map((stat) => (\n              <StatRow key={stat.name} stat={stat} />\n            ))}\n          </div>\n        ) : null}\n\n        {description ? (\n          <div className=\"flex gap-2.5 border-engram-border border-t pt-3\">\n            {icon ? (\n              <BungieImage\n                src={icon}\n                aria-hidden\n                className=\"size-5 shrink-0 object-contain\"\n              />\n            ) : null}\n            <p className=\"text-[13px] text-engram-fg/85 leading-relaxed\">\n              {description}\n            </p>\n          </div>\n        ) : null}\n\n        {note ? (\n          <div className=\"flex gap-2.5 border-engram-border border-t pt-3\">\n            <span\n              aria-hidden\n              className=\"mt-px flex size-4 shrink-0 items-center justify-center rounded-full border border-engram-muted font-bold font-engram-display text-[10px] text-engram-muted leading-none\"\n            >\n              i\n            </span>\n            <p className=\"text-[12.5px] text-engram-muted leading-relaxed\">\n              {note}\n            </p>\n          </div>\n        ) : null}\n      </div>\n\n      {footer ? (\n        <div className=\"flex flex-wrap justify-end gap-2 border-engram-border border-t bg-white/[0.03] px-4 py-2.5\">\n          {footer}\n        </div>\n      ) : null}\n    </Panel>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/engram/mod-popup.tsx"
    }
  ],
  "meta": {
    "level": "component"
  },
  "docs": "Extend without forking: edit the copied source, use `asChild` (Radix Slot) to change the rendered element, pass the typed `annotations` prop for curated data (verdict/tags/per-plug), or use slot / render-prop props for arbitrary content. Requires the @engram/tokens theme (--engram-* CSS variables).",
  "categories": [
    "loadout"
  ],
  "type": "registry:component"
}