{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "avatar",
  "type": "registry:ui",
  "title": "Avatar",
  "description": "Fluent 2-styled avatar with shadcn APIs. Built on @base-ui/react's Avatar primitive for genuine image-loading state; renders brand-tinted initials as a fallback while the image loads or if it fails.",
  "author": "graundtech <https://github.com/graundtech/fluent2-react-kit>",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "https://fluent2-react-kit.graund.io/r/utils.json"
  ],
  "files": [
    {
      "path": "components/ui/avatar.tsx",
      "type": "registry:ui",
      "target": "components/ui/avatar.tsx",
      "content": "import { Avatar as AvatarPrimitive } from \"@base-ui/react/avatar\";\nimport type { ComponentProps } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Avatar — Fluent 2-styled, shadcn-API avatar.\n *\n * This is the batch's Base UI case (conventions §9): an image-with-fallback\n * loading state is genuine behavior, not something plain markup can express,\n * so the three parts wrap `@base-ui/react/avatar` (`Avatar.Root`,\n * `Avatar.Image`, `Avatar.Fallback` — imported as a namespace from the\n * `@base-ui/react/avatar` subpath, matching the actual export shape in\n * node_modules) instead of a raw `<span>`/`<img>`.\n *\n * `\"use client\"` is intentionally omitted here. Base UI's Root/Image/Fallback\n * modules each carry their own `'use client'` directive at the source level\n * (verified in the compiled package output), so they are already client\n * boundaries on their own. This wrapper file contains no hooks/handlers of\n * its own — it only forwards props into those parts — so it can stay a plain\n * (server-renderable) module per conventions §2: a Server Component tree can\n * render a Client Component child without the parent re-declaring the\n * directive. Confirmed via `pnpm typecheck` + the test suite; add the\n * directive here only if that stops holding true.\n *\n * Aesthetics follow Fluent 2 (32px medium avatar, circular, brand-tinted\n * initials fallback); the prop surface (`Avatar` / `AvatarImage` /\n * `AvatarFallback`, no `size` prop — consumers resize via `className`, e.g.\n * `size-10`) follows the classic shadcn/ui avatar API. Fluent's\n * sized/shape/presence-badge variants are out of scope for this pass — see\n * backlog notes returned alongside this component.\n */\nfunction Avatar({\n  className,\n  ...props\n}: ComponentProps<typeof AvatarPrimitive.Root>) {\n  return (\n    <AvatarPrimitive.Root\n      data-slot=\"avatar\"\n      className={cn(\n        \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AvatarImage({\n  className,\n  ...props\n}: ComponentProps<typeof AvatarPrimitive.Image>) {\n  return (\n    <AvatarPrimitive.Image\n      data-slot=\"avatar-image\"\n      className={cn(\"aspect-square size-full object-cover\", className)}\n      {...props}\n    />\n  );\n}\n\n/**\n * Fluent-inspired brand-tinted initials fallback. Contrast checked against\n * WCAG AA (4.5:1, since 14px/600 does not clear the \"large text\" bold\n * threshold): light `brand-160`/`brand-70` ≈ 5.95:1; dark `brand-40`/`brand-140`\n * ≈ 7.73:1. Both comfortably pass.\n */\nfunction AvatarFallback({\n  className,\n  ...props\n}: ComponentProps<typeof AvatarPrimitive.Fallback>) {\n  return (\n    <AvatarPrimitive.Fallback\n      data-slot=\"avatar-fallback\"\n      className={cn(\n        \"flex size-full items-center justify-center rounded-full bg-brand-160 text-sm font-semibold text-brand-70 select-none\",\n        \"dark:bg-brand-40 dark:text-brand-140\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Avatar, AvatarImage, AvatarFallback };\n"
    }
  ]
}
