{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "card-media",
  "title": "Media card",
  "description": "Styled card: the Media set. 5 decorative card variations (ImageCard, CoverCard, OverlayCard, SplitCard, AvatarCard) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/card-media.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ImageIcon, Play } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Media card family: 5 cards carrying an image or media region. There are no remote images at all (offline and CSP safe): the media area is drawn as a token-coloured placeholder surface plus an inline SVG pattern. Colour comes ONLY from semantic tokens, transparency through color-mix. size = the padding plus radius scale (the same as card-styled). */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst radii: Record<StyledSize, string> = {\n  sm: \"rounded-lg\",\n  md: \"rounded-xl\",\n  lg: \"rounded-2xl\",\n  xl: \"rounded-2xl\",\n}\n\nconst pads: Record<StyledSize, string> = {\n  sm: \"p-4\",\n  md: \"p-5\",\n  lg: \"p-6\",\n  xl: \"p-8\",\n}\n\nconst mediaHeights: Record<StyledSize, string> = {\n  sm: \"h-20\",\n  md: \"h-24\",\n  lg: \"h-28\",\n  xl: \"h-36\",\n}\n\n/* The Overlay variant puts the text on the media, so it wants a taller media area. */\nconst overlayHeights: Record<StyledSize, string> = {\n  sm: \"h-36\",\n  md: \"h-40\",\n  lg: \"h-44\",\n  xl: \"h-52\",\n}\n\ntype Props = React.ComponentProps<\"div\"> & { size?: StyledSize }\n\nconst shell =\n  \"relative w-64 overflow-hidden border border-border bg-card text-card-foreground\"\n\n/* A token-colored placeholder surface: no remote src, only a gradient + an inline\n   SVG pattern + a lucide icon. */\nfunction MediaSurface({\n  className,\n  children,\n}: {\n  className?: string\n  children?: React.ReactNode\n}) {\n  /* The pattern id must be unique per instance, otherwise two cards on the same page share the same SVG id. */\n  const patternId = `ai2-media-grid-${React.useId().replace(/:/g, \"\")}`\n  return (\n    <div\n      aria-hidden=\"true\"\n      className={cn(\n        \"relative flex items-center justify-center overflow-hidden bg-[linear-gradient(135deg,color-mix(in_oklab,var(--color-primary)_30%,transparent),color-mix(in_oklab,var(--color-foreground)_10%,transparent))] text-muted-foreground\",\n        className\n      )}\n    >\n      <svg\n        className=\"pointer-events-none absolute inset-0 size-full text-foreground\"\n        aria-hidden=\"true\"\n      >\n        <defs>\n          <pattern id={patternId} width=\"12\" height=\"12\" patternUnits=\"userSpaceOnUse\">\n            <path\n              d=\"M12 0H0V12\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeOpacity=\"0.14\"\n              strokeWidth=\"1\"\n            />\n          </pattern>\n        </defs>\n        <rect width=\"100%\" height=\"100%\" fill={`url(#${patternId})`} />\n      </svg>\n      <span className=\"relative [&>svg]:size-6 [&>i]:text-2xl [&>i]:leading-none\">\n        {children}\n      </span>\n    </div>\n  )\n}\n\nfunction Heading({ children }: { children: React.ReactNode }) {\n  return <span className=\"text-sm font-semibold text-foreground\">{children}</span>\n}\n\nfunction Sub({ children }: { children: React.ReactNode }) {\n  return (\n    <span className=\"text-xs leading-relaxed text-muted-foreground\">{children}</span>\n  )\n}\n\nconst defaultBody = (\n  <div className=\"flex flex-col gap-1\">\n    <Heading>Card title</Heading>\n    <Sub>A short description that sits under the media region.</Sub>\n  </div>\n)\n\n/* Image: medya bolgesi ustte, metin altta. Klasik dizilim. */\nexport function ImageCard({ className, size = \"md\", children, ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-card\"\n      className={cn(shell, radii[size], className)}\n      {...props}\n    >\n      <MediaSurface className={cn(\"w-full\", mediaHeights[size])}>\n        <ImageIcon />\n      </MediaSurface>\n      <div className={pads[size]}>{children ?? defaultBody}</div>\n    </div>\n  )\n}\n\n/* Cover: full-width cover media with the text panel riding up over it. */\nexport function CoverCard({ className, size = \"md\", children, ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-card\"\n      className={cn(shell, \"bg-surface-2\", radii[size], className)}\n      {...props}\n    >\n      <MediaSurface className={cn(\"w-full\", mediaHeights[size])}>\n        <Play />\n      </MediaSurface>\n      <div className={cn(\"relative -mt-4 rounded-t-xl bg-card\", pads[size])}>\n        {children ?? defaultBody}\n      </div>\n    </div>\n  )\n}\n\n/* Overlay: the text sits on the media and stays readable thanks to a token scrim gradient underneath. */\nexport function OverlayCard({ className, size = \"md\", children, ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-card\"\n      className={cn(shell, radii[size], className)}\n      {...props}\n    >\n      <MediaSurface className={cn(\"w-full\", overlayHeights[size])}>\n        <ImageIcon />\n      </MediaSurface>\n      <div\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 bg-[linear-gradient(to_top,color-mix(in_oklab,var(--color-foreground)_75%,transparent),transparent_70%)]\"\n      />\n      <div className={cn(\"absolute inset-x-0 bottom-0\", pads[size])}>\n        {children ?? (\n          <div className=\"flex flex-col gap-1\">\n            <span className=\"text-sm font-semibold text-background\">Card title</span>\n            <span className=\"text-xs leading-relaxed text-background/80\">\n              Text that sits on the media behind a token scrim.\n            </span>\n          </div>\n        )}\n      </div>\n    </div>\n  )\n}\n\n/* Split: medya solda dar bir serit, metin sagda. Yatay dizilim. */\nexport function SplitCard({ className, size = \"md\", children, ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-card\"\n      className={cn(shell, \"flex w-80 items-stretch\", radii[size], className)}\n      {...props}\n    >\n      <MediaSurface className=\"w-24 shrink-0\">\n        <ImageIcon />\n      </MediaSurface>\n      <div className={cn(\"flex-1\", pads[size])}>{children ?? defaultBody}</div>\n    </div>\n  )\n}\n\n/* Avatar: yuvarlak token placeholder avatar + isim/rol, ortalanmis profil\n   karti. */\nexport function AvatarCard({ className, size = \"md\", children, ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-card\"\n      className={cn(shell, \"text-center\", radii[size], pads[size], className)}\n      {...props}\n    >\n      <div className=\"flex flex-col items-center gap-3\">\n        <span\n          aria-hidden=\"true\"\n          className=\"flex size-14 items-center justify-center rounded-full border border-border bg-[linear-gradient(135deg,color-mix(in_oklab,var(--color-primary)_35%,transparent),color-mix(in_oklab,var(--color-foreground)_12%,transparent))] text-sm font-semibold text-foreground\"\n        >\n          AI\n        </span>\n        {children ?? (\n          <div className=\"flex flex-col gap-1\">\n            <Heading>Full name</Heading>\n            <Sub>Role or title</Sub>\n          </div>\n        )}\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/card-media.tsx"
    }
  ],
  "categories": [
    "styled",
    "card"
  ],
  "type": "registry:component"
}