{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "avatars-badge",
  "title": "Badge avatars",
  "description": "Styled avatars: the Badge set. 5 decorative avatars variations (NotifyAvatar, StatusRingAvatar, TypingAvatar, NewAvatar, VerifiedAvatar) on the ai2 token system, powered by framer-motion, reduced-motion aware and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "motion@^12.42.2",
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/avatars-badge.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport { motion, useReducedMotion } from \"motion/react\"\nimport { Check } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Badge avatar family: 5 decorative avatars carrying a badge or status. Initials-based (no external image) - a consumer can put an <img> in place of the initials. Colour comes ONLY from tokens, size = the box scale. The badges derive from the danger/success/info/brand tokens. The typing dots bounce with framer-motion; static under reduced-motion. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst box: Record<StyledSize, string> = {\n  sm: \"size-8 text-xs\",\n  md: \"size-10 text-sm\",\n  lg: \"size-12 text-base\",\n  xl: \"size-16 text-lg\",\n}\n\nconst face =\n  \"flex size-full items-center justify-center rounded-full bg-secondary font-medium text-secondary-foreground select-none\"\n\ntype Props = React.ComponentProps<\"div\"> & { size?: StyledSize; initials?: string }\n\n/* Notify: sag-ust kosede danger token sayac rozeti. */\nexport function NotifyAvatar({\n  className,\n  size = \"md\",\n  initials = \"AI\",\n  count = 3,\n  ...props\n}: Props & { count?: number }) {\n  return (\n    <div data-slot=\"styled-avatar\" className={cn(\"relative inline-flex\", box[size], className)} {...props}>\n      <span className={face}>{initials}</span>\n      <span className=\"absolute -right-1 -top-1 flex min-w-4 items-center justify-center rounded-full border-2 border-background bg-danger px-1 text-[0.625rem] font-semibold leading-none text-danger-foreground select-none\">\n        {count > 99 ? \"99+\" : count}\n      </span>\n    </div>\n  )\n}\n\n/* StatusRing: a full success-token ring marking online (different from the Status dot). */\nexport function StatusRingAvatar({ className, size = \"md\", initials = \"AI\", ...props }: Props) {\n  return (\n    <div\n      data-slot=\"styled-avatar\"\n      className={cn(\"relative inline-flex rounded-full ring-2 ring-success ring-offset-2 ring-offset-background\", box[size], className)}\n      {...props}\n    >\n      <span className={face}>{initials}</span>\n    </div>\n  )\n}\n\n/* Typing: alt kosede animasyonlu \"yaziyor\" nokta baloncugu. */\nexport function TypingAvatar({ className, size = \"md\", initials = \"AI\", ...props }: Props) {\n  const reduce = useReducedMotion()\n  return (\n    <div data-slot=\"styled-avatar\" className={cn(\"relative inline-flex\", box[size], className)} {...props}>\n      <span className={face}>{initials}</span>\n      <span className=\"absolute -bottom-1 -right-1 flex items-center gap-0.5 rounded-full border-2 border-background bg-secondary px-1.5 py-1\">\n        {[0, 1, 2].map((i) => (\n          <motion.span\n            key={i}\n            className=\"size-1 rounded-full bg-muted-foreground\"\n            animate={reduce ? undefined : { y: [0, -2, 0], opacity: [0.5, 1, 0.5] }}\n            transition={\n              reduce ? undefined : { duration: 0.9, ease: \"easeInOut\", repeat: Infinity, delay: i * 0.15 }\n            }\n          />\n        ))}\n      </span>\n    </div>\n  )\n}\n\n/* New: sag-ust kosede kucuk \"NEW\" token cipi. */\nexport function NewAvatar({ className, size = \"md\", initials = \"AI\", ...props }: Props) {\n  return (\n    <div data-slot=\"styled-avatar\" className={cn(\"relative inline-flex\", box[size], className)} {...props}>\n      <span className={face}>{initials}</span>\n      <span className=\"absolute -right-1 -top-1 rounded-full border-2 border-background bg-info px-1.5 text-[0.5rem] font-bold uppercase leading-4 tracking-wide text-info-foreground select-none\">\n        New\n      </span>\n    </div>\n  )\n}\n\n/* Verified: sag-alt kosede kucuk check rozeti (info token). */\nexport function VerifiedAvatar({ className, size = \"md\", initials = \"AI\", ...props }: Props) {\n  return (\n    <div data-slot=\"styled-avatar\" className={cn(\"relative inline-flex\", box[size], className)} {...props}>\n      <span className={face}>{initials}</span>\n      <span className=\"absolute -bottom-0.5 -right-0.5 flex size-1/3 items-center justify-center rounded-full border-2 border-background bg-info text-info-foreground [&_svg]:size-2/3\">\n        <Check strokeWidth={3} />\n      </span>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/avatars-badge.tsx"
    }
  ],
  "categories": [
    "styled",
    "avatars"
  ],
  "type": "registry:component"
}