{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "avatar-stack",
  "title": "Avatar Stack",
  "author": "AlgorizeTech",
  "description": "A row of overlapping faces that folds the rest into a +N disc and takes a trailing action. Use it as the social-proof cue under a headline or beside a count.",
  "dependencies": [
    "@radix-ui/react-avatar",
    "motion"
  ],
  "registryDependencies": [
    "https://avaraui.com/r/tooltip.json",
    "https://avaraui.com/r/ui-avatar.json",
    "utils"
  ],
  "files": [
    {
      "path": "src/components/custom/blocks/AvatarStackBlock.tsx",
      "content": "\"use client\";\n\nimport React, { useState, useRef, useEffect, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { motion, AnimatePresence, type Transition } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipTrigger,\n} from \"@/components/custom/blocks/TooltipBlock\";\nexport { AvatarImage, AvatarFallback } from \"@/components/custom/ui/avatar\";\n\n// ==========================================\n// AVATAR STACK & AVATAR GROUP\n// A row of overlapping faces — the \"people who…\" cue under a headline or\n// beside a count. Shows up to `max` faces, folds the rest into a \"+N\" disc,\n// and takes an optional trailing action, like a follow button.\n//\n// Includes both the classic fan-out AvatarStack and the spring-shifted\n// interactive AvatarGroup (inspired by animate-ui).\n// ==========================================\n\nexport interface StackAvatar {\n  src: string;\n  alt?: string;\n  fallback?: string;\n  tooltip?: string;\n  name?: string;\n  designation?: string;\n  role?: string;\n}\n\nexport type AvatarStackSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface AvatarProps\n  extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> {\n  src?: string;\n  alt?: string;\n  size?: AvatarStackSize;\n  /** Colour of the ring around the face — match the surface it sits on. */\n  ringClassName?: string;\n}\n\nconst SIZES: Record<AvatarStackSize, { box: string; overlap: string; text: string }> = {\n  sm: { box: \"size-7\", overlap: \"-space-x-2\", text: \"text-[10px]\" },\n  md: { box: \"size-9\", overlap: \"-space-x-2.5\", text: \"text-[11px]\" },\n  lg: { box: \"size-11\", overlap: \"-space-x-3\", text: \"text-xs\" },\n  xl: { box: \"size-12\", overlap: \"-space-x-3\", text: \"text-xs\" },\n};\n\n/**\n * One face, the same disc the stack is built from. Powered by Radix Avatar Root so it\n * supports composable child components like AvatarImage & AvatarFallback, or shorthand src/alt.\n */\nexport const Avatar = React.forwardRef<\n  React.ElementRef<typeof AvatarPrimitive.Root>,\n  AvatarProps\n>(\n  (\n    {\n      src,\n      alt = \"\",\n      size = \"md\",\n      ringClassName = \"ring-background\",\n      className,\n      children,\n      ...props\n    },\n    ref,\n  ) => (\n    <AvatarPrimitive.Root\n      ref={ref}\n      data-slot=\"avatar\"\n      className={cn(\n        \"relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-muted ring-2 cursor-pointer transition-shadow\",\n        SIZES[size]?.box ?? \"size-9\",\n        ringClassName,\n        className,\n      )}\n      {...props}\n    >\n      {src ? (\n        <>\n          <AvatarPrimitive.Image\n            src={src}\n            alt={alt}\n            className=\"aspect-square h-full w-full object-cover\"\n          />\n          <AvatarPrimitive.Fallback className=\"bg-muted flex h-full w-full items-center justify-center rounded-full text-xs font-medium\">\n            {alt ? alt.slice(0, 2).toUpperCase() : \"\"}\n          </AvatarPrimitive.Fallback>\n        </>\n      ) : (\n        children\n      )}\n    </AvatarPrimitive.Root>\n  ),\n);\nAvatar.displayName = \"Avatar\";\n\n// ==========================================\n// AVATAR GROUP (Animate UI Variant)\n// Overlapping avatars that smoothly shift upward with spring physics on hover\n// and a single gliding tooltip that tracks between avatars without dipping.\n// ==========================================\n\nexport interface AvatarGroupTooltipProps {\n  className?: string;\n  children?: React.ReactNode;\n  /** Designation or subtitle displayed underneath the name. */\n  designation?: React.ReactNode;\n  /** Alias for designation. */\n  role?: React.ReactNode;\n  layout?: boolean | \"position\" | \"size\" | \"preserve-aspect\";\n}\n\n/**\n * Marker component placed inside an Avatar to declare its hover tooltip content and designation.\n */\nexport function AvatarGroupTooltip(_props: AvatarGroupTooltipProps) {\n  return null;\n}\nAvatarGroupTooltip.displayName = \"AvatarGroupTooltip\";\n\nexport interface AvatarGroupTooltipArrowProps extends React.HTMLAttributes<HTMLSpanElement> {\n  tipRadius?: number;\n}\n\nexport function AvatarGroupTooltipArrow({ className, ...props }: AvatarGroupTooltipArrowProps) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={cn(\n        \"fill-primary size-3 absolute -bottom-1 left-1/2 -translate-x-1/2 rotate-45 bg-primary pointer-events-none data-[side='bottom']:translate-y-[1px] data-[side='right']:translate-x-[1px] data-[side='left']:translate-x-[-1px] data-[side='top']:translate-y-[-1px]\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\nAvatarGroupTooltipArrow.displayName = \"AvatarGroupTooltipArrow\";\n\nexport interface AvatarGroupProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"translate\"> {\n  children?: React.ReactNode;\n  invertOverlap?: boolean;\n  translate?: string | number;\n  transition?: Transition;\n  tooltipTransition?: Transition;\n  /** Whether to show the hover tooltip. Defaults to true. */\n  showTooltip?: boolean;\n  /** Alias for showTooltip. */\n  tooltip?: boolean;\n}\n\ninterface TooltipItemData {\n  title: React.ReactNode;\n  designation?: React.ReactNode;\n}\n\nexport const AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(\n  (\n    {\n      children,\n      invertOverlap = true,\n      translate = \"-30%\",\n      transition = { type: \"spring\", stiffness: 300, damping: 17 },\n      tooltipTransition = { type: \"spring\", stiffness: 300, damping: 35 },\n      showTooltip = true,\n      tooltip = true,\n      className,\n      ...props\n    },\n    ref,\n  ) => {\n    const isTooltipEnabled = showTooltip && tooltip;\n    const [activeIndex, setActiveIndex] = useState<number | null>(null);\n    const [coords, setCoords] = useState<{ x: number; y: number } | null>(null);\n    const [mounted, setMounted] = useState(false);\n    const itemRefs = useRef<(HTMLDivElement | null)[]>([]);\n\n    useEffect(() => {\n      setMounted(true);\n    }, []);\n\n    const childArray = React.Children.toArray(children);\n    const count = childArray.length;\n    const tooltips: (TooltipItemData | null)[] = [];\n\n    const updateCoords = useCallback((index: number) => {\n      const el = itemRefs.current[index];\n      if (el) {\n        const rect = el.getBoundingClientRect();\n        setCoords({\n          x: rect.left + rect.width / 2 + (typeof window !== \"undefined\" ? window.scrollX : 0),\n          y: rect.top + (typeof window !== \"undefined\" ? window.scrollY : 0),\n        });\n      }\n    }, []);\n\n    const handleMouseEnter = (index: number) => {\n      setActiveIndex(index);\n      updateCoords(index);\n    };\n\n    useEffect(() => {\n      if (activeIndex === null) return;\n      const onScrollOrResize = () => {\n        updateCoords(activeIndex);\n      };\n      window.addEventListener(\"scroll\", onScrollOrResize, true);\n      window.addEventListener(\"resize\", onScrollOrResize);\n      return () => {\n        window.removeEventListener(\"scroll\", onScrollOrResize, true);\n        window.removeEventListener(\"resize\", onScrollOrResize);\n      };\n    }, [activeIndex, updateCoords]);\n\n    return (\n      <>\n        <div\n          ref={ref}\n          data-slot=\"avatar-group\"\n          className={cn(\"relative flex items-center h-12 -space-x-3 my-6\", className)}\n          onMouseLeave={() => setActiveIndex(null)}\n          {...props}\n        >\n          {childArray.map((child, index) => {\n            if (!React.isValidElement(child)) return child;\n\n            let tooltipNode: React.ReactNode = null;\n            let designationNode: React.ReactNode = null;\n            const childChildren = (child.props as any)?.children;\n            let remainingChildren: React.ReactNode = childChildren;\n\n            if (Array.isArray(childChildren)) {\n              const nextArr: React.ReactNode[] = [];\n              React.Children.forEach(childChildren, (nested) => {\n                if (\n                  React.isValidElement(nested) &&\n                  (nested.type === AvatarGroupTooltip ||\n                    (nested.type as any)?.displayName === \"AvatarGroupTooltip\")\n                ) {\n                  tooltipNode = (nested.props as any)?.children;\n                  designationNode = (nested.props as any)?.designation || (nested.props as any)?.role;\n                } else {\n                  nextArr.push(nested);\n                }\n              });\n              remainingChildren = nextArr;\n            } else if (\n              React.isValidElement(childChildren) &&\n              (childChildren.type === AvatarGroupTooltip ||\n                (childChildren.type as any)?.displayName === \"AvatarGroupTooltip\")\n            ) {\n              tooltipNode = (childChildren.props as any)?.children;\n              designationNode = (childChildren.props as any)?.designation || (childChildren.props as any)?.role;\n              remainingChildren = null;\n            }\n\n            tooltips[index] = tooltipNode ? { title: tooltipNode, designation: designationNode } : null;\n\n            const cleanChild = React.cloneElement(child, {\n              ...(child.props as any),\n              children: remainingChildren,\n            });\n\n            const isHovered = activeIndex === index;\n\n            return (\n              <div\n                key={index}\n                ref={(el) => {\n                  itemRefs.current[index] = el;\n                }}\n                data-slot=\"avatar-container\"\n                className=\"relative cursor-pointer select-none outline-none shrink-0\"\n                style={{\n                  zIndex: invertOverlap ? count - index : index + 1,\n                }}\n                onMouseEnter={() => handleMouseEnter(index)}\n                onFocus={() => handleMouseEnter(index)}\n                onPointerMove={() => {\n                  if (activeIndex === index) {\n                    updateCoords(index);\n                  }\n                }}\n              >\n                <motion.div\n                  animate={{ y: isHovered ? translate : 0 }}\n                  transition={transition}\n                >\n                  {cleanChild}\n                </motion.div>\n              </div>\n            );\n          })}\n        </div>\n\n        {/* Floating tooltip portaled outside to document.body to prevent flex layout shifts */}\n        {mounted &&\n          isTooltipEnabled &&\n          typeof document !== \"undefined\" &&\n          createPortal(\n            <AnimatePresence>\n              {activeIndex !== null && coords && tooltips[activeIndex] && (\n                <motion.div\n                  initial={{ opacity: 0, scale: 0.85, x: coords.x, y: coords.y - 4 }}\n                  animate={{\n                    opacity: 1,\n                    scale: 1,\n                    x: coords.x,\n                    y: coords.y - 14,\n                  }}\n                  exit={{ opacity: 0, scale: 0.85, x: coords.x, y: coords.y - 4 }}\n                  transition={tooltipTransition}\n                  style={{\n                    position: \"absolute\",\n                    top: 0,\n                    left: 0,\n                    pointerEvents: \"none\",\n                    zIndex: 9999,\n                  }}\n                >\n                  <div className=\"-translate-x-1/2 -translate-y-full flex flex-col items-center\">\n                    <div className=\"bg-primary text-primary-foreground z-50 w-fit max-w-xs rounded-md px-3.5 py-1.5 text-xs text-balance shadow-md flex items-center justify-center relative\">\n                      <div className=\"overflow-hidden whitespace-nowrap py-0.5\">\n                        <div\n                          key={activeIndex}\n                          className={cn(\n                            \"flex flex-col\",\n                            tooltips[activeIndex]?.designation\n                              ? \"items-start text-left\"\n                              : \"items-center text-center\",\n                          )}\n                        >\n                          <motion.span\n                            initial={{ opacity: 0, y: 6 }}\n                            animate={{ opacity: 1, y: 0 }}\n                            transition={{\n                              duration: 0.36,\n                              ease: [0.16, 1, 0.3, 1],\n                              delay: 0.06,\n                            }}\n                            className=\"font-semibold text-xs leading-tight tracking-tight text-primary-foreground whitespace-nowrap\"\n                          >\n                            {tooltips[activeIndex]?.title}\n                          </motion.span>\n                          {tooltips[activeIndex]?.designation && (\n                            <motion.span\n                              initial={{ opacity: 0, y: 6 }}\n                              animate={{ opacity: 1, y: 0 }}\n                              transition={{\n                                duration: 0.38,\n                                ease: [0.16, 1, 0.3, 1],\n                                delay: 0.18,\n                              }}\n                              className=\"text-[11px] text-primary-foreground/85 leading-tight mt-1 whitespace-nowrap\"\n                            >\n                              {tooltips[activeIndex]?.designation}\n                            </motion.span>\n                          )}\n                        </div>\n                      </div>\n                      <span\n                        className=\"fill-primary size-2.5 absolute -bottom-1 left-1/2 -translate-x-1/2 rotate-45 bg-primary pointer-events-none\"\n                      />\n                    </div>\n                  </div>\n                </motion.div>\n              )}\n            </AnimatePresence>,\n            document.body,\n          )}\n      </>\n    );\n  },\n);\nAvatarGroup.displayName = \"AvatarGroup\";\n\n// ==========================================\n// AVATAR STACK\n// ==========================================\n\nexport interface AvatarStackProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"translate\"> {\n  avatars: StackAvatar[];\n  size?: AvatarStackSize;\n  /** Presentation variant: `default` (smooth fan out) or `shift` (spring lift with tooltip). */\n  variant?: \"default\" | \"shift\";\n  /** Invert overlapping order so the first avatar appears on top. */\n  invertOverlap?: boolean;\n  /** Vertical displacement when an avatar is hovered (e.g. \"-30%\"). */\n  translate?: string | number;\n  /** Faces shown before the rest fold into a count. */\n  max?: number;\n  /** Colour of the gap between faces — match the surface they sit on. */\n  ringClassName?: string;\n  /** A trailing element that shares the stack's size, e.g. a \"+\" button. */\n  action?: React.ReactNode;\n  /** Faces slide apart a little when the stack is hovered. */\n  spreadOnHover?: boolean;\n  /** Pixel distance each subsequent avatar shifts to the right on hover. Defaults to 6. */\n  spreadDistance?: number;\n  /** Transition duration in milliseconds for slide/spread animations. Defaults to 500. */\n  transitionDuration?: number;\n  /** A hovered face rises above its neighbours and grows a touch, so it can be seen whole. */\n  liftOnHover?: boolean;\n  /** Whether to show a tooltip with the avatar's alt text on hover. Defaults to true. */\n  showTooltip?: boolean;\n  /** Alias for showTooltip. */\n  tooltip?: boolean;\n  /** Whether to display an arrow pointer on the tooltip. Defaults to false. */\n  showTooltipArrow?: boolean;\n}\n\nexport const AvatarStack = React.forwardRef<HTMLDivElement, AvatarStackProps>(\n  (\n    {\n      avatars,\n      size = \"md\",\n      variant = \"default\",\n      invertOverlap = true,\n      translate,\n      max = 4,\n      ringClassName = \"ring-background\",\n      action,\n      spreadOnHover = false,\n      spreadDistance = 6,\n      transitionDuration = 500,\n      liftOnHover = true,\n      showTooltip = true,\n      tooltip = true,\n      showTooltipArrow = false,\n      className,\n      ...props\n    },\n    ref,\n  ) => {\n    const [isHovered, setIsHovered] = useState(false);\n    const [hoveredAvatarIndex, setHoveredAvatarIndex] = useState<number | string | null>(null);\n    const s = SIZES[size] ?? SIZES.md;\n    const shown = avatars.slice(0, max);\n    const rest = avatars.length - shown.length;\n    const enableTooltip = showTooltip && tooltip;\n    const dist = spreadDistance;\n\n    // Shift on hover variant (matches animate-ui behavior)\n    if (variant === \"shift\") {\n      return (\n        <AvatarGroup\n          ref={ref}\n          invertOverlap={invertOverlap}\n          translate={translate ?? \"-30%\"}\n          showTooltip={enableTooltip}\n          className={className}\n          {...props}\n        >\n          {shown.map((a, i) => (\n            <Avatar\n              key={i}\n              className={cn(s.box, \"border-3 border-background ring-0 cursor-pointer\", ringClassName)}\n            >\n              <img src={a.src} alt={a.alt ?? a.name ?? \"\"} className=\"h-full w-full object-cover\" />\n              {(enableTooltip && (a.tooltip || a.alt || a.name)) && (\n                <AvatarGroupTooltip designation={a.designation || a.role}>\n                  {a.name || a.tooltip || a.alt}\n                </AvatarGroupTooltip>\n              )}\n            </Avatar>\n          ))}\n          {rest > 0 && (\n            <Avatar\n              className={cn(\n                s.box,\n                \"border-3 border-background ring-0 bg-muted text-muted-foreground font-semibold text-xs flex items-center justify-center cursor-pointer\",\n                ringClassName,\n              )}\n            >\n              +{rest}\n            </Avatar>\n          )}\n          {action}\n        </AvatarGroup>\n      );\n    }\n\n    // Default variant: smooth rightward fan-out spread on hover & z-index elevation on hover\n    return (\n      <div\n        ref={ref}\n        className={cn(\"group flex items-center\", s.overlap, className)}\n        onMouseEnter={() => setIsHovered(true)}\n        onMouseLeave={() => {\n          setIsHovered(false);\n          setHoveredAvatarIndex(null);\n        }}\n        {...props}\n      >\n        {shown.map((a, i) => {\n          const shiftX = isHovered && spreadOnHover ? i * dist : 0;\n          const isThisHovered = hoveredAvatarIndex === i;\n          const currentZIndex = isThisHovered ? 50 : shown.length - i;\n          const shiftY = isThisHovered && translate ? (typeof translate === \"number\" ? `${translate}px` : translate) : \"0px\";\n          const avatarElement = (\n            <span\n              key={a.src}\n              onMouseEnter={() => setHoveredAvatarIndex(i)}\n              onMouseLeave={() => setHoveredAvatarIndex(null)}\n              className={cn(\n                \"relative grid shrink-0 place-items-center overflow-hidden rounded-full ring-2 cursor-pointer bg-muted outline-none\",\n                s.box,\n                ringClassName,\n              )}\n              style={\n                enableTooltip\n                  ? {\n                      transform: liftOnHover && isThisHovered ? \"scale(1.15)\" : \"scale(1)\",\n                      transition: `transform ${transitionDuration}ms cubic-bezier(0.16, 1, 0.3, 1)`,\n                    }\n                  : {\n                      transform: `translateX(${shiftX}px) translateY(${shiftY}) ${liftOnHover && isThisHovered ? \"scale(1.15)\" : \"scale(1)\"}`,\n                      zIndex: currentZIndex,\n                      transition: `transform ${transitionDuration}ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 200ms ease, z-index 0ms`,\n                    }\n              }\n            >\n              <img src={a.src} alt={a.alt ?? \"\"} className=\"h-full w-full object-cover\" />\n            </span>\n          );\n\n          const title = a.name ?? a.alt ?? a.tooltip;\n          const designation = a.designation ?? a.role;\n\n          if (enableTooltip && title) {\n            return (\n              <Tooltip key={a.src} delayDuration={50}>\n                <TooltipTrigger\n                  className={cn(\"inline-block relative outline-none\", isThisHovered && \"!z-50\")}\n                  style={{\n                    transform: `translateX(${shiftX}px) translateY(${shiftY})`,\n                    zIndex: currentZIndex,\n                    transition: `transform ${transitionDuration}ms cubic-bezier(0.16, 1, 0.3, 1), z-index 0ms`,\n                  }}\n                  onMouseEnter={() => setHoveredAvatarIndex(i)}\n                  onMouseLeave={() => setHoveredAvatarIndex(null)}\n                >\n                  {avatarElement}\n                </TooltipTrigger>\n                <TooltipContent\n                  side=\"top\"\n                  showArrow={showTooltipArrow}\n                  animated={showTooltipArrow ? \"pop\" : undefined}\n                >\n                  <div\n                    className={cn(\n                      \"flex flex-col\",\n                      designation ? \"items-start text-left\" : \"items-center text-center\",\n                    )}\n                  >\n                    <span className=\"font-semibold text-xs leading-tight whitespace-nowrap\">{title}</span>\n                    {designation && (\n                      <span className=\"text-[10px] opacity-80 whitespace-nowrap mt-0.5\">{designation}</span>\n                    )}\n                  </div>\n                </TooltipContent>\n              </Tooltip>\n            );\n          }\n\n          return avatarElement;\n        })}\n        {rest > 0 && (() => {\n          const shiftRestX = isHovered && spreadOnHover ? shown.length * dist : 0;\n          const isRestHovered = hoveredAvatarIndex === \"rest\";\n          const shiftRestY = isRestHovered && translate ? (typeof translate === \"number\" ? `${translate}px` : translate) : \"0px\";\n          const restElement = (\n            <span\n              onMouseEnter={() => setHoveredAvatarIndex(\"rest\")}\n              onMouseLeave={() => setHoveredAvatarIndex(null)}\n              className={cn(\n                \"relative grid shrink-0 place-items-center overflow-hidden rounded-full ring-2 cursor-pointer bg-primary font-semibold text-primary-foreground outline-none\",\n                s.box,\n                s.text,\n                ringClassName,\n              )}\n              style={\n                enableTooltip\n                  ? {\n                      transform: liftOnHover && isRestHovered ? \"scale(1.15)\" : \"scale(1)\",\n                      transition: `transform ${transitionDuration}ms cubic-bezier(0.16, 1, 0.3, 1)`,\n                    }\n                  : {\n                      transform: `translateX(${shiftRestX}px) translateY(${shiftRestY}) ${liftOnHover && isRestHovered ? \"scale(1.15)\" : \"scale(1)\"}`,\n                      zIndex: isRestHovered ? 50 : 0,\n                      transition: `transform ${transitionDuration}ms cubic-bezier(0.16, 1, 0.3, 1)`,\n                    }\n              }\n            >\n              +{rest}\n            </span>\n          );\n\n          if (enableTooltip) {\n            return (\n              <Tooltip key=\"rest-count\" delayDuration={50}>\n                <TooltipTrigger\n                  className={cn(\"inline-block relative outline-none\", isRestHovered && \"!z-50\")}\n                  style={{\n                    transform: `translateX(${shiftRestX}px) translateY(${shiftRestY})`,\n                    zIndex: isRestHovered ? 50 : 0,\n                    transition: `transform ${transitionDuration}ms cubic-bezier(0.16, 1, 0.3, 1), z-index 0ms`,\n                  }}\n                  onMouseEnter={() => setHoveredAvatarIndex(\"rest\")}\n                  onMouseLeave={() => setHoveredAvatarIndex(null)}\n                >\n                  {restElement}\n                </TooltipTrigger>\n                <TooltipContent\n                  side=\"top\"\n                  showArrow={showTooltipArrow}\n                  animated={showTooltipArrow ? \"pop\" : undefined}\n                >\n                  <div className=\"flex flex-col items-center text-center\">\n                    <span className=\"font-semibold text-xs leading-tight whitespace-nowrap\">+{rest} more</span>\n                  </div>\n                </TooltipContent>\n              </Tooltip>\n            );\n          }\n\n          return restElement;\n        })()}\n        {action && (\n          <span\n            onMouseEnter={() => setHoveredAvatarIndex(\"action\")}\n            onMouseLeave={() => setHoveredAvatarIndex(null)}\n            className={cn(\n              \"relative grid shrink-0 place-items-center overflow-visible rounded-full ring-0 cursor-pointer\",\n              s.box,\n              hoveredAvatarIndex === \"action\" && \"scale-110\",\n            )}\n            style={{\n              transform: `translateX(${isHovered && spreadOnHover ? (shown.length + (rest > 0 ? 1 : 0)) * dist : 0}px) translateY(${hoveredAvatarIndex === \"action\" && translate ? (typeof translate === \"number\" ? `${translate}px` : translate) : \"0px\"})`,\n              zIndex: hoveredAvatarIndex === \"action\" ? 50 : 0,\n              transition: `transform ${transitionDuration}ms cubic-bezier(0.16, 1, 0.3, 1)`,\n            }}\n          >\n            {action}\n          </span>\n        )}\n      </div>\n    );\n  },\n);\nAvatarStack.displayName = \"AvatarStack\";\n\nexport default AvatarStack;\n",
      "type": "registry:component",
      "target": "components/custom/blocks/AvatarStackBlock.tsx"
    }
  ],
  "docs": "Named export: AvatarStack. `avatars` are { src, alt? }; `size` sm | md | lg; `max` faces before the +N disc; `ringClassName` is the gap colour; `action` renders last at face size; `spreadOnHover` fans the faces apart under the pointer; `liftOnHover` raises the hovered face above its neighbours; `showTooltip` controls hover tooltips.",
  "categories": [
    "data-display"
  ],
  "type": "registry:component"
}
