{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "chat",
  "title": "Chat",
  "author": "AlgorizeTech",
  "description": "Ask the user to pick one of 4 chat variants: https://avaraui.com/view/chat. This item holds 4 of them as looks of one component (default, minimal, glass, liquid-glass). Skip the question if the user already named one. A complete messaging interface with contact list, conversation pane and composer. Use it as the shell for a support or direct-messaging feature.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/components/custom/blocks/Chat.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n  CheckCheck,\n  Menu,\n  MessageCircle,\n  Mic,\n  MoreVertical,\n  Paperclip,\n  Phone,\n  Search,\n  Send,\n  Video,\n} from \"lucide-react\";\nimport { useEffect, useRef, useState } from \"react\";\n\n// ==========================================\n// VARIANT & COLOR CONFIGURATION\n// ==========================================\nexport type ChatVariant = \"default\" | \"minimal\" | \"glass\" | \"liquid-glass\";\n\n// Added (string & {}) so it accepts arbitrary hex codes without losing IDE autocomplete for the presets\nexport type ChatColor = \"indigo\" | \"rose\" | \"emerald\" | \"zinc\" | (string & {});\n\nexport function LiquidGlassSvgFilter() {\n  return (\n    <>\n      <img\n        src=\"https://res.cloudinary.com/dodndg7ai/image/upload/f_webp,q_auto,w_1200,c_limit/v1790146209/photo-1470071459604-3b5ec3a7fe05-1790146212205.jpg\"\n        alt=\"\"\n        aria-hidden=\"true\"\n        style={{\n          position: \"fixed\",\n          top: \"-9999px\",\n          left: \"-9999px\",\n          width: \"1px\",\n          height: \"1px\",\n          opacity: 0,\n          pointerEvents: \"none\",\n        }}\n      />\n      <svg\n        style={{\n          position: \"fixed\",\n          top: \"-9999px\",\n          left: \"-9999px\",\n          width: 0,\n          height: 0,\n          pointerEvents: \"none\",\n        }}\n        aria-hidden=\"true\"\n      >\n        <defs>\n          <filter\n            id=\"glass-blur\"\n            x=\"0\"\n            y=\"0\"\n            width=\"100%\"\n            height=\"100%\"\n            filterUnits=\"objectBoundingBox\"\n          >\n            <feTurbulence\n              type=\"fractalNoise\"\n              baseFrequency=\"0.003 0.007\"\n              numOctaves=\"1\"\n              result=\"turbulence\"\n            />\n            <feDisplacementMap\n              in=\"SourceGraphic\"\n              in2=\"turbulence\"\n              scale=\"200\"\n              xChannelSelector=\"R\"\n              yChannelSelector=\"G\"\n            />\n          </filter>\n        </defs>\n      </svg>\n    </>\n  );\n}\n\nconst chatVariants: Record<ChatVariant, Record<string, string>> = {\n  default: {\n    wrapper:\n      \"bg-background border border-border rounded-2xl\",\n    sidebar:\n      \"bg-card/90 backdrop-blur-xl border-r border-border\",\n    main: \"bg-background\",\n    header:\n      \"bg-background/80 border-b border-border backdrop-blur-xl\",\n    footer:\n      \"bg-background/80 border-t border-border backdrop-blur-xl\",\n    inputBg: \"bg-muted border border-transparent\",\n    msgThem:\n      \"bg-card text-foreground rounded-2xl rounded-bl-sm border border-border shadow-sm\",\n    msgMe: \"rounded-2xl rounded-br-sm shadow-sm border border-transparent\",\n    composer: \"\",\n  },\n  // Two cards, not one: the contact list and the thread are separate\n  // bordered cards with a gap between them, and the wrapper draws nothing —\n  // so the chat sits on the page as two panels rather than one big card.\n  minimal: {\n    wrapper: \"bg-transparent border-none shadow-none rounded-none gap-4\",\n    sidebar: \"bg-card border border-border rounded-2xl shadow-sm overflow-hidden\",\n    main: \"bg-card border border-border rounded-2xl shadow-sm overflow-hidden\",\n    header: \"bg-transparent border-b border-border\",\n    footer: \"bg-transparent border-t border-border\",\n    inputBg: \"bg-muted border border-transparent\",\n    composer: \"\",\n    msgThem: \"bg-muted text-foreground rounded-2xl rounded-bl-sm\",\n    msgMe: \"rounded-2xl rounded-br-sm shadow-sm\",\n  },\n  glass: {\n    wrapper:\n      \"bg-white/40 dark:bg-black/40 backdrop-blur-2xl border border-white/20 dark:border-white/10 rounded-2xl\",\n    sidebar:\n      \"bg-white/10 dark:bg-black/10 border-r border-white/20 dark:border-white/10\",\n    main: \"bg-transparent\",\n    header:\n      \"bg-white/10 dark:bg-black/10 border-b border-white/20 dark:border-white/10 backdrop-blur-md\",\n    footer:\n      \"bg-white/10 dark:bg-black/10 border-t border-white/20 dark:border-white/10 backdrop-blur-md\",\n    inputBg:\n      \"bg-white/30 dark:bg-black/30 border border-white/30 dark:border-white/10 backdrop-blur-md\",\n    msgThem:\n      \"bg-white/50 dark:bg-black/50 backdrop-blur-md text-foreground border border-white/30 dark:border-white/10 rounded-2xl rounded-bl-sm\",\n    msgMe: \"rounded-2xl rounded-br-sm shadow-lg\",\n    composer: \"\",\n  },\n  \"liquid-glass\": {\n    wrapper:\n      \"bg-transparent border-0 shadow-[0_25px_60px_rgba(0,0,0,0.45)] text-white rounded-[22px] sm:rounded-[28px] [--foreground:#ffffff] [--muted-foreground:rgba(255,255,255,0.75)] [--color-foreground:#ffffff] [--color-muted-foreground:rgba(255,255,255,0.75)]\",\n    sidebar:\n      \"bg-white/[0.07] dark:bg-black/25 border-r border-white/20 dark:border-white/10\",\n    main: \"bg-transparent\",\n    header:\n      \"bg-white/[0.07] dark:bg-black/25 border-b border-white/20 dark:border-white/10\",\n    footer:\n      \"bg-white/[0.07] dark:bg-black/25 border-t border-white/20 dark:border-white/10\",\n    inputBg:\n      \"bg-white/15 dark:bg-black/30 border border-white/20 dark:border-white/10 text-white placeholder:text-white/60\",\n    msgThem:\n      \"bg-white/15 dark:bg-white/10 text-white border border-white/20 dark:border-white/15 rounded-2xl rounded-bl-sm backdrop-blur-md shadow-sm\",\n    msgMe: \"rounded-2xl rounded-br-sm shadow-md border border-white/20\",\n    composer: \"\",\n  },\n};\n\nconst colorThemes: Record<string, Record<string, string>> = {\n  primary: {\n    text: \"text-primary\",\n    bg: \"bg-primary hover:bg-primary/90 text-primary-foreground\",\n    lightBg: \"bg-primary/10 text-primary\",\n    gradient: \"from-primary to-primary/80\",\n    shadow: \"shadow-primary/20\",\n    focusRing:\n      \"focus-within:border-primary/30 focus-within:ring-primary/10 dark:focus-within:ring-primary/20\",\n  },\n  indigo: {\n    text: \"text-indigo-500 dark:text-indigo-400\",\n    bg: \"bg-indigo-500 hover:bg-indigo-600 text-white\",\n    lightBg:\n      \"bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-300\",\n    gradient: \"from-indigo-500 to-purple-600\",\n    shadow: \"shadow-indigo-500/20\",\n    focusRing:\n      \"focus-within:border-indigo-500/30 focus-within:ring-indigo-500/10 dark:focus-within:ring-indigo-500/20\",\n  },\n  rose: {\n    text: \"text-rose-500 dark:text-rose-400\",\n    bg: \"bg-rose-500 hover:bg-rose-600 text-white\",\n    lightBg: \"bg-rose-50 dark:bg-rose-500/10 text-rose-700 dark:text-rose-300\",\n    gradient: \"from-rose-500 to-orange-500\",\n    shadow: \"shadow-rose-500/20\",\n    focusRing:\n      \"focus-within:border-rose-500/30 focus-within:ring-rose-500/10 dark:focus-within:ring-rose-500/20\",\n  },\n  emerald: {\n    text: \"text-emerald-500 dark:text-emerald-400\",\n    bg: \"bg-emerald-500 hover:bg-emerald-600 text-white\",\n    lightBg:\n      \"bg-emerald-50 dark:bg-emerald-500/10 text-emerald-700 dark:text-emerald-300\",\n    gradient: \"from-emerald-500 to-teal-500\",\n    shadow: \"shadow-emerald-500/20\",\n    focusRing:\n      \"focus-within:border-emerald-500/30 focus-within:ring-emerald-500/10 dark:focus-within:ring-emerald-500/20\",\n  },\n  zinc: {\n    text: \"text-zinc-900 dark:text-zinc-100\",\n    bg: \"bg-zinc-900 hover:bg-zinc-800 dark:bg-zinc-100 dark:hover:bg-zinc-200 text-white dark:text-zinc-900\",\n    lightBg: \"bg-zinc-100 dark:bg-zinc-800/50 text-zinc-900 dark:text-zinc-100\",\n    gradient: \"from-zinc-700 to-zinc-900 dark:from-zinc-300 dark:to-zinc-500\",\n    shadow: \"shadow-zinc-900/10 dark:shadow-white/10\",\n    focusRing:\n      \"focus-within:border-zinc-500/30 focus-within:ring-zinc-500/10 dark:focus-within:ring-zinc-500/20\",\n  },\n};\n\n/** One bubble in a conversation. */\nexport type ChatMessage = {\n  id: string | number;\n  text: string;\n  sender: \"me\" | \"them\";\n  time: string;\n  /** Only meaningful on your own messages. */\n  status?: \"delivered\" | \"read\";\n};\n\nexport type Contact = {\n  id: string | number;\n  name: string;\n  message: string;\n  date: string;\n  unread: number;\n  status: \"online\" | \"offline\" | (string & {});\n  avatar?: string;\n  initials?: string;\n  color?: string;\n};\n\nexport type CurrentUser = {\n  avatar: string;\n  status: \"online\" | \"offline\" | (string & {});\n  name?: string;\n};\n\nconst BulletproofAvatar = ({\n  src,\n  initials,\n  color,\n  status,\n  size = 40,\n  statusBorder = \"border-background\",\n}: {\n  src?: string;\n  initials?: string;\n  color?: string;\n  status?: string;\n  size?: number;\n  statusBorder?: string;\n}) => (\n  <div\n    className=\"relative shrink-0 flex-none rounded-full\"\n    style={{ width: size, height: size, minWidth: size, minHeight: size }}\n  >\n    <div className=\"w-full h-full rounded-full overflow-hidden bg-muted flex items-center justify-center shadow-sm\">\n      {src ? (\n        <img\n          src={src}\n          alt=\"Avatar\"\n          className=\"w-full h-full object-cover block m-0 p-0\"\n        />\n      ) : (\n        <div\n          className={`w-full h-full flex items-center justify-center font-semibold text-sm m-0 p-0 tracking-wider ${color}`}\n        >\n          {initials}\n        </div>\n      )}\n    </div>\n    {status && (\n      <span\n        className={`absolute bottom-0 right-0 w-3 h-3 rounded-full border-2 z-10 m-0 p-0 ${statusBorder} ${status === \"online\" ? \"bg-emerald-500\" : status === \"offline\" ? \"bg-muted-foreground\" : \"bg-rose-500\"}`}\n      />\n    )}\n  </div>\n);\n\nexport default function ChatApp({\n  currentUser,\n  contactsData,\n  variant = \"default\",\n  color = \"primary\",\n}: {\n  currentUser: CurrentUser;\n  contactsData: Contact[];\n  variant?: ChatVariant;\n  color?: ChatColor;\n}) {\n  // Custom hex injection logic\n  const isCustomHex = color?.startsWith(\"#\");\n  const customVars = isCustomHex\n    ? ({\n        \"--chat-custom\": color,\n        \"--chat-custom-10\": `${color}1a`,\n        \"--chat-custom-20\": `${color}33`,\n        \"--chat-custom-50\": `${color}80`,\n      } as React.CSSProperties)\n    : {};\n\n  const theme = isCustomHex\n    ? {\n        text: \"text-[var(--chat-custom)]\",\n        bg: \"bg-[var(--chat-custom)] hover:brightness-110 text-white\",\n        lightBg: \"bg-[var(--chat-custom-10)] text-[var(--chat-custom)]\",\n        gradient: \"from-[var(--chat-custom)] to-[var(--chat-custom-50)]\",\n        shadow: \"shadow-[0_4px_14px_0_var(--chat-custom-20)]\",\n        focusRing:\n          \"focus-within:border-[var(--chat-custom-50)] focus-within:ring-2 focus-within:ring-[var(--chat-custom-20)]\",\n      }\n    : colorThemes[color] || colorThemes[\"primary\"];\n\n  const styles = chatVariants[variant];\n\n  // Text sitting on the accent colour. Read it off `theme.bg` instead of\n  // assuming white: `primary` is near-black in light mode and near-white in\n  // dark, so a hardcoded white disappears on one side or the other.\n  const onAccentText =\n    theme.bg\n      .split(\" \")\n      .filter((c) => c.startsWith(\"text-\") || c.startsWith(\"dark:text-\"))\n      .join(\" \") || \"text-primary-foreground\";\n\n  const [searchQuery, setSearchQuery] = useState(\"\");\n  const [activeContact, setActiveContact] = useState<Contact | null>(null);\n  const [isSidebarOpen, setIsSidebarOpen] = useState(true);\n  const [filterType, setFilterType] = useState<\"all\" | \"online\">(\"all\");\n\n  const [contacts, setContacts] = useState(contactsData);\n  const [inputValue, setInputValue] = useState(\"\");\n  const [isTyping, setIsTyping] = useState<string | number | null>(null);\n\n  const chatScrollRef = useRef<HTMLDivElement>(null);\n\n  const [chatHistories, setChatHistories] = useState<Record<string, ChatMessage[]>>(\n    () => {\n      const initialChats: Record<string, ChatMessage[]> = {};\n      contactsData.forEach((contact) => {\n        initialChats[contact.id] = [\n          {\n            id: `initial-${contact.id}`,\n            text: contact.message,\n            sender: \"them\",\n            time: contact.date,\n            status: \"read\",\n          },\n        ];\n      });\n      return initialChats;\n    },\n  );\n\n  useEffect(() => {\n    if (chatScrollRef.current) {\n      chatScrollRef.current.scrollTop = chatScrollRef.current.scrollHeight;\n    }\n  }, [chatHistories, activeContact, isTyping]);\n\n  useEffect(() => {\n    const handleResize = () => {\n      if (window.innerWidth >= 640) {\n        setIsSidebarOpen(true);\n      }\n    };\n    window.addEventListener(\"resize\", handleResize);\n    return () => window.removeEventListener(\"resize\", handleResize);\n  }, []);\n\n  const filteredContacts = contacts.filter((contact) => {\n    const matchesSearch = contact.name\n      .toLowerCase()\n      .includes(searchQuery.toLowerCase());\n    const matchesFilter = filterType === \"all\" || contact.status === \"online\";\n    return matchesSearch && matchesFilter;\n  });\n\n  const handleSendMessage = (e?: React.FormEvent) => {\n    if (e) e.preventDefault();\n    if (!inputValue.trim() || !activeContact) return;\n\n    const currentTime = new Date().toLocaleTimeString([], {\n      hour: \"2-digit\",\n      minute: \"2-digit\",\n    });\n    const newUserMsg: ChatMessage = {\n      id: Date.now(),\n      text: inputValue,\n      sender: \"me\",\n      time: currentTime,\n      status: \"delivered\",\n    };\n\n    setChatHistories((prev) => ({\n      ...prev,\n      [activeContact.id]: [...(prev[activeContact.id] || []), newUserMsg],\n    }));\n    setContacts((prev) =>\n      prev.map((c) =>\n        c.id === activeContact.id\n          ? { ...c, message: inputValue, date: currentTime }\n          : c,\n      ),\n    );\n    setInputValue(\"\");\n    setIsTyping(activeContact.id);\n\n    setTimeout(() => {\n      setIsTyping(null);\n      const replyTime = new Date().toLocaleTimeString([], {\n        hour: \"2-digit\",\n        minute: \"2-digit\",\n      });\n      const replyMsg: ChatMessage = {\n        id: Date.now() + 1,\n        text: \"That sounds perfect! Let's get it done. 🚀\",\n        sender: \"them\",\n        time: replyTime,\n        status: \"read\",\n      };\n\n      setChatHistories((prev) => {\n        const updatedHistory = [...(prev[activeContact.id] || [])];\n        const lastMsg = updatedHistory[updatedHistory.length - 1];\n        if (lastMsg.sender === \"me\") lastMsg.status = \"read\";\n        return { ...prev, [activeContact.id]: [...updatedHistory, replyMsg] };\n      });\n\n      setContacts((prev) =>\n        prev.map((c) =>\n          c.id === activeContact.id\n            ? { ...c, message: replyMsg.text, date: replyTime, unread: 0 }\n            : c,\n        ),\n      );\n    }, 2000);\n  };\n\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n    if (e.key === \"Enter\" && !e.shiftKey) {\n      e.preventDefault();\n      handleSendMessage();\n    }\n  };\n\n  const handleContactClick = (contact: Contact) => {\n    setActiveContact(contact);\n    setContacts((prev) =>\n      prev.map((c) => (c.id === contact.id ? { ...c, unread: 0 } : c)),\n    );\n    if (typeof window !== \"undefined\" && window.innerWidth < 640)\n      setIsSidebarOpen(false);\n  };\n\n  return (\n    <div\n      style={customVars}\n      className={cn(\n        \"w-full max-w-full h-[750px] flex overflow-hidden relative font-sans box-border transition-colors duration-300 isolate [contain:paint] [transform:translateZ(0)]\",\n        styles.wrapper,\n      )}\n    >\n      <LiquidGlassSvgFilter />\n      {variant === \"liquid-glass\" && (\n        <>\n          {/* Inner Clipping Container for Liquid Background Stack */}\n          <div className=\"absolute inset-0 overflow-hidden rounded-[22px] sm:rounded-[28px] pointer-events-none z-0\">\n            {/* Layer 0: Liquid SVG Displaced Wave Background */}\n            <div\n              className=\"absolute -inset-10\"\n              style={{\n                backgroundImage:\n                  'url(\"https://res.cloudinary.com/dodndg7ai/image/upload/f_webp,q_auto,w_1200,c_limit/v1790146209/photo-1470071459604-3b5ec3a7fe05-1790146212205.jpg\")',\n                backgroundSize: \"cover\",\n                backgroundPosition: \"center\",\n                filter: \"url(#glass-blur)\",\n                transform: \"scale(1.1)\",\n              }}\n            />\n\n            {/* Layer 1: Contrast overlay & soft backdrop blur */}\n            <div className=\"absolute inset-0 bg-black/30 dark:bg-black/45 backdrop-blur-[2px]\" />\n\n            {/* Layer 2: Ambient Drop Shadow & Subtle Glow */}\n            <div\n              className=\"absolute inset-0 rounded-[22px] sm:rounded-[28px]\"\n              style={{\n                boxShadow:\n                  \"0 20px 50px rgba(0, 0, 0, 0.4), 0 0 20px rgba(255, 255, 255, 0.08)\",\n              }}\n            />\n          </div>\n\n          {/* Layer 3: Specular Inner Border Highlight */}\n          <div\n            className=\"absolute inset-0 z-40 pointer-events-none rounded-[22px] sm:rounded-[28px] border border-white/40 dark:border-white/15\"\n            style={{\n              boxShadow:\n                \"inset 2px 2px 2px 0 rgba(255, 255, 255, 0.45), inset -2px -2px 2px 0 rgba(255, 255, 255, 0.3)\",\n            }}\n          />\n        </>\n      )}\n\n      {/* === LEFT SIDEBAR === */}\n      <aside\n        className={cn(\n          `absolute sm:relative z-30 w-[300px] sm:w-80 h-full shrink-0 flex-none flex flex-col transition-transform duration-300 ease-in-out overflow-hidden ${isSidebarOpen ? \"translate-x-0\" : \"-translate-x-full sm:translate-x-0\"}`,\n          styles.sidebar,\n          variant === \"liquid-glass\" && \"rounded-l-[22px] sm:rounded-l-[28px] max-sm:rounded-r-2xl max-sm:border-r max-sm:border-white/20\",\n          variant === \"glass\" && \"max-sm:rounded-r-2xl max-sm:bg-white/80 max-sm:dark:bg-black/60 max-sm:backdrop-blur-2xl max-sm:shadow-2xl\",\n          variant === \"default\" && \"max-sm:rounded-r-2xl max-sm:shadow-2xl\",\n        )}\n      >\n        {variant === \"liquid-glass\" && (\n          <div className=\"absolute inset-0 pointer-events-none z-0 overflow-hidden\">\n            {/* Liquid SVG Displaced Wave Background in Sidebar */}\n            <div\n              className=\"absolute -inset-10\"\n              style={{\n                backgroundImage:\n                  'url(\"https://res.cloudinary.com/dodndg7ai/image/upload/f_webp,q_auto,w_1200,c_limit/v1790146209/photo-1470071459604-3b5ec3a7fe05-1790146212205.jpg\")',\n                backgroundSize: \"cover\",\n                backgroundPosition: \"left center\",\n                filter: \"url(#glass-blur)\",\n                transform: \"scale(1.1)\",\n              }}\n            />\n            <div className=\"absolute inset-0 bg-black/35 dark:bg-black/50 backdrop-blur-[2px]\" />\n          </div>\n        )}\n\n        <div className=\"relative z-10 flex flex-col h-full\">\n          <div className=\"pt-6 pb-4 px-5 shrink-0 flex-none min-w-0 box-border\">\n            <div className=\"flex items-center justify-between mb-6\">\n              <h1 className={cn(\n                \"text-xl font-semibold tracking-tight\",\n                variant === \"liquid-glass\" ? \"text-white\" : \"text-foreground\"\n              )}>\n                Messages\n              </h1>\n              <BulletproofAvatar\n                src={currentUser.avatar}\n                status={currentUser.status}\n                size={36}\n                statusBorder={\n                  variant === \"liquid-glass\" || variant === \"glass\"\n                    ? \"border-transparent\"\n                    : \"border-card\"\n                }\n              />\n            </div>\n\n            <div className=\"relative w-full min-w-0 mb-4 group\">\n              <Search className={cn(\n                \"w-4 h-4 absolute left-3.5 top-1/2 -translate-y-1/2 shrink-0 transition-colors\",\n                variant === \"liquid-glass\" ? \"text-white/60 group-focus-within:text-white\" : \"text-muted-foreground group-focus-within:text-muted-foreground\"\n              )} />\n              <input\n                type=\"text\"\n                placeholder=\"Search...\"\n                value={searchQuery}\n                onChange={(e) => setSearchQuery(e.target.value)}\n                className={cn(\n                  \"w-full min-w-0 rounded-xl py-2 pl-10 pr-4 text-sm outline-none text-foreground transition-all placeholder:text-muted-foreground\",\n                  styles.inputBg,\n                  theme.focusRing,\n                )}\n              />\n            </div>\n\n            <div\n              className={cn(\n                \"flex gap-1 p-1 rounded-lg\",\n                variant === \"liquid-glass\"\n                  ? \"bg-white/15 dark:bg-black/30 border border-white/20 dark:border-white/10\"\n                  : variant === \"glass\"\n                    ? \"bg-black/20\"\n                    : \"bg-muted/80\",\n              )}\n            >\n              <button\n                onClick={() => setFilterType(\"all\")}\n                className={cn(\n                  \"flex-1 py-1.5 text-xs font-semibold rounded-md transition-all cursor-pointer\",\n                  filterType === \"all\"\n                    ? variant === \"liquid-glass\"\n                      ? \"bg-white text-zinc-900 font-semibold shadow-sm\"\n                      : \"bg-card text-foreground shadow-sm\"\n                    : variant === \"liquid-glass\"\n                      ? \"text-white/70 hover:text-white\"\n                      : \"text-muted-foreground hover:text-foreground\"\n                )}\n              >\n                All\n              </button>\n              <button\n                onClick={() => setFilterType(\"online\")}\n                className={cn(\n                  \"flex-1 py-1.5 text-xs font-semibold rounded-md transition-all cursor-pointer\",\n                  filterType === \"online\"\n                    ? variant === \"liquid-glass\"\n                      ? \"bg-white text-zinc-900 font-semibold shadow-sm\"\n                      : \"bg-card text-foreground shadow-sm\"\n                    : variant === \"liquid-glass\"\n                      ? \"text-white/70 hover:text-white\"\n                      : \"text-muted-foreground hover:text-foreground\"\n                )}\n              >\n                Online\n              </button>\n            </div>\n          </div>\n\n          <div className=\"flex-1 overflow-y-auto px-2 pb-4 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]\">\n            {filteredContacts.length > 0 ? (\n              filteredContacts.map((contact) => (\n                <div\n                  key={contact.id}\n                  onClick={() => handleContactClick(contact)}\n                  className={cn(\n                    \"px-3 py-2 flex items-center gap-3 cursor-pointer transition-all rounded-xl\",\n                    activeContact?.id === contact.id\n                      ? variant === \"liquid-glass\"\n                        ? \"bg-white text-zinc-900 font-semibold shadow-md\"\n                        : theme.lightBg\n                      : variant === \"liquid-glass\"\n                        ? \"hover:bg-white/10 text-white/80\"\n                        : \"hover:bg-muted/80\"\n                  )}\n                >\n                  <BulletproofAvatar\n                    src={contact.avatar}\n                    initials={contact.initials}\n                    color={contact.color}\n                    status={contact.status}\n                    size={44}\n                    statusBorder={\n                      activeContact?.id === contact.id\n                        ? \"border-transparent\"\n                        : variant === \"liquid-glass\" || variant === \"glass\"\n                          ? \"border-transparent\"\n                          : \"border-card\"\n                    }\n                  />\n                  <div className=\"flex-1 min-w-0 overflow-hidden flex flex-col justify-center\">\n                    <div className=\"flex justify-between items-baseline mb-1 gap-2\">\n                      <h4\n                        className={cn(\n                          \"text-sm mb-0 font-semibold truncate\",\n                          activeContact?.id === contact.id\n                            ? variant === \"liquid-glass\"\n                              ? \"text-zinc-900\"\n                              : theme.text\n                            : variant === \"liquid-glass\"\n                              ? \"text-white\"\n                              : \"text-foreground\"\n                        )}\n                      >\n                        {contact.name}\n                      </h4>\n                      <span\n                        className={cn(\n                          \"text-[10px] font-medium shrink-0\",\n                          activeContact?.id === contact.id\n                            ? variant === \"liquid-glass\"\n                              ? \"text-zinc-700 font-semibold\"\n                              : theme.text\n                            : variant === \"liquid-glass\"\n                              ? \"text-white/60\"\n                              : \"text-muted-foreground\"\n                        )}\n                      >\n                        {contact.date}\n                      </span>\n                    </div>\n                    <div className=\"flex justify-between items-center gap-2\">\n                      <p\n                        className={cn(\n                          \"text-xs mt-0 truncate\",\n                          activeContact?.id === contact.id\n                            ? variant === \"liquid-glass\"\n                              ? \"text-zinc-700 font-medium\"\n                              : theme.text\n                            : variant === \"liquid-glass\"\n                              ? \"text-white/70\"\n                              : \"text-muted-foreground opacity-80\"\n                        )}\n                      >\n                        {contact.message}\n                      </p>\n                      {contact.unread > 0 && (\n                        <span\n                          className={cn(\n                            \"w-4 h-4 rounded-full flex items-center justify-center text-[9px] font-semibold shrink-0 shadow-sm\",\n                            activeContact?.id === contact.id && variant === \"liquid-glass\"\n                              ? \"bg-zinc-900 text-white\"\n                              : cn(\"text-white\", theme.bg)\n                          )}\n                        >\n                          {contact.unread}\n                        </span>\n                      )}\n                    </div>\n                  </div>\n                </div>\n              ))\n            ) : (\n              <div className={cn(\n                \"p-8 text-center text-sm flex flex-col items-center gap-2\",\n                variant === \"liquid-glass\" ? \"text-white/60\" : \"text-muted-foreground\"\n              )}>\n                <MessageCircle className=\"w-8 h-8 opacity-40\" /> No contacts found\n              </div>\n            )}\n          </div>\n        </div>\n      </aside>\n\n      {isSidebarOpen && (\n        <div\n          className={cn(\n            \"absolute inset-0 z-20 sm:hidden cursor-pointer rounded-[inherit] overflow-hidden\",\n            variant === \"liquid-glass\"\n              ? \"bg-black/25 backdrop-blur-[2px]\"\n              : variant === \"glass\"\n                ? \"bg-black/30 backdrop-blur-sm\"\n                : \"bg-black/40 dark:bg-black/60 backdrop-blur-sm\",\n          )}\n          onClick={() => setIsSidebarOpen(false)}\n        />\n      )}\n\n      {/* === MAIN CHAT AREA === */}\n      <main\n        className={cn(\n          \"flex-1 flex flex-col min-w-0 w-full h-full relative z-10 transition-colors duration-300\",\n          styles.main,\n        )}\n      >\n        {!activeContact ? (\n          <div className=\"flex-1 flex flex-col items-center justify-center p-6 text-center\">\n            <div\n              className={cn(\n                \"w-24 h-24 rounded-3xl flex items-center justify-center mb-6 rotate-3 shrink-0 flex-none shadow-xl\",\n                variant === \"liquid-glass\"\n                  ? \"border bg-white/20 border-white/30 text-white backdrop-blur-md shadow-2xl\"\n                  : cn(\"bg-gradient-to-tr border border-border\", theme.gradient, theme.shadow, onAccentText),\n              )}\n            >\n              <MessageCircle className=\"w-10 h-10 -rotate-3\" />\n            </div>\n            <h3 className={cn(\n              \"text-xl font-semibold mb-2\",\n              variant === \"liquid-glass\" ? \"text-white\" : \"text-foreground\"\n            )}>\n              Your Messages\n            </h3>\n            <p className={cn(\n              \"text-sm max-w-xs\",\n              variant === \"liquid-glass\" ? \"text-white/70\" : \"text-muted-foreground\"\n            )}>\n              Select a conversation from the sidebar or start a new one to begin\n              chatting.\n            </p>\n            <button\n              className={cn(\n                \"mt-8 px-6 py-2.5 rounded-full text-sm font-semibold sm:hidden transition-transform active:scale-95 shadow-lg cursor-pointer\",\n                theme.bg,\n                theme.shadow,\n              )}\n              onClick={() => setIsSidebarOpen(true)}\n            >\n              Open Contacts\n            </button>\n          </div>\n        ) : (\n          <>\n            <header\n              className={cn(\n                \"h-[76px] px-4 sm:px-6 flex justify-between items-center shrink-0 flex-none min-w-0 w-full box-border z-10 transition-colors duration-300\",\n                styles.header,\n              )}\n            >\n              <div className=\"flex items-center gap-3 sm:gap-4 min-w-0\">\n                <button\n                  className={cn(\n                    \"sm:hidden p-2 -ml-2 shrink-0 flex-none cursor-pointer\",\n                    variant === \"liquid-glass\" ? \"text-white/80 hover:text-white\" : \"text-muted-foreground hover:text-foreground\"\n                  )}\n                  onClick={() => setIsSidebarOpen(true)}\n                >\n                  <Menu className=\"w-5 h-5\" />\n                </button>\n                <BulletproofAvatar\n                  src={activeContact.avatar}\n                  initials={activeContact.initials}\n                  color={activeContact.color}\n                  status={activeContact.status}\n                  size={42}\n                  statusBorder={\n                    variant === \"liquid-glass\" || variant === \"glass\"\n                      ? \"border-transparent\"\n                      : \"border-background\"\n                  }\n                />\n                <div className=\"min-w-0 flex-1\">\n                  <h2 className={cn(\n                    \"text-base font-semibold leading-tight truncate\",\n                    variant === \"liquid-glass\" ? \"text-white\" : \"text-foreground\"\n                  )}>\n                    {activeContact.name}\n                  </h2>\n                  <div className=\"flex items-center gap-1.5 mt-0.5\">\n                    <span\n                      className={`w-1.5 h-1.5 rounded-full ${activeContact.status === \"online\" ? \"bg-emerald-500\" : \"bg-muted-foreground\"}`}\n                    />\n                    <p className={cn(\n                      \"text-xs font-medium capitalize truncate\",\n                      variant === \"liquid-glass\" ? \"text-white/70\" : \"text-muted-foreground\"\n                    )}>\n                      {isTyping === activeContact.id ? (\n                        <span className={cn(\"animate-pulse\", theme.text)}>\n                          Typing...\n                        </span>\n                      ) : (\n                        activeContact.status\n                      )}\n                    </p>\n                  </div>\n                </div>\n              </div>\n              <div className={cn(\n                \"flex items-center gap-1 sm:gap-2 shrink-0 flex-none ml-2\",\n                variant === \"liquid-glass\" ? \"text-white/80\" : \"text-muted-foreground\"\n              )}>\n                <button className={cn(\n                  \"p-2 rounded-full transition-colors hidden sm:block cursor-pointer\",\n                  variant === \"liquid-glass\" ? \"hover:bg-white/10 hover:text-white\" : \"hover:bg-muted\"\n                )}>\n                  <Phone className=\"w-4 h-4\" />\n                </button>\n                <button className={cn(\n                  \"p-2 rounded-full transition-colors hidden sm:block cursor-pointer\",\n                  variant === \"liquid-glass\" ? \"hover:bg-white/10 hover:text-white\" : \"hover:bg-muted\"\n                )}>\n                  <Video className=\"w-4 h-4\" />\n                </button>\n                <button className={cn(\n                  \"p-2 rounded-full transition-colors cursor-pointer\",\n                  variant === \"liquid-glass\" ? \"hover:bg-white/10 hover:text-white\" : \"hover:bg-muted\"\n                )}>\n                  <MoreVertical className=\"w-4 h-4\" />\n                </button>\n              </div>\n            </header>\n\n            <div\n              ref={chatScrollRef}\n              className=\"flex-1 p-4 sm:p-6 overflow-y-auto overflow-x-hidden w-full scroll-smooth\"\n            >\n              <div className=\"flex flex-col gap-6 w-full pb-2\">\n                {chatHistories[activeContact.id]?.map((msg) => {\n                  const isMe = msg.sender === \"me\";\n                  return (\n                    <div\n                      key={msg.id}\n                      className={`flex items-end gap-2.5 w-full ${isMe ? \"justify-end\" : \"justify-start\"}`}\n                    >\n                      {!isMe && (\n                        <BulletproofAvatar\n                          src={activeContact.avatar}\n                          initials={activeContact.initials}\n                          color={activeContact.color}\n                          size={28}\n                        />\n                      )}\n                      <div\n                        className={`flex flex-col gap-1 max-w-[85%] sm:max-w-[70%] ${isMe ? \"items-end\" : \"items-start\"}`}\n                      >\n                        <div\n                          className={cn(\n                            \"px-4 py-2.5\",\n                            isMe\n                              ? cn(\n                                  styles.msgMe,\n                                  \"bg-gradient-to-br\",\n                                  theme.gradient,\n                                  onAccentText,\n                                )\n                              : styles.msgThem,\n                          )}\n                        >\n                          <p className=\"text-[14px] whitespace-pre-wrap break-words leading-relaxed\">\n                            {msg.text}\n                          </p>\n                        </div>\n                        <div\n                          className={`flex items-center gap-1.5 px-1 ${isMe ? \"flex-row-reverse\" : \"flex-row\"}`}\n                        >\n                          <span className={cn(\n                            \"text-[10px] font-medium\",\n                            variant === \"liquid-glass\" ? \"text-white/60\" : \"text-muted-foreground\"\n                          )}>\n                            {msg.time}\n                          </span>\n                          {isMe && (\n                            <CheckCheck\n                              className={cn(\n                                \"w-3.5 h-3.5\",\n                                msg.status === \"read\"\n                                  ? theme.text\n                                  : variant === \"liquid-glass\" ? \"text-white/50\" : \"text-muted-foreground/50\",\n                              )}\n                            />\n                          )}\n                        </div>\n                      </div>\n                    </div>\n                  );\n                })}\n\n                {isTyping === activeContact.id && (\n                  <div className=\"flex items-end gap-2.5 w-full justify-start animate-in fade-in slide-in-from-bottom-2 duration-300\">\n                    <BulletproofAvatar\n                      src={activeContact.avatar}\n                      initials={activeContact.initials}\n                      color={activeContact.color}\n                      size={28}\n                    />\n                    <div\n                      className={cn(\n                        \"px-4 py-3.5 flex items-center gap-1.5\",\n                        styles.msgThem,\n                      )}\n                    >\n                      <span className={cn(\n                        \"w-1.5 h-1.5 rounded-full animate-bounce [animation-delay:-0.3s]\",\n                        variant === \"liquid-glass\" ? \"bg-white/60\" : \"bg-muted-foreground\"\n                      )} />\n                      <span className={cn(\n                        \"w-1.5 h-1.5 rounded-full animate-bounce [animation-delay:-0.15s]\",\n                        variant === \"liquid-glass\" ? \"bg-white/60\" : \"bg-muted-foreground\"\n                      )} />\n                      <span className={cn(\n                        \"w-1.5 h-1.5 rounded-full animate-bounce\",\n                        variant === \"liquid-glass\" ? \"bg-white/60\" : \"bg-muted-foreground\"\n                      )} />\n                    </div>\n                  </div>\n                )}\n              </div>\n            </div>\n\n            <div\n              className={cn(\n                \"p-3 sm:p-4 shrink-0 flex-none w-full box-border z-10 transition-colors duration-300\",\n                styles.footer,\n              )}\n            >\n              <form\n                onSubmit={handleSendMessage}\n                className={cn(\n                  \"flex items-center gap-2 sm:gap-3 w-full rounded-full transition-all px-4 py-1.5\",\n                  styles.inputBg,\n                  styles.composer,\n                  theme.focusRing,\n                )}\n              >\n                <button\n                  type=\"button\"\n                  className={cn(\n                    \"p-1.5 -ml-1.5 transition-colors shrink-0 cursor-pointer\",\n                    variant === \"liquid-glass\" ? \"text-white/70 hover:text-white\" : \"text-muted-foreground hover:text-foreground\"\n                  )}\n                >\n                  <Paperclip className=\"w-5 h-5\" />\n                </button>\n                <input\n                  type=\"text\"\n                  placeholder=\"Message...\"\n                  value={inputValue}\n                  onChange={(e) => setInputValue(e.target.value)}\n                  onKeyDown={handleKeyDown}\n                  className={cn(\n                    \"flex-1 min-w-0 w-full bg-transparent border-none focus:outline-none text-[15px] text-foreground py-1.5\",\n                    variant === \"liquid-glass\" ? \"placeholder:text-white/40\" : \"placeholder:text-muted-foreground\"\n                  )}\n                />\n                <button\n                  type=\"button\"\n                  className={cn(\n                    \"p-1.5 transition-colors shrink-0 mr-1 cursor-pointer\",\n                    variant === \"liquid-glass\" ? \"text-white/70 hover:text-white\" : \"text-muted-foreground hover:text-foreground\"\n                  )}\n                >\n                  <Mic className=\"w-4 h-4\" />\n                </button>\n                <button\n                  type=\"submit\"\n                  disabled={!inputValue.trim()}\n                  className={cn(\n                    \"w-10 h-10 rounded-full flex items-center justify-center shrink-0 flex-none hover:scale-105 active:scale-95 disabled:opacity-50 disabled:hover:scale-100 disabled:shadow-none transition-all cursor-pointer shadow-md\",\n                    theme.bg,\n                    theme.shadow,\n                  )}\n                >\n                  <Send className=\"w-4 h-4 ml-0.5 text-white\" />\n                </button>\n              </form>\n            </div>\n          </>\n        )}\n      </main>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/custom/blocks/Chat.tsx"
    }
  ],
  "docs": "Named exports: ChatApp, plus Contact and CurrentUser types. A full application layout rather than a single element — it ships demo contacts and messages you replace with your own data. Variants: default | minimal | glass. For individual message bubbles, use `chat-bubble`.",
  "categories": [
    "communication"
  ],
  "type": "registry:component"
}
