{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "item-popup",
  "title": "Item popup",
  "description": "The item inspect flyout — a dark glass panel modeled on the in-game tooltip: a rarity header band, a damage-type + power/ammo readout, flavor, an optional kill tracker, the stat block, the intrinsic frame row, a perk band (`children`, e.g. a `SocketGrid`), and an action `footer` (e.g. Apply).",
  "dependencies": [
    "@engram/core"
  ],
  "registryDependencies": [
    "@engram/ammo-icon",
    "@engram/breaker-icon",
    "@engram/bungie-image",
    "@engram/chip",
    "@engram/cn",
    "@engram/element-icon",
    "@engram/item-hover-card",
    "@engram/item-popup-header",
    "@engram/item-stats",
    "@engram/panel",
    "@engram/roll-verdict",
    "@engram/token-utils",
    "@engram/tokens"
  ],
  "files": [
    {
      "path": "src/components/item-popup.tsx",
      "content": "import type {\n  ItemPopupHeaderProps as HeaderData,\n  ImageRef,\n  ItemAnnotations,\n  StatProps,\n} from \"@engram/core\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.js\";\nimport { elementVar } from \"../lib/tokens.js\";\nimport { AmmoIcon } from \"./ammo-icon.js\";\nimport { BreakerIcon } from \"./breaker-icon.js\";\nimport { BungieImage } from \"./bungie-image.js\";\nimport { Chip } from \"./chip.js\";\nimport { ElementIcon } from \"./element-icon.js\";\nimport { INSPECT_PANEL_ATTR } from \"./item-hover-card.js\";\nimport { ItemPopupHeader } from \"./item-popup-header.js\";\nimport { ItemStats } from \"./item-stats.js\";\nimport { Panel } from \"./panel.js\";\nimport { RollVerdictBadge } from \"./roll-verdict.js\";\n\n/** The intrinsic frame / archetype row — a weapon frame, or an exotic armor /\n *  weapon's signature perk (with a description). */\nexport interface WeaponFrameRef {\n  name: string;\n  icon?: ImageRef;\n  /** Short key-stats summary shown at the right, e.g. \"140 RPM · 14 Mag\". */\n  keyStats?: string;\n  /** Longer perk description (e.g. an exotic intrinsic). */\n  description?: string;\n}\n\n/** A kill / usage tracker row (e.g. \"Enemies Defeated — 3,910\"). */\nexport interface ItemTracker {\n  label: string;\n  value: string | number;\n}\n\nexport interface ItemPopupProps {\n  header: HeaderData;\n  /** Season watermark shown in the header's tier strip (matches the tile). */\n  seasonIcon?: ImageRef;\n  /** New-armor archetype (Brawler/Paragon/…) shown beside the power readout. */\n  archetype?: { name: string; icon?: ImageRef };\n  stats?: StatProps[];\n  /** Intrinsic frame row (weapons). */\n  frame?: WeaponFrameRef;\n  /** Kill / usage tracker row. */\n  tracker?: ItemTracker;\n  /** Typed curated-roll annotations — verdict + tags. */\n  annotations?: ItemAnnotations;\n  /** Perk / socket content (e.g. a `SocketGrid`). */\n  children?: ReactNode;\n  /** Action buttons (e.g. Apply / Compare). */\n  footer?: ReactNode;\n  className?: string;\n}\n\n/**\n * The item inspect flyout — a dark glass panel modeled on the in-game tooltip:\n * a rarity header band, a damage-type + power/ammo readout, flavor, an optional\n * kill tracker, the stat block, the intrinsic frame row, a perk band\n * (`children`, e.g. a `SocketGrid`), and an action `footer` (e.g. Apply).\n */\nexport function ItemPopup({\n  header,\n  seasonIcon,\n  archetype,\n  stats,\n  frame,\n  tracker,\n  annotations,\n  children,\n  footer,\n  className,\n}: ItemPopupProps) {\n  const {\n    name,\n    typeName,\n    rarity,\n    element,\n    ammo,\n    breaker,\n    power,\n    flavor,\n    tier,\n    masterwork,\n  } = header;\n  const hasReadout = Boolean(element || ammo || breaker || power != null);\n  const hasVerdict = Boolean(annotations?.verdict || annotations?.tags?.length);\n  // Armor shows a summed stat total beneath its six stats.\n  const statTotal =\n    archetype && stats ? stats.reduce((n, s) => n + s.value, 0) : undefined;\n  return (\n    <Panel\n      tone=\"glass\"\n      // Marks this as an inspect panel so a nested, panel-anchored card (e.g. a\n      // mod's ModPopup) can sit beside the whole panel instead of the cursor.\n      {...{ [INSPECT_PANEL_ATTR]: \"\" }}\n      className={cn(\n        // Destiny defines floating surfaces by their frosted fill + blur (the\n        // glass tone) and a hairline edge — not a skeuomorphic drop shadow.\n        \"flex w-[340px] max-w-full flex-col border border-engram-border-strong\",\n        className,\n      )}\n    >\n      <ItemPopupHeader\n        name={name}\n        typeName={typeName}\n        rarity={rarity}\n        seasonIcon={seasonIcon}\n        tier={tier}\n        masterwork={masterwork}\n      />\n\n      <div className=\"px-4 py-3.5\">\n        {hasReadout ? (\n          <div className=\"flex items-center gap-2.5\">\n            {power != null ? (\n              <span className=\"flex items-center gap-2\">\n                {element ? <ElementIcon element={element} size={26} /> : null}\n                <span\n                  className=\"font-engram-display font-bold text-[30px] leading-none tabular-nums\"\n                  style={{\n                    color: element\n                      ? elementVar(element)\n                      : archetype\n                        ? \"var(--engram-fg)\"\n                        : \"var(--engram-gold)\",\n                  }}\n                >\n                  {power}\n                </span>\n              </span>\n            ) : element ? (\n              <ElementIcon element={element} size={22} />\n            ) : null}\n            {archetype ? (\n              <>\n                <span className=\"h-7 w-px bg-engram-border\" aria-hidden />\n                <span className=\"flex items-center gap-2\">\n                  {archetype.icon ? (\n                    <BungieImage\n                      src={archetype.icon}\n                      aria-hidden\n                      className=\"w-[26px] object-contain\"\n                    />\n                  ) : null}\n                  <span className=\"font-engram-display font-semibold text-[15px] text-engram-fg uppercase tracking-[0.06em]\">\n                    {archetype.name}\n                  </span>\n                </span>\n              </>\n            ) : null}\n            {(power != null || element) && ammo ? (\n              <span className=\"h-6 w-px bg-engram-border\" aria-hidden />\n            ) : null}\n            {ammo ? (\n              <span className=\"flex items-center gap-1.5\">\n                <AmmoIcon ammo={ammo} size={15} />\n                <span className=\"font-engram-display text-engram-muted text-xs uppercase tracking-[0.08em]\">\n                  {ammo}\n                </span>\n              </span>\n            ) : null}\n            {breaker ? (\n              <BreakerIcon\n                breaker={breaker}\n                size={18}\n                className=\"ml-auto text-engram-muted\"\n              />\n            ) : null}\n          </div>\n        ) : null}\n\n        {flavor ? (\n          <p className=\"mt-3 text-engram-muted text-sm italic leading-relaxed\">\n            {flavor}\n          </p>\n        ) : null}\n\n        {tracker ? (\n          <div className=\"mt-3 flex items-center gap-2 border-engram-border border-y py-2 text-[13px]\">\n            <span className=\"text-engram-muted\">{tracker.label}</span>\n            <span className=\"ml-auto font-engram-display font-bold text-engram-fg tabular-nums\">\n              {tracker.value}\n            </span>\n          </div>\n        ) : null}\n\n        {hasVerdict ? (\n          <div className=\"mt-3 flex flex-wrap items-center gap-2\">\n            {annotations?.verdict ? (\n              <RollVerdictBadge verdict={annotations.verdict} />\n            ) : null}\n            {annotations?.tags?.map((tag) => (\n              <Chip key={tag}>{tag}</Chip>\n            ))}\n          </div>\n        ) : null}\n\n        {stats && stats.length > 0 ? (\n          <div className=\"mt-3 border-engram-border border-t pt-3\">\n            <ItemStats stats={stats} total={statTotal} />\n          </div>\n        ) : null}\n\n        {frame ? (\n          <div className=\"-mx-4 mt-3.5 border-engram-border border-t bg-white/[0.025] px-4 py-2.5\">\n            <div className=\"flex items-center gap-2.5\">\n              {frame.icon ? (\n                <BungieImage\n                  src={frame.icon}\n                  className=\"size-6 object-contain text-engram-accent-2\"\n                />\n              ) : null}\n              <span className=\"font-engram-display font-semibold text-[13px] text-engram-fg tracking-[0.02em]\">\n                {frame.name}\n              </span>\n              {frame.keyStats ? (\n                <span className=\"ml-auto font-engram-display text-engram-muted text-xs tabular-nums tracking-[0.04em]\">\n                  {frame.keyStats}\n                </span>\n              ) : null}\n            </div>\n            {frame.description ? (\n              <p className=\"mt-1.5 text-engram-muted text-xs italic leading-relaxed\">\n                {frame.description}\n              </p>\n            ) : null}\n          </div>\n        ) : null}\n\n        {children ? (\n          <div\n            className={cn(\n              \"-mx-4 px-4 py-3.5\",\n              frame\n                ? \"border-engram-border/60 border-t\"\n                : \"mt-3.5 border-engram-border border-t\",\n              \"bg-white/[0.02]\",\n            )}\n          >\n            {children}\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/item-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": [
    "item"
  ],
  "type": "registry:component"
}