{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "avatar",
  "type": "registry:ui",
  "title": "Avatar",
  "description": "Rounded profile image with resilient initials fallback and status dot.",
  "dependencies": [
    "clsx",
    "tailwind-merge"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "components/ui/avatar.tsx",
      "content": "import * as React from 'react'\nimport { User } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {\n  src?: string\n  alt?: string\n  fallback?: React.ReactNode\n  icon?: React.ReactNode\n  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n  variant?: 'purple' | 'yellow' | 'pink' | 'orange' | 'cyan' | 'lime' | 'mint' | 'zinc'\n  shape?: 'circle' | 'square'\n  status?: 'online' | 'busy' | 'offline' | 'away'\n  badge?: string | number\n  name?: React.ReactNode\n  description?: React.ReactNode\n}\n\nconst sizeClasses = {\n  xs: 'h-7 w-7 text-[10px]',\n  sm: 'h-9 w-9 text-xs',\n  md: 'h-11 w-11 text-sm',\n  lg: 'h-14 w-14 text-base',\n  xl: 'h-18 w-18 text-xl',\n  '2xl': 'h-24 w-24 text-3xl',\n}\n\nconst iconSizeClasses = {\n  xs: 'h-3.5 w-3.5',\n  sm: 'h-4 w-4',\n  md: 'h-5 w-5',\n  lg: 'h-7 w-7',\n  xl: 'h-9 w-9',\n  '2xl': 'h-12 w-12',\n}\n\nconst variantClasses = {\n  purple: 'bg-rk-lavender text-rk-ink',\n  yellow: 'bg-rk-primary text-rk-ink',\n  pink: 'bg-rk-pink text-rk-ink',\n  orange: 'bg-rk-secondary text-rk-ink',\n  cyan: 'bg-rk-sky text-rk-ink',\n  lime: 'bg-[#A3E635] text-rk-ink',\n  mint: 'bg-rk-success text-rk-ink',\n  zinc: 'bg-rk-canvas text-rk-ink',\n}\n\nconst statusClasses = {\n  online: 'bg-rk-success',\n  busy: 'bg-rk-error',\n  offline: 'bg-[#9CA3AF]',\n  away: 'bg-rk-primary-hover',\n}\n\nexport const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(\n  (\n    {\n      src,\n      alt = '',\n      fallback,\n      icon,\n      size = 'md',\n      variant = 'purple',\n      shape = 'circle',\n      status,\n      badge,\n      name,\n      description,\n      className,\n      ...props\n    },\n    ref\n  ) => {\n    const [hasError, setHasError] = React.useState(false)\n\n    const renderContent = () => {\n      if (src && !hasError) {\n        return (\n          <img\n            src={src}\n            alt={alt}\n            onError={() => setHasError(true)}\n            className=\"h-full w-full object-cover\"\n          />\n        )\n      }\n\n      if (icon) {\n        return React.isValidElement(icon)\n          ? React.cloneElement(icon as React.ReactElement<{ className?: string }>, {\n              className: cn(iconSizeClasses[size], (icon.props as { className?: string })?.className),\n            })\n          : icon\n      }\n\n      if (fallback) {\n        return <span aria-hidden={Boolean(alt)}>{fallback}</span>\n      }\n\n      if (alt) {\n        return <span aria-hidden={Boolean(alt)}>{alt.slice(0, 2).toUpperCase()}</span>\n      }\n\n      return <User className={iconSizeClasses[size]} />\n    }\n\n    const avatarBox = (\n      <div className=\"relative inline-flex shrink-0\">\n        <div\n          className={cn(\n            'flex items-center justify-center overflow-hidden font-display font-black rk-border rk-shadow-sm transition-transform hover:-translate-y-0.5',\n            shape === 'circle' ? 'rounded-full' : 'rounded-2xl',\n            sizeClasses[size],\n            variantClasses[variant]\n          )}\n        >\n          {renderContent()}\n        </div>\n\n        {status && (\n          <span\n            aria-label={status}\n            className={cn(\n              'absolute bottom-0 right-0 rounded-full border-2 border-rk-ink rk-shadow-xs',\n              size === 'xs' || size === 'sm' ? 'h-2.5 w-2.5' : 'h-3.5 w-3.5',\n              statusClasses[status]\n            )}\n          />\n        )}\n\n        {badge !== undefined && (\n          <span className=\"absolute -top-1.5 -right-1.5 flex h-5 min-w-[20px] items-center justify-center rounded-full border-2 border-rk-ink bg-rk-pink px-1 font-mono text-[10px] font-black text-rk-ink rk-shadow-xs\">\n            {badge}\n          </span>\n        )}\n      </div>\n    )\n\n    if (name || description) {\n      return (\n        <div ref={ref} className={cn('inline-flex items-center gap-3', className)} {...props}>\n          {avatarBox}\n          <div className=\"flex flex-col text-left\">\n            {name && <span className=\"font-display text-sm font-extrabold text-rk-ink leading-snug\">{name}</span>}\n            {description && <span className=\"font-sans text-xs font-semibold text-rk-ink/60\">{description}</span>}\n          </div>\n        </div>\n      )\n    }\n\n    return (\n      <div ref={ref} className={cn('inline-flex shrink-0', className)} {...props}>\n        {avatarBox}\n      </div>\n    )\n  }\n)\nAvatar.displayName = 'Avatar'\n\nexport interface AvatarGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n  children: React.ReactNode\n  max?: number\n}\n\nexport const AvatarGroup: React.FC<AvatarGroupProps> = ({ children, max, className, ...props }) => {\n  const childrenArray = React.Children.toArray(children)\n  const displayChildren = max ? childrenArray.slice(0, max) : childrenArray\n  const overflowCount = max ? childrenArray.length - max : 0\n\n  return (\n    <div className={cn('flex items-center -space-x-3.5', className)} {...props}>\n      {displayChildren.map((child, index) => (\n        <div key={index} className=\"relative z-10 transition-transform hover:z-20 hover:-translate-y-1\">\n          {child}\n        </div>\n      ))}\n      {overflowCount > 0 && (\n        <div className=\"relative z-10 flex h-11 w-11 items-center justify-center rounded-full bg-rk-primary font-mono text-xs font-black text-rk-ink rk-border rk-shadow-sm\">\n          +{overflowCount}\n        </div>\n      )}\n    </div>\n  )\n}\n\n",
      "type": "registry:ui",
      "target": "components/ui/avatar.tsx"
    }
  ]
}