{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "trainer-cards",
  "title": "Table cards",
  "description": "Card faces sized for a poker table: hole cards, the board, and Omaha layouts that follow the table's width.",
  "registryDependencies": [
    "https://www.pokerstudy.ai/r/playing-card.json"
  ],
  "files": [
    {
      "path": "src/components/trainer/cards.tsx",
      "content": "\"use client\";\n\nimport { CARD_FACE_CLASS, CardIndices, cardFaceParts, cardFaceStyle } from \"@/components/pokerstudy/playing-card\";\n\nexport type CardSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"table\" | \"board\";\n\nconst SIZE_CLASS: Record<CardSize | \"tablePlo\" | \"tablePlo6\" | \"heroPlo\", string> = {\n  xs: \"h-8 w-6 text-[0.65rem]\",\n  sm: \"h-11 w-8 text-sm\",\n  md: \"h-[4.5rem] w-[3.25rem] text-lg\",\n  lg: \"h-24 w-[4.25rem] text-xl\",\n  // Follow the table container, not the viewport: `sm:` (640px) was painting\n  // desktop tiles on tablets. Keep them compact until the oval itself is wide.\n  table:\n    \"h-11 w-8 text-sm @[64rem]:h-24 @[64rem]:w-[4.25rem] @[64rem]:text-xl\",\n  board:\n    \"h-[4.25rem] w-[3.05rem] text-[1.05rem] @[32rem]:h-[5.35rem] @[32rem]:w-[3.85rem] @[32rem]:text-[1.35rem]\",\n  tablePlo:\n    \"h-8 w-6 text-[0.65rem] @[64rem]:h-[4.5rem] @[64rem]:w-[3.25rem] @[64rem]:text-lg\",\n  // The replayer hero's 4–5 Omaha cards beside their seat: as big as a phone\n  // leaves room for, board-sized once the table is wide.\n  heroPlo:\n    \"h-9 w-[1.6rem] text-xs @[40rem]:h-11 @[40rem]:w-8 @[40rem]:text-sm @[64rem]:h-[4.5rem] @[64rem]:w-[3.25rem] @[64rem]:text-lg\",\n  tablePlo6:\n    \"h-7 w-5 text-[0.6rem] @[64rem]:h-11 @[64rem]:w-8 @[64rem]:text-sm\",\n};\n\n/**\n * One playing card: solid four-color face, white rank and suit in the\n * top-left, larger rank plus suit in the lower-right. An empty slot is a\n * faint outline so a short board can still reserve the later streets.\n */\nexport function PlayingCard({\n  card,\n  size = \"md\",\n}: {\n  card?: string | null;\n  size?: CardSize | \"tablePlo\" | \"tablePlo6\" | \"heroPlo\";\n}) {\n  const cls = SIZE_CLASS[size];\n  if (!card) {\n    return (\n      <div\n        aria-hidden\n        className={`${cls} shrink-0 rounded-[7px] border border-dashed border-white/15 bg-black/20`}\n      />\n    );\n  }\n  const { rank, sym, bg } = cardFaceParts(card);\n  return (\n    <div\n      aria-label={`${rank}${sym}`}\n      style={cardFaceStyle(bg)}\n      className={`${cls} ${CARD_FACE_CLASS}`}\n    >\n      <CardIndices rank={rank} sym={sym} />\n    </div>\n  );\n}\n\n/** A small inline card: the `playing-card` registry item's MiniCard. */\nexport { MiniCard } from \"@/components/pokerstudy/playing-card\";\n\n/** The hero's hand: two cards for Hold'em, four for PLO, six for PLO6 (which shrink to fit). */\nexport function HoleCards({\n  cards,\n  size = \"md\",\n}: {\n  cards: string[] | null;\n  size?: CardSize;\n}) {\n  const faces = cards && cards.length > 0 ? cards : [null, null];\n  const cardSize: CardSize | \"tablePlo\" | \"tablePlo6\" =\n    size === \"table\" && faces.length > 4\n      ? \"tablePlo6\"\n      : size === \"table\" && faces.length > 2\n        ? \"tablePlo\"\n        : faces.length > 2 && size !== \"xs\" && size !== \"table\" && size !== \"board\"\n          ? downOne(size)\n          : size;\n  return (\n    <div className=\"flex items-center justify-center gap-1\">\n      {faces.map((c, i) => (\n        <PlayingCard key={c ?? `empty-${i}`} card={c} size={cardSize} />\n      ))}\n    </div>\n  );\n}\n\nfunction downOne(size: CardSize): CardSize {\n  if (size === \"lg\") return \"md\";\n  if (size === \"md\") return \"sm\";\n  return \"xs\";\n}\n",
      "type": "registry:component",
      "target": "components/trainer/cards.tsx"
    }
  ],
  "type": "registry:component"
}