{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "plug",
  "title": "Plug",
  "description": "A single socket plug — a perk circle or a mod square. A selected perk gets the in-game azure fill (blue→gold when enhanced, with the gold ▲ badge); a selected mod keeps the bright ring.",
  "dependencies": [
    "@engram/core"
  ],
  "registryDependencies": [
    "@engram/bungie-image",
    "@engram/cn",
    "@engram/tokens"
  ],
  "files": [
    {
      "path": "src/components/plug.tsx",
      "content": "import type { PlugProps as PlugData } from \"@engram/core\";\nimport type { ButtonHTMLAttributes, CSSProperties, ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.js\";\nimport { BungieImage } from \"./bungie-image.js\";\n\nexport interface PlugProps\n  extends PlugData,\n    Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"type\" | \"name\"> {\n  /** Perks render as circles, mods as squares. */\n  kind?: \"perk\" | \"mod\";\n  /** Pixel size. */\n  size?: number;\n  /** Overlay slot (e.g. a curated-roll badge) — the extension hook. */\n  badge?: ReactNode;\n}\n\n// The in-game selected-perk fill: a mid-azure, brighter at the top. The enhanced\n// variant washes that blue into gold toward the bottom (the endgame \"enhanced\"\n// look). Canonical Destiny perk colors — kept fixed rather than themed so a perk\n// circle reads the same everywhere.\nconst PERK_BLUE = \"linear-gradient(180deg, #5aa0d8 0%, #3f7fb5 100%)\";\nconst PERK_ENHANCED =\n  \"linear-gradient(180deg, #5aa0d8 0%, #4a86b6 42%, #d8b458 100%)\";\nconst ENHANCED_GOLD = \"#f5c93f\";\n\n/** The gold ▲ badge overlaid on an enhanced trait (top-left, as in-game). */\nfunction EnhancedArrow({ size }: { size: number }) {\n  const s = Math.max(7, Math.round(size * 0.26));\n  return (\n    <span\n      aria-hidden\n      className=\"pointer-events-none absolute top-0 left-0 z-10 drop-shadow-[0_1px_1px_rgba(0,0,0,0.7)]\"\n      style={{\n        width: 0,\n        height: 0,\n        borderLeft: `${s / 2}px solid transparent`,\n        borderRight: `${s / 2}px solid transparent`,\n        borderBottom: `${s}px solid ${ENHANCED_GOLD}`,\n      }}\n    />\n  );\n}\n\n/**\n * A single socket plug — a perk circle or a mod square. A selected perk gets the\n * in-game azure fill (blue→gold when enhanced, with the gold ▲ badge); a selected\n * mod keeps the bright ring. Unselected plugs sit dim on a dark chip; disabled\n * plugs dim further. `badge` overlays curated-roll info.\n */\nexport function Plug({\n  hash: _hash,\n  name,\n  icon,\n  enabled,\n  selected,\n  enhanced,\n  backing,\n  kind = \"perk\",\n  size = 36,\n  badge,\n  className,\n  style,\n  ...props\n}: PlugProps) {\n  const isPerk = kind !== \"mod\";\n  // Perks: selected circles take the azure/enhanced fill; mods keep the ring.\n  const perkFill: CSSProperties | undefined =\n    isPerk && selected\n      ? { backgroundImage: enhanced ? PERK_ENHANCED : PERK_BLUE }\n      : undefined;\n  return (\n    <span\n      className=\"relative inline-block shrink-0\"\n      style={{ width: size, height: size }}\n    >\n      <button\n        type=\"button\"\n        title={name}\n        aria-label={name}\n        aria-pressed={selected}\n        disabled={enabled === false}\n        className={cn(\n          \"grid h-full w-full place-items-center overflow-hidden border transition-colors\",\n          isPerk ? \"rounded-full\" : \"rounded-none\",\n          isPerk\n            ? selected\n              ? cn(\n                  // Selected perk: the azure fill, ringed white (gold when\n                  // enhanced). The fill itself is set via `perkFill`.\n                  enhanced\n                    ? \"border-[#f0cf6a] shadow-[0_0_9px_rgba(216,180,88,0.45)]\"\n                    : \"border-white/85 shadow-[0_0_8px_rgba(90,160,216,0.4)]\",\n                )\n              : // Unselected perk: a dim chip you can still read.\n                \"border-engram-border-strong bg-engram-raised/70 hover:border-engram-fg/60\"\n            : selected\n              ? \"border-engram-fg bg-engram-raised-2 shadow-[0_0_8px_rgba(255,255,255,0.35)]\"\n              : cn(\n                  \"border-engram-border-strong hover:border-engram-fg/60\",\n                  // Plugs flagged `backing` (transparent-bg art, e.g. tuning\n                  // mods) get a gray card backing so they read like the gray the\n                  // other mod icons bake into their scalloped chip.\n                  backing ? \"bg-[#3C4046]\" : \"bg-engram-raised\",\n                ),\n          enabled === false && \"opacity-40\",\n          className,\n        )}\n        style={{ ...perkFill, ...style }}\n        {...props}\n      >\n        {icon ? (\n          <BungieImage\n            src={icon}\n            // Mod icons bake in their own framed \"card\" (gray scalloped chip);\n            // scale it to bleed past the socket edge so every mod fills the\n            // square uniformly, like in-game (the button clips the overflow).\n            // Perk glyphs keep a touch of padding inside their circle, and dim\n            // when the perk isn't the selected one.\n            className={cn(\n              \"h-full w-full object-contain\",\n              isPerk ? \"p-1\" : \"scale-[1.18]\",\n              isPerk && !selected && \"opacity-70\",\n            )}\n          />\n        ) : (\n          <span className=\"size-2 rounded-full bg-engram-muted\" aria-hidden />\n        )}\n      </button>\n      {isPerk && selected && enhanced ? <EnhancedArrow size={size} /> : null}\n      {badge ? (\n        <span className=\"pointer-events-none absolute -top-1 -right-1 z-10\">\n          {badge}\n        </span>\n      ) : null}\n    </span>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/engram/plug.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": [
    "socket"
  ],
  "type": "registry:component"
}