@helpway/react 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../widget-core/src/client.ts","../../widget-core/src/visitor-id.ts","../../types/src/realtime-events.ts","../../widget-core/src/ws.ts","../../widget-core/src/store.ts","../../widget-core/src/api.ts","../../widget-core/src/theme.ts","../../widget-core/src/events.ts","../../widget-core/src/i18n.ts","../../widget-core/src/utils.ts","../src/provider.tsx","../src/themed/default-widget.tsx","../src/hooks/use-composer.ts","../src/hooks/use-conversations.ts","../src/hooks/use-i18n.ts","../src/hooks/use-presence.ts","../src/hooks/use-timeline.ts","../src/hooks/use-unread.ts","../src/hooks/use-widget.ts","../src/themed/composer.tsx","../src/themed/icons.tsx","../src/themed/message-bubble.tsx","../src/themed/content/simple-markdown.tsx","../src/themed/debug-overlay.tsx","../src/themed/content/content-tab-view.tsx","../src/hooks/use-content-tab.ts","../src/themed/content/content-detail-view.tsx","../src/themed/content/content-list-view.tsx","../src/themed/content/grouped-content-tab-view.tsx","../src/hooks/use-grouped-content-tab.ts","../src/themed/content/tab-icon.tsx","../src/themed/message-list.tsx","#style-inject:#style-inject","../src/themed/styles.css","../src/helpway-widget.tsx","../src/hooks/use-realtime.ts"],"sourcesContent":["import { createTRPCClient, httpBatchLink } from \"@trpc/client\";\nimport { getOrCreateVisitorId } from \"./visitor-id\";\n\n// The real AppRouter lives in apps/api/src/trpc/ but importing it pulls in CF Worker\n// source files. We type the client as `any` here — real type safety is in the\n// Zustand store (widget-react). The tRPC link config is the same at runtime.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type WidgetClient = any;\n\n/**\n * Create a tRPC vanilla client for widget API calls.\n *\n * Visitor identity uses a dual strategy:\n * 1. X-Visitor-Id header (localStorage-based) — always works, even cross-origin\n * 2. hw_visitor cookie (server-set) — additional persistence layer\n *\n * This ensures visitor identity survives 3rd-party cookie blocking\n * (Safari ITP, Firefox ETP, Chrome Privacy Sandbox).\n */\nexport function createWidgetClient(config: {\n\tapiUrl: string;\n\tapiKey: string;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n}): any {\n\treturn createTRPCClient({\n\t\tlinks: [\n\t\t\thttpBatchLink({\n\t\t\t\turl: `${config.apiUrl}/trpc`,\n\t\t\t\theaders() {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t\"X-Public-Key\": config.apiKey,\n\t\t\t\t\t\t\"X-Visitor-Id\": getOrCreateVisitorId(config.apiKey),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\tfetch(url, options) {\n\t\t\t\t\t// credentials: \"include\" sends cookies cross-origin (when not blocked)\n\t\t\t\t\treturn globalThis.fetch(url, { ...options, credentials: \"include\" });\n\t\t\t\t},\n\t\t\t}),\n\t\t],\n\t});\n}\n","/**\n * Per-site visitor identity storage (localStorage).\n *\n * Matches Intercom's `intercom-id-[app_id]` pattern — each publicKey gets\n * its own localStorage slot so a single browser visiting multiple Helpway\n * workspaces never bleeds identities across them.\n *\n * Storage key: `helpway:visitor:<publicKey-suffix>` (last 16 chars of the key,\n * which is always random — see `generatePublicKey` in apps/api/src/lib/id.ts).\n */\n\nconst PREFIX = \"helpway:visitor\";\nconst LEGACY_KEY = \"helpway:visitor-id\";\n\nfunction keyFor(publicKey: string): string {\n\t// Last 16 chars of publicKey — enough uniqueness (2^80 collision space for nanoid alphabet)\n\t// and keeps localStorage key short. Stable for a given site.\n\tconst suffix = publicKey.slice(-16);\n\treturn `${PREFIX}:${suffix}`;\n}\n\nfunction generateId(): string {\n\tconst ts = Date.now().toString(36);\n\tconst rand = Math.random().toString(36).slice(2, 10);\n\treturn `${ts}${rand}`;\n}\n\n/**\n * Get or create a persistent visitor ID scoped to `publicKey`.\n * Returns a stable per-site ID across page loads.\n */\nexport function getOrCreateVisitorId(publicKey: string): string {\n\ttry {\n\t\tconst storageKey = keyFor(publicKey);\n\t\tconst existing = localStorage.getItem(storageKey);\n\t\tif (existing) return existing;\n\n\t\t// One-time migration: if a legacy global key exists AND no per-site key\n\t\t// is set yet, seed this site with it. Keeps returning visitors identified\n\t\t// on their FIRST post-upgrade site load. Subsequent sites get fresh IDs.\n\t\tconst legacy = localStorage.getItem(LEGACY_KEY);\n\t\tif (legacy) {\n\t\t\tlocalStorage.setItem(storageKey, legacy);\n\t\t\tlocalStorage.removeItem(LEGACY_KEY);\n\t\t\treturn legacy;\n\t\t}\n\n\t\tconst id = generateId();\n\t\tlocalStorage.setItem(storageKey, id);\n\t\treturn id;\n\t} catch {\n\t\t// localStorage unavailable (SSR, private mode, quota exceeded)\n\t\treturn generateId();\n\t}\n}\n\n/** Sync the server-assigned canonical visitor ID back into localStorage. */\nexport function syncVisitorId(publicKey: string, serverVisitorId: string): void {\n\ttry {\n\t\tlocalStorage.setItem(keyFor(publicKey), serverVisitorId);\n\t} catch {\n\t\t// ignore\n\t}\n}\n\n/** Clear the visitor ID for a specific site (used by playground \"simulate anonymous\"). */\nexport function clearVisitorId(publicKey: string): void {\n\ttry {\n\t\tlocalStorage.removeItem(keyFor(publicKey));\n\t} catch {\n\t\t// ignore\n\t}\n}\n","import type { Conversation } from \"./conversation\";\nimport type { TimelineItem } from \"./timeline-item\";\n\n// ── Union of all realtime events ──────────────────────────\n\nexport type RealtimeEvent =\n\t| ConnectionEstablishedEvent\n\t| ConversationCreatedEvent\n\t| ConversationUpdatedEvent\n\t| TimelineItemCreatedEvent\n\t| TimelineItemUpdatedEvent\n\t| TimelineItemDeletedEvent\n\t| ConversationSeenEvent\n\t| ConversationTypingEvent\n\t| AiProcessingProgressEvent\n\t| AiProcessingCompletedEvent\n\t| VisitorPresenceChangedEvent;\n\n// ── Connection ────────────────────────────────────────────\n\nexport interface ConnectionEstablishedEvent {\n\ttype: \"connectionEstablished\";\n\tconnectionId: string;\n}\n\n// ── Conversation lifecycle ────────────────────────────────\n\nexport interface ConversationCreatedEvent {\n\ttype: \"conversationCreated\";\n\tconversation: Conversation;\n}\n\nexport interface ConversationUpdatedEvent {\n\ttype: \"conversationUpdated\";\n\tconversationId: string;\n\tupdates: Partial<Conversation>;\n}\n\n// ── Timeline items ────────────────────────────────────────\n\nexport interface TimelineItemCreatedEvent {\n\ttype: \"timelineItemCreated\";\n\tconversationId: string;\n\titem: TimelineItem;\n}\n\nexport interface TimelineItemUpdatedEvent {\n\ttype: \"timelineItemUpdated\";\n\tconversationId: string;\n\titem: TimelineItem;\n}\n\nexport interface TimelineItemDeletedEvent {\n\ttype: \"timelineItemDeleted\";\n\tconversationId: string;\n\titemId: string;\n}\n\n// ── Presence / read receipts ──────────────────────────────\n\nexport interface ConversationSeenEvent {\n\ttype: \"conversationSeen\";\n\tconversationId: string;\n\tuserId?: string;\n\tvisitorId?: string;\n\tlastSeenAt: string;\n}\n\nexport interface ConversationTypingEvent {\n\ttype: \"conversationTyping\";\n\tconversationId: string;\n\tuserId?: string;\n\tvisitorId?: string;\n\tisTyping: boolean;\n}\n\n// ── AI processing indicators ──────────────────────────────\n\nexport interface AiProcessingProgressEvent {\n\ttype: \"aiProcessingProgress\";\n\tconversationId: string;\n\tphase: \"thinking\" | \"searching\" | \"responding\";\n}\n\nexport interface AiProcessingCompletedEvent {\n\ttype: \"aiProcessingCompleted\";\n\tconversationId: string;\n\tstatus: \"success\" | \"error\" | \"skipped\";\n}\n\n// ── Visitor presence ─────────────────────────────────────\n\nexport interface VisitorPresenceChangedEvent {\n\ttype: \"visitorPresenceChanged\";\n\tvisitorId: string;\n\tstatus: \"online\" | \"offline\";\n}\n\n// ── Event type guard helper ───────────────────────────────\n\nexport function isRealtimeEvent(data: unknown): data is RealtimeEvent {\n\treturn (\n\t\ttypeof data === \"object\" &&\n\t\tdata !== null &&\n\t\t\"type\" in data &&\n\t\ttypeof (data as RealtimeEvent).type === \"string\"\n\t);\n}\n","import { type RealtimeEvent, isRealtimeEvent } from \"@helpway/types\";\n\nexport type EventHandler = (event: RealtimeEvent) => void;\n\ninterface WebSocketManagerConfig {\n\tapiUrl: string;\n\tvisitorId: string;\n\twebsiteId: string;\n}\n\n/**\n * WebSocket connection manager for ChatRoom Durable Object.\n * Handles connect, disconnect, auto-reconnect with exponential backoff,\n * ping/pong keep-alive, and event dispatching.\n *\n * Ping gating — visibility-aware:\n * Ping doubles as a presence heartbeat on the server (refreshes KV\n * presence key with a 150s TTL). When the tab is hidden we pause the\n * ping so a forgotten background tab naturally drops offline within\n * ~2.5 minutes. The socket itself stays open; only the heartbeat stops.\n */\nexport class WebSocketManager {\n\tprivate ws: WebSocket | null = null;\n\tprivate handlers = new Set<EventHandler>();\n\tprivate config: WebSocketManagerConfig;\n\tprivate reconnectAttempts = 0;\n\tprivate maxReconnectAttempts = 10;\n\tprivate reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate pingTimer: ReturnType<typeof setInterval> | null = null;\n\tprivate isDestroyed = false;\n\tprivate visibilityHandler: (() => void) | null = null;\n\n\tconstructor(config: WebSocketManagerConfig) {\n\t\tthis.config = config;\n\t\tthis.setupVisibilityListener();\n\t}\n\n\tprivate setupVisibilityListener(): void {\n\t\tif (typeof document === \"undefined\") return;\n\t\tthis.visibilityHandler = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\t// Tab backgrounded — stop heartbeat so KV TTL drops user offline.\n\t\t\t\tthis.stopPing();\n\t\t\t} else if (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\t\t// Tab visible again — resume heartbeat immediately to restore presence.\n\t\t\t\tthis.startPing();\n\t\t\t\tthis.send({ type: \"ping\" });\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener(\"visibilitychange\", this.visibilityHandler);\n\t}\n\n\t/** Update connection parameters (call before connect) */\n\tconfigure(params: Partial<WebSocketManagerConfig>): void {\n\t\tObject.assign(this.config, params);\n\t}\n\n\t/** Connect to the ChatRoom Durable Object WebSocket */\n\tconnect(): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) return;\n\t\t// Reset destroyed flag — allows reconnect after React StrictMode remount\n\t\tthis.isDestroyed = false;\n\n\t\tconst protocol = this.config.apiUrl.startsWith(\"https\") ? \"wss\" : \"ws\";\n\t\tconst base = this.config.apiUrl.replace(/^https?/, protocol);\n\t\tconst params = new URLSearchParams({\n\t\t\ttype: \"visitor\",\n\t\t\tid: this.config.visitorId,\n\t\t\twebsiteId: this.config.websiteId,\n\t\t});\n\n\t\tconst ws = new WebSocket(`${base}/ws?${params}`);\n\n\t\tws.onopen = () => {\n\t\t\tthis.reconnectAttempts = 0;\n\t\t\t// Only start heartbeat if the tab is visible — the visibility\n\t\t\t// listener resumes it automatically when the user returns.\n\t\t\tif (typeof document === \"undefined\" || document.visibilityState === \"visible\") {\n\t\t\t\tthis.startPing();\n\t\t\t}\n\t\t};\n\n\t\tws.onmessage = (event) => {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(event.data as string);\n\t\t\t\tif (data.type === \"pong\") return;\n\t\t\t\tif (isRealtimeEvent(data)) {\n\t\t\t\t\tfor (const handler of this.handlers) {\n\t\t\t\t\t\thandler(data);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Malformed message — ignore\n\t\t\t}\n\t\t};\n\n\t\tws.onclose = () => {\n\t\t\tthis.stopPing();\n\t\t\tthis.ws = null;\n\t\t\tif (!this.isDestroyed) {\n\t\t\t\tthis.scheduleReconnect();\n\t\t\t}\n\t\t};\n\n\t\tws.onerror = () => {\n\t\t\t// onclose will fire after onerror\n\t\t};\n\n\t\tthis.ws = ws;\n\t}\n\n\t/** Disconnect and stop reconnecting */\n\tdisconnect(): void {\n\t\tthis.isDestroyed = true;\n\t\tthis.stopPing();\n\t\tif (this.reconnectTimer) {\n\t\t\tclearTimeout(this.reconnectTimer);\n\t\t\tthis.reconnectTimer = null;\n\t\t}\n\t\tif (this.visibilityHandler && typeof document !== \"undefined\") {\n\t\t\tdocument.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n\t\t\tthis.visibilityHandler = null;\n\t\t}\n\t\tif (this.ws) {\n\t\t\tthis.ws.close(1000, \"Client disconnect\");\n\t\t\tthis.ws = null;\n\t\t}\n\t}\n\n\t/** Send a JSON message through the WebSocket */\n\tsend(data: Record<string, unknown>): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\tthis.ws.send(JSON.stringify(data));\n\t\t}\n\t}\n\n\t/** Send typing indicator */\n\tsendTyping(conversationId: string, isTyping: boolean): void {\n\t\tthis.send({ type: \"typing\", conversationId, isTyping });\n\t}\n\n\t/** Subscribe to realtime events */\n\tonEvent(handler: EventHandler): () => void {\n\t\tthis.handlers.add(handler);\n\t\treturn () => {\n\t\t\tthis.handlers.delete(handler);\n\t\t};\n\t}\n\n\t/** Check if connected */\n\tget isConnected(): boolean {\n\t\treturn this.ws?.readyState === WebSocket.OPEN;\n\t}\n\n\t// ── Private ──────────────────────────────────────────\n\n\tprivate scheduleReconnect(): void {\n\t\tif (this.reconnectAttempts >= this.maxReconnectAttempts) return;\n\n\t\tconst delay = Math.min(1000 * 2 ** this.reconnectAttempts, 30000);\n\t\tthis.reconnectAttempts++;\n\n\t\tthis.reconnectTimer = setTimeout(() => {\n\t\t\tthis.connect();\n\t\t}, delay);\n\t}\n\n\tprivate startPing(): void {\n\t\tthis.stopPing();\n\t\tthis.pingTimer = setInterval(() => {\n\t\t\tthis.send({ type: \"ping\" });\n\t\t}, 25000);\n\t}\n\n\tprivate stopPing(): void {\n\t\tif (this.pingTimer) {\n\t\t\tclearInterval(this.pingTimer);\n\t\t\tthis.pingTimer = null;\n\t\t}\n\t}\n}\n","import type { PublicVisitor, RealtimeEvent, TimelineItem } from \"@helpway/types\";\nimport { createStore } from \"zustand/vanilla\";\n\n// ── Agent Config (from bootstrap) ────────────────────────\n\nexport interface WidgetContentTab {\n\tid: string;\n\tlabel: string;\n\ticon: string;\n\tmodelSlug: string;\n\tdisplay?: {\n\t\tsubtitleField?: string;\n\t\tbadgeField?: string;\n\t\timageField?: string;\n\t\tdateField?: string;\n\t};\n\ttabType?: \"flat\" | \"grouped\";\n\titemsModelSlug?: string;\n\tgroupField?: string;\n}\n\nexport interface AgentConfig {\n\tid: string;\n\tname: string;\n\tavatarUrl: string | null;\n\tavatarPreset: string | null;\n\twelcomeMessage: string | null;\n\tsubtitleText: string | null;\n\tbrandColor: string;\n\twidgetPosition: \"bottom-right\" | \"bottom-left\";\n\tlauncherStyle: \"icon\" | \"bubble\" | \"help\";\n\tbubbleStyle: \"rounded\" | \"square\" | \"pill\";\n\t/** Show/hide Messages tab in widget footer */\n\tshowMessagesTab: boolean;\n\t/** Require visitor to provide email before starting a conversation */\n\trequireVisitorEmail: boolean;\n\t/** Dynamic content tabs from Better i18n Content CMS integration */\n\tcontentTabs: WidgetContentTab[];\n}\n\n// ── Content Cache ──────────────────────────────────────────\n\nexport interface ContentCacheEntry {\n\tdata: unknown;\n\tts: number;\n}\n\nexport const CONTENT_CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\n// ── State Shape ──────────────────────────────────────────\n\nexport interface WidgetState {\n\t// Connection\n\tisReady: boolean;\n\tisConnecting: boolean;\n\n\t// Identity\n\tvisitor: PublicVisitor | null;\n\twebsite: { id: string; name: string; domain: string | null; logoUrl: string | null } | null;\n\n\t// Agent config (from bootstrap)\n\tagentConfig: AgentConfig | null;\n\n\t// Conversations\n\tconversations: ConversationSummary[];\n\tactiveConversationId: string | null;\n\n\t// Messages per conversation\n\tmessages: Map<string, TimelineItem[]>;\n\n\t// Presence\n\ttypingUsers: Map<string, boolean>; // conversationId → someone is typing\n\taiProcessing: Map<string, boolean>; // conversationId → AI is processing\n\n\t// UI state\n\tisOpen: boolean;\n\tisDismissed: boolean;\n\tview: \"home\" | \"conversation\" | \"new\";\n\n\t// Incoming message preview (shown when widget is closed)\n\tincomingPreview: { text: string; conversationId: string; timestamp: number } | null;\n\n\t// Pre-filled text for new conversation (set via global API)\n\tnewConversationPrefill: string | null;\n\n\t// Content cache (survives tab switches — keyed by request params)\n\tcontentCache: Map<string, ContentCacheEntry>;\n}\n\nexport interface ConversationSummary {\n\tid: string;\n\ttitle: string | null;\n\tstatus: string;\n\tlastMessageText: string | null;\n\tlastMessageAt: string | null;\n\tlastMessageSenderType: string | null;\n\tlastMessageSenderName: string | null;\n\tlastMessageSenderImage: string | null;\n\tunreadCount: number;\n}\n\n// ── Actions ──────────────────────────────────────────────\n\nexport interface WidgetActions {\n\t// Lifecycle\n\tsetReady(\n\t\tvisitor: WidgetState[\"visitor\"],\n\t\twebsite: WidgetState[\"website\"],\n\t\tagentConfig?: AgentConfig | null,\n\t): void;\n\tsetConnecting(connecting: boolean): void;\n\n\t// Conversations\n\tsetConversations(conversations: ConversationSummary[]): void;\n\taddConversation(conversation: ConversationSummary): void;\n\tsetActiveConversation(id: string | null): void;\n\n\t// Messages\n\tsetMessages(conversationId: string, items: TimelineItem[]): void;\n\taddMessage(conversationId: string, item: TimelineItem): void;\n\t/**\n\t * Replace a message by ID (used by optimistic send — swaps\n\t * temp `optimistic-*` id for the server-confirmed item).\n\t */\n\treplaceMessage(conversationId: string, oldId: string, item: TimelineItem): void;\n\t/** Remove a message by ID (used for optimistic rollback on send failure) */\n\tremoveMessage(conversationId: string, id: string): void;\n\t/**\n\t * Move an optimistic conversation to its server-assigned ID.\n\t * Copies messages + updates activeConversationId + conversations list.\n\t */\n\tremapConversationId(oldId: string, newId: string): void;\n\n\t// Presence\n\tsetTyping(conversationId: string, isTyping: boolean): void;\n\tsetAiProcessing(conversationId: string, processing: boolean): void;\n\n\t// Identity\n\tupdateVisitorContact(contact: { id: string; name: string | null; email: string | null }): void;\n\n\t// Unread\n\tclearUnread(conversationId: string): void;\n\n\t// UI\n\tsetOpen(open: boolean): void;\n\tsetDismissed(dismissed: boolean): void;\n\tsetView(view: WidgetState[\"view\"]): void;\n\tsetNewConversationPrefill(text: string | null): void;\n\tdismissPreview(): void;\n\n\t// Content cache\n\tsetContentCache(key: string, data: unknown): void;\n\n\t// Realtime\n\thandleRealtimeEvent(event: RealtimeEvent): void;\n}\n\nexport type WidgetStore = WidgetState & WidgetActions;\n\n// ── Store Factory ────────────────────────────────────────\n\nexport function createWidgetStore() {\n\treturn createStore<WidgetStore>((set, get) => ({\n\t\t// Initial state\n\t\tisReady: false,\n\t\tisConnecting: true,\n\t\tvisitor: null,\n\t\twebsite: null,\n\t\tagentConfig: null,\n\t\tconversations: [],\n\t\tactiveConversationId: null,\n\t\tmessages: new Map(),\n\t\ttypingUsers: new Map(),\n\t\taiProcessing: new Map(),\n\t\tisOpen: false,\n\t\tisDismissed: false,\n\t\tview: \"home\",\n\t\tincomingPreview: null,\n\t\tnewConversationPrefill: null,\n\t\tcontentCache: new Map(),\n\n\t\t// ── Lifecycle ────────────────────────────────────\n\n\t\tsetReady(visitor, website, agentConfig) {\n\t\t\tset({\n\t\t\t\tisReady: true,\n\t\t\t\tisConnecting: false,\n\t\t\t\tvisitor,\n\t\t\t\twebsite,\n\t\t\t\tagentConfig: agentConfig ?? null,\n\t\t\t});\n\t\t},\n\n\t\tsetConnecting(connecting) {\n\t\t\tset({ isConnecting: connecting });\n\t\t},\n\n\t\t// ── Conversations ────────────────────────────────\n\n\t\tsetConversations(conversations) {\n\t\t\tset({ conversations });\n\t\t},\n\n\t\taddConversation(conversation) {\n\t\t\tset((state) => ({\n\t\t\t\tconversations: [conversation, ...state.conversations],\n\t\t\t}));\n\t\t},\n\n\t\tsetActiveConversation(id) {\n\t\t\tset({ activeConversationId: id, view: id ? \"conversation\" : \"home\" });\n\t\t},\n\n\t\t// ── Messages ─────────────────────────────────────\n\n\t\tsetMessages(conversationId, items) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.messages);\n\t\t\t\tnext.set(conversationId, items);\n\t\t\t\treturn { messages: next };\n\t\t\t});\n\t\t},\n\n\t\taddMessage(conversationId, item) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.messages);\n\t\t\t\tconst existing = next.get(conversationId) ?? [];\n\t\t\t\t// Deduplicate by ID — WS echoes may arrive twice (once from broadcast,\n\t\t\t\t// once from the mutation response path).\n\t\t\t\tif (existing.some((m) => m.id === item.id)) return state;\n\t\t\t\t// Agent welcome messages are always the opener of a conversation.\n\t\t\t\t// If the first existing item is a visitor message, prepend the welcome\n\t\t\t\t// so the greeting stays above — don't rely on createdAt (client clock\n\t\t\t\t// vs server clock drift can flip the order).\n\t\t\t\tconst isAgentWelcome = !!item.aiAgentId && !item.visitorId;\n\t\t\t\tconst firstIsVisitor = existing[0]?.visitorId != null;\n\t\t\t\tif (isAgentWelcome && firstIsVisitor) {\n\t\t\t\t\tnext.set(conversationId, [item, ...existing]);\n\t\t\t\t\treturn { messages: next };\n\t\t\t\t}\n\t\t\t\t// General case: insert chronologically. Sort only when the newcomer\n\t\t\t\t// is older than the current tail (rare — WS reorders).\n\t\t\t\tconst last = existing[existing.length - 1];\n\t\t\t\tconst isOutOfOrder = last && item.createdAt < last.createdAt;\n\t\t\t\tconst merged = [...existing, item];\n\t\t\t\tif (isOutOfOrder) {\n\t\t\t\t\tmerged.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n\t\t\t\t}\n\t\t\t\tnext.set(conversationId, merged);\n\t\t\t\treturn { messages: next };\n\t\t\t});\n\t\t},\n\n\t\treplaceMessage(conversationId, oldId, item) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.messages);\n\t\t\t\tconst existing = next.get(conversationId) ?? [];\n\t\t\t\t// Race with WS echo: if the real item already landed, just drop the optimistic\n\t\t\t\tif (existing.some((m) => m.id === item.id && m.id !== oldId)) {\n\t\t\t\t\tnext.set(\n\t\t\t\t\t\tconversationId,\n\t\t\t\t\t\texisting.filter((m) => m.id !== oldId),\n\t\t\t\t\t);\n\t\t\t\t\treturn { messages: next };\n\t\t\t\t}\n\t\t\t\t// Preserve the optimistic ID as _stableKey so the React key\n\t\t\t\t// stays constant across the optimistic → real ID swap.\n\t\t\t\tnext.set(\n\t\t\t\t\tconversationId,\n\t\t\t\t\texisting.map((m) =>\n\t\t\t\t\t\tm.id === oldId\n\t\t\t\t\t\t\t? { ...item, _stableKey: (m as unknown as { _stableKey?: string })._stableKey ?? oldId }\n\t\t\t\t\t\t\t: m,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn { messages: next };\n\t\t\t});\n\t\t},\n\n\t\tremoveMessage(conversationId, id) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.messages);\n\t\t\t\tconst existing = next.get(conversationId);\n\t\t\t\tif (!existing) return state;\n\t\t\t\tnext.set(\n\t\t\t\t\tconversationId,\n\t\t\t\t\texisting.filter((m) => m.id !== id),\n\t\t\t\t);\n\t\t\t\treturn { messages: next };\n\t\t\t});\n\t\t},\n\n\t\tremapConversationId(oldId, newId) {\n\t\t\tset((state) => {\n\t\t\t\t// Merge messages from tempId + newId — WS echo may have inserted\n\t\t\t\t// items under the real id BEFORE the createConversation mutation\n\t\t\t\t// resolved. Dedupe by id so we don't lose the WS-delivered items.\n\t\t\t\tconst nextMessages = new Map(state.messages);\n\t\t\t\tconst tempItems = nextMessages.get(oldId) ?? [];\n\t\t\t\tconst existingItems = nextMessages.get(newId) ?? [];\n\t\t\t\tconst tempRewritten = tempItems.map((m) => ({ ...m, conversationId: newId }));\n\t\t\t\tconst isAgentMsg = (m: TimelineItem) =>\n\t\t\t\t\t!!m.aiAgentId && !m.visitorId && !m.userId;\n\t\t\t\t// Prefer the seed welcome that came in via the temp conversation.\n\t\t\t\t// Keeping its DOM node stable is the whole point of openNewConversation\n\t\t\t\t// seeding; if we let the server-welcome (different id, same text)\n\t\t\t\t// take its slot, React unmounts the seed bubble and the animation\n\t\t\t\t// replays — exactly the \"git-gel\" the seed exists to prevent.\n\t\t\t\tconst seen = new Set<string>();\n\t\t\t\tconst merged: TimelineItem[] = [];\n\t\t\t\tlet keptAgentWelcome = false;\n\t\t\t\tfor (const m of tempRewritten) {\n\t\t\t\t\tif (seen.has(m.id)) continue;\n\t\t\t\t\tseen.add(m.id);\n\t\t\t\t\tmerged.push(m);\n\t\t\t\t\tif (isAgentMsg(m) && merged.length === 1) keptAgentWelcome = true;\n\t\t\t\t}\n\t\t\t\tfor (const m of existingItems) {\n\t\t\t\t\tif (seen.has(m.id)) continue;\n\t\t\t\t\t// Drop server's welcome echo if we already kept the seed welcome.\n\t\t\t\t\tif (isAgentMsg(m) && keptAgentWelcome) continue;\n\t\t\t\t\tseen.add(m.id);\n\t\t\t\t\tmerged.push(m);\n\t\t\t\t}\n\t\t\t\tnextMessages.delete(oldId);\n\t\t\t\tnextMessages.set(newId, merged);\n\n\t\t\t\t// Dedupe conversation list — WS conversationCreated may have\n\t\t\t\t// prepended newId already; in that case drop the temp entry.\n\t\t\t\tconst hasNewId = state.conversations.some((c) => c.id === newId);\n\t\t\t\tconst conversations = hasNewId\n\t\t\t\t\t? state.conversations.filter((c) => c.id !== oldId)\n\t\t\t\t\t: state.conversations.map((c) => (c.id === oldId ? { ...c, id: newId } : c));\n\n\t\t\t\treturn {\n\t\t\t\t\tmessages: nextMessages,\n\t\t\t\t\tconversations,\n\t\t\t\t\tactiveConversationId:\n\t\t\t\t\t\tstate.activeConversationId === oldId ? newId : state.activeConversationId,\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\n\t\t// ── Presence ─────────────────────────────────────\n\n\t\tsetTyping(conversationId, isTyping) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.typingUsers);\n\t\t\t\tnext.set(conversationId, isTyping);\n\t\t\t\treturn { typingUsers: next };\n\t\t\t});\n\t\t},\n\n\t\tsetAiProcessing(conversationId, processing) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.aiProcessing);\n\t\t\t\tnext.set(conversationId, processing);\n\t\t\t\treturn { aiProcessing: next };\n\t\t\t});\n\t\t},\n\n\t\t// ── Identity ─────────────────────────────────────\n\n\t\tupdateVisitorContact(contact) {\n\t\t\tset((state) => ({\n\t\t\t\tvisitor: state.visitor ? { ...state.visitor, contact } : state.visitor,\n\t\t\t}));\n\t\t},\n\n\t\t// ── Unread ───────────────────────────────────────\n\n\t\tclearUnread(conversationId) {\n\t\t\tset((s) => ({\n\t\t\t\tconversations: s.conversations.map((c) =>\n\t\t\t\t\tc.id === conversationId ? { ...c, unreadCount: 0 } : c,\n\t\t\t\t),\n\t\t\t}));\n\t\t},\n\n\t\t// ── UI ───────────────────────────────────────────\n\n\t\tsetOpen(open) {\n\t\t\tset((s) => ({\n\t\t\t\tisOpen: open,\n\t\t\t\tincomingPreview: open ? null : s.incomingPreview,\n\t\t\t}));\n\t\t},\n\n\t\tsetDismissed(dismissed) {\n\t\t\tset({ isDismissed: dismissed });\n\t\t},\n\n\t\tsetView(view) {\n\t\t\tset({ view });\n\t\t},\n\n\t\tsetNewConversationPrefill(text) {\n\t\t\tset({ newConversationPrefill: text });\n\t\t},\n\n\t\tdismissPreview() {\n\t\t\tset({ incomingPreview: null });\n\t\t},\n\n\t\t// ── Content Cache ────────────────────────────────\n\n\t\tsetContentCache(key, data) {\n\t\t\tget().contentCache.set(key, { data, ts: Date.now() });\n\t\t},\n\n\t\t// ── Realtime Event Handler ───────────────────────\n\n\t\thandleRealtimeEvent(event) {\n\t\t\tconst state = get();\n\n\t\t\tswitch (event.type) {\n\t\t\t\tcase \"timelineItemCreated\": {\n\t\t\t\t\t// Only add public messages (widget shouldn't see private notes)\n\t\t\t\t\tif (event.item.visibility === \"public\") {\n\t\t\t\t\t\t// When the widget seeded a local welcome bubble (openNewConversation)\n\t\t\t\t\t\t// the server's createConversation path ALSO emits its own welcome\n\t\t\t\t\t\t// timeline item. The *only* duplicate we care about is the opener:\n\t\t\t\t\t\t// a timeline that holds exactly the seed welcome and nothing else,\n\t\t\t\t\t\t// where an agent-authored WS event with a different id would\n\t\t\t\t\t\t// double-render. If the visitor has already sent a message (list\n\t\t\t\t\t\t// length ≥ 2), every incoming agent item is a genuine AI reply and\n\t\t\t\t\t\t// MUST be rendered — otherwise the visitor never sees the answer.\n\t\t\t\t\t\tconst isAgentAuthored =\n\t\t\t\t\t\t\t!!event.item.aiAgentId &&\n\t\t\t\t\t\t\t!event.item.visitorId &&\n\t\t\t\t\t\t\t!event.item.userId;\n\t\t\t\t\t\tconst existing = state.messages.get(event.conversationId);\n\t\t\t\t\t\tconst seedId = existing?.[0]?.id;\n\t\t\t\t\t\tconst isSeedWelcomeEcho =\n\t\t\t\t\t\t\tisAgentAuthored &&\n\t\t\t\t\t\t\t!!existing &&\n\t\t\t\t\t\t\texisting.length === 1 &&\n\t\t\t\t\t\t\ttypeof seedId === \"string\" &&\n\t\t\t\t\t\t\tseedId.startsWith(\"seed-welcome-\") &&\n\t\t\t\t\t\t\tseedId !== event.item.id;\n\t\t\t\t\t\tif (isSeedWelcomeEcho) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.addMessage(event.conversationId, event.item);\n\t\t\t\t\t}\n\t\t\t\t\t// Clear typing/processing indicators as soon as the AI message arrives\n\t\t\t\t\t// (don't wait for aiProcessingCompleted which comes later after auto-title etc.)\n\t\t\t\t\tif (event.item.aiAgentId) {\n\t\t\t\t\t\tstate.setAiProcessing(event.conversationId, false);\n\t\t\t\t\t\tstate.setTyping(event.conversationId, false);\n\t\t\t\t\t}\n\t\t\t\t\t// Update conversation preview + unread count\n\t\t\t\t\tif (event.item.type === \"message\" && event.item.text) {\n\t\t\t\t\t\tconst isIncoming = !event.item.visitorId; // team or AI message\n\t\t\t\t\t\tconst currentState = get();\n\t\t\t\t\t\tconst isViewingThis =\n\t\t\t\t\t\t\tcurrentState.isOpen && currentState.activeConversationId === event.conversationId;\n\n\t\t\t\t\t\tset((s) => ({\n\t\t\t\t\t\t\tconversations: s.conversations.map((c) =>\n\t\t\t\t\t\t\t\tc.id === event.conversationId\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t...c,\n\t\t\t\t\t\t\t\t\t\t\tlastMessageText: event.item.text,\n\t\t\t\t\t\t\t\t\t\t\tlastMessageAt: event.item.createdAt,\n\t\t\t\t\t\t\t\t\t\t\t// Increment unread if incoming and not actively viewing\n\t\t\t\t\t\t\t\t\t\t\t...(isIncoming && !isViewingThis ? { unreadCount: c.unreadCount + 1 } : {}),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: c,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t// Show preview bubble if widget is closed and message is incoming\n\t\t\t\t\t\t\t...(isIncoming && !currentState.isOpen\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tincomingPreview: {\n\t\t\t\t\t\t\t\t\t\t\ttext: event.item.text ?? \"\",\n\t\t\t\t\t\t\t\t\t\t\tconversationId: event.conversationId,\n\t\t\t\t\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t}));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"conversationUpdated\": {\n\t\t\t\t\tset((s) => ({\n\t\t\t\t\t\tconversations: s.conversations.map((c) =>\n\t\t\t\t\t\t\tc.id === event.conversationId ? { ...c, ...event.updates } : c,\n\t\t\t\t\t\t),\n\t\t\t\t\t}));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"conversationTyping\": {\n\t\t\t\t\t// Only show typing for non-visitor (team/AI typing)\n\t\t\t\t\tif (!event.visitorId) {\n\t\t\t\t\t\tstate.setTyping(event.conversationId, event.isTyping);\n\t\t\t\t\t\t// Auto-clear after 5 seconds\n\t\t\t\t\t\tif (event.isTyping) {\n\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\tstate.setTyping(event.conversationId, false);\n\t\t\t\t\t\t\t}, 5000);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"aiProcessingProgress\": {\n\t\t\t\t\t// Track AI processing separately for distinct UI indicator\n\t\t\t\t\tstate.setAiProcessing(event.conversationId, true);\n\t\t\t\t\tstate.setTyping(event.conversationId, true);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"aiProcessingCompleted\": {\n\t\t\t\t\tstate.setAiProcessing(event.conversationId, false);\n\t\t\t\t\tstate.setTyping(event.conversationId, false);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"conversationCreated\": {\n\t\t\t\t\t// Race-safe insert: WS may arrive before OR after the HTTP\n\t\t\t\t\t// createConversation response. If after, remapConversationId\n\t\t\t\t\t// already renamed tempId → realId, so the entry exists.\n\t\t\t\t\t// If before, we prepend here; the later remap call hits the\n\t\t\t\t\t// `hasNewId=true` branch and drops the temp entry.\n\t\t\t\t\tconst conv = event.conversation as unknown as {\n\t\t\t\t\t\tid: string;\n\t\t\t\t\t\ttitle: string | null;\n\t\t\t\t\t\tstatus: string;\n\t\t\t\t\t\tlastMessageText?: string | null;\n\t\t\t\t\t\tlastMessageAt?: string | null;\n\t\t\t\t\t\tlastMessageSenderType?: string | null;\n\t\t\t\t\t};\n\t\t\t\t\tconst alreadyPresent = state.conversations.some((c) => c.id === conv.id);\n\t\t\t\t\tif (alreadyPresent) break;\n\t\t\t\t\tstate.addConversation({\n\t\t\t\t\t\tid: conv.id,\n\t\t\t\t\t\ttitle: conv.title,\n\t\t\t\t\t\tstatus: conv.status,\n\t\t\t\t\t\tlastMessageText: conv.lastMessageText ?? null,\n\t\t\t\t\t\tlastMessageAt: conv.lastMessageAt ?? null,\n\t\t\t\t\t\tlastMessageSenderType: conv.lastMessageSenderType ?? null,\n\t\t\t\t\t\tlastMessageSenderName: null,\n\t\t\t\t\t\tlastMessageSenderImage: null,\n\t\t\t\t\t\tunreadCount: 0,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t}));\n}\n","import type { StoreApi } from \"zustand/vanilla\";\nimport type { Listener, WidgetEventEmitter, WidgetEventName, WidgetEvents } from \"./events\";\nimport type { WidgetStore } from \"./store\";\nimport { clearVisitorId } from \"./visitor-id\";\n\n/**\n * The programmatic widget API — all the methods consumers can call\n * once the widget is mounted. Returned by `createHelpwayAPI()`.\n *\n * The global `window.Helpway` is the *callable* wrapper around this\n * (see `HelpwayAPI` and `installCallable`).\n */\nexport interface HelpwayMethods {\n\t/** Open the widget panel */\n\topen(): void;\n\t/** Close the widget panel */\n\tclose(): void;\n\t/** Toggle the widget panel open/closed */\n\ttoggle(): void;\n\t/** Dismiss the widget entirely (launcher + panel). Use for page-specific hiding. */\n\tdismiss(): void;\n\t/** Show the widget again after dismiss */\n\tshow(): void;\n\t/** Full reset: clear session, cookies, visitor identity */\n\tshutdown(): void;\n\t/** Identify the visitor (link to contact) */\n\tidentify(data: {\n\t\texternalId: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}): Promise<void>;\n\t/** Open a new conversation, optionally pre-filling the message */\n\tnewConversation(prefill?: string): void;\n\t/** Open a specific conversation by ID */\n\topenConversation(id: string): void;\n\t/** Get the current unread count */\n\treadonly unreadCount: number;\n\t/** Whether the widget panel is currently open */\n\treadonly isOpen: boolean;\n\t/** Subscribe to widget events */\n\ton<K extends WidgetEventName>(event: K, fn: Listener<WidgetEvents[K]>): void;\n\t/** Unsubscribe from widget events */\n\toff<K extends WidgetEventName>(event: K, fn: Listener<WidgetEvents[K]>): void;\n}\n\n/**\n * The global `window.Helpway` shape: callable (Intercom-style snippet API)\n * AND object (typed methods). Build one of these from a `HelpwayMethods`\n * via `installCallable()`.\n */\nexport interface HelpwayAPI extends HelpwayMethods {\n\t(command: string, ...args: unknown[]): unknown;\n}\n\n/**\n * Install a callable wrapper around any methods object onto `window.Helpway`,\n * draining any calls that the snippet stub queued before the widget mounted.\n * Returns the callable so callers can compare identities on cleanup.\n *\n * Generic in `T` so both the rich `HelpwayMethods` (from widget-react) and\n * the slimmer script-tag API (from widget-embed) can use the same plumbing.\n */\nexport function installCallable<T extends object>(\n\tmethods: T,\n): T & ((command: string, ...args: unknown[]) => unknown) {\n\tconst dispatch = (command: string, ...args: unknown[]): unknown => {\n\t\tconst fn = (methods as unknown as Record<string, unknown>)[command];\n\t\tif (typeof fn === \"function\") {\n\t\t\treturn (fn as (...a: unknown[]) => unknown)(...args);\n\t\t}\n\t\tconsole.warn(`[Helpway] Unknown command: ${command}`);\n\t\treturn undefined;\n\t};\n\tconst callable = Object.assign(dispatch, methods);\n\tconst previous = window.Helpway as { q?: unknown[][] } | undefined;\n\twindow.Helpway = callable as unknown as HelpwayAPI;\n\tconst queue = previous?.q;\n\tif (queue?.length) {\n\t\tfor (const entry of queue) {\n\t\t\ttry {\n\t\t\t\tdispatch(...(entry as [string, ...unknown[]]));\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[Helpway] queued call failed:\", err);\n\t\t\t}\n\t\t}\n\t}\n\treturn callable;\n}\n\nexport function createHelpwayAPI(deps: {\n\tstore: StoreApi<WidgetStore>;\n\temitter: WidgetEventEmitter;\n\tidentify: (data: {\n\t\texternalId: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}) => Promise<void>;\n\tapiKey: string;\n}): HelpwayMethods {\n\tconst { store, emitter, identify, apiKey } = deps;\n\n\treturn {\n\t\topen() {\n\t\t\tstore.getState().setOpen(true);\n\t\t\tstore.getState().setDismissed(false);\n\t\t},\n\n\t\tclose() {\n\t\t\tstore.getState().setOpen(false);\n\t\t},\n\n\t\ttoggle() {\n\t\t\tconst s = store.getState();\n\t\t\tif (s.isDismissed) {\n\t\t\t\ts.setDismissed(false);\n\t\t\t\ts.setOpen(true);\n\t\t\t\temitter.emit(\"show\");\n\t\t\t} else {\n\t\t\t\ts.setOpen(!s.isOpen);\n\t\t\t}\n\t\t},\n\n\t\tdismiss() {\n\t\t\tstore.getState().setOpen(false);\n\t\t\tstore.getState().setDismissed(true);\n\t\t\temitter.emit(\"dismiss\");\n\t\t},\n\n\t\tshow() {\n\t\t\tstore.getState().setDismissed(false);\n\t\t\temitter.emit(\"show\");\n\t\t},\n\n\t\tshutdown() {\n\t\t\tstore.getState().setOpen(false);\n\t\t\tstore.getState().setDismissed(false);\n\t\t\tclearVisitorId(apiKey);\n\t\t\tif (typeof document !== \"undefined\") {\n\t\t\t\tdocument.cookie = \"hw_visitor=; Path=/; Max-Age=0\";\n\t\t\t}\n\t\t},\n\n\t\tidentify,\n\n\t\tnewConversation(prefill?: string) {\n\t\t\tconst s = store.getState();\n\t\t\ts.setDismissed(false);\n\t\t\ts.setOpen(true);\n\t\t\ts.setNewConversationPrefill(prefill ?? \"\");\n\t\t},\n\n\t\topenConversation(id: string) {\n\t\t\tconst s = store.getState();\n\t\t\ts.setDismissed(false);\n\t\t\ts.setActiveConversation(id);\n\t\t\ts.setOpen(true);\n\t\t},\n\n\t\tget unreadCount() {\n\t\t\treturn store.getState().conversations.reduce((sum, c) => sum + c.unreadCount, 0);\n\t\t},\n\n\t\tget isOpen() {\n\t\t\treturn store.getState().isOpen;\n\t\t},\n\n\t\ton(event, fn) {\n\t\t\temitter.on(event, fn);\n\t\t},\n\n\t\toff(event, fn) {\n\t\t\temitter.off(event, fn);\n\t\t},\n\t};\n}\n","/**\n * Widget theming — typed surface over the CSS custom properties baked\n * into the default themed widget. Consumers pass a `WidgetTheme` object;\n * `applyTheme` writes the values onto the host element so the cascade\n * picks them up inside the Shadow DOM.\n *\n * Common cases (color, position, radius) get their own first-class\n * fields. Anything else can still be set via `cssVariables` — it's a\n * raw passthrough for custom var names we don't model yet.\n *\n * **Note for SDK consumers:** prefer dashboard-driven theming when you\n * can — changes go live without a redeploy. This API is for runtime-\n * resolved values (multi-tenant, dark/light sync with the host app).\n *\n * @see https://helpway.ai/docs/customization for the full reference,\n * the dashboard config UI, and the multi-tenant example.\n */\n\nexport type WidgetPosition = \"bottom-right\" | \"bottom-left\";\n\nexport interface WidgetTheme {\n\t/** Launcher background + accent color. Hover variant is auto-derived. */\n\tprimaryColor?: string;\n\t/** Text/icon color rendered ON TOP of `primaryColor`. Defaults to white. */\n\tonPrimaryColor?: string;\n\t/** Visitor (outgoing) message bubble background. Defaults to `primaryColor`. */\n\tbubbleColor?: string;\n\t/** Visitor message bubble text color. Defaults to `onPrimaryColor`. */\n\tbubbleTextColor?: string;\n\t/** Widget panel background color. */\n\tbackgroundColor?: string;\n\t/** Widget panel text color. */\n\ttextColor?: string;\n\t/** Border color used inside the panel. */\n\tborderColor?: string;\n\t/** Corner radius for the panel + cards (any valid CSS length). */\n\tradius?: string;\n\t/** Font family stack for everything inside the widget. */\n\tfontFamily?: string;\n\t/** Launcher + panel placement. Defaults to \"bottom-right\". */\n\tposition?: WidgetPosition;\n\t/**\n\t * Escape hatch: any CSS custom property not modeled above. Keys must\n\t * start with `--`. Wins over the typed fields above when both set.\n\t */\n\tcssVariables?: Record<`--${string}`, string>;\n}\n\n/** Validate a hex like `#aabbcc`. We're conservative on purpose. */\nfunction isValidHex(color: string): boolean {\n\treturn /^#[0-9a-fA-F]{6}$/.test(color);\n}\n\n/**\n * Lighten a #rrggbb hex by a fixed amount (used as the hover variant\n * of `primaryColor`). Non-hex inputs return unchanged so callers can\n * pass `oklch(...)`, `hsl(...)`, etc. and bring their own hover.\n */\nfunction lighten(hex: string): string {\n\tif (!isValidHex(hex)) return hex;\n\tconst r = Math.min(255, Number.parseInt(hex.slice(1, 3), 16) + 30);\n\tconst g = Math.min(255, Number.parseInt(hex.slice(3, 5), 16) + 30);\n\tconst b = Math.min(255, Number.parseInt(hex.slice(5, 7), 16) + 30);\n\tconst hex2 = (n: number) => n.toString(16).padStart(2, \"0\");\n\treturn `#${hex2(r)}${hex2(g)}${hex2(b)}`;\n}\n\n/** Map a single typed field onto its CSS variable(s). */\nfunction setVar(host: HTMLElement, name: string, value: string | undefined) {\n\tif (value == null || value === \"\") return;\n\thost.style.setProperty(name, value);\n}\n\n/**\n * Write a `WidgetTheme` onto the host element. Safe to call multiple\n * times — every call is incremental, only the keys you provide are\n * touched. Pass `undefined` for a field to leave the existing value alone;\n * call `clearTheme()` if you want to reset.\n */\nexport function applyTheme(host: HTMLElement, theme: WidgetTheme | undefined) {\n\tif (!host || !theme) return;\n\n\tif (theme.primaryColor) {\n\t\tsetVar(host, \"--hw-primary\", theme.primaryColor);\n\t\tsetVar(host, \"--hw-primary-hover\", lighten(theme.primaryColor));\n\t\tsetVar(host, \"--hw-brand\", theme.primaryColor);\n\t}\n\tsetVar(host, \"--hw-on-brand\", theme.onPrimaryColor);\n\tsetVar(host, \"--hw-visitor-bubble-bg\", theme.bubbleColor ?? theme.primaryColor);\n\tsetVar(host, \"--hw-visitor-bubble-text\", theme.bubbleTextColor ?? theme.onPrimaryColor);\n\tsetVar(host, \"--hw-bg\", theme.backgroundColor);\n\tsetVar(host, \"--hw-text\", theme.textColor);\n\tsetVar(host, \"--hw-border\", theme.borderColor);\n\tsetVar(host, \"--hw-radius\", theme.radius);\n\tsetVar(host, \"--hw-font\", theme.fontFamily);\n\n\tif (theme.position === \"bottom-left\") {\n\t\tsetVar(host, \"--hw-position-right\", \"auto\");\n\t\tsetVar(host, \"--hw-position-left\", \"20px\");\n\t\tsetVar(host, \"--hw-window-right\", \"auto\");\n\t\tsetVar(host, \"--hw-window-left\", \"0\");\n\t} else if (theme.position === \"bottom-right\") {\n\t\thost.style.removeProperty(\"--hw-position-right\");\n\t\thost.style.removeProperty(\"--hw-position-left\");\n\t\thost.style.removeProperty(\"--hw-window-right\");\n\t\thost.style.removeProperty(\"--hw-window-left\");\n\t}\n\n\tif (theme.cssVariables) {\n\t\tfor (const [key, value] of Object.entries(theme.cssVariables)) {\n\t\t\tif (key.startsWith(\"--\")) host.style.setProperty(key, value);\n\t\t}\n\t}\n}\n","export type Listener<T = unknown> = (data: T) => void;\n\nexport interface WidgetEvents {\n\topen: undefined;\n\tclose: undefined;\n\tdismiss: undefined;\n\tshow: undefined;\n\tunreadChange: number;\n\tmessageReceived: { conversationId: string; text: string; senderName: string | null };\n\tready: undefined;\n}\n\nexport type WidgetEventName = keyof WidgetEvents;\n\nexport class WidgetEventEmitter {\n\tprivate listeners = new Map<string, Set<Listener>>();\n\n\ton<K extends WidgetEventName>(event: K, fn: Listener<WidgetEvents[K]>): void {\n\t\tif (!this.listeners.has(event)) this.listeners.set(event, new Set());\n\t\tthis.listeners.get(event)!.add(fn as Listener);\n\t}\n\n\toff<K extends WidgetEventName>(event: K, fn: Listener<WidgetEvents[K]>): void {\n\t\tthis.listeners.get(event)?.delete(fn as Listener);\n\t}\n\n\temit<K extends WidgetEventName>(\n\t\tevent: K,\n\t\t...args: WidgetEvents[K] extends undefined ? [] : [WidgetEvents[K]]\n\t): void {\n\t\tconst data = args[0];\n\t\tthis.listeners.get(event)?.forEach((fn) => {\n\t\t\ttry {\n\t\t\t\tfn(data);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`[Helpway] Event handler error (${event}):`, err);\n\t\t\t}\n\t\t});\n\t}\n\n\tremoveAll(): void {\n\t\tthis.listeners.clear();\n\t}\n}\n","/**\n * Widget i18n — lightweight, zero-dependency translation system.\n *\n * Architecture:\n * - English strings bundled as fallback (zero-latency, always works)\n * - Other locales fetched from Better i18n CDN at runtime\n * - Locale detection: data-locale > identify metadata > navigator.language > \"en\"\n * - Simple key-value lookup with t(\"widget.key\") syntax\n *\n * CDN URL: https://cdn.better-i18n.com/helpway/widget/{locale}/translations.json\n */\n\n// ── Bundled English fallback strings ────────────────────────\n\nconst en: Record<string, string> = {\n\t// Navigation & tabs\n\t\"widget.home\": \"Home\",\n\t\"widget.messages\": \"Messages\",\n\t\"widget.help\": \"Help\",\n\n\t// Home screen\n\t\"widget.send_us_message\": \"Send us a message\",\n\t\"widget.reply_time\": \"We typically reply in a few minutes\",\n\t\"widget.recent_conversations\": \"Recent conversations\",\n\t\"widget.see_all\": \"See all conversations\",\n\n\t// Messages tab\n\t\"widget.no_messages\": \"No messages yet\",\n\t\"widget.no_messages_desc\": \"Start a conversation to get help\",\n\t\"widget.start_conversation\": \"Start a conversation\",\n\t\"widget.no_preview\": \"No messages yet\",\n\n\t// Conversation\n\t\"widget.new_conversation\": \"New conversation\",\n\t\"widget.resolved_text\": \"This conversation has been resolved\",\n\t\"widget.send_followup\": \"Send a follow-up\",\n\t\"widget.start_a_conversation\": \"Start a conversation\",\n\n\t// Composer\n\t\"widget.placeholder\": \"Send a message...\",\n\t\"widget.placeholder_new\": \"How can we help?\",\n\t\"widget.drop_files\": \"Drop files here\",\n\n\t// CSAT\n\t\"widget.csat_label\": \"How was your experience?\",\n\t\"widget.csat_thanks\": \"Thanks for your feedback!\",\n\n\t// Inline email collection (after AI reply)\n\t\"widget.email_title\": \"Stay in the loop\",\n\t\"widget.email_subtitle\": \"Get notified when we reply\",\n\t\"widget.email_placeholder\": \"you@email.com\",\n\t\"widget.email_continue\": \"Notify me\",\n\t\"widget.email_saved\": \"You'll be notified by email\",\n\t\"widget.email_dismiss\": \"No thanks\",\n\n\t// Errors\n\t\"widget.error_title\": \"Something went wrong\",\n\t\"widget.error_desc\": \"Failed to load. Please try again.\",\n\t\"widget.retry\": \"Retry\",\n\t\"widget.reconnecting\": \"Reconnecting...\",\n\t\"widget.send_error\": \"Message not sent\",\n\n\t// Date separators (today is implicit — never rendered)\n\t\"widget.yesterday\": \"Yesterday\",\n\n\t// Sender labels\n\t\"widget.helpway_ai\": \"Helpway AI\",\n\t\"widget.support\": \"Support\",\n\n\t// Events\n\t\"widget.joined\": \"joined the conversation\",\n\t\"widget.left\": \"left the conversation\",\n\n\t// Content/search\n\t\"widget.content\": \"Content\",\n\t\"widget.search\": \"Search...\",\n\t\"widget.no_results\": \"No results found\",\n\t\"widget.try_different\": \"Try a different search term\",\n\t\"widget.nothing_yet\": \"Nothing here yet\",\n\t\"widget.check_back\": \"Check back later for updates\",\n\t\"widget.load_more\": \"Load more\",\n\t\"widget.loading\": \"Loading...\",\n\n\t// Copy\n\t\"widget.copy\": \"Copy message\",\n\t\"widget.copied\": \"Copied\",\n\n\t// File upload\n\t\"widget.file_too_large\": \"File too large (max 10 MB)\",\n\t\"widget.click_to_open\": \"Click to open\",\n\t\"widget.caption_required\": \"Add a message to send with your attachment\",\n\n\t// Accessibility\n\t\"widget.aria_chat\": \"Support chat\",\n\t\"widget.aria_close\": \"Close\",\n\t\"widget.aria_back\": \"Back\",\n\t\"widget.aria_send\": \"Send message\",\n\t\"widget.aria_attach\": \"Attach file\",\n\t\"widget.aria_input\": \"Message input\",\n\t\"widget.aria_remove\": \"Remove\",\n\t\"widget.aria_dismiss\": \"Dismiss\",\n\t\"widget.aria_open\": \"Open support\",\n\t\"widget.aria_close_support\": \"Close support\",\n\t\"widget.aria_good\": \"Good\",\n\t\"widget.aria_bad\": \"Bad\",\n\t\"widget.aria_messages\": \"Messages\",\n\n\t// Time (relative)\n\t\"widget.time_now\": \"now\",\n\t\"widget.time_yesterday\": \"Yesterday\",\n\n\t// Powered by\n\t\"widget.powered_by\": \"Powered by\",\n\n\t// Hero / home screen\n\t\"widget.welcome_message\": \"Hi there 👋\\nHow can we help?\",\n\t\"widget.subtitle_text\": \"Usually replies in minutes\",\n};\n\n// ── State ───────────────────────────────────────────────────\n\nlet currentLocale = \"en\";\nlet translations: Record<string, string> = {};\nlet isLoaded = false;\nlet revision = 0; // Incremented on every translation change — React hook watches this\nconst listeners: Array<() => void> = [];\n\n// ── Public API ──────────────────────────────────────────────\n\n/**\n * Translate a key. Falls back to English bundled string, then to the key itself.\n *\n * Supports simple interpolation: t(\"widget.key\", { name: \"John\" })\n * Template: \"Hello {{name}}\" → \"Hello John\"\n */\nexport function t(key: string, params?: Record<string, string | number>): string {\n\tconst value = translations[key] ?? en[key] ?? key;\n\n\tif (!params) return value;\n\n\treturn value.replace(/\\{\\{(\\w+)\\}\\}/g, (_, k: string) => {\n\t\treturn params[k]?.toString() ?? `{{${k}}}`;\n\t});\n}\n\n/** Get the current locale code */\nexport function getLocale(): string {\n\treturn currentLocale;\n}\n\n/** Get current revision number — changes when translations are loaded/updated */\nexport function getI18nRevision(): number {\n\treturn revision;\n}\n\n/** Check if translations have been loaded */\nexport function isI18nReady(): boolean {\n\treturn isLoaded;\n}\n\n/** Subscribe to locale/translation changes. Returns unsubscribe fn. */\nexport function onLocaleChange(fn: () => void): () => void {\n\tlisteners.push(fn);\n\treturn () => {\n\t\tconst idx = listeners.indexOf(fn);\n\t\tif (idx >= 0) listeners.splice(idx, 1);\n\t};\n}\n\n// ── Initialization ──────────────────────────────────────────\n\n/**\n * Detect locale from available signals and fetch translations.\n *\n * Priority:\n * 1. Explicit `locale` param (from data-locale attribute)\n * 2. navigator.language (browser preference)\n * 3. \"en\" fallback\n */\nexport async function initI18n(options?: { locale?: string; cdnBase?: string }): Promise<void> {\n\tif (options?.cdnBase) {\n\t\tcdnBase = options.cdnBase;\n\t}\n\n\tconst detected =\n\t\toptions?.locale ?? (typeof navigator !== \"undefined\" ? navigator.language : \"en\");\n\n\t// Normalize: \"fr-FR\" → \"fr\", \"pt-BR\" → \"pt-BR\" (keep regional if meaningful)\n\tcurrentLocale = normalizeLocale(detected);\n\n\t// English is bundled — no fetch needed\n\tif (currentLocale === \"en\") {\n\t\tisLoaded = true;\n\t\tnotify();\n\t\treturn;\n\t}\n\n\t// Fetch from CDN\n\ttry {\n\t\tconst data = await fetchTranslations(currentLocale);\n\t\tif (data) {\n\t\t\t// Only pick widget.* keys from the full namespace bundle\n\t\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttranslations[`widget.${key}`] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (err) {\n\t\tconsole.warn(`[Helpway] Failed to fetch ${currentLocale} translations, using English`, err);\n\t}\n\n\tisLoaded = true;\n\tnotify();\n}\n\n/**\n * Update locale at runtime (e.g., after identify() provides metadata.locale).\n * Re-fetches translations if locale changed.\n */\nexport async function setLocale(locale: string): Promise<void> {\n\tconst normalized = normalizeLocale(locale);\n\tif (normalized === currentLocale) return;\n\n\tcurrentLocale = normalized;\n\ttranslations = {}; // Clear old translations\n\n\tif (normalized === \"en\") {\n\t\tnotify();\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst data = await fetchTranslations(normalized);\n\t\tif (data) {\n\t\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttranslations[`widget.${key}`] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Silent fallback to English\n\t}\n\n\tnotify();\n}\n\n// ── Internals ───────────────────────────────────────────────\n\nlet cdnBase = \"https://cdn.better-i18n.com/helpway/widget\";\n\nasync function fetchTranslations(locale: string): Promise<Record<string, string> | null> {\n\t// All namespaces live in a single translations.json — widget keys nested under \"widget\" key\n\tconst url = `${cdnBase}/${locale}/translations.json`;\n\n\tlet res = await fetch(url);\n\tif (!res.ok && locale.includes(\"-\")) {\n\t\t// Try base locale: \"pt-BR\" → \"pt\"\n\t\tconst base = locale.split(\"-\")[0];\n\t\tres = await fetch(`${cdnBase}/${base}/translations.json`);\n\t}\n\tif (!res.ok) return null;\n\n\tconst data: Record<string, unknown> = await res.json();\n\t// CDN structure is nested: { \"widget\": { \"home\": \"Ana Sayfa\", ... }, \"sidebar\": {...} }\n\tconst widgetNs = data.widget;\n\tif (widgetNs && typeof widgetNs === \"object\" && !Array.isArray(widgetNs)) {\n\t\tconst result: Record<string, string> = {};\n\t\tfor (const [k, v] of Object.entries(widgetNs)) {\n\t\t\tif (typeof v === \"string\") result[k] = v;\n\t\t}\n\t\treturn result;\n\t}\n\treturn null;\n}\n\nfunction normalizeLocale(input: string): string {\n\t// Keep regional variants that are commonly distinct: pt-BR, zh-CN, zh-TW\n\tconst regional = [\"pt-br\", \"zh-cn\", \"zh-tw\", \"zh-hk\"];\n\tconst lower = input.toLowerCase().replace(\"_\", \"-\");\n\n\tfor (const r of regional) {\n\t\tif (lower.startsWith(r)) return r;\n\t}\n\n\t// Otherwise just use base: \"fr-FR\" → \"fr\"\n\treturn lower.split(\"-\")[0] ?? \"en\";\n}\n\nfunction notify(): void {\n\trevision++;\n\tfor (const fn of listeners) {\n\t\ttry {\n\t\t\tfn();\n\t\t} catch {\n\t\t\t/* ignore */\n\t\t}\n\t}\n}\n","import { t, getLocale } from \"./i18n\";\n\n/**\n * Format a date as relative time string.\n * Uses i18n for \"now\" and \"Yesterday\". Locale-aware date formatting.\n */\nexport function formatRelativeTime(date: string | Date): string {\n\tconst now = Date.now();\n\tconst then = typeof date === \"string\" ? new Date(date).getTime() : date.getTime();\n\tconst diffMs = now - then;\n\tconst diffMin = Math.floor(diffMs / 60000);\n\tconst diffHour = Math.floor(diffMs / 3600000);\n\tconst diffDay = Math.floor(diffMs / 86400000);\n\n\tif (diffMin < 1) return t(\"widget.time_now\");\n\tif (diffMin < 60) return `${diffMin}m`;\n\tif (diffHour < 24) return `${diffHour}h`;\n\tif (diffDay === 1) return t(\"widget.time_yesterday\");\n\tif (diffDay < 7) return `${diffDay}d`;\n\n\tconst d = typeof date === \"string\" ? new Date(date) : date;\n\treturn d.toLocaleDateString(getLocale(), { month: \"short\", day: \"numeric\" });\n}\n\n/**\n * Format time for message bubbles (HH:MM).\n */\nexport function formatTime(date: string | Date): string {\n\tconst d = typeof date === \"string\" ? new Date(date) : date;\n\treturn d.toLocaleTimeString(undefined, { hour: \"2-digit\", minute: \"2-digit\" });\n}\n\n/**\n * Resolve a label that may be a translation key (\"widget.*\") or plain text.\n * When the key resolves to itself (missing), falls back to a humanized form\n * so the UI never leaks raw \"widget.changelog\" strings to the visitor.\n */\nexport function resolveLabel(label: string): string {\n\tif (!label.startsWith(\"widget.\")) return label;\n\tconst resolved = t(label);\n\tif (resolved === label) {\n\t\treturn label\n\t\t\t.replace(\"widget.\", \"\")\n\t\t\t.replace(/_/g, \" \")\n\t\t\t.replace(/^\\w/, (c) => c.toUpperCase());\n\t}\n\treturn resolved;\n}\n\n/**\n * Get initials from a name or email.\n */\nexport function getInitials(value: string): string {\n\tif (!value) return \"?\";\n\n\t// Email: take first letter\n\tif (value.includes(\"@\")) return (value[0] ?? \"?\").toUpperCase();\n\n\t// Name: take first letter of first two words\n\tconst parts = value.trim().split(/\\s+/);\n\tif (parts.length >= 2) {\n\t\treturn ((parts[0]?.[0] ?? \"\") + (parts[1]?.[0] ?? \"\")).toUpperCase();\n\t}\n\treturn (parts[0]?.[0] ?? \"?\").toUpperCase();\n}\n","\"use client\";\n\nimport {\n\tWebSocketManager,\n\tWidgetEventEmitter,\n\ttype HelpwayMethods,\n\ttype WidgetClient,\n\ttype WidgetStore,\n\ttype WidgetTheme,\n\tapplyTheme,\n\tcreateHelpwayAPI,\n\tcreateWidgetClient,\n\tcreateWidgetStore,\n\tinitI18n,\n\tinstallCallable,\n\tsetLocale,\n\tsyncVisitorId,\n} from \"@helpway/widget-core\";\nimport {\n\ttype ReactNode,\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { type StoreApi, useStore } from \"zustand\";\n\n// ── Context ──────────────────────────────────────────────\n\nexport interface IdentifyData {\n\texternalId: string;\n\temail?: string;\n\tname?: string;\n\timage?: string;\n\tmetadata?: Record<string, unknown>;\n}\n\ninterface WidgetContextValue {\n\tclient: WidgetClient;\n\tstore: StoreApi<WidgetStore>;\n\tws: WebSocketManager;\n\tidentify: (data: IdentifyData) => Promise<void>;\n\tapi: HelpwayMethods;\n\temitter: WidgetEventEmitter;\n\thasBootstrapError: boolean;\n\twsDisconnected: boolean;\n\tretryBootstrap: () => void;\n}\n\nconst WidgetContext = createContext<WidgetContextValue | null>(null);\n\nexport function useWidgetContext(): WidgetContextValue {\n\tconst ctx = useContext(WidgetContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"useWidgetContext must be used within <SupportProvider>\");\n\t}\n\treturn ctx;\n}\n\n/** Use a slice of the widget store with auto re-render */\nexport function useWidgetStore<T>(selector: (state: WidgetStore) => T): T {\n\tconst { store } = useWidgetContext();\n\treturn useStore(store, selector);\n}\n\n/** Hook to identify the current visitor (link to customer contact) */\nexport function useIdentify() {\n\tconst { identify } = useWidgetContext();\n\treturn identify;\n}\n\n// ── Provider ─────────────────────────────────────────────\n\ninterface SupportProviderProps {\n\tapiKey: string;\n\tapiUrl?: string;\n\tlocale?: string;\n\tinitialConversationId?: string;\n\tonReady?: (api: HelpwayMethods) => void;\n\tcustomLauncherSelector?: string;\n\tonOpen?: () => void;\n\tonClose?: () => void;\n\tonUnreadChange?: (count: number) => void;\n\t/**\n\t * Developer-side theme override. Most consumers should configure\n\t * appearance in the Helpway dashboard (see\n\t * https://helpway.ai/docs/customization) so changes apply without\n\t * a redeploy. Use this prop only when you need the widget to inherit\n\t * a host-app theme that the dashboard can't see (e.g. a tenant-\n\t * specific brand color resolved at runtime). Values here are written\n\t * as CSS custom properties on the widget host and override the\n\t * dashboard config for this mount only.\n\t */\n\ttheme?: WidgetTheme;\n\tchildren: ReactNode;\n}\n\n/**\n * Root provider for the Helpway widget.\n * Creates tRPC client, WebSocket connection, and state store.\n *\n * Visitor identity is managed via server-side cookies (hw_visitor).\n * No localStorage or client-side ID management needed.\n */\nexport function SupportProvider({\n\tapiKey,\n\tapiUrl,\n\tlocale,\n\tinitialConversationId,\n\tonReady,\n\tcustomLauncherSelector,\n\tonOpen,\n\tonClose,\n\tonUnreadChange,\n\ttheme,\n\tchildren,\n}: SupportProviderProps) {\n\tconst initRef = useRef<{\n\t\tclient: WidgetClient;\n\t\tstore: StoreApi<WidgetStore>;\n\t\tws: WebSocketManager;\n\t\tidentify: (data: IdentifyData) => Promise<void>;\n\t\tapi: HelpwayMethods;\n\t\temitter: WidgetEventEmitter;\n\t} | null>(null);\n\tconst [hasBootstrapError, setHasBootstrapError] = useState(false);\n\tconst [wsDisconnected, setWsDisconnected] = useState(false);\n\tconst [bootstrapAttempt, setBootstrapAttempt] = useState(0);\n\n\tif (!initRef.current) {\n\t\tconst resolvedApiUrl = apiUrl ?? inferApiUrl();\n\n\t\tconst client = createWidgetClient({\n\t\t\tapiUrl: resolvedApiUrl,\n\t\t\tapiKey,\n\t\t});\n\n\t\tconst store = createWidgetStore();\n\t\tconst emitter = new WidgetEventEmitter();\n\n\t\tconst ws = new WebSocketManager({\n\t\t\tapiUrl: resolvedApiUrl,\n\t\t\tvisitorId: \"\",\n\t\t\twebsiteId: \"\",\n\t\t});\n\n\t\tconst identify = async (data: IdentifyData) => {\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.identify.mutate(data);\n\t\t\t\tif (result.contact) {\n\t\t\t\t\tstore.getState().updateVisitorContact({\n\t\t\t\t\t\tid: result.contact.id,\n\t\t\t\t\t\tname: result.contact.name ?? null,\n\t\t\t\t\t\temail: result.contact.email ?? null,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst metaLocale = data.metadata?.locale;\n\t\t\t\tif (typeof metaLocale === \"string\" && metaLocale.length > 0) {\n\t\t\t\t\tsetLocale(metaLocale);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[Helpway] identify failed:\", err);\n\t\t\t}\n\t\t};\n\n\t\tconst api = createHelpwayAPI({ store, emitter, identify, apiKey });\n\n\t\tinitRef.current = { client, store, ws, identify, api, emitter };\n\t}\n\n\tconst { client, store, ws, identify, api, emitter } = initRef.current;\n\n\tconst retryBootstrap = useCallback(() => {\n\t\tsetHasBootstrapError(false);\n\t\tsetBootstrapAttempt((n) => n + 1);\n\t}, []);\n\n\t// Bootstrap on mount (re-runs on retry)\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tasync function bootstrap() {\n\t\t\ttry {\n\t\t\t\tconst data = await client.widget.bootstrap.query();\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\t// Initialize i18n BEFORE setReady to avoid flash of English text.\n\t\t\t\t// Priority: explicit `locale` prop → server-side detection\n\t\t\t\t// (Accept-Language + CF-IPCountry) → widget-core bundled default.\n\t\t\t\tconst resolvedLocale =\n\t\t\t\t\tlocale ?? (data as { detectedLocale?: string | null }).detectedLocale ?? undefined;\n\t\t\t\tawait initI18n({\n\t\t\t\t\tlocale: resolvedLocale,\n\t\t\t\t\tcdnBase: (data.agentConfig as { i18nCdnBase?: string } | null)?.i18nCdnBase ?? undefined,\n\t\t\t\t});\n\n\t\t\t\tstore.getState().setReady(data.visitor, data.website, data.agentConfig);\n\t\t\t\tsetHasBootstrapError(false);\n\n\t\t\t\t// Sync server-assigned visitor ID to localStorage\n\t\t\t\t// Ensures client uses canonical ID on subsequent page loads\n\t\t\t\tif (data.visitor?.id) {\n\t\t\t\t\tsyncVisitorId(apiKey, data.visitor.id);\n\t\t\t\t}\n\n\t\t\t\tconst convData = await client.widget.listConversations.query();\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tstore.getState().setConversations(\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any -- tRPC inferred type\n\t\t\t\t\t\tconvData.conversations.map(\n\t\t\t\t\t\t\t(c: {\n\t\t\t\t\t\t\t\tid: string;\n\t\t\t\t\t\t\t\ttitle: string | null;\n\t\t\t\t\t\t\t\tstatus: string;\n\t\t\t\t\t\t\t\tlastMessageText: string | null;\n\t\t\t\t\t\t\t\tlastMessageAt: string | null;\n\t\t\t\t\t\t\t\tlastMessageSenderType: string | null;\n\t\t\t\t\t\t\t\tlastMessageSenderName: string | null;\n\t\t\t\t\t\t\t\tlastMessageSenderImage: string | null;\n\t\t\t\t\t\t\t}) => ({\n\t\t\t\t\t\t\t\tid: c.id,\n\t\t\t\t\t\t\t\ttitle: c.title,\n\t\t\t\t\t\t\t\tstatus: c.status,\n\t\t\t\t\t\t\t\tlastMessageText: c.lastMessageText,\n\t\t\t\t\t\t\t\tlastMessageAt: c.lastMessageAt,\n\t\t\t\t\t\t\t\tlastMessageSenderType: c.lastMessageSenderType,\n\t\t\t\t\t\t\t\tlastMessageSenderName: c.lastMessageSenderName,\n\t\t\t\t\t\t\t\tlastMessageSenderImage: c.lastMessageSenderImage,\n\t\t\t\t\t\t\t\tunreadCount: 0,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (typeof window !== \"undefined\") {\n\t\t\t\t\tclient.widget.updatePage\n\t\t\t\t\t\t.mutate({\n\t\t\t\t\t\t\turl: window.location.href,\n\t\t\t\t\t\t\ttitle: document.title || window.location.pathname,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch(() => {});\n\t\t\t\t}\n\n\t\t\t\tif (data.website?.id && data.visitor?.id) {\n\t\t\t\t\tws.configure({ websiteId: data.website.id, visitorId: data.visitor.id });\n\t\t\t\t\tws.connect();\n\t\t\t\t}\n\n\t\t\t\tif (initialConversationId && !cancelled) {\n\t\t\t\t\tstore.getState().setActiveConversation(initialConversationId);\n\t\t\t\t\tstore.getState().setOpen(true);\n\t\t\t\t}\n\n\t\t\t\temitter.emit(\"ready\");\n\t\t\t\tonReady?.(initRef.current!.api);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[Helpway] Bootstrap failed:\", err);\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tstore.getState().setConnecting(false);\n\t\t\t\t\tsetHasBootstrapError(true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbootstrap();\n\n\t\t// Debounced markSeen — coalesces rapid events (AI may stream multiple\n\t\t// messages, plus the typing/processing events fire too).\n\t\tlet markSeenTimer: ReturnType<typeof setTimeout> | null = null;\n\t\tconst scheduleMarkSeen = (conversationId: string) => {\n\t\t\tif (markSeenTimer) clearTimeout(markSeenTimer);\n\t\t\tmarkSeenTimer = setTimeout(() => {\n\t\t\t\tclient.widget.markSeen.mutate({ conversationId }).catch(() => {});\n\t\t\t\tstore.getState().clearUnread(conversationId);\n\t\t\t}, 400);\n\t\t};\n\n\t\tconst unsub = ws.onEvent((event) => {\n\t\t\tstore.getState().handleRealtimeEvent(event);\n\n\t\t\tif (event.type === \"timelineItemCreated\") {\n\t\t\t\tconst item = event.item;\n\t\t\t\tconst isPublicIncoming = item?.visibility === \"public\" && !item.visitorId;\n\n\t\t\t\t// Emit messageReceived for public incoming messages\n\t\t\t\tif (isPublicIncoming && item?.text) {\n\t\t\t\t\temitter.emit(\"messageReceived\", {\n\t\t\t\t\t\tconversationId: event.conversationId,\n\t\t\t\t\t\ttext: item.text,\n\t\t\t\t\t\tsenderName: \"aiAgentId\" in item && item.aiAgentId ? \"AI\" : null,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (!isPublicIncoming) return;\n\t\t\t\tconst s = store.getState();\n\t\t\t\tconst isViewing = s.isOpen && s.activeConversationId === event.conversationId;\n\t\t\t\tif (isViewing) scheduleMarkSeen(event.conversationId);\n\t\t\t}\n\t\t});\n\n\t\t// Monitor WebSocket connection state\n\t\tconst wsCheck = setInterval(() => {\n\t\t\tsetWsDisconnected(!ws.isConnected);\n\t\t}, 3000);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\tunsub();\n\t\t\tclearInterval(wsCheck);\n\t\t\tif (markSeenTimer) clearTimeout(markSeenTimer);\n\t\t\tws.disconnect();\n\t\t};\n\t}, [client, store, ws, bootstrapAttempt]);\n\n\t// Re-initialize translations when locale prop changes after bootstrap\n\tuseEffect(() => {\n\t\tif (locale != null) {\n\t\t\tsetLocale(locale);\n\t\t}\n\t}, [locale]);\n\n\t// Wire up event callbacks: emit open/close events\n\tuseEffect(() => {\n\t\tconst unsub = store.subscribe((state, prev) => {\n\t\t\tif (state.isOpen && !prev.isOpen) {\n\t\t\t\temitter.emit(\"open\");\n\t\t\t\tonOpen?.();\n\t\t\t}\n\t\t\tif (!state.isOpen && prev.isOpen) {\n\t\t\t\temitter.emit(\"close\");\n\t\t\t\tonClose?.();\n\t\t\t}\n\t\t\tconst prevUnread = prev.conversations.reduce((s, c) => s + c.unreadCount, 0);\n\t\t\tconst nextUnread = state.conversations.reduce((s, c) => s + c.unreadCount, 0);\n\t\t\tif (nextUnread !== prevUnread) {\n\t\t\t\temitter.emit(\"unreadChange\", nextUnread);\n\t\t\t\tonUnreadChange?.(nextUnread);\n\t\t\t}\n\t\t});\n\t\treturn unsub;\n\t}, [store, emitter, onOpen, onClose, onUnreadChange]);\n\n\t// Custom launcher selector: attach click handler with MutationObserver fallback for SPAs\n\tuseEffect(() => {\n\t\tif (!customLauncherSelector) return;\n\t\tconst handler = (e: Event) => {\n\t\t\te.preventDefault();\n\t\t\tapi.toggle();\n\t\t};\n\n\t\tconst attach = () => {\n\t\t\tconst el = document.querySelector(customLauncherSelector);\n\t\t\tif (el) {\n\t\t\t\tel.addEventListener(\"click\", handler);\n\t\t\t\treturn el;\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\n\t\tlet el = attach();\n\t\tlet observer: MutationObserver | null = null;\n\n\t\tif (!el) {\n\t\t\tobserver = new MutationObserver(() => {\n\t\t\t\tel = attach();\n\t\t\t\tif (el) observer?.disconnect();\n\t\t\t});\n\t\t\tobserver.observe(document.body, { childList: true, subtree: true });\n\t\t}\n\n\t\treturn () => {\n\t\t\tel?.removeEventListener(\"click\", handler);\n\t\t\tobserver?.disconnect();\n\t\t};\n\t}, [customLauncherSelector, api]);\n\n\t// Sync window.Helpway with the current api instance on mount,\n\t// restore on unmount. Must live in an effect (not the init block)\n\t// so React StrictMode's double mount/unmount cycle doesn't leave\n\t// the global undefined: the effect re-runs on each mount and\n\t// re-installs the callable, while the init block only fires once\n\t// because initRef.current is preserved across remounts.\n\t//\n\t// IMPORTANT: window.Helpway is exposed as a CALLABLE function (Intercom-style)\n\t// so that `Helpway(\"identify\", payload)` works alongside `Helpway.identify(payload)`.\n\t// Earlier versions assigned the raw `api` object here, which clobbered the\n\t// callable installed by the widget-embed loader and made the documented\n\t// `Helpway(\"cmd\", ...)` form throw \"is not a function\" downstream.\n\t// Apply developer-side theme overrides. We target the host that the\n\t// widget script created (#helpway-widget) when running under the\n\t// embed loader; otherwise fall back to documentElement so the CSS\n\t// vars cascade into a Light-DOM React mount. See:\n\t// https://helpway.ai/docs/customization\n\tuseEffect(() => {\n\t\tif (!theme || typeof document === \"undefined\") return;\n\t\tconst target =\n\t\t\t(document.getElementById(\"helpway-widget\") as HTMLElement | null) ??\n\t\t\tdocument.documentElement;\n\t\tapplyTheme(target, theme);\n\t}, [theme]);\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\") return;\n\t\tconst callable = installCallable(api);\n\t\treturn () => {\n\t\t\tif (window.Helpway === callable) {\n\t\t\t\twindow.Helpway = undefined;\n\t\t\t}\n\t\t\temitter.removeAll();\n\t\t};\n\t}, [api, emitter]);\n\n\tconst ctxValue: WidgetContextValue = {\n\t\tclient,\n\t\tstore,\n\t\tws,\n\t\tidentify,\n\t\tapi,\n\t\temitter,\n\t\thasBootstrapError,\n\t\twsDisconnected,\n\t\tretryBootstrap,\n\t};\n\n\treturn <WidgetContext.Provider value={ctxValue}>{children}</WidgetContext.Provider>;\n}\n\n// ── Helpers ──────────────────────────────────────────────\n\n/**\n * Resolve the API origin when the consumer doesn't pass `apiUrl` explicitly.\n *\n * Order of precedence:\n * 1. CDN script-tag origin — when the widget loads via\n * `<script src=\"https://cdn.helpway.ai/widget.js\" data-key=\"...\">` we\n * derive the origin from the script's URL so the bootstrap call hits\n * the API that owns the public key.\n * 2. Production default — `https://api.helpway.ai`. Matches the JSDoc\n * contract on the `apiUrl` prop.\n *\n * Earlier versions fell back to `window.location.origin` after the script\n * lookup, which broke any framework integration without the script tag\n * (Next App Router, Vite SPA, etc.) — bootstrap hit the consumer's own\n * server and 404'd. The `https://api.helpway.ai` fallback removes that\n * footgun.\n */\nfunction inferApiUrl(): string {\n\tif (typeof document !== \"undefined\") {\n\t\tconst script = document.querySelector(\"script[data-key][src]\");\n\t\tif (script) {\n\t\t\tconst src = script.getAttribute(\"src\");\n\t\t\tif (src) {\n\t\t\t\ttry {\n\t\t\t\t\tconst url = new URL(src);\n\t\t\t\t\treturn `${url.protocol}//${url.host}`;\n\t\t\t\t} catch {\n\t\t\t\t\t// Fall through to the production default.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn \"https://api.helpway.ai\";\n}\n","\"use client\";\n\nimport { formatRelativeTime, t } from \"@helpway/widget-core\";\nimport type { ConversationSummary, WidgetContentTab } from \"@helpway/widget-core\";\nimport type { TimelineItem } from \"@helpway/types\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n/** Resolve a label that might be a translation key (widget.*) or raw text */\nfunction resolveLabel(label: string): string {\n\tif (!label.startsWith(\"widget.\")) return label;\n\tconst resolved = t(label);\n\t// If t() returned the key itself (no translation found), humanize it\n\tif (resolved === label)\n\t\treturn label\n\t\t\t.replace(\"widget.\", \"\")\n\t\t\t.replace(/_/g, \" \")\n\t\t\t.replace(/^\\w/, (c) => c.toUpperCase());\n\treturn resolved;\n}\n\nimport { useComposer } from \"../hooks/use-composer\";\nimport { useConversations } from \"../hooks/use-conversations\";\nimport { useI18n } from \"../hooks/use-i18n\";\nimport { usePresence } from \"../hooks/use-presence\";\nimport { useTimeline } from \"../hooks/use-timeline\";\nimport { useUnread } from \"../hooks/use-unread\";\nimport { useWidget } from \"../hooks/use-widget\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\nimport { Composer } from \"./composer\";\nimport { WidgetDebugOverlay } from \"./debug-overlay\";\nimport { ContentTabView } from \"./content/content-tab-view\";\nimport { ContentTabIconComponent } from \"./content/tab-icon\";\nimport { HomeIcon, MessagesIcon, SendIcon, XIcon } from \"./icons\";\nimport { MessageBubble } from \"./message-bubble\";\nimport { MessageList } from \"./message-list\";\n\nimport type { SubView, Tab } from \"./default-widget/types\";\n\nconst EMPTY_CONTENT_TABS: WidgetContentTab[] = [];\n\n/**\n * Factory-default admin strings. If the admin never customized these\n * values, the widget falls back to t() so visitors see their locale's\n * translation from the CDN bundle instead of frozen English.\n *\n * Keep in sync with packages/api seed defaults + widget-core/src/i18n.ts.\n */\nconst DEFAULT_EN_WELCOME = \"Hi there 👋\\nHow can we help?\";\nconst DEFAULT_EN_SUBTITLE = \"Usually replies in minutes\";\n\n/**\n * Helpway brand mark — octagonal outer with stylized \"W\" inside. Used as\n * the widget's own fallback avatar when the customer hasn't configured a\n * custom avatar/preset and the host site didn't set a logo either. Keeps\n * unconfigured widgets looking intentional rather than generic.\n */\nfunction HelpwayMark({ className }: { className?: string }) {\n\treturn (\n\t\t<svg\n\t\t\tclassName={className}\n\t\t\twidth=\"100%\"\n\t\t\theight=\"100%\"\n\t\t\tviewBox=\"0 0 42 42\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<path\n\t\t\t\td=\"M28.7 0H12.8L0 12.8V28.7L12.8 41.5H28.7L41.5 28.7V12.8L28.7 0ZM15 28.9L6.80002 20.7L15 12.5C18.1 9.4 23.2 9.4 26.3 12.5L34.5 20.7L26.3 28.9C23.2 32 18.2 32 15 28.9Z\"\n\t\t\t\tfill=\"currentColor\"\n\t\t\t/>\n\t\t</svg>\n\t);\n}\n\n/**\n * WidgetLogo — renders agent avatar or website logo with fallback chain:\n * 1. Agent uploaded image (avatarUrl)\n * 2. Agent icon preset (avatarPreset + brandColor)\n * 3. Website logo (logoUrl)\n * 4. Helpway brand mark (octagonal) as the true last-resort fallback\n */\nfunction WidgetLogo({ className }: { className?: string }) {\n\tconst agentConfig = useWidgetStore((s) => s.agentConfig);\n\tconst logoUrl = useWidgetStore((s) => s.website?.logoUrl);\n\n\t// Agent uploaded image takes priority\n\tif (agentConfig?.avatarUrl) {\n\t\treturn <img src={agentConfig.avatarUrl} alt=\"\" className={`hw-agent-img ${className ?? \"\"}`} />;\n\t}\n\n\t// Agent icon preset\n\tif (agentConfig?.avatarPreset) {\n\t\tconst color = agentConfig.brandColor ?? \"#0a0a0a\";\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={`hw-agent-icon ${className ?? \"\"}`}\n\t\t\t\tstyle={{\n\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tjustifyContent: \"center\",\n\t\t\t\t\tborderRadius: 8,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<AgentPresetIcon presetId={agentConfig.avatarPreset} />\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Website logo\n\tif (logoUrl) {\n\t\treturn <img src={logoUrl} alt=\"\" className={`hw-agent-img ${className ?? \"\"}`} />;\n\t}\n\n\treturn <HelpwayMark className={className} />;\n}\n\n/**\n * Exact SVG paths extracted from @central-icons-react at build time.\n * Pixel-perfect match with the dashboard picker. Using static trusted\n * strings (NOT user input) rendered via innerHTML — safe because content\n * is hardcoded SVG from our own icon library, never from external sources.\n */\nconst PRESET_SVG: Record<string, string> = {\n\t// Helpway brand mark — octagonal chamfer with stylized \"W\" inside.\n\t// First entry so it's the default preset for new orgs.\n\thelpway:\n\t\t'<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M16.4 0H7.31L0 7.31V16.4L7.31 23.71H16.4L23.71 16.4V7.31L16.4 0ZM8.57 16.51L3.89 11.83L8.57 7.14C10.34 5.37 13.26 5.37 15.03 7.14L19.71 11.83L15.03 16.51C13.26 18.29 10.4 18.29 8.57 16.51Z\" fill=\"white\"/>',\n\tatom: '<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M9.67904 3.29155C10.7467 1.56948 13.2537 1.56948 14.3214 3.29155L15.1308 4.59707C15.2462 4.7833 15.3634 4.9684 15.4823 5.15233C15.7005 5.1305 15.9185 5.10662 16.1363 5.08068L17.6626 4.89893C19.6747 4.65934 21.2396 6.61723 20.5571 8.52637L20.0401 9.97255C19.9664 10.1786 19.8947 10.3854 19.825 10.5927C19.9779 10.7493 20.1323 10.9045 20.2882 11.0583L21.3821 12.1371C22.8256 13.5609 22.2668 16.0039 20.3491 16.6605L18.895 17.1584C18.6876 17.2294 18.4809 17.3023 18.275 17.3772C18.2478 17.5943 18.2226 17.8117 18.1995 18.0294L18.0372 19.5565C17.823 21.572 15.5635 22.6577 13.8546 21.5695L12.5584 20.7442C12.3734 20.6264 12.1873 20.5103 12.0002 20.3961C11.8131 20.5103 11.627 20.6264 11.442 20.7442L10.1458 21.5695C8.4369 22.6577 6.17739 21.572 5.96321 19.5565L5.80094 18.0294C5.7778 17.8117 5.75263 17.5943 5.72541 17.3772C5.51949 17.3023 5.31282 17.2294 5.10542 17.1584L3.65133 16.6605C1.7336 16.0039 1.17475 13.5609 2.61829 12.1371L3.71216 11.0583C3.86807 10.9045 4.0225 10.7493 4.17541 10.5927C4.10567 10.3854 4.03395 10.1786 3.96028 9.97255L3.44329 8.52637C2.7608 6.61723 4.32567 4.65934 6.33777 4.89893L7.86408 5.08068C8.08191 5.10662 8.29993 5.1305 8.5181 5.15233C8.63698 4.9684 8.75417 4.7833 8.86963 4.59707L9.67904 3.29155ZM7.61407 6.4827L6.16966 6.31071C5.20357 6.19567 4.45578 7.13505 4.78207 8.04778L5.2716 9.41715C6.10452 8.48167 6.88648 7.5021 7.61407 6.4827ZM5.78854 10.961C7.04552 9.61105 8.19784 8.16742 9.23549 6.64268C11.076 6.78287 12.9244 6.78287 14.7649 6.64268C15.8026 8.16743 16.9549 9.61105 18.2119 10.961C17.6657 12.722 17.2545 14.522 16.9818 16.3454C15.2628 17.0169 13.5974 17.8181 12.0002 18.7422C10.403 17.8181 8.73761 17.0169 7.01863 16.3454C6.74592 14.522 6.3347 12.722 5.78854 10.961ZM4.65269 12.1275L3.61666 13.1494C2.92581 13.8308 3.19234 15.0006 4.11188 15.3154L5.48873 15.7868C5.27593 14.553 4.99684 13.3315 4.65269 12.1275ZM7.22343 17.9611L7.377 19.4062C7.47946 20.3704 8.56185 20.8926 9.38218 20.3703L10.6083 19.5895C9.51004 18.9865 8.38012 18.4429 7.22343 17.9611ZM13.3921 19.5895L14.6182 20.3703C15.4385 20.8926 16.5209 20.3704 16.6234 19.4062L16.777 17.9611C15.6203 18.4429 14.4903 18.9865 13.3921 19.5895ZM18.5117 15.7868L19.8885 15.3154C20.8081 15.0006 21.0746 13.8308 20.3837 13.1494L19.3477 12.1275C19.0035 13.3315 18.7245 14.553 18.5117 15.7868ZM18.7288 9.41715L19.2183 8.04778C19.5446 7.13505 18.7968 6.19567 17.8307 6.31071L16.3863 6.4827C17.1139 7.5021 17.8959 8.48167 18.7288 9.41715ZM13.8786 5.2756C12.6272 5.3429 11.3731 5.3429 10.1218 5.2756L10.8874 4.04072C11.3991 3.21542 12.6013 3.21542 13.113 4.04072L13.8786 5.2756Z\" fill=\"white\"/>',\n\tbrain:\n\t\t'<path d=\"M15 10C13.3431 10 12 8.65685 12 7\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9 14C10.6569 14 12 15.3431 12 17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12 3.53516L12 20.2422\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M21 14.5C21 15.9633 20.102 17.2168 18.8271 17.7396C18.2888 19.6221 16.5553 21 14.5 21C13.5749 21 12.7151 20.7209 12 20.2422C11.285 20.7209 10.4251 21 9.5 21C7.44468 21 5.71119 19.6221 5.17291 17.7396C3.89797 17.2168 3 15.9633 3 14.5C3 13.5207 3.40223 12.6353 4.05051 12C3.40223 11.3647 3 10.4793 3 9.5C3 7.69511 4.36618 6.20931 6.12085 6.0203C6.55779 4.28478 8.12886 3 10 3C10.7286 3 11.4117 3.19479 12 3.53513C12.5883 3.19479 13.2714 3 14 3C15.8711 3 17.4422 4.28478 17.8792 6.0203C19.6338 6.20931 21 7.69511 21 9.5C21 10.4793 20.5978 11.3647 19.9495 12C20.5978 12.6353 21 13.5207 21 14.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\trobot:\n\t\t'<path d=\"M12 4H7C5.89543 4 5 4.89543 5 6V11C5 12.1046 5.89543 13 7 13H17C18.1046 13 19 12.1046 19 11V6C19 4.89543 18.1046 4 17 4H12ZM12 4V2M6 15L4 17M6 15C6 18.3137 8.68629 21 12 21C15.3137 21 18 18.3137 18 15M6 15V13M18 15L20 17M18 15V13M9 8V9M15 8V9\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tsparkle:\n\t\t'<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M21 12.5C14.75 12.5 12 15.4028 12 22C12 15.4028 9.25 12.5 3 12.5C9.25 12.5 12 9.59722 12 3C12 9.59722 14.75 12.5 21 12.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linejoin=\"round\"/>',\n\tbolt: '<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M13.1981 20.0571C11.7326 20.0571 10.2936 19.5252 9.46756 18.3817L9.1762 19.7304L3.79688 22.5824L4.3776 19.7304L8.2951 2H13.0916L11.7059 8.24953C12.8251 7.02621 13.8643 6.57412 15.1967 6.57412C18.0746 6.57412 19.9931 8.46227 19.9931 11.9194C19.9931 15.483 17.7815 20.0571 13.1981 20.0571ZM15.0368 12.9301C15.0368 14.5788 13.8643 15.8287 12.3455 15.8287C11.4927 15.8287 10.72 15.5096 10.2137 14.9511L10.9598 11.6802C11.5194 11.1216 12.1589 10.8025 12.905 10.8025C14.0509 10.8025 15.0368 11.6536 15.0368 12.9301Z\" fill=\"white\"/>',\n\tagent:\n\t\t'<path d=\"M12 8.5V12M12 12H8C6.89543 12 6 12.8954 6 14V15.5M12 12H16C17.1046 12 18 12.8954 18 14V15.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"12\" cy=\"6\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"6\" cy=\"18\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"18\" cy=\"18\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/>',\n\tbubble:\n\t\t'<path d=\"M4.00195 6.00003C4.00195 4.89546 4.89738 4.00003 6.00195 4.00002L18.0019 4C19.1065 4 20.002 4.89543 20.002 6V16.0358C20.002 17.1403 19.1065 18.0358 18.002 18.0358L15.3757 18.0358C15.1427 18.0358 14.9171 18.1171 14.7377 18.2657L11.9977 20.5358L9.29398 18.2694C9.11393 18.1185 8.8865 18.0358 8.65157 18.0358H6.00195C4.89738 18.0358 4.00195 17.1403 4.00195 16.0358V6.00003Z\" fill=\"white\"/><path d=\"M13.2395 9.43518L12.5426 7.62334C12.4561 7.39842 12.24 7.25 11.999 7.25C11.758 7.25 11.5419 7.39842 11.4554 7.62334L10.7586 9.43518C10.657 9.69927 10.4483 9.90797 10.1842 10.0095L8.37236 10.7064C8.14744 10.7929 7.99902 11.009 7.99902 11.25C7.99902 11.491 8.14744 11.7071 8.37236 11.7936L10.1842 12.4905C10.4483 12.592 10.657 12.8007 10.7586 13.0648L11.4554 14.8767C11.5419 15.1016 11.758 15.25 11.999 15.25C12.24 15.25 12.4561 15.1016 12.5426 14.8767L13.2395 13.0648C13.3411 12.8007 13.5498 12.592 13.8138 12.4905L15.6257 11.7936C15.8506 11.7071 15.999 11.491 15.999 11.25C15.999 11.009 15.8506 10.7929 15.6257 10.7064L13.8138 10.0095C13.5498 9.90797 13.3411 9.69927 13.2395 9.43518Z\" fill=\"white\"/>',\n\tlightbulb:\n\t\t'<path d=\"M10 21H14M15.6076 15C17.6404 13.7751 19 11.5463 19 9C19 5.13401 15.866 2 12 2C8.13401 2 5 5.13401 5 9C5 11.5463 6.35958 13.7751 8.39241 15M15.6076 15C15.4111 15.1184 15.2084 15.2274 15 15.3264V17C15 17.5523 14.5523 18 14 18H10C9.44772 18 9 17.5523 9 17V15.3264C8.7916 15.2274 8.58886 15.1184 8.39241 15M15.6076 15H8.39241\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\twand: '<path d=\"M11.3908 12.6089L4 19.9996\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M18.3943 5.2792C18.5999 5.1944 18.8056 5.40008 18.7208 5.60565L17.1697 9.36581C17.1339 9.45248 17.1497 9.55186 17.2105 9.62323L19.8476 12.72C19.9918 12.8894 19.8597 13.1485 19.638 13.1314L15.5826 12.8182C15.4891 12.811 15.3994 12.8566 15.3503 12.9365L13.22 16.4015C13.1035 16.591 12.8163 16.5455 12.764 16.3293L11.8087 12.3756C11.7867 12.2844 11.7156 12.2133 11.6244 12.1913L7.67069 11.236C7.45453 11.1837 7.40903 10.8964 7.59847 10.78L11.0635 8.64965C11.1434 8.60055 11.189 8.51089 11.1818 8.41743L10.8686 4.36198C10.8515 4.14027 11.1106 4.00822 11.2799 4.15239L14.3768 6.78952C14.4481 6.8503 14.5475 6.86604 14.6342 6.83029L18.3943 5.2792Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tchip: '<path d=\"M8 5.5V4M12 5.5V4M16 5.5V4M8 20V18.5M12 20V18.5M16 20V18.5M8.75 15H15.25C15.6642 15 16 14.6642 16 14.25V9.75C16 9.33579 15.6642 9 15.25 9H8.75C8.33579 9 8 9.33579 8 9.75V14.25C8 14.6642 8.33579 15 8.75 15ZM6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6V18C4 19.1046 4.89543 20 6 20Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tcode: '<path d=\"M10 9.5L8.20711 11.2929C7.81658 11.6834 7.81658 12.3166 8.20711 12.7071L10 14.5M14 9.5L15.7929 11.2929C16.1834 11.6834 16.1834 12.3166 15.7929 12.7071L14 14.5M6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6V18C4 19.1046 4.89543 20 6 20Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tlightning:\n\t\t'<path d=\"M4.11593 12.2764L8.61593 3.27639C8.70063 3.107 8.87376 3 9.06315 3H17.121C17.5097 3 17.7497 3.42399 17.5498 3.75725L15.4585 7.24275C15.2585 7.57601 15.4986 8 15.8872 8H20.6909C21.1505 8 21.3666 8.56776 21.0235 8.87338L7.38117 21.0236C7.00034 21.3628 6.41568 20.981 6.57301 20.4959L8.79194 13.6543C8.8967 13.3312 8.6559 13 8.31633 13H4.56314C4.19145 13 3.94971 12.6088 4.11593 12.2764Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tvibe: '<path d=\"M18.9847 2.4329C18.9568 2.18651 18.7485 2.00025 18.5005 2C18.2525 1.99975 18.0438 2.18557 18.0154 2.43191C17.838 3.96993 16.9699 4.83801 15.4319 5.01541C15.1856 5.04382 14.9997 5.25253 15 5.5005C15.0003 5.74847 15.1865 5.9568 15.4329 5.9847C16.9491 6.15645 17.8774 7.01617 18.0141 8.55536C18.0365 8.80725 18.2477 9.00028 18.5005 9C18.7534 8.99971 18.9642 8.80621 18.986 8.55426C19.1173 7.03683 20.0368 6.11734 21.5543 5.98599C21.8062 5.96418 21.9997 5.75344 22 5.50055C22.0003 5.24766 21.8073 5.03648 21.5554 5.01411C20.0162 4.87738 19.1564 3.94911 18.9847 2.4329Z\" fill=\"white\"/><path d=\"M2 20C2 16.6863 4.68629 14 8 14H8.5\" fill=\"white\"/><path d=\"M11 20L12.6892 14.0879C12.8732 13.444 13.4617 13 14.1315 13H20.5417C21.2725 13 21.8001 13.6995 21.5994 14.4022L20.2072 19.2747C20.0846 19.704 19.6922 20 19.2457 20H11ZM11 20H7\" fill=\"white\"/><circle cx=\"8.75\" cy=\"7.5\" r=\"3.5\" stroke=\"white\" stroke-width=\"2\"/>',\n\tnetwork:\n\t\t'<path d=\"M12 6.8501L16 7.2501M17.75 10.0001L16.55 14.0001M13.5 14.3572L12 12.0001L10.4091 9.5001M6.25 14.0001L7.45 10.0001M8 16.7501L12 17.1501\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"18.5\" cy=\"7.5\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"5.5\" cy=\"16.5\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"8.5\" cy=\"6.5\" r=\"3.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"15.5\" cy=\"17.5\" r=\"3.5\" stroke=\"white\" stroke-width=\"2\"/>',\n\tconsole:\n\t\t'<path d=\"M7.5 8L9.25 9.75L7.5 11.5M12 11.5H14M6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6V18C4 19.1046 4.89543 20 6 20Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tprompt:\n\t\t'<path d=\"M6 5H5C3.89543 5 3 5.89543 3 7V8\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M18 5H19C20.1046 5 21 5.89543 21 7V8\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M21 16V17C21 18.1046 20.1046 19 19 19H18\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 19H5C3.89543 19 3 18.1046 3 17V16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M8 10H16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M8 14H14\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tglobe:\n\t\t'<path d=\"M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M21 12H3\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12 21C10.067 21 8.5 16.9706 8.5 12C8.5 7.02944 10.067 3 12 3C13.933 3 15.5 7.02944 15.5 12C15.5 16.9706 13.933 21 12 21Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\ttarget:\n\t\t'<path d=\"M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M17 12C17 14.7614 14.7614 17 12 17C9.23858 17 7 14.7614 7 12C7 9.23858 9.23858 7 12 7C14.7614 7 17 9.23858 17 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M13 12C13 12.5523 12.5523 13 12 13C11.4477 13 11 12.5523 11 12C11 11.4477 11.4477 11 12 11C12.5523 11 13 11.4477 13 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tdiamond:\n\t\t'<path d=\"M8.28256 4C7.77978 4 7.29545 4.18937 6.926 4.53039L2.53016 8.58809C1.69548 9.35857 1.66929 10.6687 2.47251 11.4719L10.5864 19.5858C11.3674 20.3668 12.6338 20.3668 13.4148 19.5858L21.5287 11.4719C22.3319 10.6687 22.3057 9.35857 21.471 8.58809L17.0752 4.53039C16.7057 4.18937 16.2214 4 15.7186 4H8.28256Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9.5 8L7.5 10L9.5 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tstar: '<path d=\"M11.5288 2.29524C11.7179 1.90159 12.2821 1.90159 12.4712 2.29524L14.9458 7.44648C15.0219 7.60491 15.1735 7.71434 15.3487 7.73728L21.0456 8.4832C21.4809 8.5402 21.6552 9.07312 21.3368 9.37342L17.1693 13.303C17.0412 13.4238 16.9832 13.6009 17.0154 13.7735L18.0616 19.3857C18.1416 19.8146 17.6852 20.144 17.2993 19.9359L12.249 17.2133C12.0937 17.1296 11.9063 17.1296 11.751 17.2133L6.70073 19.9359C6.3148 20.144 5.85841 19.8146 5.93837 19.3857L6.98459 13.7735C7.01677 13.6009 6.95885 13.4238 6.83068 13.303L2.66324 9.37342C2.34476 9.07312 2.51909 8.5402 2.95444 8.4832L8.65127 7.73728C8.82648 7.71434 8.97811 7.60491 9.05422 7.44648L11.5288 2.29524Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\theart:\n\t\t'<path d=\"M21 10C21 15.75 12.75 20 12 20C11.25 20 3 15.75 3 10C3 6 5.5 4 8 4C10.5 4 12 5.5 12 5.5C12 5.5 13.5 4 16 4C18.5 4 21 6 21 10Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tshield:\n\t\t'<path d=\"M20 7.17737C20 6.32338 19.4578 5.56361 18.6502 5.286L12.6502 3.2235C12.2288 3.07866 11.7712 3.07866 11.3498 3.22349L5.34984 5.286C4.54224 5.56361 4 6.32338 4 7.17737V11.9123C4 16.8848 8 19 12 21.1579C16 19 20 16.8848 20 11.9123V7.17737Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\trocket:\n\t\t'<path d=\"M3 21H5C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19V21Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.00098 13H4.76717C3.98987 13 3.50976 12.152 3.90968 11.4855L5.41837 8.97101C5.77982 8.3686 6.43083 8 7.13336 8H11.251C13.7671 5.25513 16.4925 3.3474 20.0017 3.04278C20.5519 2.99502 21.006 3.44906 20.9582 3.99927C20.6536 7.50845 18.7459 10.2339 16.001 12.75V16.8676C16.001 17.5701 15.6324 18.2212 15.03 18.5826L12.5155 20.0913C11.849 20.4912 11.001 20.0111 11.001 19.2338V17L7.00098 13Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 13L11.25 8\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M16 12.75L11 17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tcrown:\n\t\t'<path d=\"M4.16831 17.4079L2 7L8 10L12 4L16 10L22 7L19.8317 17.4079C19.6385 18.3353 18.8211 19 17.8737 19H6.12628C5.17892 19 4.36153 18.3353 4.16831 17.4079Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\ttrophy:\n\t\t'<path d=\"M12.0039 17V14\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M18 5H19C20.1046 5 21 5.89543 21 7C21 8.65685 19.6569 10 18 10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 5C6 3.89543 6.89543 3 8 3H16C17.1046 3 18 3.89543 18 5V8C18 11.3137 15.3137 14 12 14C8.68629 14 6 11.3137 6 8V5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 19C7 17.8954 7.89543 17 9 17H15C16.1046 17 17 17.8954 17 19C17 20.1046 16.1046 21 15 21H9C7.89543 21 7 20.1046 7 19Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 5H5C3.89543 5 3 5.89543 3 7C3 8.65685 4.34315 10 6 10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tcompass:\n\t\t'<path d=\"M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M14.6558 8.73023L10.5513 9.84965C10.2097 9.94281 9.94281 10.2097 9.84965 10.5513L8.73023 14.6558C8.62843 15.0291 8.97092 15.3716 9.34417 15.2698L13.4487 14.1504C13.7903 14.0572 14.0572 13.7903 14.1504 13.4487L15.2698 9.34417C15.3716 8.97092 15.0291 8.62843 14.6558 8.73023Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tfire: '<path d=\"M19.5 13.8122C19.5 23.3907 4.5 23.4012 4.5 13.8122C4.5 6.61352 12 2.5 12 2.5C12 2.5 19.5 6.61352 19.5 13.8122Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M15.5 17.4061C15.5 22.1954 8.5 22.2006 8.5 17.4061C8.5 13.8068 12 11.75 12 11.75C12 11.75 15.5 13.8068 15.5 17.4061Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tkey: '<path d=\"M20.8002 9.8753L20.0194 10.5L20.0194 10.5L20.8002 9.8753ZM22.0002 11.3753L21.2194 12V12L22.0002 11.3753ZM22.0002 12.6247L21.2194 12V12L22.0002 12.6247ZM20.8002 14.1247L20.0194 13.5L20.0194 13.5L20.8002 14.1247ZM18 14.5L17.5528 15.3944C17.6916 15.4639 17.8448 15.5 18 15.5V14.5ZM16 13.5L16.4472 12.6056C16.1657 12.4648 15.8343 12.4648 15.5528 12.6056L16 13.5ZM14 14.5V15.5C14.1552 15.5 14.3084 15.4639 14.4472 15.3944L14 14.5ZM11.0141 9.01843L11.8165 8.42152L11.8165 8.42152L11.0141 9.01843ZM11.0141 14.9816L10.2118 14.3847V14.3847L11.0141 14.9816ZM6.5 12C6.5 11.7239 6.72386 11.5 7 11.5V13.5C7.82843 13.5 8.5 12.8284 8.5 12H6.5ZM7 11.5C7.27614 11.5 7.5 11.7239 7.5 12H5.5C5.5 12.8284 6.17157 13.5 7 13.5V11.5ZM7.5 12C7.5 12.2761 7.27614 12.5 7 12.5V10.5C6.17157 10.5 5.5 11.1716 5.5 12H7.5ZM7 12.5C6.72386 12.5 6.5 12.2761 6.5 12H8.5C8.5 11.1716 7.82843 10.5 7 10.5V12.5ZM6.5 13H7.5V11H6.5V13ZM7 16C4.79086 16 3 14.2091 3 12H1C1 15.3137 3.68629 18 7 18V16ZM3 12C3 9.79086 4.79086 8 7 8V6C3.68629 6 1 8.68629 1 12H3ZM20.0194 10.5L21.2194 12L22.7811 10.7506L21.5811 9.25061L20.0194 10.5ZM21.2194 12L20.0194 13.5L21.5811 14.7494L22.7811 13.2494L21.2194 12ZM20.0194 13.5H18V15.5H20.0194V13.5ZM18.4472 13.6056L16.4472 12.6056L15.5528 14.3944L17.5528 15.3944L18.4472 13.6056ZM15.5528 12.6056L13.5528 13.6056L14.4472 15.3944L16.4472 14.3944L15.5528 12.6056ZM11.9079 10.5H20.0194V8.5H11.9079V10.5ZM7 8C8.31459 8 9.48107 8.63311 10.2118 9.61533L11.8165 8.42152C10.7246 6.9539 8.97356 6 7 6V8ZM14 13.5H11.9079V15.5H14V13.5ZM10.2118 14.3847C9.48107 15.3669 8.31459 16 7 16V18C8.97356 18 10.7246 17.0461 11.8165 15.5785L10.2118 14.3847ZM11.9079 13.5C11.1751 13.5 10.5749 13.8967 10.2118 14.3847L11.8165 15.5785C11.8445 15.5408 11.8734 15.5183 11.8929 15.5074C11.9106 15.4976 11.9148 15.5 11.9079 15.5V13.5ZM20.0194 13.5L20.0194 13.5V15.5C20.6269 15.5 21.2016 15.2238 21.5811 14.7494L20.0194 13.5ZM11.9079 8.5C11.9148 8.5 11.9106 8.50239 11.8929 8.49258C11.8734 8.48172 11.8445 8.45923 11.8165 8.42152L10.2118 9.61533C10.5749 10.1033 11.1751 10.5 11.9079 10.5V8.5ZM21.2194 12V12L22.7811 13.2494C23.3655 12.519 23.3655 11.481 22.7811 10.7506L21.2194 12ZM21.5811 9.25061C21.2016 8.77618 20.6269 8.5 20.0194 8.5V10.5L20.0194 10.5L21.5811 9.25061Z\" fill=\"white\"/>',\n\tlock: '<path d=\"M5 12C5 10.8954 5.89543 10 7 10H17C18.1046 10 19 10.8954 19 12V19C19 20.1046 18.1046 21 17 21H7C5.89543 21 5 20.1046 5 19V12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M16 9.5V7C16 4.79086 14.2091 3 12 3C9.79086 3 8 4.79086 8 7V9.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12 14V17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tbookmark:\n\t\t'<path d=\"M19 19.9948V5C19 3.89543 18.1046 3 17 3H7C5.89543 3 5 3.89543 5 5V19.9948C5 20.8047 5.91243 21.2787 6.57503 20.813L10.8499 17.8083C11.54 17.3233 12.46 17.3233 13.1501 17.8083L17.425 20.813C18.0876 21.2787 19 20.8047 19 19.9948Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tstore:\n\t\t'<path d=\"M4 10V18C4 19.1046 4.89543 20 6 20H18C19.1046 20 20 19.1046 20 18V10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M14.4996 4H9.49956L9.2133 8.00762C9.0978 9.62461 10.3785 11 11.9996 11C13.6207 11 14.9013 9.62461 14.7858 8.00763L14.4996 4Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9.50047 4H5.73506C4.73976 4 3.89592 4.73186 3.75516 5.71716L3.4699 7.71396C3.22214 9.44831 4.56792 11 6.31987 11C7.83025 11 9.08385 9.83276 9.19146 8.32621L9.50047 4Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M18.2654 4H14.5L14.809 8.32621C14.9166 9.83276 16.1702 11 17.6806 11C19.4326 11 20.7783 9.44831 20.5306 7.71396L20.2453 5.71716C20.1046 4.73186 19.2607 4 18.2654 4Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tbag: '<path d=\"M15.0001 8C15.0001 9.65685 13.6569 11 12.0001 11C10.3432 11 9.00008 9.65685 9.00008 8M4.88288 5.87524L4.13288 17.8752C4.06092 19.0266 4.97534 20 6.12899 20H17.8712C19.0248 20 19.9392 19.0266 19.8673 17.8752L19.1173 5.87524C19.0514 4.82117 18.1773 4 17.1212 4H6.87899C5.82286 4 4.94876 4.82117 4.88288 5.87524Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\t\"credit-card\":\n\t\t'<path d=\"M3 10V17C3 18.1046 3.89543 19 5 19H19C20.1046 19 21 18.1046 21 17V10M3 10V7C3 5.89543 3.89543 5 5 5H19C20.1046 5 21 5.89518 21 6.99975V10M3 10H21\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\treceipt:\n\t\t'<path d=\"M9 8H15M9 12H11M19 21V5C19 3.89543 18.1046 3 17 3H7C5.89543 3 5 3.89543 5 5V21L7.33333 19L9.66667 21L12 19L14.3333 21L16.6667 19L19 21Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tbank: '<path d=\"M11.1056 2.94723L3.68328 6.65838C3.26452 6.86776 3 7.29576 3 7.76395C3 8.44661 3.55341 9.00002 4.23607 9.00002H19.7639C20.4466 9.00002 21 8.44661 21 7.76395C21 7.29576 20.7355 6.86776 20.3167 6.65838L12.8944 2.94723C12.3314 2.6657 11.6686 2.6657 11.1056 2.94723Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19.6126 20H4.38749C3.70493 20 3.22296 19.3313 3.4388 18.6838L3.54421 18.3675C3.81644 17.5509 4.58072 17 5.44158 17H18.5585C19.4194 17 20.1837 17.5509 20.4559 18.3675L20.5613 18.6838C20.7772 19.3313 20.2952 20 19.6126 20Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19 9V17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M15 17V9\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5 9V17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9 17V9\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\twallet:\n\t\t'<path d=\"M3 8V7C3 5.89543 3.89543 5 5 5H19C20.1046 5 21 5.89543 21 7V8M3 8H21M3 8V11M21 8V11M21 11V17C21 18.1046 20.1046 19 19 19H5C3.89543 19 3 18.1046 3 17V11M21 11H15C15 12.1046 14.1046 13 13 13H11C9.89543 13 9 12.1046 9 11H3\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tpackage:\n\t\t'<path d=\"M9 4V7.5C9 8.32843 9.67157 9 10.5 9H13.5C14.3284 9 15 8.32843 15 7.5V4M14 16H16M4 6V18C4 19.1046 4.89543 20 6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\ttruck:\n\t\t'<path d=\"M10 16.5C10 17.8807 8.88071 19 7.5 19C6.11929 19 5 17.8807 5 16.5C5 15.1193 6.11929 14 7.5 14C8.88071 14 10 15.1193 10 16.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19 16.5C19 17.8807 17.8807 19 16.5 19C15.1193 19 14 17.8807 14 16.5C14 15.1193 15.1193 14 16.5 14C17.8807 14 19 15.1193 19 16.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M10 16H14\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9 14V7H6.07037C5.40166 7 4.7772 7.3342 4.40627 7.8906L3.3359 9.49615C3.11688 9.82469 3 10.2107 3 10.6056V14.2857C3 15.2325 3.76751 16 4.71429 16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9 9V7C9 5.89543 9.89543 5 11 5H19C20.1046 5 21 5.89543 21 7V14C21 15.1046 20.1046 16 19 16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tmegaphone:\n\t\t'<path d=\"M17.9961 14.0001C19.6529 14.0001 20.9961 12.657 20.9961 11.0001C20.9961 9.34325 19.6529 8.0001 17.9961 8.0001M12.8254 18.0001C12.4136 19.1653 11.3023 20.0001 9.99609 20.0001C8.33924 20.0001 6.99609 18.657 6.99609 17.0001V15.5001M6.99829 6.5001V15.5001M17.9961 5.73752V16.2627C17.9961 17.617 16.6784 18.5797 15.3882 18.1681L4.38819 14.6585C3.55899 14.394 2.99609 13.6235 2.99609 12.7532V9.24704C2.99609 8.37667 3.55899 7.60622 4.38819 7.34167L15.3882 3.83215C16.6784 3.42051 17.9961 4.38325 17.9961 5.73752Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\temail:\n\t\t'<path d=\"M20.782 6.09202L19.891 6.54601L19.891 6.54601L20.782 6.09202ZM19.908 5.21799L20.362 4.32698V4.32698L19.908 5.21799ZM4.09202 5.21799L3.63803 4.32698L3.63803 4.32698L4.09202 5.21799ZM3.21799 6.09202L2.32698 5.63803L2.32698 5.63803L3.21799 6.09202ZM3.21799 17.908L4.10899 17.454L4.10899 17.454L3.21799 17.908ZM4.09202 18.782L4.54601 17.891H4.54601L4.09202 18.782ZM19.908 18.782L20.362 19.673V19.673L19.908 18.782ZM20.782 17.908L19.891 17.454L19.891 17.454L20.782 17.908ZM21 8.2H20V15.8H21H22V8.2H21ZM21 8.2H22C22 7.65645 22.0008 7.18864 21.9694 6.80497C21.9371 6.40963 21.8658 6.01641 21.673 5.63803L20.782 6.09202L19.891 6.54601C19.9162 6.59545 19.9539 6.69617 19.9761 6.96784C19.9992 7.25117 20 7.62345 20 8.2H21ZM20.782 6.09202L21.673 5.63803C21.3854 5.07354 20.9265 4.6146 20.362 4.32698L19.908 5.21799L19.454 6.10899C19.6422 6.20487 19.7951 6.35785 19.891 6.54601L20.782 6.09202ZM17.8 5V6C18.3766 6 18.7488 6.00078 19.0322 6.02393C19.3038 6.04612 19.4045 6.0838 19.454 6.10899L19.908 5.21799L20.362 4.32698C19.9836 4.13419 19.5904 4.06287 19.195 4.03057C18.8114 3.99922 18.3436 4 17.8 4V5ZM6.2 5V6H17.8V5V4H6.2V5ZM6.2 5V4C5.65645 4 5.18864 3.99922 4.80497 4.03057C4.40963 4.06287 4.01641 4.13419 3.63803 4.32698L4.09202 5.21799L4.54601 6.10899C4.59545 6.0838 4.69617 6.04612 4.96784 6.02393C5.25117 6.00078 5.62345 6 6.2 6V5ZM3.21799 6.09202L4.10899 6.54601C4.20487 6.35785 4.35785 6.20487 4.54601 6.10899L4.09202 5.21799L3.63803 4.32698C3.07354 4.6146 2.6146 5.07354 2.32698 5.63803L3.21799 6.09202ZM3 8.2H4C4 7.62345 4.00078 7.25117 4.02393 6.96784C4.04612 6.69617 4.0838 6.59545 4.10899 6.54601L3.21799 6.09202L2.32698 5.63803C2.13419 6.01641 2.06287 6.40963 2.03057 6.80497C1.99922 7.18864 2 7.65645 2 8.2H3ZM3 15.8H4V8.2H3H2V15.8H3ZM3 15.8H2C2 16.3435 1.99922 16.8114 2.03057 17.195C2.06287 17.5904 2.13419 17.9836 2.32698 18.362L3.21799 17.908L4.10899 17.454C4.0838 17.4045 4.04612 17.3038 4.02393 17.0322C4.00078 16.7488 4 16.3765 4 15.8H3ZM4.09202 18.782L4.54601 17.891C4.35785 17.7951 4.20487 17.6421 4.10899 17.454L3.21799 17.908L2.32698 18.362C2.6146 18.9265 3.07354 19.3854 3.63803 19.673L4.09202 18.782ZM6.2 19V18C5.62345 18 5.25117 17.9992 4.96784 17.9761C4.69617 17.9539 4.59545 17.9162 4.54601 17.891L4.09202 18.782L3.63803 19.673C4.01641 19.8658 4.40963 19.9371 4.80497 19.9694C5.18864 20.0008 5.65645 20 6.2 20V19ZM17.8 19V18H6.2V19V20H17.8V19ZM17.8 19V20C18.3436 20 18.8114 20.0008 19.195 19.9694C19.5904 19.9371 19.9836 19.8658 20.362 19.673L19.908 18.782L19.454 17.891C19.4045 17.9162 19.3038 17.9539 19.0322 17.9761C18.7488 17.9992 18.3766 18 17.8 18V19ZM20.782 17.908L19.891 17.454C19.7951 17.6421 19.6422 17.7951 19.454 17.891L19.908 18.782L20.362 19.673C20.9265 19.3854 21.3854 18.9265 21.673 18.362L20.782 17.908ZM21 15.8H20C20 16.3765 19.9992 16.7488 19.9761 17.0322C19.9539 17.3038 19.9162 17.4045 19.891 17.454L20.782 17.908L21.673 18.362C21.8658 17.9836 21.9371 17.5904 21.9694 17.195C22.0008 16.8114 22 16.3435 22 15.8H21Z\" fill=\"white\"/><path d=\"M21 5.63635L13.2665 11.9638C12.5297 12.5666 11.4703 12.5666 10.7335 11.9638L3 5.63635\" fill=\"white\"/>',\n\tbell: '<path d=\"M4.69376 9.44981C5.15435 5.76511 8.28661 3 12 3C15.7134 3 18.8456 5.76511 19.3062 9.44981L19.969 14.7519C20.1182 15.9456 19.1874 17 17.9844 17H6.01555C4.81256 17 3.88178 15.9456 4.031 14.7519L4.69376 9.44981Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M16 17C16 19.2091 14.2091 21 12 21C9.79086 21 8 19.2091 8 17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tpeople:\n\t\t'<path d=\"M15.5 6.5C15.5 8.433 13.933 10 12 10C10.067 10 8.5 8.433 8.5 6.5C8.5 4.567 10.067 3 12 3C13.933 3 15.5 4.567 15.5 6.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12.0011 13C8.60997 13 6.03711 15.0143 4.9836 17.8629C4.5748 18.9682 5.51944 20 6.69796 20H17.3043C18.4828 20 19.4274 18.9682 19.0186 17.8629C17.9651 15.0143 15.3923 13 12.0011 13Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tsupport:\n\t\t'<path d=\"M6 10H4.5C3.67157 10 3 10.6716 3 11.5V15C3 15.8284 3.67157 16.5 4.5 16.5H6V10Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M20 10H18.5V16.5H20C20.8284 16.5 21.5 15.8284 21.5 15V11.5C21.5 10.6716 20.8284 10 20 10Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19.5 10V9.75C19.5 6.02208 16.2541 3 12.25 3C8.24594 3 5 6.02208 5 9.75V10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12 19V19.5C12 20.3284 12.6716 21 13.5 21H15.25C17.7353 21 19.75 18.9853 19.75 16.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\thandshake:\n\t\t'<path d=\"M11.8305 5.68856C9.57907 3.43715 5.92881 3.43715 3.6774 5.68856C1.57785 7.78811 1.40103 11.1544 3.42019 13.3313C5.71921 15.8101 8.14783 18.1408 10.7345 20.3519C11.4619 20.9737 12.5313 20.9737 13.2587 20.3519C15.8453 18.1408 18.2739 15.8101 20.573 13.3313C22.5921 11.1544 22.4153 7.78811 20.3158 5.68856C18.0644 3.43715 14.4141 3.43715 12.1627 5.68856L8.8146 9.03664C8.22881 9.62243 8.22881 10.5722 8.8146 11.158C9.98617 12.3295 11.8857 12.3295 13.0572 11.158L13.7643 10.4509C14.1549 10.0603 14.788 10.0603 15.1786 10.4509L18.7141 13.9864\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tpill: '<path d=\"M17.4541 10.0962C18.6109 8.31497 18.4083 5.90826 16.8462 4.34619C15.0513 2.55127 12.1411 2.55127 10.3462 4.34619L4.34619 10.3462C2.55127 12.1411 2.55127 15.0513 4.34619 16.8462C5.90826 18.4083 8.31497 18.6109 10.0962 17.4541\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 7.5L11 11\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M16.5 20.5L14.5 10.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"15.5\" cy=\"15.5\" r=\"5.5\" stroke=\"white\" stroke-width=\"2\"/>',\n\t\"heart-beat\":\n\t\t'<path d=\"M16 12H14.5L13 14L10.5 10L9.25 12H8M12 5.76835C18.1619 -0.481837 28.7252 11.1257 12 20.5C-4.72523 11.1257 5.83803 -0.481838 12 5.76835Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tbook: '<path d=\"M9 6C8.44772 6 8 6.44772 8 7C8 7.55228 8.44772 8 9 8V6ZM15 8C15.5523 8 16 7.55228 16 7C16 6.44772 15.5523 6 15 6V8ZM9 10C8.44772 10 8 10.4477 8 11C8 11.5523 8.44772 12 9 12V10ZM12 12C12.5523 12 13 11.5523 13 11C13 10.4477 12.5523 10 12 10V12ZM7 4H17V2H7V4ZM18 5V19H20V5H18ZM17 20H7V22H17V20ZM6 19V5H4V19H6ZM7 20C6.44771 20 6 19.5523 6 19H4C4 20.6569 5.34315 22 7 22V20ZM18 19C18 19.5523 17.5523 20 17 20V22C18.6569 22 20 20.6569 20 19H18ZM17 4C17.5523 4 18 4.44772 18 5H20C20 3.34315 18.6569 2 17 2V4ZM7 2C5.34315 2 4 3.34315 4 5H6C6 4.44772 6.44772 4 7 4V2ZM18 12V15H20V12H18ZM17 16H7V18H17V16ZM7 22H10V20H7V22ZM7 16C5.34315 16 4 17.3431 4 19H6C6 18.4477 6.44772 18 7 18V16ZM18 15C18 15.5523 17.5523 16 17 16V18C18.6569 18 20 16.6569 20 15H18ZM9 8H15V6H9V8ZM9 12H12V10H9V12Z\" fill=\"white\"/>',\n\tgraduate:\n\t\t'<path d=\"M23 9L12 14L1 9L12 4L23 9ZM23 9V16M5 11V15.3025C5 16.0398 5.40565 16.7173 6.05556 17.0655L11.0556 19.744C11.6455 20.0601 12.3545 20.0601 12.9444 19.744L17.9444 17.0655C18.5944 16.7173 19 16.0398 19 15.3025V11\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n};\n\n/**\n * Renders preset icon SVG — uses trusted static SVG content extracted from\n * @central-icons-react at build time. Content is hardcoded (not user input),\n * so innerHTML usage is safe from XSS.\n */\nfunction AgentPresetIcon({ presetId }: { presetId: string }) {\n\tconst svgContent = PRESET_SVG[presetId] ?? PRESET_SVG.sparkle;\n\treturn (\n\t\t// biome-ignore lint: trusted static SVG content from our icon library\n\t\t<svg\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tstyle={{ width: \"55%\", height: \"55%\" }}\n\t\t\tdangerouslySetInnerHTML={{ __html: svgContent ?? \"\" }}\n\t\t/>\n\t);\n}\n\n/**\n * Unified support widget — Intercom-style with tab navigation.\n * Two tabs: Home + Messages. Sub-views: conversation + new conversation.\n */\nexport function DefaultWidget({ hideLauncher = false }: { hideLauncher?: boolean } = {}) {\n\tconst { isReady, website, agentConfig } = useWidget();\n\tuseI18n();\n\tconst { client, store, hasBootstrapError, wsDisconnected, retryBootstrap } = useWidgetContext();\n\tconst { conversations, create, isCreating, setActiveConversation } = useConversations();\n\tconst activeId = useWidgetStore((s) => s.activeConversationId);\n\tconst isDismissed = useWidgetStore((s) => s.isDismissed);\n\tconst { totalUnread } = useUnread();\n\n\tconst contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_CONTENT_TABS;\n\n\tconst visitorContact = useWidgetStore((s) => s.visitor?.contact);\n\n\t// DEV: email prompt debug\n\tif (process.env.NODE_ENV !== \"production\") {\n\t\tconsole.debug(\"[Widget]\", {\n\t\t\treqEmail: agentConfig?.requireVisitorEmail,\n\t\t\tcontact: visitorContact?.email ?? null,\n\t\t\tactiveId,\n\t\t});\n\t}\n\n\tconst storeIsOpen = useWidgetStore((s) => s.isOpen);\n\tconst [isClosing, setIsClosing] = useState(false);\n\tconst isOpen = storeIsOpen || isClosing;\n\tconst [activeTab, setActiveTab] = useState<Tab>(\"home\");\n\tconst [subView, setSubView] = useState<SubView>(null);\n\tconst [newText, setNewText] = useState(\"\");\n\tconst [contentDetailSlug, setContentDetailSlug] = useState<string | null>(null);\n\tconst [contentCategoryName, setContentCategoryName] = useState<string | null>(null);\n\n\t// Sync API-driven navigation: when store.activeConversationId changes externally\n\t// (via window.Helpway.openConversation), drive the local subView to match.\n\tconst prevActiveIdRef = useRef(activeId);\n\tuseEffect(() => {\n\t\tif (activeId && activeId !== prevActiveIdRef.current && subView !== \"conversation\") {\n\t\t\tsetSubView(\"conversation\");\n\t\t}\n\t\tprevActiveIdRef.current = activeId;\n\t}, [activeId, subView]);\n\n\t// Consume newConversationPrefill from global API (window.Helpway.newConversation)\n\tconst prefill = useWidgetStore((s) => s.newConversationPrefill);\n\tuseEffect(() => {\n\t\tif (prefill !== null) {\n\t\t\tif (prefill.length > 0) setNewText(prefill);\n\t\t\tsetSubView(\"new\");\n\t\t\tsetActiveTab(\"home\");\n\t\t\tstore.getState().setNewConversationPrefill(null);\n\t\t}\n\t}, [prefill, store]);\n\tconst closeTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n\t// Resolve welcome/subtitle here (used both by openNewConversation seed\n\t// and by the header). Hoisted above openNewConversation so the callback\n\t// captures a defined binding instead of hitting the TDZ at closure time.\n\tconst welcomeMsgRaw = agentConfig?.welcomeMessage;\n\tconst welcomeIsFactoryDefault =\n\t\t!welcomeMsgRaw || welcomeMsgRaw === DEFAULT_EN_WELCOME;\n\tconst welcomeMessage = welcomeMsgRaw?.startsWith(\"widget.\")\n\t\t? t(welcomeMsgRaw)\n\t\t: welcomeIsFactoryDefault\n\t\t\t? t(\"widget.welcome_message\")\n\t\t\t: welcomeMsgRaw;\n\n\tconst openConversation = useCallback(\n\t\t(id: string) => {\n\t\t\tsetActiveConversation(id);\n\t\t\tsetSubView(\"conversation\");\n\t\t},\n\t\t[setActiveConversation],\n\t);\n\n\tconst openNewConversation = useCallback(() => {\n\t\t// Seed a temp conversation + a stable welcome bubble and drop the user\n\t\t// straight into \"conversation\" view. This keeps the welcome bubble\n\t\t// mounted in the SAME React subtree across the first-send transition\n\t\t// (previously: \"new\" view → \"conversation\" view = unmount + remount =\n\t\t// CSS `hw-msg-appear` animation replays = the \"git-gel\" flash).\n\t\t//\n\t\t// useComposer notices the temp id and routes through createConversation\n\t\t// when the visitor sends their first message.\n\t\tconst agentId = agentConfig?.id;\n\t\tif (!agentId) {\n\t\t\t// No agent config yet — skip the seed and let the server decide.\n\t\t\t// The user can still compose; submit will call createConversation.\n\t\t\tsetSubView(\"new\");\n\t\t\treturn;\n\t\t}\n\t\tconst tempId = `temp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\t\tconst seedWelcome: TimelineItem = {\n\t\t\tid: `seed-welcome-${tempId}`,\n\t\t\tconversationId: tempId,\n\t\t\torganizationId: \"\",\n\t\t\ttype: \"message\",\n\t\t\tvisibility: \"public\",\n\t\t\ttext: welcomeMessage,\n\t\t\tparts: null,\n\t\t\tuserId: null,\n\t\t\tvisitorId: null,\n\t\t\taiAgentId: agentId,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t\teditedAt: null,\n\t\t\tdeletedAt: null,\n\t\t};\n\t\tstore.getState().setMessages(tempId, [seedWelcome]);\n\t\tsetActiveConversation(tempId);\n\t\tsetSubView(\"conversation\");\n\t}, [agentConfig?.id, store, setActiveConversation, welcomeMessage]);\n\n\tconst goBack = useCallback(() => {\n\t\tif (subView === \"content-detail\") {\n\t\t\t// If inside a grouped tab, go back to category items, not all the way to categories\n\t\t\tconst tabId = activeTab.startsWith(\"content:\") ? activeTab.slice(8) : null;\n\t\t\tconst activeContentTab = tabId ? contentTabs.find((t) => t.id === tabId) : null;\n\t\t\tif (activeContentTab?.tabType === \"grouped\" && contentCategoryName) {\n\t\t\t\tsetSubView(\"content-category\");\n\t\t\t\tsetContentDetailSlug(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetSubView(null);\n\t\t\tsetContentDetailSlug(null);\n\t\t\treturn;\n\t\t}\n\t\tif (subView === \"content-category\") {\n\t\t\tsetSubView(null);\n\t\t\tsetContentCategoryName(null);\n\t\t\treturn;\n\t\t}\n\t\t// Race-immune mark-seen: when leaving a conversation, the visitor has\n\t\t// effectively \"seen\" everything currently in it — including any AI reply\n\t\t// that may have arrived via WS milliseconds before they tapped back.\n\t\t// Without this, the WS event arriving AFTER setActiveConversation(null)\n\t\t// finds isViewing=false and increments unreadCount.\n\t\t// Skip temp-* IDs (server doesn't know about them yet).\n\t\tconst leavingId = store.getState().activeConversationId;\n\t\tif (leavingId && !leavingId.startsWith(\"temp-\")) {\n\t\t\tstore.getState().clearUnread(leavingId);\n\t\t\tclient.widget.markSeen.mutate({ conversationId: leavingId }).catch(() => {});\n\t\t}\n\t\tsetActiveConversation(null);\n\t\tsetSubView(null);\n\t}, [setActiveConversation, subView, activeTab, contentTabs, contentCategoryName, client, store]);\n\n\tconst switchTab = useCallback(\n\t\t(tab: Tab) => {\n\t\t\t// Save current tab state\n\t\t\ttabStateRef.current[activeTab] = { subView, activeId };\n\t\t\t// Restore target tab state (if any)\n\t\t\tconst saved = tabStateRef.current[tab];\n\t\t\tsetActiveTab(tab);\n\t\t\tsetSubView(saved?.subView ?? null);\n\t\t\tif (saved?.activeId != null) {\n\t\t\t\tsetActiveConversation(saved.activeId);\n\t\t\t} else if (!saved) {\n\t\t\t\tsetActiveConversation(null);\n\t\t\t}\n\t\t},\n\t\t[activeTab, subView, activeId, setActiveConversation],\n\t);\n\n\tconst setStoreOpen = useWidgetStore((s) => s.setOpen);\n\n\tconst handleBubbleClick = useCallback(() => {\n\t\tif (storeIsOpen) {\n\t\t\tconst leavingId = store.getState().activeConversationId;\n\t\t\tif (leavingId && !leavingId.startsWith(\"temp-\")) {\n\t\t\t\tstore.getState().clearUnread(leavingId);\n\t\t\t\tclient.widget.markSeen.mutate({ conversationId: leavingId }).catch(() => {});\n\t\t\t}\n\t\t\tsetIsClosing(true);\n\t\t\tcloseTimerRef.current = setTimeout(() => {\n\t\t\t\tsetIsClosing(false);\n\t\t\t\tsetStoreOpen(false);\n\t\t\t}, 200);\n\t\t} else {\n\t\t\tsetIsClosing(false);\n\t\t\tsetSubView(null);\n\t\t\tsetActiveTab(\"home\");\n\t\t\tsetStoreOpen(true);\n\t\t}\n\t}, [storeIsOpen, setStoreOpen, client, store]);\n\n\tconst handleClose = useCallback(() => {\n\t\tconst leavingId = store.getState().activeConversationId;\n\t\tif (leavingId && !leavingId.startsWith(\"temp-\")) {\n\t\t\tstore.getState().clearUnread(leavingId);\n\t\t\tclient.widget.markSeen.mutate({ conversationId: leavingId }).catch(() => {});\n\t\t}\n\t\tsetIsClosing(true);\n\t\tcloseTimerRef.current = setTimeout(() => {\n\t\t\tsetIsClosing(false);\n\t\t\tsetStoreOpen(false);\n\t\t}, 200);\n\t}, [setStoreOpen, client, store]);\n\n\tconst handleNewConversation = useCallback(async () => {\n\t\tconst trimmed = newText.trim();\n\t\tif (!trimmed || isCreating) return;\n\t\tconst conv = await create(trimmed);\n\t\tif (conv) {\n\t\t\tsetNewText(\"\");\n\t\t\tsetSubView(\"conversation\");\n\t\t}\n\t}, [newText, isCreating, create]);\n\n\tconst windowRef = useRef<HTMLDivElement>(null);\n\tconst bubbleRef = useRef<HTMLButtonElement>(null);\n\tconst tabStateRef = useRef<{ [tab: string]: { subView: SubView; activeId: string | null } }>({});\n\tconst touchStartY = useRef(0);\n\tconst touchDeltaY = useRef(0);\n\n\tconst handleTouchStart = useCallback((e: React.TouchEvent) => {\n\t\ttouchStartY.current = e.touches[0]?.clientY ?? 0;\n\t\ttouchDeltaY.current = 0;\n\t}, []);\n\n\tconst handleTouchMove = useCallback((e: React.TouchEvent) => {\n\t\tconst delta = (e.touches[0]?.clientY ?? 0) - touchStartY.current;\n\t\ttouchDeltaY.current = delta;\n\t\tif (delta > 0 && windowRef.current) {\n\t\t\twindowRef.current.style.transform = `translateY(${Math.min(delta, 200)}px)`;\n\t\t\twindowRef.current.style.opacity = `${Math.max(1 - delta / 400, 0.5)}`;\n\t\t}\n\t}, []);\n\n\tconst handleTouchEnd = useCallback(() => {\n\t\tif (windowRef.current) {\n\t\t\twindowRef.current.style.transform = \"\";\n\t\t\twindowRef.current.style.opacity = \"\";\n\t\t}\n\t\tif (touchDeltaY.current > 80) {\n\t\t\thandleClose();\n\t\t}\n\t}, [handleClose]);\n\n\t// iOS virtual keyboard — `height: 100%` in CSS refers to the LAYOUT\n\t// viewport, which doesn't shrink when the keyboard opens on iOS Safari.\n\t// The result: composer gets pushed below the visible area and visitors\n\t// can't see what they're typing. visualViewport.height is the one\n\t// reliable API that reflects post-keyboard space. We write it to a CSS\n\t// custom property the mobile @media block consumes.\n\tuseEffect(() => {\n\t\tif (!isOpen || !windowRef.current) return;\n\t\tconst vv = window.visualViewport;\n\t\tif (!vv) return;\n\t\tconst win = windowRef.current;\n\t\tconst applyHeight = () => {\n\t\t\twin.style.setProperty(\"--hw-visible-height\", `${vv.height}px`);\n\t\t};\n\t\tapplyHeight();\n\t\tvv.addEventListener(\"resize\", applyHeight);\n\t\tvv.addEventListener(\"scroll\", applyHeight);\n\t\treturn () => {\n\t\t\tvv.removeEventListener(\"resize\", applyHeight);\n\t\t\tvv.removeEventListener(\"scroll\", applyHeight);\n\t\t\twin.style.removeProperty(\"--hw-visible-height\");\n\t\t};\n\t}, [isOpen]);\n\n\t// Escape to close / back — listener attached to the widget window, NOT\n\t// document. Two reasons: (1) widget lives inside a shadow DOM; document\n\t// listeners fire for host-page key events too, which would close the\n\t// widget when a visitor presses ESC in the host site's own search box.\n\t// (2) WCAG 2.1 AA requires focus-scoped escape behavior for dialogs.\n\tuseEffect(() => {\n\t\tif (!isOpen || !windowRef.current) return;\n\t\tconst win = windowRef.current;\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (e.key === \"Escape\") {\n\t\t\t\tif (subView) {\n\t\t\t\t\tgoBack();\n\t\t\t\t} else {\n\t\t\t\t\thandleClose();\n\t\t\t\t\tsetTimeout(() => bubbleRef.current?.focus(), 220);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\twin.addEventListener(\"keydown\", handleKeyDown);\n\t\treturn () => win.removeEventListener(\"keydown\", handleKeyDown);\n\t}, [isOpen, subView, handleClose, goBack]);\n\n\t// Focus trap — same rationale: listen on the widget window so only\n\t// keydowns inside the widget are trapped. `document.activeElement`\n\t// returns the shadow HOST when focus is inside a shadow root; to find\n\t// the actually-focused element we walk into the shadow root.\n\tuseEffect(() => {\n\t\tif (!isOpen || !windowRef.current) return;\n\t\tconst win = windowRef.current;\n\t\tconst getFocusable = () =>\n\t\t\twin.querySelectorAll<HTMLElement>(\n\t\t\t\t'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n\t\t\t);\n\t\tconst getActive = (): Element | null => {\n\t\t\t// Prefer the shadow root's activeElement so focus tracking works\n\t\t\t// even when the widget is mounted inside a closed/open shadow DOM.\n\t\t\tconst root = win.getRootNode();\n\t\t\tif (root instanceof ShadowRoot) return root.activeElement;\n\t\t\treturn document.activeElement;\n\t\t};\n\t\tconst handleTab = (e: KeyboardEvent) => {\n\t\t\tif (e.key !== \"Tab\") return;\n\t\t\tconst focusable = getFocusable();\n\t\t\tif (focusable.length === 0) return;\n\t\t\tconst first = focusable[0];\n\t\t\tconst last = focusable[focusable.length - 1];\n\t\t\tconst active = getActive();\n\t\t\tif (e.shiftKey && active === first) {\n\t\t\t\te.preventDefault();\n\t\t\t\tlast?.focus();\n\t\t\t} else if (!e.shiftKey && active === last) {\n\t\t\t\te.preventDefault();\n\t\t\t\tfirst?.focus();\n\t\t\t}\n\t\t};\n\t\twin.addEventListener(\"keydown\", handleTab);\n\t\tconst focusable = getFocusable();\n\t\tif (focusable.length > 0) focusable[0]?.focus();\n\t\treturn () => win.removeEventListener(\"keydown\", handleTab);\n\t}, [isOpen]);\n\n\tconst showTabBar = subView === null;\n\tconst activeConvSummary = useWidgetStore((s) => {\n\t\tconst id = s.activeConversationId;\n\t\treturn id ? s.conversations.find((c) => c.id === id) : null;\n\t});\n\tconst hasTeamAgent = activeConvSummary?.lastMessageSenderType === \"team\" && activeConvSummary?.lastMessageSenderName;\n\tconst headerName = hasTeamAgent ? activeConvSummary.lastMessageSenderName! : (agentConfig?.name ?? website?.name ?? \"Support\");\n\tconst companyName = agentConfig?.name ?? website?.name ?? \"Support\";\n\tconst subtitleMsg = agentConfig?.subtitleText;\n\tconst subtitleIsFactoryDefault =\n\t\t!subtitleMsg || subtitleMsg === DEFAULT_EN_SUBTITLE;\n\tconst subtitleText = subtitleMsg?.startsWith(\"widget.\")\n\t\t? t(subtitleMsg)\n\t\t: subtitleIsFactoryDefault\n\t\t\t? t(\"widget.subtitle_text\")\n\t\t\t: subtitleMsg;\n\tconst brandColor = agentConfig?.brandColor ?? \"#0a0a0a\";\n\tconst widgetPosition = agentConfig?.widgetPosition ?? \"bottom-right\";\n\tconst launcherStyle = agentConfig?.launcherStyle ?? \"icon\";\n\tconst bubbleStyle = agentConfig?.bubbleStyle ?? \"rounded\";\n\n\treturn (\n\t\t<div\n\t\t\tclassName=\"hw-widget\"\n\t\t\tstyle={\n\t\t\t\t{\n\t\t\t\t\t\"--hw-primary\": brandColor,\n\t\t\t\t\t\"--hw-position-right\": widgetPosition === \"bottom-right\" ? \"20px\" : \"auto\",\n\t\t\t\t\t\"--hw-position-left\": widgetPosition === \"bottom-left\" ? \"20px\" : \"auto\",\n\t\t\t\t\t\"--hw-window-right\": widgetPosition === \"bottom-right\" ? \"0\" : \"auto\",\n\t\t\t\t\t\"--hw-window-left\": widgetPosition === \"bottom-left\" ? \"0\" : \"auto\",\n\t\t\t\t} as React.CSSProperties\n\t\t\t}\n\t\t>\n\t\t\t{isOpen && !isReady && !hasBootstrapError && (\n\t\t\t\t<div className={`hw-window ${isClosing ? \"hw-window--closing\" : \"\"}`}>\n\t\t\t\t\t<div className=\"hw-skeleton-loading\">\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 120 }} />\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 200 }} />\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 160 }} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{isOpen && hasBootstrapError && (\n\t\t\t\t<div className={`hw-window ${isClosing ? \"hw-window--closing\" : \"\"}`}>\n\t\t\t\t\t<div className=\"hw-bootstrap-error\">\n\t\t\t\t\t\t<div className=\"hw-bootstrap-error-text\">{t(\"widget.error_desc\")}</div>\n\t\t\t\t\t\t<button type=\"button\" className=\"hw-bootstrap-error-retry\" onClick={retryBootstrap}>\n\t\t\t\t\t\t\t{t(\"widget.retry\")}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{isOpen && isReady && (\n\t\t\t\t<div\n\t\t\t\t\tref={windowRef}\n\t\t\t\t\tclassName={`hw-window ${isClosing ? \"hw-window--closing\" : \"\"} ${\n\t\t\t\t\t\tsubView === \"content-detail\" ? \"hw-window--reading\" : \"\"\n\t\t\t\t\t}`}\n\t\t\t\t\trole=\"dialog\"\n\t\t\t\t\taria-label={t(\"widget.aria_chat\")}\n\t\t\t\t\taria-modal=\"true\"\n\t\t\t\t\tonTouchStart={handleTouchStart}\n\t\t\t\t\tonTouchMove={handleTouchMove}\n\t\t\t\t\tonTouchEnd={handleTouchEnd}\n\t\t\t\t>\n\t\t\t\t\t{/* Drag handle for mobile swipe-down */}\n\t\t\t\t\t<div className=\"hw-drag-handle\">\n\t\t\t\t\t\t<div className=\"hw-drag-handle-pill\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t{/* WebSocket disconnect banner */}\n\t\t\t\t\t{wsDisconnected && (\n\t\t\t\t\t\t<div className=\"hw-disconnect\">\n\t\t\t\t\t\t\t<div className=\"hw-disconnect-dot\" />\n\t\t\t\t\t\t\t{t(\"widget.reconnecting\")}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t{/* ── Sub-view header: content-detail/content-category gets centered title ── */}\n\t\t\t\t\t{(subView === \"content-detail\" || subView === \"content-category\") &&\n\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\tconst tabId = activeTab.replace(\"content:\", \"\");\n\t\t\t\t\t\t\tconst contentTab = contentTabs.find((t) => t.id === tabId);\n\t\t\t\t\t\t\t// Show category name when viewing items within a category\n\t\t\t\t\t\t\tconst headerTitle =\n\t\t\t\t\t\t\t\tsubView === \"content-category\" && contentCategoryName\n\t\t\t\t\t\t\t\t\t? contentCategoryName\n\t\t\t\t\t\t\t\t\t: contentTab?.label\n\t\t\t\t\t\t\t\t\t\t? resolveLabel(contentTab.label)\n\t\t\t\t\t\t\t\t\t\t: t(\"widget.content\");\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div className=\"hw-header hw-header--centered\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"hw-header-back\"\n\t\t\t\t\t\t\t\t\t\tonClick={goBack}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_back\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M15 18l-6-6 6-6\" />\n\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-title\">{headerTitle}</div>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"hw-header-close\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})()}\n\t\t\t\t\t{subView !== null && subView !== \"content-detail\" && subView !== \"content-category\" && (\n\t\t\t\t\t\t<div className=\"hw-header hw-header--sub\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-header-back\"\n\t\t\t\t\t\t\t\tonClick={goBack}\n\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_back\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<path d=\"M15 18l-6-6 6-6\" />\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<div className=\"hw-header-identity\">\n\t\t\t\t\t\t\t\t<div className={`hw-header-bot-icon${hasTeamAgent ? \" hw-header-bot-icon--team\" : \"\"}`}>\n\t\t\t\t\t\t\t\t\t{hasTeamAgent && activeConvSummary?.lastMessageSenderImage ? (\n\t\t\t\t\t\t\t\t\t\t<img src={activeConvSummary.lastMessageSenderImage} alt={headerName} className=\"hw-header-agent-img\" />\n\t\t\t\t\t\t\t\t\t) : hasTeamAgent ? (\n\t\t\t\t\t\t\t\t\t\t<span className=\"hw-header-agent-initials\">\n\t\t\t\t\t\t\t\t\t\t\t{headerName.split(\" \").map((w: string) => w[0]).join(\"\").slice(0, 2).toUpperCase()}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<WidgetLogo />\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"hw-header-info\">\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-name\">{headerName}</div>\n\t\t\t\t\t\t\t\t\t{/* Keep the subtitle identical in both \"new\" and \"conversation\"\n\t\t\t\t\t\t\t\t\t sub-views — otherwise the header reads \"New conversation\"\n\t\t\t\t\t\t\t\t\t while composing and snaps to \"Usually replies in minutes\"\n\t\t\t\t\t\t\t\t\t the moment you send, which feels like the whole header\n\t\t\t\t\t\t\t\t\t rebuilt. */}\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-status\">{subtitleText}</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-header-close\"\n\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Home: hero header with gradient + sheet overlay ── */}\n\t\t\t\t\t{subView === null && activeTab === \"home\" && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<div className=\"hw-hero\">\n\t\t\t\t\t\t\t\t<div className=\"hw-hero-top\">\n\t\t\t\t\t\t\t\t\t<div className=\"hw-hero-bot-icon\">\n\t\t\t\t\t\t\t\t\t\t<WidgetLogo />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"hw-hero-close\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"hw-hero-greeting\">\n\t\t\t\t\t\t\t\t\t{welcomeMessage.split(\"\\n\").map((line, i) => (\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\t\t\t\t\t\tclassName={i === 0 ? \"hw-hero-greeting-name\" : \"hw-hero-greeting-question\"}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{i > 0 && <br />}\n\t\t\t\t\t\t\t\t\t\t\t{line}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"hw-hero-subtitle\">{subtitleText}</div>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{/* Sheet — overlaps hero, Intercom-style white drawer */}\n\t\t\t\t\t\t\t<div className=\"hw-sheet\">\n\t\t\t\t\t\t\t\t<div className=\"hw-sheet-inner\">\n\t\t\t\t\t\t\t\t\t<button type=\"button\" className=\"hw-card\" onClick={openNewConversation}>\n\t\t\t\t\t\t\t\t\t\t<div className=\"hw-card-body\">\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"hw-card-title\">{t(\"widget.send_us_message\")}</div>\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"hw-card-meta\">{t(\"widget.reply_time\")}</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"hw-card-arrow\">\n\t\t\t\t\t\t\t\t\t\t\t<SendIcon />\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<HomeView\n\t\t\t\t\t\t\t\t\t\tconversations={conversations}\n\t\t\t\t\t\t\t\t\t\tonSelect={openConversation}\n\t\t\t\t\t\t\t\t\t\tonMessagesClick={() => switchTab(\"messages\")}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Messages tab header ── */}\n\t\t\t\t\t{subView === null && activeTab === \"messages\" && (\n\t\t\t\t\t\t<div className=\"hw-header hw-header--centered\">\n\t\t\t\t\t\t\t<div className=\"hw-header-spacer\" />\n\t\t\t\t\t\t\t<div className=\"hw-header-title\">{t(\"widget.messages\")}</div>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-header-close\"\n\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Content tab header (list view, not detail) ── */}\n\t\t\t\t\t{subView === null &&\n\t\t\t\t\t\tactiveTab.startsWith(\"content:\") &&\n\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\tconst tabId = activeTab.replace(\"content:\", \"\");\n\t\t\t\t\t\t\tconst contentTab = contentTabs.find((t) => t.id === tabId);\n\t\t\t\t\t\t\tif (!contentTab) return null;\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div className=\"hw-header hw-header--centered\">\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-spacer\" />\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-title\">{resolveLabel(contentTab.label)}</div>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"hw-header-close\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})()}\n\n\t\t\t\t\t{/* ── Content (non-home views) ── */}\n\t\t\t\t\t{(subView !== null || activeTab !== \"home\") && (\n\t\t\t\t\t\t<div className=\"hw-content\">\n\t\t\t\t\t\t\t{subView === null && activeTab === \"messages\" && (\n\t\t\t\t\t\t\t\t<MessagesView\n\t\t\t\t\t\t\t\t\tconversations={conversations}\n\t\t\t\t\t\t\t\t\tonSelect={openConversation}\n\t\t\t\t\t\t\t\t\tonNewClick={openNewConversation}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{subView === \"new\" && (\n\t\t\t\t\t\t\t\t<NewConversationView\n\t\t\t\t\t\t\t\t\ttext={newText}\n\t\t\t\t\t\t\t\t\tonTextChange={setNewText}\n\t\t\t\t\t\t\t\t\tonSubmit={handleNewConversation}\n\t\t\t\t\t\t\t\t\tisSubmitting={isCreating}\n\t\t\t\t\t\t\t\t\twelcomeMessage={welcomeMessage}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{subView === \"conversation\" && activeId && (\n\t\t\t\t\t\t\t\t<ConversationView conversationId={activeId} />\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{/* ── Content tab views ── */}\n\t\t\t\t\t\t\t{activeTab.startsWith(\"content:\") &&\n\t\t\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\t\t\tconst tabId = activeTab.replace(\"content:\", \"\");\n\t\t\t\t\t\t\t\t\tconst contentTab = contentTabs.find((t) => t.id === tabId);\n\t\t\t\t\t\t\t\t\tif (!contentTab) return null;\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<ContentTabView\n\t\t\t\t\t\t\t\t\t\t\ttab={contentTab}\n\t\t\t\t\t\t\t\t\t\t\tshowDetail={subView === \"content-detail\"}\n\t\t\t\t\t\t\t\t\t\t\tdetailSlug={contentDetailSlug}\n\t\t\t\t\t\t\t\t\t\t\tsubView={subView}\n\t\t\t\t\t\t\t\t\t\t\tonSelectEntry={(slug) => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetContentDetailSlug(slug);\n\t\t\t\t\t\t\t\t\t\t\t\tsetSubView(\"content-detail\");\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonSelectCategory={(cat) => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetContentCategoryName(cat.title);\n\t\t\t\t\t\t\t\t\t\t\t\tsetSubView(\"content-category\");\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t})()}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Tab Bar ── */}\n\t\t\t\t\t{showTabBar && (\n\t\t\t\t\t\t<TabBar\n\t\t\t\t\t\t\tactiveTab={activeTab}\n\t\t\t\t\t\t\tonTabChange={switchTab}\n\t\t\t\t\t\t\tunreadCount={totalUnread}\n\t\t\t\t\t\t\tcontentTabs={contentTabs}\n\t\t\t\t\t\t\tshowMessagesTab={agentConfig?.showMessagesTab ?? true}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Footer ── */}\n\t\t\t\t\t<div className=\"hw-powered\">\n\t\t\t\t\t\t{t(\"widget.powered_by\")}{\" \"}\n\t\t\t\t\t\t<a href=\"https://helpway.ai\" target=\"_blank\" rel=\"noopener noreferrer\">\n\t\t\t\t\t\t\tHelpway\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Message Preview — shown when widget is closed and not dismissed */}\n\t\t\t{!isOpen && !isDismissed && !hideLauncher && <MessagePreview onOpen={handleBubbleClick} />}\n\n\t\t\t{/* Dev-only debug overlay — activates via ?hwdebug=1 or localStorage hw:debug=1 */}\n\t\t\t<WidgetDebugOverlay />\n\n\t\t\t{/* Bubble — hidden when dismissed or hideLauncher is set */}\n\t\t\t{!isDismissed && !hideLauncher && (\n\t\t\t\t<button\n\t\t\t\t\tref={bubbleRef}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={[\n\t\t\t\t\t\t\"hw-bubble\",\n\t\t\t\t\t\t`hw-bubble--${bubbleStyle}`,\n\t\t\t\t\t\tlauncherStyle !== \"icon\" ? `hw-bubble--launcher-${launcherStyle}` : \"\",\n\t\t\t\t\t\tisOpen ? \"hw-bubble--open\" : \"\",\n\t\t\t\t\t\twebsite?.logoUrl ? \"hw-bubble--avatar\" : \"\",\n\t\t\t\t\t]\n\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t.join(\" \")}\n\t\t\t\t\tonClick={handleBubbleClick}\n\t\t\t\t\taria-label={isOpen ? t(\"widget.aria_close_support\") : t(\"widget.aria_open\")}\n\t\t\t\t\taria-expanded={isOpen}\n\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName={`hw-bubble-icon hw-bubble-icon--bot ${isOpen ? \"hw-bubble-icon--hidden\" : \"\"}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<WidgetLogo />\n\t\t\t\t\t</span>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName={`hw-bubble-icon hw-bubble-icon--close ${!isOpen ? \"hw-bubble-icon--hidden\" : \"\"}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<XIcon size={24} />\n\t\t\t\t\t</span>\n\t\t\t\t\t{launcherStyle !== \"icon\" && !isOpen && (\n\t\t\t\t\t\t<span className=\"hw-bubble-label\">\n\t\t\t\t\t\t\t{launcherStyle === \"help\" ? t(\"widget.help\") : companyName}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{!isOpen && totalUnread > 0 && <div className=\"hw-bubble-badge\">{totalUnread}</div>}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ── Tab Bar ─────────────────────────────────────────────\n\nfunction TabBar({\n\tactiveTab,\n\tonTabChange,\n\tunreadCount,\n\tcontentTabs,\n\tshowMessagesTab = true,\n}: {\n\tactiveTab: Tab;\n\tonTabChange: (tab: Tab) => void;\n\tunreadCount: number;\n\tcontentTabs: WidgetContentTab[];\n\tshowMessagesTab?: boolean;\n}) {\n\treturn (\n\t\t<div className=\"hw-tabs\" role=\"tablist\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={`hw-tabs-item ${activeTab === \"home\" ? \"hw-tabs-item--active\" : \"\"}`}\n\t\t\t\tonClick={() => onTabChange(\"home\")}\n\t\t\t\trole=\"tab\"\n\t\t\t\taria-selected={activeTab === \"home\"}\n\t\t\t>\n\t\t\t\t<HomeIcon />\n\t\t\t\t<span>{t(\"widget.home\")}</span>\n\t\t\t</button>\n\t\t\t{showMessagesTab && (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={`hw-tabs-item ${activeTab === \"messages\" ? \"hw-tabs-item--active\" : \"\"}`}\n\t\t\t\t\tonClick={() => onTabChange(\"messages\")}\n\t\t\t\t\trole=\"tab\"\n\t\t\t\t\taria-selected={activeTab === \"messages\"}\n\t\t\t\t>\n\t\t\t\t\t<span className=\"hw-tabs-icon-wrap\">\n\t\t\t\t\t\t<MessagesIcon />\n\t\t\t\t\t\t{unreadCount > 0 && (\n\t\t\t\t\t\t\t<span className=\"hw-tabs-badge\">{unreadCount > 99 ? \"99+\" : unreadCount}</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</span>\n\t\t\t\t\t<span>{t(\"widget.messages\")}</span>\n\t\t\t\t</button>\n\t\t\t)}\n\t\t\t{/* Dynamic content tabs from Better i18n Content CMS */}\n\t\t\t{contentTabs.map((tab) => (\n\t\t\t\t<button\n\t\t\t\t\tkey={tab.id}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={`hw-tabs-item ${activeTab === `content:${tab.id}` ? \"hw-tabs-item--active\" : \"\"}`}\n\t\t\t\t\tonClick={() => onTabChange(`content:${tab.id}`)}\n\t\t\t\t\trole=\"tab\"\n\t\t\t\t\taria-selected={activeTab === `content:${tab.id}`}\n\t\t\t\t>\n\t\t\t\t\t<ContentTabIconComponent icon={tab.icon} />\n\t\t\t\t\t<span>{resolveLabel(tab.label)}</span>\n\t\t\t\t</button>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\n// ── Home Tab ────────────────────────────────────────────\n\nfunction HomeView({\n\tconversations,\n\tonSelect,\n\tonMessagesClick,\n}: {\n\tconversations: ConversationSummary[];\n\tonSelect: (id: string) => void;\n\tonMessagesClick: () => void;\n}) {\n\tconst recent = conversations.slice(0, 3);\n\tif (recent.length === 0) return null;\n\n\treturn (\n\t\t<div className=\"hw-recent-card\">\n\t\t\t<div className=\"hw-recent-header\">{t(\"widget.recent_conversations\")}</div>\n\t\t\t{recent.map((conv, i) => (\n\t\t\t\t<ConversationRow\n\t\t\t\t\tkey={conv.id}\n\t\t\t\t\tconversation={conv}\n\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\tisLast={i === recent.length - 1}\n\t\t\t\t/>\n\t\t\t))}\n\t\t\t{conversations.length > 3 && (\n\t\t\t\t<button type=\"button\" className=\"hw-recent-see-all\" onClick={onMessagesClick}>\n\t\t\t\t\t{t(\"widget.see_all\")}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ── Messages Tab ────────────────────────────────────────\n\nfunction MessagesView({\n\tconversations,\n\tonSelect,\n\tonNewClick,\n}: {\n\tconversations: ConversationSummary[];\n\tonSelect: (id: string) => void;\n\tonNewClick: () => void;\n}) {\n\tif (conversations.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"hw-empty-state\">\n\t\t\t\t<div className=\"hw-empty-icon-wrap\">\n\t\t\t\t\t<MessagesIcon />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hw-empty-title\">{t(\"widget.no_messages\")}</div>\n\t\t\t\t<div className=\"hw-empty-desc\">{t(\"widget.no_messages_desc\")}</div>\n\t\t\t\t<button type=\"button\" className=\"hw-empty-btn\" onClick={onNewClick}>\n\t\t\t\t\t{t(\"widget.start_conversation\")}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"hw-msgs-tab\">\n\t\t\t{conversations.map((conv) => (\n\t\t\t\t<ConversationCard key={conv.id} conversation={conv} onSelect={onSelect} />\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\n// ── Shared conversation body (avatar + name + time + preview) ──\n\nfunction ConvCardBody({ conv }: { conv: ConversationSummary }) {\n\tconst agentName = useWidgetStore((s) => s.agentConfig?.name) ?? \"Support\";\n\tconst isTeam = conv.lastMessageSenderType === \"team\" && conv.lastMessageSenderName;\n\tconst displayName = isTeam ? conv.lastMessageSenderName! : agentName;\n\tconst preview = conv.lastMessageText ?? t(\"widget.no_preview\");\n\treturn (\n\t\t<>\n\t\t\t<div className={`hw-conv-card-avatar${isTeam ? \" hw-conv-card-avatar--team\" : \"\"}`}>\n\t\t\t\t{isTeam ? (\n\t\t\t\t\tconv.lastMessageSenderImage ? (\n\t\t\t\t\t\t<img src={conv.lastMessageSenderImage} alt={displayName} className=\"hw-conv-card-avatar-img\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span className=\"hw-conv-card-avatar-initials\">\n\t\t\t\t\t\t\t{displayName.split(\" \").map((w) => w[0]).join(\"\").slice(0, 2).toUpperCase()}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)\n\t\t\t\t) : (\n\t\t\t\t\t<WidgetLogo />\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<div className=\"hw-conv-card-content\">\n\t\t\t\t<div className=\"hw-conv-card-top\">\n\t\t\t\t\t<span className=\"hw-conv-card-name\">{displayName}</span>\n\t\t\t\t\t{conv.lastMessageAt && (\n\t\t\t\t\t\t<span className=\"hw-conv-card-time\">{formatRelativeTime(conv.lastMessageAt)}</span>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hw-conv-card-preview\">{preview}</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n\n// ── Conversation Card (Intercom-style, Messages tab) ─────\n\nfunction ConversationCard({\n\tconversation: conv,\n\tonSelect,\n}: {\n\tconversation: ConversationSummary;\n\tonSelect: (id: string) => void;\n}) {\n\tconst hasUnread = conv.unreadCount > 0;\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={`hw-conv-card ${hasUnread ? \"hw-conv-card--unread\" : \"\"}`}\n\t\t\tonClick={() => onSelect(conv.id)}\n\t\t>\n\t\t\t<div className=\"hw-conv-card-row\">\n\t\t\t\t<ConvCardBody conv={conv} />\n\t\t\t</div>\n\t\t\t{hasUnread && <div className=\"hw-conv-card-badge\">{conv.unreadCount}</div>}\n\t\t</button>\n\t);\n}\n\n// ── Conversation Row (inside Home tab grouped card) ───────\n\nfunction ConversationRow({\n\tconversation: conv,\n\tonSelect,\n\tisLast,\n}: {\n\tconversation: ConversationSummary;\n\tonSelect: (id: string) => void;\n\tisLast: boolean;\n}) {\n\tconst hasUnread = conv.unreadCount > 0;\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={`hw-recent-row ${hasUnread ? \"hw-recent-row--unread\" : \"\"} ${isLast ? \"hw-recent-row--last\" : \"\"}`}\n\t\t\tonClick={() => onSelect(conv.id)}\n\t\t>\n\t\t\t<ConvCardBody conv={conv} />\n\t\t\t{hasUnread && <div className=\"hw-recent-row-badge\">{conv.unreadCount}</div>}\n\t\t</button>\n\t);\n}\n\n// ── Inline Email Prompt (post-first-reply) ─────────────\n\nfunction InlineEmailPrompt({ conversationId }: { conversationId?: string }) {\n\tconst { client, store } = useWidgetContext();\n\tconst updateContact = useWidgetStore((s) => s.updateVisitorContact);\n\tconst [email, setEmail] = useState(\"\");\n\tconst [isSubmitting, setIsSubmitting] = useState(false);\n\tconst [isSuccess, setIsSuccess] = useState(false);\n\tconst [hasError, setHasError] = useState(false);\n\n\tconst handleSubmit = async () => {\n\t\tconst trimmed = email.trim();\n\t\tif (!trimmed || !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) {\n\t\t\tsetHasError(true);\n\t\t\treturn;\n\t\t}\n\t\tsetHasError(false);\n\n\t\tconst previousContact = store.getState().visitor?.contact ?? null;\n\t\tconst optimisticContactId = previousContact?.id ?? `optimistic-contact-${Date.now()}`;\n\t\tupdateContact({\n\t\t\tid: optimisticContactId,\n\t\t\tname: previousContact?.name ?? null,\n\t\t\temail: trimmed,\n\t\t});\n\t\tsetIsSuccess(true);\n\t\tsetIsSubmitting(true);\n\t\ttry {\n\t\t\tconst result = await client.widget.collectEmail.mutate({\n\t\t\t\temail: trimmed,\n\t\t\t\t...(conversationId ? { conversationId } : {}),\n\t\t\t});\n\t\t\tif (result.contact) {\n\t\t\t\tupdateContact({\n\t\t\t\t\tid: result.contact.id,\n\t\t\t\t\tname: result.contact.name,\n\t\t\t\t\temail: result.contact.email,\n\t\t\t\t});\n\t\t\t}\n\t\t\t// needsEmail will become false via optimistic contact update\n\t\t} catch {\n\t\t\tif (previousContact) {\n\t\t\t\tupdateContact(previousContact);\n\t\t\t} else {\n\t\t\t\tupdateContact({ id: \"\", name: null, email: null });\n\t\t\t}\n\t\t\tsetIsSuccess(false);\n\t\t} finally {\n\t\t\tsetIsSubmitting(false);\n\t\t}\n\t};\n\n\tif (isSuccess) {\n\t\treturn (\n\t\t\t<div className=\"hw-email-card hw-email-card--success\">\n\t\t\t\t<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#22c55e\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t\t\t<polyline points=\"20 6 9 17 4 12\" />\n\t\t\t\t</svg>\n\t\t\t\t{t(\"widget.email_saved\")}\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"hw-email-card\">\n\t\t\t<div className=\"hw-email-card-header\">\n\t\t\t\t<div className=\"hw-email-card-icon\">\n\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t\t\t\t<rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" />\n\t\t\t\t\t\t<path d=\"M22 7l-10 7L2 7\" />\n\t\t\t\t\t</svg>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<p className=\"hw-email-card-title\">{t(\"widget.email_title\")}</p>\n\t\t\t\t\t<p className=\"hw-email-card-subtitle\">{t(\"widget.email_subtitle\")}</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<input\n\t\t\t\ttype=\"email\"\n\t\t\t\tclassName={`hw-email-card-input${hasError ? \" hw-email-card-input--error\" : \"\"}`}\n\t\t\t\tvalue={email}\n\t\t\t\tonChange={(e) => { setEmail(e.target.value); setHasError(false); }}\n\t\t\t\tonKeyDown={(e) => { if (e.key === \"Enter\") handleSubmit(); }}\n\t\t\t\tplaceholder={t(\"widget.email_placeholder\")}\n\t\t\t/>\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"hw-email-card-submit\"\n\t\t\t\tonClick={handleSubmit}\n\t\t\t\tdisabled={isSubmitting || !email.trim()}\n\t\t\t>\n\t\t\t\t{isSubmitting ? (\n\t\t\t\t\t<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n\t\t\t\t\t\t<circle cx=\"12\" cy=\"12\" r=\"10\" strokeDasharray=\"32\" strokeDashoffset=\"32\">\n\t\t\t\t\t\t\t<animate attributeName=\"stroke-dashoffset\" values=\"32;0\" dur=\"1s\" repeatCount=\"indefinite\" />\n\t\t\t\t\t\t</circle>\n\t\t\t\t\t</svg>\n\t\t\t\t) : t(\"widget.email_continue\")}\n\t\t\t</button>\n\n\t\t</div>\n\t);\n}\n\n// ── New Conversation ────────────────────────────────────\n\nfunction NewConversationView({\n\ttext,\n\tonTextChange,\n\tonSubmit,\n\tisSubmitting,\n\twelcomeMessage,\n}: {\n\ttext: string;\n\tonTextChange: (t: string) => void;\n\tonSubmit: () => void;\n\tisSubmitting: boolean;\n\twelcomeMessage: string;\n}) {\n\t// Stable timestamp so the bubble doesn't tick/re-render while the user types.\n\treturn (\n\t\t<div className=\"hw-new\">\n\t\t\t{/* Use the same MessageBubble that renders inside ConversationView so\n\t\t\t the welcome message looks IDENTICAL before and after the first send\n\t\t\t — same markdown rendering (line breaks preserved), same styles,\n\t\t\t same meta row. Without this the \"new\" view uses a raw string render\n\t\t\t and the user sees the bubble visually change the moment the\n\t\t\t conversation is created. */}\n\t\t\t<div className=\"hw-new-welcome\">\n\t\t\t\t<MessageBubble\n\t\t\t\t\ttext={welcomeMessage}\n\t\t\t\t\tsender=\"ai\"\n\t\t\t\t\tparts={null}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<Composer\n\t\t\t\ttext={text}\n\t\t\t\tonTextChange={onTextChange}\n\t\t\t\tonSubmit={onSubmit}\n\t\t\t\tisSubmitting={isSubmitting}\n\t\t\t\tplaceholder={t(\"widget.placeholder_new\")}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\n// ── Conversation View ───────────────────────────────────\n\nfunction ConversationView({ conversationId }: { conversationId: string }) {\n\tconst { items, isLoading, hasMore, loadMore } = useTimeline(conversationId);\n\tconst {\n\t\ttext,\n\t\tsetText,\n\t\tsubmit,\n\t\tisSubmitting,\n\t\tattachments,\n\t\taddFiles,\n\t\tremoveAttachment,\n\t\tsendError,\n\t\tclearSendError,\n\t\temailGateConvId,\n\t} = useComposer(conversationId);\n\tconst { isTyping, isAiProcessing, setTyping } = usePresence(conversationId);\n\tconst agentConfig = useWidgetStore((s) => s.agentConfig);\n\tconst visitorContact = useWidgetStore((s) => s.visitor?.contact);\n\n\tconst isResolved = useWidgetStore((s) => {\n\t\tconst conv = s.conversations.find((c) => c.id === conversationId);\n\t\treturn conv?.status === \"resolved\";\n\t});\n\n\t// Email prompt gate (BETTER-227 — Intercom pattern).\n\t// Show ONLY after:\n\t// (1) visitor sent at least one real message (not the welcome bubble), AND\n\t// (2) AI has replied at least once (so the visitor has seen value from the widget)\n\t// Prevents the \"Get notified when we reply\" card from appearing on widget open\n\t// before the visitor has even typed. Matches Intercom's post-first-response flow.\n\tconst hasVisitorMessage = items.some(\n\t\t(it) => it.type === \"message\" && Boolean((it as { visitorId?: string | null }).visitorId),\n\t);\n\tconst hasAiReply = items.some(\n\t\t(it) => it.type === \"message\" && Boolean((it as { aiAgentId?: string | null }).aiAgentId),\n\t);\n\t// Email is satisfied if EITHER the contact has one (fully identified\n\t// visitor) OR the visitor itself has one (collected via the gate but\n\t// not yet linked to a Contact row). Without the visitor.email fallback,\n\t// the gate re-shows on every refresh until a Contact is created.\n\tconst visitorOwnEmail = useWidgetStore((s) => s.visitor?.email);\n\tconst hasEmail = !!visitorContact?.email || !!visitorOwnEmail;\n\tconst needsEmailPostReply =\n\t\t!!agentConfig?.requireVisitorEmail &&\n\t\t!hasEmail &&\n\t\thasVisitorMessage &&\n\t\thasAiReply;\n\tconst needsEmail = needsEmailPostReply || !!emailGateConvId;\n\n\tif (isLoading && items.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"hw-messages\">\n\t\t\t\t<div className=\"hw-skeleton-messages\">\n\t\t\t\t\t{/* AI message skeleton */}\n\t\t\t\t\t<div className=\"hw-skeleton-msg\">\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-avatar\" />\n\t\t\t\t\t\t<div className=\"hw-skeleton-bubble\">\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 140 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 200 }} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{/* Visitor message skeleton */}\n\t\t\t\t\t<div className=\"hw-skeleton-msg hw-skeleton-msg--right\">\n\t\t\t\t\t\t<div className=\"hw-skeleton-bubble\" style={{ alignItems: \"flex-end\" }}>\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 160 }} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{/* AI reply skeleton */}\n\t\t\t\t\t<div className=\"hw-skeleton-msg\">\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-avatar\" />\n\t\t\t\t\t\t<div className=\"hw-skeleton-bubble\">\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 180 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 120 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 80 }} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<MessageList\n\t\t\t\titems={items}\n\t\t\t\tisTyping={isTyping}\n\t\t\t\tisAiProcessing={isAiProcessing}\n\t\t\t\thasMore={hasMore}\n\t\t\t\tisLoadingMore={isLoading}\n\t\t\t\tonLoadMore={loadMore}\n\t\t\t/>\n\t\t\t{isResolved ? (\n\t\t\t\t<ResolvedBanner conversationId={conversationId} />\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t{needsEmail && <InlineEmailPrompt conversationId={emailGateConvId ?? undefined} />}\n\t\t\t\t\t{sendError && (\n\t\t\t\t\t\t<div className=\"hw-send-error\">\n\t\t\t\t\t\t\t{sendError}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-send-error-retry\"\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tclearSendError();\n\t\t\t\t\t\t\t\t\tsubmit();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{t(\"widget.retry\")}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t<Composer\n\t\t\t\t\t\ttext={text}\n\t\t\t\t\t\tonTextChange={setText}\n\t\t\t\t\t\tonSubmit={submit}\n\t\t\t\t\t\tonTyping={setTyping}\n\t\t\t\t\t\tisSubmitting={isSubmitting}\n\t\t\t\t\t\tattachments={attachments}\n\t\t\t\t\t\tonAddFiles={addFiles}\n\t\t\t\t\t\tonRemoveAttachment={removeAttachment}\n\t\t\t\t\t\tdisabled={needsEmail}\n\t\t\t\t\t/>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</>\n\t);\n}\n\n// ── Resolved Banner with CSAT ───────────────────────────\n\nfunction ResolvedBanner({ conversationId }: { conversationId: string }) {\n\tconst { client } = useWidgetContext();\n\tconst [csatRating, setCsatRating] = useState<\"good\" | \"bad\" | null>(null);\n\tconst [csatSubmitted, setCsatSubmitted] = useState(false);\n\n\tconst handleReopen = async () => {\n\t\ttry {\n\t\t\tawait client.widget.sendMessage.mutate({ conversationId, text: t(\"widget.send_followup\") });\n\t\t\t// Store update will be applied via WebSocket event from server\n\t\t} catch (err) {\n\t\t\tconsole.error(\"Failed to reopen:\", err);\n\t\t}\n\t};\n\n\tconst handleCsat = (rating: \"good\" | \"bad\") => {\n\t\tsetCsatRating(rating);\n\t\tsetCsatSubmitted(true);\n\t\t// Send CSAT via API (fire and forget)\n\t\tclient.widget.sendCsat.mutate({ conversationId, rating }).catch(() => {});\n\t};\n\n\treturn (\n\t\t<div className=\"hw-resolved\">\n\t\t\t<div className=\"hw-resolved-text\">{t(\"widget.resolved_text\")}</div>\n\t\t\t{!csatSubmitted ? (\n\t\t\t\t<div className=\"hw-csat\">\n\t\t\t\t\t<div className=\"hw-csat-label\">{t(\"widget.csat_label\")}</div>\n\t\t\t\t\t<div className=\"hw-csat-buttons\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={`hw-csat-btn ${csatRating === \"good\" ? \"hw-csat-btn--selected\" : \"\"}`}\n\t\t\t\t\t\t\tonClick={() => handleCsat(\"good\")}\n\t\t\t\t\t\t\taria-label={t(\"widget.aria_good\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t👍\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={`hw-csat-btn ${csatRating === \"bad\" ? \"hw-csat-btn--selected\" : \"\"}`}\n\t\t\t\t\t\t\tonClick={() => handleCsat(\"bad\")}\n\t\t\t\t\t\t\taria-label={t(\"widget.aria_bad\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t👎\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"hw-csat-thanks\">{t(\"widget.csat_thanks\")}</div>\n\t\t\t)}\n\t\t\t<div className=\"hw-resolved-actions\">\n\t\t\t\t<button type=\"button\" className=\"hw-resolved-reopen\" onClick={handleReopen}>\n\t\t\t\t\t{t(\"widget.send_followup\")}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// ── Message Preview Bubble ─────────────────────\n\nfunction MessagePreview({ onOpen }: { onOpen: () => void }) {\n\tconst preview = useWidgetStore((s) => s.incomingPreview);\n\tconst dismissPreview = useWidgetStore((s) => s.dismissPreview);\n\tconst agentName = useWidgetStore((s) => s.agentConfig?.name) ?? \"Support\";\n\tconst [closing, setClosing] = useState(false);\n\n\t// Auto-dismiss after 8 seconds\n\tuseEffect(() => {\n\t\tif (!preview) return;\n\t\tconst timer = setTimeout(() => {\n\t\t\tsetClosing(true);\n\t\t\tsetTimeout(() => dismissPreview(), 200);\n\t\t}, 8000);\n\t\treturn () => clearTimeout(timer);\n\t}, [preview, dismissPreview]);\n\n\tif (!preview) return null;\n\n\tconst handleClose = (e: React.MouseEvent) => {\n\t\te.stopPropagation();\n\t\tsetClosing(true);\n\t\tsetTimeout(() => {\n\t\t\tdismissPreview();\n\t\t\tsetClosing(false);\n\t\t}, 200);\n\t};\n\n\tconst handleClick = () => {\n\t\tdismissPreview();\n\t\tonOpen();\n\t};\n\n\treturn (\n\t\t<div\n\t\t\tclassName={`hw-preview ${closing ? \"hw-preview--closing\" : \"\"}`}\n\t\t\tonClick={handleClick}\n\t\t\trole=\"button\"\n\t\t\ttabIndex={0}\n\t\t>\n\t\t\t<div className=\"hw-preview-header\">\n\t\t\t\t<div className=\"hw-preview-avatar\">\n\t\t\t\t\t<WidgetLogo />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hw-preview-name\">{agentName}</div>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"hw-preview-close\"\n\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\taria-label={t(\"widget.aria_dismiss\")}\n\t\t\t\t>\n\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div className=\"hw-preview-body\">{preview.text}</div>\n\t\t</div>\n\t);\n}\n","import type { TimelineItem } from \"@helpway/types\";\nimport { t } from \"@helpway/widget-core\";\nimport { useCallback, useState } from \"react\";\nimport { useWidgetContext } from \"../provider\";\n\nexport interface PendingAttachment {\n\tid: string;\n\tfile: File;\n\tpreviewUrl: string | null; // blob URL for images\n\tisUploading: boolean;\n\terror: string | null;\n\t/** Resolved after upload — the part to include in sendMessage */\n\tpart:\n\t\t| { type: \"image\"; url: string; mimeType: string }\n\t\t| { type: \"file\"; url: string; fileName: string; fileSize: number; mimeType: string }\n\t\t| null;\n}\n\nconst MAX_ATTACHMENTS = 10;\nconst MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB\n\n/**\n * Composer state — text input + attachments + submit for a conversation.\n */\nexport function useComposer(conversationId: string | null) {\n\tconst { client, ws, store } = useWidgetContext();\n\tconst [text, setText] = useState(\"\");\n\tconst [isSubmitting, setIsSubmitting] = useState(false);\n\tconst [attachments, setAttachments] = useState<PendingAttachment[]>([]);\n\tconst [sendError, setSendError] = useState<string | null>(null);\n\tconst [emailGateConvId, setEmailGateConvId] = useState<string | null>(null);\n\n\tconst addFiles = useCallback(\n\t\tasync (files: File[]) => {\n\t\t\tif (!conversationId) return;\n\n\t\t\tconst remaining = MAX_ATTACHMENTS - attachments.length;\n\t\t\tconst toAdd = files.slice(0, remaining);\n\t\t\tif (toAdd.length === 0) return;\n\n\t\t\t// Create pending entries\n\t\t\tconst pending: PendingAttachment[] = toAdd.map((file) => ({\n\t\t\t\tid: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n\t\t\t\tfile,\n\t\t\t\tpreviewUrl: file.type.startsWith(\"image/\") ? URL.createObjectURL(file) : null,\n\t\t\t\tisUploading: true,\n\t\t\t\terror: null,\n\t\t\t\tpart: null,\n\t\t\t}));\n\n\t\t\tsetAttachments((prev) => [...prev, ...pending]);\n\n\t\t\t// Upload each file\n\t\t\tfor (const item of pending) {\n\t\t\t\ttry {\n\t\t\t\t\tif (item.file.size > MAX_FILE_SIZE) {\n\t\t\t\t\t\tthrow new Error(t(\"widget.file_too_large\"));\n\t\t\t\t\t}\n\n\t\t\t\t\t// Read file as base64\n\t\t\t\t\tconst base64 = await fileToBase64(item.file);\n\n\t\t\t\t\t// For temp conversations (before first send) skip the\n\t\t\t\t\t// conversationId — server scopes the R2 key to the visitor\n\t\t\t\t\t// and the file is attached to the timeline item by\n\t\t\t\t\t// createConversation when submit fires.\n\t\t\t\t\tconst convIdForUpload = conversationId.startsWith(\"temp-\")\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: conversationId;\n\t\t\t\t\tconst result = await client.widget.uploadAttachment.mutate({\n\t\t\t\t\t\t...(convIdForUpload ? { conversationId: convIdForUpload } : {}),\n\t\t\t\t\t\tbase64,\n\t\t\t\t\t\tmimeType: item.file.type || \"application/octet-stream\",\n\t\t\t\t\t\tfileName: item.file.name,\n\t\t\t\t\t});\n\n\t\t\t\t\tsetAttachments((prev) =>\n\t\t\t\t\t\tprev.map((a) =>\n\t\t\t\t\t\t\ta.id === item.id ? { ...a, isUploading: false, part: result.part } : a,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst message = err instanceof Error ? err.message : \"Upload failed\";\n\t\t\t\t\tsetAttachments((prev) =>\n\t\t\t\t\t\tprev.map((a) => (a.id === item.id ? { ...a, isUploading: false, error: message } : a)),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[conversationId, attachments.length, client],\n\t);\n\n\tconst removeAttachment = useCallback((id: string) => {\n\t\tsetAttachments((prev) => {\n\t\t\tconst item = prev.find((a) => a.id === id);\n\t\t\tif (item?.previewUrl) URL.revokeObjectURL(item.previewUrl);\n\t\t\treturn prev.filter((a) => a.id !== id);\n\t\t});\n\t}, []);\n\n\tconst submit = useCallback(async () => {\n\t\tconst trimmed = text.trim();\n\t\tconst readyParts = attachments.filter((a) => a.part !== null).map((a) => a.part!);\n\t\tconst hasText = trimmed.length > 0;\n\t\tconst hasAttachments = readyParts.length > 0;\n\n\t\tif (!conversationId || isSubmitting) return;\n\n\t\t// Policy 2026-04-19: every outgoing message must have a text body.\n\t\t// An attachment on its own renders as an empty bubble in the\n\t\t// dashboard and leaves the AI with no caption to reason about.\n\t\t// Surface a soft inline error instead of silently no-op'ing so\n\t\t// the visitor understands *why* the send didn't go through.\n\t\tif (!hasText) {\n\t\t\tif (hasAttachments) {\n\t\t\t\tsetSendError(t(\"widget.caption_required\"));\n\t\t\t\tsetTimeout(() => setSendError(null), 4000);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Don't send while uploads are in progress\n\t\tconst stillUploading = attachments.some((a) => a.isUploading);\n\t\tif (stillUploading) return;\n\n\t\t// ── OPTIMISTIC: message appears in the widget INSTANTLY ──\n\t\t// The user sees their message the moment they hit send; the mutation\n\t\t// runs in the background. On success we swap the optimistic placeholder\n\t\t// for the server-confirmed item (preserving scroll + bubble position).\n\t\t// On failure we remove the placeholder and restore the composer text.\n\t\tconst optimisticId = `optimistic-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\t\tconst now = new Date().toISOString();\n\t\tconst currentVisitorId = store.getState().visitor?.id ?? null;\n\t\tconst optimisticItem: TimelineItem = {\n\t\t\tid: optimisticId,\n\t\t\tconversationId,\n\t\t\torganizationId: \"\",\n\t\t\ttype: \"message\",\n\t\t\tvisibility: \"public\",\n\t\t\ttext: hasText ? trimmed : null,\n\t\t\tparts:\n\t\t\t\thasText || hasAttachments\n\t\t\t\t\t? ([\n\t\t\t\t\t\t\t...(hasText ? [{ type: \"text\" as const, text: trimmed }] : []),\n\t\t\t\t\t\t\t...readyParts,\n\t\t\t\t\t\t] as TimelineItem[\"parts\"])\n\t\t\t\t\t: null,\n\t\t\tuserId: null,\n\t\t\tvisitorId: currentVisitorId,\n\t\t\taiAgentId: null,\n\t\t\tcreatedAt: now,\n\t\t\teditedAt: null,\n\t\t\tdeletedAt: null,\n\t\t};\n\n\t\t// Flush UI immediately\n\t\tconst attachmentsSnapshot = attachments;\n\t\tconst textSnapshot = text;\n\t\tstore.getState().addMessage(conversationId, optimisticItem);\n\t\tsetText(\"\");\n\t\tsetAttachments([]);\n\t\tws.sendTyping(conversationId, false);\n\t\tsetIsSubmitting(true);\n\t\ttry {\n\t\t\t// Temp conversation IDs (seeded by openNewConversation) don't exist on\n\t\t\t// the server yet. On the first send we have to call createConversation\n\t\t\t// instead — the API allocates the real ID and returns the visitor item.\n\t\t\t// The welcome item from the response is DROPPED because the widget is\n\t\t\t// already showing a seed welcome bubble; keeping the same bubble\n\t\t\t// instance across this transition is what prevents the \"git-gel\" flash.\n\t\t\tconst isTempConversation = conversationId.startsWith(\"temp-\");\n\t\t\tif (isTempConversation) {\n\t\t\t\tconst result = await client.widget.createConversation.mutate({\n\t\t\t\t\t...(hasText ? { text: trimmed } : {}),\n\t\t\t\t\t...(hasAttachments ? { parts: readyParts } : {}),\n\t\t\t\t});\n\t\t\t\tconst conv = result.conversation;\n\t\t\t\t// Move the temp conversation's messages (seed welcome + optimistic\n\t\t\t\t// visitor) onto the server-assigned id. remapConversationId merges\n\t\t\t\t// with any existing items under the real id (WS races are fine).\n\t\t\t\tstore.getState().remapConversationId(conversationId, conv.id);\n\t\t\t\tif (result.item) {\n\t\t\t\t\tstore\n\t\t\t\t\t\t.getState()\n\t\t\t\t\t\t.replaceMessage(conv.id, optimisticId, result.item as TimelineItem);\n\t\t\t\t}\n\t\t\t\tif (result.requireEmail) {\n\t\t\t\t\tsetEmailGateConvId(conv.id);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst result = await client.widget.sendMessage.mutate({\n\t\t\t\t\tconversationId,\n\t\t\t\t\t...(hasText ? { text: trimmed } : {}),\n\t\t\t\t\t...(hasAttachments ? { parts: readyParts } : {}),\n\t\t\t\t});\n\n\t\t\t\t// Replace optimistic placeholder with server-confirmed item.\n\t\t\t\t// If the WS echo already landed with the real id, replaceMessage\n\t\t\t\t// just drops the placeholder (race-safe, see store implementation).\n\t\t\t\tstore.getState().replaceMessage(conversationId, optimisticId, result.item as TimelineItem);\n\t\t\t}\n\n\t\t\t// Clean up blob URLs for uploaded attachments\n\t\t\tfor (const a of attachmentsSnapshot) {\n\t\t\t\tif (a.previewUrl) URL.revokeObjectURL(a.previewUrl);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(\"[useComposer] Send failed:\", err);\n\t\t\t// Roll back: remove placeholder, restore text + attachments so user can retry\n\t\t\tstore.getState().removeMessage(conversationId, optimisticId);\n\t\t\tsetText(textSnapshot);\n\t\t\tsetAttachments(attachmentsSnapshot);\n\t\t\tsetSendError(err instanceof Error ? err.message : t(\"widget.send_error\"));\n\t\t\t// Auto-clear after 5 seconds\n\t\t\tsetTimeout(() => setSendError(null), 5000);\n\t\t} finally {\n\t\t\tsetIsSubmitting(false);\n\t\t}\n\t}, [text, attachments, conversationId, isSubmitting, client, ws, store]);\n\n\tconst clearSendError = useCallback(() => setSendError(null), []);\n\n\treturn {\n\t\ttext,\n\t\tsetText,\n\t\tsubmit,\n\t\tisSubmitting,\n\t\tattachments,\n\t\taddFiles,\n\t\tremoveAttachment,\n\t\tsendError,\n\t\tclearSendError,\n\t\temailGateConvId,\n\t};\n}\n\n// ── Helpers ─────────────────────────────────────\n\nfunction fileToBase64(file: File): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst reader = new FileReader();\n\t\treader.onload = () => {\n\t\t\t// result is \"data:<mime>;base64,<data>\" — strip the prefix\n\t\t\tconst result = reader.result as string;\n\t\t\tconst base64 = result.split(\",\")[1];\n\t\t\tif (!base64) return reject(new Error(\"Failed to encode file\"));\n\t\t\tresolve(base64);\n\t\t};\n\t\treader.onerror = () => reject(new Error(\"Failed to read file\"));\n\t\treader.readAsDataURL(file);\n\t});\n}\n","import type { TimelineItem } from \"@helpway/types\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\n/**\n * Conversation list + create new conversation.\n */\nexport function useConversations() {\n\tconst { client, store } = useWidgetContext();\n\tconst conversations = useWidgetStore((s) => s.conversations);\n\tconst setActiveConversation = useWidgetStore((s) => s.setActiveConversation);\n\tconst [isCreating, setIsCreating] = useState(false);\n\n\tconst clientRef = useRef(client);\n\tconst storeRef = useRef(store);\n\tclientRef.current = client;\n\tstoreRef.current = store;\n\n\tconst create = useCallback(async (text: string) => {\n\t\tsetIsCreating(true);\n\n\t\t// OPTIMISTIC: show the visitor's message + open the conversation view\n\t\t// BEFORE the server roundtrip completes. The conversation gets a temp\n\t\t// id (`temp-<random>`) that's remapped to the server id on success.\n\t\t// Welcome message + any AI reply flow in via the same path the API\n\t\t// returns them — either by replacing the temp conv or via WS.\n\t\tconst tempConversationId = `temp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\t\tconst now = new Date().toISOString();\n\t\tconst optimisticMessageId = `optimistic-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\t\tconst currentVisitorId = storeRef.current.getState().visitor?.id ?? null;\n\n\t\tconst optimisticMsg: TimelineItem = {\n\t\t\tid: optimisticMessageId,\n\t\t\tconversationId: tempConversationId,\n\t\t\torganizationId: \"\",\n\t\t\ttype: \"message\",\n\t\t\tvisibility: \"public\",\n\t\t\ttext,\n\t\t\tparts: null,\n\t\t\tuserId: null,\n\t\t\tvisitorId: currentVisitorId,\n\t\t\taiAgentId: null,\n\t\t\tcreatedAt: now,\n\t\t\teditedAt: null,\n\t\t\tdeletedAt: null,\n\t\t};\n\n\t\t// Flush UI immediately: fake conversation + message + switch view\n\t\tconst store = storeRef.current.getState();\n\t\tstore.addConversation({\n\t\t\tid: tempConversationId,\n\t\t\ttitle: null,\n\t\t\tstatus: \"open\",\n\t\t\tlastMessageText: text,\n\t\t\tlastMessageAt: now,\n\t\t\tlastMessageSenderType: \"visitor\",\n\t\t\tlastMessageSenderName: null,\n\t\t\tlastMessageSenderImage: null,\n\t\t\tunreadCount: 0,\n\t\t});\n\t\tstore.setMessages(tempConversationId, [optimisticMsg]);\n\t\tstore.setActiveConversation(tempConversationId);\n\n\t\ttry {\n\t\t\tconst result = await clientRef.current.widget.createConversation.mutate({ text });\n\t\t\tconst conv = result.conversation;\n\n\t\t\t// Remap temp ID → real ID (rewrites conversations list + messages map + active ref).\n\t\t\t// The optimistic message's id becomes stale (conversationId changed) — replaceMessage\n\t\t\t// with the server-confirmed item.\n\t\t\tstoreRef.current.getState().remapConversationId(tempConversationId, conv.id);\n\t\t\tif (result.item) {\n\t\t\t\tstoreRef.current\n\t\t\t\t\t.getState()\n\t\t\t\t\t.replaceMessage(conv.id, optimisticMessageId, result.item as TimelineItem);\n\t\t\t}\n\t\t\t// Insert welcome message if the agent sent one.\n\t\t\t// The welcome is ALWAYS the very first item in a new conversation, so\n\t\t\t// we place it at index 0 deterministically — never trust createdAt sort,\n\t\t\t// because client-clock (optimistic visitor) vs server-clock (welcome)\n\t\t\t// can be off by enough to re-order the pair. Dedup by id so a WS echo\n\t\t\t// doesn't double-insert.\n\t\t\tif (result.welcomeItem) {\n\t\t\t\tconst welcome = result.welcomeItem as TimelineItem;\n\t\t\t\tconst existing = storeRef.current.getState().messages.get(conv.id) ?? [];\n\t\t\t\tconst withoutWelcome = existing.filter((m) => m.id !== welcome.id);\n\t\t\t\tstoreRef.current.getState().setMessages(conv.id, [welcome, ...withoutWelcome]);\n\t\t\t}\n\t\t\treturn conv;\n\t\t} catch (err) {\n\t\t\t// Roll back: remove the fake conversation + message; let the caller surface the error\n\t\t\tstoreRef.current.getState().removeMessage(tempConversationId, optimisticMessageId);\n\t\t\tconst convs = storeRef.current\n\t\t\t\t.getState()\n\t\t\t\t.conversations.filter((c) => c.id !== tempConversationId);\n\t\t\tstoreRef.current.setState({ conversations: convs, activeConversationId: null });\n\t\t\tthrow err;\n\t\t} finally {\n\t\t\tsetIsCreating(false);\n\t\t}\n\t}, []);\n\n\treturn { conversations, create, isCreating, setActiveConversation };\n}\n","import { useEffect, useState } from \"react\";\nimport { onLocaleChange, getI18nRevision } from \"@helpway/widget-core\";\n\n/**\n * React hook that triggers re-render when widget translations load or locale changes.\n * Place this in the top-level widget component so all children get fresh t() values.\n *\n * Returns the current i18n revision number (for debugging).\n */\nexport function useI18n(): number {\n\tconst [rev, setRev] = useState(() => getI18nRevision());\n\n\tuseEffect(() => {\n\t\t// Subscribe to locale/translation changes\n\t\treturn onLocaleChange(() => {\n\t\t\tsetRev(getI18nRevision());\n\t\t});\n\t}, []);\n\n\treturn rev;\n}\n","import { useCallback, useRef } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\n/**\n * Typing presence — show \"is typing\" + send own typing status.\n *\n * Debounced: only sends WS event when typing state *changes*.\n * While typing, auto-stops after 3 seconds of inactivity.\n *\n * Usage:\n * ```tsx\n * const { isTyping, setTyping } = usePresence(conversationId)\n * ```\n */\nexport function usePresence(conversationId: string | null) {\n\tconst { ws } = useWidgetContext();\n\tconst isTyping = useWidgetStore((s) =>\n\t\tconversationId ? (s.typingUsers.get(conversationId) ?? false) : false,\n\t);\n\tconst isAiProcessing = useWidgetStore((s) =>\n\t\tconversationId ? (s.aiProcessing.get(conversationId) ?? false) : false,\n\t);\n\tconst typingTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\tconst isSendingTyping = useRef(false);\n\n\tconst setTyping = useCallback(\n\t\t(typing: boolean) => {\n\t\t\tif (!conversationId) return;\n\n\t\t\t// Clear any pending auto-stop\n\t\t\tif (typingTimer.current) clearTimeout(typingTimer.current);\n\n\t\t\tif (typing) {\n\t\t\t\t// Only send \"typing: true\" if we haven't already\n\t\t\t\tif (!isSendingTyping.current) {\n\t\t\t\t\tisSendingTyping.current = true;\n\t\t\t\t\tws.sendTyping(conversationId, true);\n\t\t\t\t}\n\t\t\t\t// Auto-stop after 3 seconds of inactivity\n\t\t\t\ttypingTimer.current = setTimeout(() => {\n\t\t\t\t\tisSendingTyping.current = false;\n\t\t\t\t\tws.sendTyping(conversationId, false);\n\t\t\t\t}, 3000);\n\t\t\t} else {\n\t\t\t\t// Immediately send stop\n\t\t\t\tif (isSendingTyping.current) {\n\t\t\t\t\tisSendingTyping.current = false;\n\t\t\t\t\tws.sendTyping(conversationId, false);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[conversationId, ws],\n\t);\n\n\treturn { isTyping, isAiProcessing, setTyping };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\nimport type { TimelineItem } from \"@helpway/types\";\n\nconst EMPTY_ITEMS: TimelineItem[] = [];\n\n/**\n * Timeline items for a conversation + real-time updates.\n */\nexport function useTimeline(conversationId: string | null) {\n\tconst { client, store } = useWidgetContext();\n\tconst messages = useWidgetStore((s) =>\n\t\tconversationId ? s.messages.get(conversationId) ?? EMPTY_ITEMS : EMPTY_ITEMS,\n\t);\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [hasMore, setHasMore] = useState(false);\n\tconst cursorRef = useRef<string | undefined>(undefined);\n\n\t// Stable refs to avoid effect re-triggers\n\tconst clientRef = useRef(client);\n\tconst storeRef = useRef(store);\n\tclientRef.current = client;\n\tstoreRef.current = store;\n\n\t// Load initial timeline when conversation changes\n\tuseEffect(() => {\n\t\tif (!conversationId) return;\n\n\t\t// Skip server fetch for optimistic temp IDs — they don't exist server-side.\n\t\t// useConversations.create() owns the seed for these; once remap fires this\n\t\t// effect re-runs with the real id and the fetch happens then.\n\t\tif (conversationId.startsWith(\"temp-\")) return;\n\n\t\tlet cancelled = false;\n\n\t\t// If createConversation already seeded the messages store (welcome + first\n\t\t// visitor message), the server has nothing new to tell us — skip the fetch.\n\t\t// Overwriting the seed with the server payload causes a full array-identity\n\t\t// flip, a brief key-swap for the optimistic→server id transition, and\n\t\t// restarts CSS enter animations — the \"mesajlar gidip tekrar geliyor\" flash.\n\t\t// New items still flow in via WS.addMessage, which dedupes by id.\n\t\tconst existingMessages = storeRef.current.getState().messages.get(conversationId);\n\t\tconst hasSeed = !!existingMessages && existingMessages.length > 0;\n\t\tif (hasSeed) {\n\t\t\tstoreRef.current.getState().clearUnread(conversationId);\n\t\t\tclientRef.current.widget.markSeen\n\t\t\t\t.mutate({ conversationId })\n\t\t\t\t.catch(() => {});\n\t\t\treturn () => {\n\t\t\t\tcancelled = true;\n\t\t\t};\n\t\t}\n\n\t\tsetIsLoading(true);\n\t\tasync function load() {\n\t\t\ttry {\n\t\t\t\tconst data = await clientRef.current.widget.getTimeline.query({\n\t\t\t\t\tconversationId: conversationId!,\n\t\t\t\t\tlimit: 50,\n\t\t\t\t});\n\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\t// Only overwrite if API returned items — don't wipe seed messages with empty response\n\t\t\t\tif (data.items.length > 0) {\n\t\t\t\t\tstoreRef.current.getState().setMessages(conversationId!, data.items as TimelineItem[]);\n\t\t\t\t}\n\t\t\t\tsetHasMore(data.hasMore);\n\t\t\t\tcursorRef.current = data.nextCursor ?? undefined;\n\n\t\t\t\t// Mark as seen + clear local unread count\n\t\t\t\tstoreRef.current.getState().clearUnread(conversationId!);\n\t\t\t\tclientRef.current.widget.markSeen.mutate({ conversationId: conversationId! }).catch(() => {});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useTimeline] Failed to load:\", err);\n\t\t\t} finally {\n\t\t\t\tif (!cancelled) setIsLoading(false);\n\t\t\t}\n\t\t}\n\n\t\tload();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [conversationId]); // Only re-run when conversationId changes\n\n\tconst loadMore = useCallback(async () => {\n\t\tif (!conversationId || !hasMore || isLoading) return;\n\n\t\tsetIsLoading(true);\n\t\ttry {\n\t\t\tconst data = await clientRef.current.widget.getTimeline.query({\n\t\t\t\tconversationId,\n\t\t\t\tcursor: cursorRef.current,\n\t\t\t\tlimit: 50,\n\t\t\t});\n\n\t\t\tconst existing = storeRef.current.getState().messages.get(conversationId) ?? [];\n\t\t\tstoreRef.current.getState().setMessages(conversationId, [...data.items as TimelineItem[], ...existing]);\n\t\t\tsetHasMore(data.hasMore);\n\t\t\tcursorRef.current = data.nextCursor ?? undefined;\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [conversationId, hasMore, isLoading]);\n\n\treturn { items: messages, isLoading, hasMore, loadMore };\n}\n","import { useWidgetStore } from \"../provider\";\n\n/**\n * Total unread count across all conversations.\n *\n * Usage:\n * ```tsx\n * const { totalUnread } = useUnread()\n * ```\n */\nexport function useUnread() {\n\tconst totalUnread = useWidgetStore((s) =>\n\t\ts.conversations.reduce((sum, c) => sum + c.unreadCount, 0),\n\t);\n\n\treturn { totalUnread };\n}\n","import { useWidgetContext, useWidgetStore } from \"../provider\";\n\n/**\n * Core widget state — connection status, visitor identity, website info.\n *\n * Usage:\n * ```tsx\n * const { isReady, visitor, website, identify } = useWidget()\n * ```\n */\nexport function useWidget() {\n\tconst { client } = useWidgetContext();\n\tconst isReady = useWidgetStore((s) => s.isReady);\n\tconst isConnecting = useWidgetStore((s) => s.isConnecting);\n\tconst visitor = useWidgetStore((s) => s.visitor);\n\tconst website = useWidgetStore((s) => s.website);\n\tconst agentConfig = useWidgetStore((s) => s.agentConfig);\n\n\tasync function identify(data: {\n\t\texternalId: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}) {\n\t\treturn client.widget.identify.mutate(data);\n\t}\n\n\treturn { isReady, isConnecting, visitor, website, agentConfig, identify };\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { t } from \"@helpway/widget-core\";\nimport type { PendingAttachment } from \"../hooks/use-composer\";\nimport { SendIcon, PaperclipIcon, XIcon } from \"./icons\";\nimport { AnchoredPreview } from \"./message-bubble\";\n\nconst MAX_CHARS = 5000;\nconst CHAR_WARN_THRESHOLD = 4800;\n\nconst ACCEPTED_TYPES = [\n\t\"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\", \"image/svg+xml\",\n\t\"application/pdf\", \"text/plain\", \"text/csv\", \"application/zip\",\n\t\"application/msword\",\n\t\"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n\t\"application/vnd.ms-excel\",\n\t\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n].join(\",\");\n\ninterface ComposerProps {\n\ttext: string;\n\tonTextChange: (text: string) => void;\n\tonSubmit: () => void;\n\tonTyping?: (isTyping: boolean) => void;\n\tisSubmitting?: boolean;\n\tplaceholder?: string;\n\t/** Compact mode — single-line input without footer row */\n\tcompact?: boolean;\n\t/** Pending attachments to preview */\n\tattachments?: PendingAttachment[];\n\t/** Called when files are added (paste, drop, or file picker) */\n\tonAddFiles?: (files: File[]) => void;\n\t/** Called to remove a pending attachment */\n\tonRemoveAttachment?: (id: string) => void;\n\t/** Disable entire composer (e.g. email required before sending) */\n\tdisabled?: boolean;\n}\n\n/** Widget composer — auto-resize, Enter-to-send, paste/drop attachments */\nexport function Composer({\n\ttext,\n\tonTextChange,\n\tonSubmit,\n\tonTyping,\n\tisSubmitting,\n\tplaceholder,\n\tcompact,\n\tattachments,\n\tonAddFiles,\n\tonRemoveAttachment,\n\tdisabled,\n}: ComposerProps) {\n\tconst ref = useRef<HTMLTextAreaElement>(null);\n\tconst fileInputRef = useRef<HTMLInputElement>(null);\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent) => {\n\t\t\tif (e.key === \"Enter\" && !e.shiftKey) {\n\t\t\t\te.preventDefault();\n\t\t\t\tonSubmit();\n\t\t\t}\n\t\t},\n\t\t[onSubmit],\n\t);\n\n\tconst handleChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\t\tconst value = e.target.value;\n\t\t\tif (value.length > MAX_CHARS) return; // Hard cap\n\t\t\tonTextChange(value);\n\t\t\tonTyping?.(value.length > 0);\n\n\t\t\t// Auto-resize (kept in sync with .hw-composer-input max-height in\n\t\t\t// styles.css — both at 220px / ~10 lines before internal scroll).\n\t\t\tconst el = ref.current;\n\t\t\tif (el) {\n\t\t\t\tel.style.height = \"auto\";\n\t\t\t\tel.style.height = `${Math.min(el.scrollHeight, 220)}px`;\n\t\t\t}\n\t\t},\n\t\t[onTextChange, onTyping],\n\t);\n\n\t// ── Clipboard paste ──────────────────────────\n\tconst handlePaste = useCallback(\n\t\t(e: React.ClipboardEvent) => {\n\t\t\tif (!onAddFiles) return;\n\t\t\tconst files = extractFiles(e.clipboardData);\n\t\t\tif (files.length > 0) {\n\t\t\t\te.preventDefault();\n\t\t\t\tonAddFiles(files);\n\t\t\t}\n\t\t},\n\t\t[onAddFiles],\n\t);\n\n\t// ── Drag & drop ──────────────────────────────\n\tconst [isDragging, setIsDragging] = useState(false);\n\tconst dragCountRef = useRef(0);\n\n\tconst handleDragEnter = useCallback((e: React.DragEvent) => {\n\t\te.preventDefault();\n\t\tdragCountRef.current++;\n\t\tif (dragCountRef.current === 1) setIsDragging(true);\n\t}, []);\n\n\tconst handleDragLeave = useCallback((e: React.DragEvent) => {\n\t\te.preventDefault();\n\t\tdragCountRef.current--;\n\t\tif (dragCountRef.current === 0) setIsDragging(false);\n\t}, []);\n\n\tconst handleDragOver = useCallback((e: React.DragEvent) => {\n\t\te.preventDefault();\n\t\te.dataTransfer.dropEffect = \"copy\";\n\t}, []);\n\n\tconst handleDrop = useCallback(\n\t\t(e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\tdragCountRef.current = 0;\n\t\t\tsetIsDragging(false);\n\t\t\tif (!onAddFiles) return;\n\t\t\tconst files = extractFiles(e.dataTransfer);\n\t\t\tif (files.length > 0) onAddFiles(files);\n\t\t},\n\t\t[onAddFiles],\n\t);\n\n\t// ── File picker ──────────────────────────────\n\tconst handleFileClick = useCallback(() => {\n\t\tfileInputRef.current?.click();\n\t}, []);\n\n\tconst handleFileChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\tif (!onAddFiles || !e.target.files) return;\n\t\t\tonAddFiles(Array.from(e.target.files));\n\t\t\te.target.value = \"\"; // reset so same file can be picked again\n\t\t},\n\t\t[onAddFiles],\n\t);\n\n\tconst hasText = text.trim().length > 0;\n\tconst hasAttachments = attachments && attachments.some((a) => a.part !== null);\n\tconst stillUploading = attachments?.some((a) => a.isUploading) ?? false;\n\t// Button stays clickable whenever there's *something* to send — the\n\t// actual text-required guard lives in `useComposer.submit` and\n\t// surfaces as an inline error if the visitor tries to send an\n\t// attachment without a caption. Feels less sticky than a disabled\n\t// arrow the user can't interpret.\n\tconst canSend = (hasText || hasAttachments) && !stillUploading;\n\tconst showCharCount = text.length >= CHAR_WARN_THRESHOLD;\n\tconst isOverLimit = text.length > MAX_CHARS;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={`hw-composer ${compact ? \"hw-composer--compact\" : \"\"} ${isDragging ? \"hw-composer--dragging\" : \"\"}`}\n\t\t\tonDragEnter={handleDragEnter}\n\t\t\tonDragLeave={handleDragLeave}\n\t\t\tonDragOver={handleDragOver}\n\t\t\tonDrop={handleDrop}\n\t\t>\n\t\t\t<div className=\"hw-composer-box\" style={{ position: \"relative\" }}>\n\t\t\t\t{/* Drag overlay */}\n\t\t\t\t{isDragging && (\n\t\t\t\t\t<div className=\"hw-composer-drop-overlay\">\n\t\t\t\t\t\t<span className=\"hw-composer-drop-text\">{t(\"widget.drop_files\")}</span>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{/* Attachment previews */}\n\t\t\t\t{attachments && attachments.length > 0 && (\n\t\t\t\t\t<div className=\"hw-composer-previews\">\n\t\t\t\t\t\t{attachments.map((a) => (\n\t\t\t\t\t\t\t<PreviewThumb\n\t\t\t\t\t\t\t\tkey={a.id}\n\t\t\t\t\t\t\t\tattachment={a}\n\t\t\t\t\t\t\t\tonRemove={onRemoveAttachment ? () => onRemoveAttachment(a.id) : undefined}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t<textarea\n\t\t\t\t\tref={ref}\n\t\t\t\t\tclassName=\"hw-composer-input\"\n\t\t\t\t\tvalue={text}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\tonPaste={handlePaste}\n\t\t\t\t\tplaceholder={placeholder ?? t(\"widget.placeholder\")}\n\t\t\t\t\trows={1}\n\t\t\t\t\tdisabled={disabled || isSubmitting}\n\t\t\t\t\taria-label={t(\"widget.aria_input\")}\n\t\t\t\t/>\n\t\t\t\t<div className=\"hw-composer-toolbar\">\n\t\t\t\t\t<div className=\"hw-composer-toolbar-left\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"hw-composer-attach\"\n\t\t\t\t\t\t\tonClick={handleFileClick}\n\t\t\t\t\t\t\tdisabled={disabled || isSubmitting}\n\t\t\t\t\t\t\taria-label={t(\"widget.aria_attach\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<PaperclipIcon />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tref={fileInputRef}\n\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\taccept={ACCEPTED_TYPES}\n\t\t\t\t\t\t\tmultiple\n\t\t\t\t\t\t\thidden\n\t\t\t\t\t\t\tonChange={handleFileChange}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{showCharCount && (\n\t\t\t\t\t\t\t<span className={`hw-composer-charcount ${isOverLimit ? \"hw-composer-charcount--over\" : \"\"}`}>\n\t\t\t\t\t\t\t\t{MAX_CHARS - text.length}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName={`hw-composer-send ${canSend && !isOverLimit && !disabled ? \"hw-composer-send--active\" : \"hw-composer-send--inactive\"}`}\n\t\t\t\t\t\tonClick={onSubmit}\n\t\t\t\t\t\tdisabled={disabled || !canSend || isSubmitting || isOverLimit}\n\t\t\t\t\t\taria-label={t(\"widget.aria_send\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t<SendIcon />\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// ── Preview thumbnail with hover ─────────────────\n\nfunction PreviewThumb({ attachment: a, onRemove }: { attachment: PendingAttachment; onRemove?: () => void }) {\n\tconst [hover, setHover] = useState(false);\n\tconst ref = useRef<HTMLDivElement>(null);\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={`hw-composer-preview ${a.error ? \"hw-composer-preview--error\" : \"\"}`}\n\t\t\tonMouseEnter={() => setHover(true)}\n\t\t\tonMouseLeave={() => setHover(false)}\n\t\t>\n\t\t\t{a.previewUrl ? (\n\t\t\t\t<img src={a.previewUrl} alt={a.file.name} className=\"hw-composer-preview-img\" />\n\t\t\t) : (\n\t\t\t\t<div className=\"hw-composer-preview-file\">\n\t\t\t\t\t<span className=\"hw-composer-preview-ext\">\n\t\t\t\t\t\t{a.file.name.split(\".\").pop()?.toUpperCase() ?? \"FILE\"}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{a.isUploading && <div className=\"hw-composer-preview-loader\" />}\n\t\t\t{a.error && <div className=\"hw-composer-preview-badge\" title={a.error}>!</div>}\n\t\t\t{onRemove && (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"hw-composer-preview-remove\"\n\t\t\t\t\tonClick={onRemove}\n\t\t\t\t\taria-label={t(\"widget.aria_remove\")}\n\t\t\t\t>\n\t\t\t\t\t<XIcon />\n\t\t\t\t</button>\n\t\t\t)}\n\t\t\t{/* Hover preview for images */}\n\t\t\t{hover && a.previewUrl && !a.isUploading && (\n\t\t\t\t<AnchoredPreview src={a.previewUrl} anchorRef={ref} />\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ── Helpers ──────────────────────────────────────\n\nfunction extractFiles(data: DataTransfer): File[] {\n\tconst files: File[] = [];\n\tif (data.files) {\n\t\tfor (let i = 0; i < data.files.length; i++) {\n\t\t\tconst file = data.files[i];\n\t\t\tif (file) files.push(file);\n\t\t}\n\t}\n\treturn files;\n}\n","// AUTO-GENERATED — DO NOT EDIT.\n// Run `bun scripts/sync-icons.ts` to regenerate from\n// @central-icons-react/round-outlined-radius-2-stroke-2 (devDep, not shipped).\n//\n// To add or rename an icon: edit MANIFEST in scripts/sync-icons.ts, re-run.\n\nimport type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement> & { size?: number | string };\n\n// IconBubble2\nexport function MessageIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M5.00195 4H19.002C20.1065 4 21.002 4.89543 21.002 6V16C21.002 17.1046 20.1065 18 19.002 18H12.002L7.00195 21V18H5.00195C3.89738 18 3.00195 17.1046 3.00195 16V6C3.00195 4.89543 3.89738 4 5.00195 4Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"square\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconCrossMedium\nexport function XIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M6.5 6.5L17.5 17.5M17.5 6.5L6.5 17.5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconArrowLeft\nexport function ArrowLeftIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M10 6L4 12L10 18\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M5 12H20\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconChevronRight\nexport function ChevronRightIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M9 4L15.5858 10.5858C16.3668 11.3668 16.3668 12.6331 15.5858 13.4142L9 20\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconSparklesSoft\nexport function SparklesIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M19 13C14.0987 13.4243 11.4243 16.0987 11 21C10.5578 16.0225 7.89737 13.5547 3 13C7.97478 12.4262 10.4262 9.97478 11 5C11.5547 9.89737 14.0225 12.5578 19 13Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M18.8864 2.34512C18.8642 2.14869 18.6981 2.0002 18.5004 2C18.3027 1.9998 18.1363 2.14794 18.1137 2.34433C18.0082 3.25861 17.7367 3.88584 17.3113 4.31127C16.8858 4.7367 16.2586 5.00822 15.3443 5.11367C15.1479 5.13632 14.9998 5.30271 15 5.5004C15.0002 5.69809 15.1487 5.86417 15.3451 5.88642C16.2439 5.98823 16.8855 6.25969 17.3217 6.68804C17.7556 7.11407 18.0322 7.74041 18.1126 8.64552C18.1305 8.84634 18.2988 9.00023 18.5004 9C18.702 8.99977 18.8701 8.84551 18.8874 8.64465C18.9645 7.75483 19.2409 7.11438 19.6776 6.67764C20.1144 6.24091 20.7548 5.96446 21.6446 5.88744C21.8455 5.87005 21.9998 5.70205 22 5.50044C22.0002 5.29883 21.8463 5.13048 21.6455 5.11264C20.7404 5.03224 20.1141 4.75557 19.688 4.3217C19.2597 3.88545 18.9882 3.24394 18.8864 2.34512Z\" fill=\"currentColor\" />\n\t\t</svg>\n\t);\n}\n\n// IconPaperPlaneTopRight\nexport function SendIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M9.61946 10.8613L20.9997 4.55422M9.04735 10.9043L4.10061 5.68812C3.49632 5.05091 3.94803 4 4.82621 4H20.2513C21.0247 4 21.5054 4.84039 21.1132 5.50702L13.1902 18.9762C12.7433 19.7358 11.6035 19.5879 11.3654 18.7393L9.28458 11.3223C9.24066 11.1658 9.15923 11.0223 9.04735 10.9043Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconPaperclip1\nexport function PaperclipIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M6 11V15C6 18.3137 8.68629 21 12 21C15.3137 21 18 18.3137 18 15V7C18 4.79086 16.2091 3 14 3C11.7909 3 10 4.79086 10 7V15C10 16.1046 10.8954 17 12 17C13.1046 17 14 16.1046 14 15V7\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconArrowUp\nexport function ArrowUpIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M12 5V20\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M6 10L12 4L18 10\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconHome\nexport function HomeIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M4 9.77313C4 9.2136 4 8.93383 4.07063 8.67517C4.1332 8.446 4.23609 8.22982 4.3745 8.03675C4.53071 7.81882 4.74784 7.6424 5.1821 7.28957L9.9821 3.38956C10.7014 2.80513 11.0611 2.51291 11.4609 2.40099C11.8135 2.30229 12.1865 2.30229 12.5391 2.40099C12.9389 2.51291 13.2986 2.80513 14.0179 3.38957L18.8179 7.28957C19.2522 7.6424 19.4693 7.81882 19.6255 8.03675C19.7639 8.22982 19.8668 8.446 19.9294 8.67517C20 8.93383 20 9.2136 20 9.77313V16.8C20 17.9201 20 18.4802 19.782 18.908C19.5903 19.2843 19.2843 19.5903 18.908 19.782C18.4802 20 17.9201 20 16.8 20H7.2C6.07989 20 5.51984 20 5.09202 19.782C4.71569 19.5903 4.40973 19.2843 4.21799 18.908C4 18.4802 4 17.9201 4 16.8V9.77313Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconBubbleDots\nexport function MessagesIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M4.00195 6.00003C4.00195 4.89546 4.89738 4.00003 6.00195 4.00002L18.0019 4C19.1065 4 20.002 4.89543 20.002 6V16.0358C20.002 17.1403 19.1065 18.0358 18.002 18.0358L15.3757 18.0358C15.1427 18.0358 14.9171 18.1171 14.7377 18.2657L11.9977 20.5358L9.29398 18.2694C9.11393 18.1185 8.8865 18.0358 8.65157 18.0358H6.00195C4.89738 18.0358 4.00195 17.1403 4.00195 16.0358V6.00003Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M6.875 11.25C6.875 11.7332 7.26675 12.125 7.75 12.125C8.23325 12.125 8.625 11.7332 8.625 11.25C8.625 10.7668 8.23325 10.375 7.75 10.375C7.26675 10.375 6.875 10.7668 6.875 11.25ZM11.125 11.25C11.125 11.7332 11.5168 12.125 12 12.125C12.4832 12.125 12.875 11.7332 12.875 11.25C12.875 10.7668 12.4832 10.375 12 10.375C11.5168 10.375 11.125 10.7668 11.125 11.25ZM15.375 11.25C15.375 11.7332 15.7668 12.125 16.25 12.125C16.7332 12.125 17.125 11.7332 17.125 11.25C17.125 10.7668 16.7332 10.375 16.25 10.375C15.7668 10.375 15.375 10.7668 15.375 11.25Z\" fill=\"currentColor\" stroke=\"currentColor\" strokeWidth=\"0.75\" strokeLinecap=\"square\" />\n\t\t</svg>\n\t);\n}\n\n// IconMagnifyingGlass\nexport function SearchIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M11 18C14.866 18 18 14.866 18 11C18 7.13401 14.866 4 11 4C7.13401 4 4 7.13401 4 11C4 14.866 7.13401 18 11 18Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t\t<path d=\"M20 20L16.05 16.05\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconBubblePlus\nexport function NewChatIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M11.9998 8L11.9998 11M11.9998 11V14M11.9998 11H8.99976M11.9998 11H14.9998M11.9977 20.5358L14.7377 18.2657C14.9171 18.1171 15.1427 18.0358 15.3757 18.0358L18.002 18.0358C19.1065 18.0357 20.002 17.1403 20.002 16.0358V6C20.002 4.89543 19.1065 4 18.0019 4L6.00195 4.00002C4.89738 4.00002 4.00195 4.89545 4.00195 6.00002V16.0358C4.00195 17.1403 4.89738 18.0358 6.00195 18.0358H8.65157C8.8865 18.0358 9.11393 18.1185 9.29398 18.2694L11.9977 20.5358Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconAppleIntelligence\nexport function BotIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path fillRule=\"evenodd\" clipRule=\"evenodd\" d=\"M9.67904 3.29155C10.7467 1.56948 13.2537 1.56948 14.3214 3.29155L15.1308 4.59707C15.2462 4.7833 15.3634 4.9684 15.4823 5.15233C15.7005 5.1305 15.9185 5.10662 16.1363 5.08068L17.6626 4.89893C19.6747 4.65934 21.2396 6.61723 20.5571 8.52637L20.0401 9.97255C19.9664 10.1786 19.8947 10.3854 19.825 10.5927C19.9779 10.7493 20.1323 10.9045 20.2882 11.0583L21.3821 12.1371C22.8256 13.5609 22.2668 16.0039 20.3491 16.6605L18.895 17.1584C18.6876 17.2294 18.4809 17.3023 18.275 17.3772C18.2478 17.5943 18.2226 17.8117 18.1995 18.0294L18.0372 19.5565C17.823 21.572 15.5635 22.6577 13.8546 21.5695L12.5584 20.7442C12.3734 20.6264 12.1873 20.5103 12.0002 20.3961C11.8131 20.5103 11.627 20.6264 11.442 20.7442L10.1458 21.5695C8.4369 22.6577 6.17739 21.572 5.96321 19.5565L5.80094 18.0294C5.7778 17.8117 5.75263 17.5943 5.72541 17.3772C5.51949 17.3023 5.31282 17.2294 5.10542 17.1584L3.65133 16.6605C1.7336 16.0039 1.17475 13.5609 2.61829 12.1371L3.71216 11.0583C3.86807 10.9045 4.0225 10.7493 4.17541 10.5927C4.10567 10.3854 4.03395 10.1786 3.96028 9.97255L3.44329 8.52637C2.7608 6.61723 4.32567 4.65934 6.33777 4.89893L7.86408 5.08068C8.08191 5.10662 8.29993 5.1305 8.5181 5.15233C8.63698 4.9684 8.75417 4.7833 8.86963 4.59707L9.67904 3.29155ZM7.61407 6.4827L6.16966 6.31071C5.20357 6.19567 4.45578 7.13505 4.78207 8.04778L5.2716 9.41715C6.10452 8.48167 6.88648 7.5021 7.61407 6.4827ZM5.78854 10.961C7.04552 9.61105 8.19784 8.16742 9.23549 6.64268C11.076 6.78287 12.9244 6.78287 14.7649 6.64268C15.8026 8.16743 16.9549 9.61105 18.2119 10.961C17.6657 12.722 17.2545 14.522 16.9818 16.3454C15.2628 17.0169 13.5974 17.8181 12.0002 18.7422C10.403 17.8181 8.73761 17.0169 7.01863 16.3454C6.74592 14.522 6.3347 12.722 5.78854 10.961ZM4.65269 12.1275L3.61666 13.1494C2.92581 13.8308 3.19234 15.0006 4.11188 15.3154L5.48873 15.7868C5.27593 14.553 4.99684 13.3315 4.65269 12.1275ZM7.22343 17.9611L7.377 19.4062C7.47946 20.3704 8.56185 20.8926 9.38218 20.3703L10.6083 19.5895C9.51004 18.9865 8.38012 18.4429 7.22343 17.9611ZM13.3921 19.5895L14.6182 20.3703C15.4385 20.8926 16.5209 20.3704 16.6234 19.4062L16.777 17.9611C15.6203 18.4429 14.4903 18.9865 13.3921 19.5895ZM18.5117 15.7868L19.8885 15.3154C20.8081 15.0006 21.0746 13.8308 20.3837 13.1494L19.3477 12.1275C19.0035 13.3315 18.7245 14.553 18.5117 15.7868ZM18.7288 9.41715L19.2183 8.04778C19.5446 7.13505 18.7968 6.19567 17.8307 6.31071L16.3863 6.4827C17.1139 7.5021 17.8959 8.48167 18.7288 9.41715ZM13.8786 5.2756C12.6272 5.3429 11.3731 5.3429 10.1218 5.2756L10.8874 4.04072C11.3991 3.21542 12.6013 3.21542 13.113 4.04072L13.8786 5.2756Z\" fill=\"currentColor\" />\n\t\t</svg>\n\t);\n}\n\n// IconBook\nexport function BookIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M9 6C8.44772 6 8 6.44772 8 7C8 7.55228 8.44772 8 9 8V6ZM15 8C15.5523 8 16 7.55228 16 7C16 6.44772 15.5523 6 15 6V8ZM9 10C8.44772 10 8 10.4477 8 11C8 11.5523 8.44772 12 9 12V10ZM12 12C12.5523 12 13 11.5523 13 11C13 10.4477 12.5523 10 12 10V12ZM7 4H17V2H7V4ZM18 5V19H20V5H18ZM17 20H7V22H17V20ZM6 19V5H4V19H6ZM7 20C6.44771 20 6 19.5523 6 19H4C4 20.6569 5.34315 22 7 22V20ZM18 19C18 19.5523 17.5523 20 17 20V22C18.6569 22 20 20.6569 20 19H18ZM17 4C17.5523 4 18 4.44772 18 5H20C20 3.34315 18.6569 2 17 2V4ZM7 2C5.34315 2 4 3.34315 4 5H6C6 4.44772 6.44772 4 7 4V2ZM18 12V15H20V12H18ZM17 16H7V18H17V16ZM7 22H10V20H7V22ZM7 16C5.34315 16 4 17.3431 4 19H6C6 18.4477 6.44772 18 7 18V16ZM18 15C18 15.5523 17.5523 16 17 16V18C18.6569 18 20 16.6569 20 15H18ZM9 8H15V6H9V8ZM9 12H12V10H9V12Z\" fill=\"currentColor\" />\n\t\t</svg>\n\t);\n}\n\n// IconMegaphone\nexport function MegaphoneIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M17.9961 14.0001C19.6529 14.0001 20.9961 12.657 20.9961 11.0001C20.9961 9.34325 19.6529 8.0001 17.9961 8.0001M12.8254 18.0001C12.4136 19.1653 11.3023 20.0001 9.99609 20.0001C8.33924 20.0001 6.99609 18.657 6.99609 17.0001V15.5001M6.99829 6.5001V15.5001M17.9961 5.73752V16.2627C17.9961 17.617 16.6784 18.5797 15.3882 18.1681L4.38819 14.6585C3.55899 14.394 2.99609 13.6235 2.99609 12.7532V9.24704C2.99609 8.37667 3.55899 7.60622 4.38819 7.34167L15.3882 3.83215C16.6784 3.42051 17.9961 4.38325 17.9961 5.73752Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconLightBulb\nexport function LightbulbIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M10 21H14M15.6076 15C17.6404 13.7751 19 11.5463 19 9C19 5.13401 15.866 2 12 2C8.13401 2 5 5.13401 5 9C5 11.5463 6.35958 13.7751 8.39241 15M15.6076 15C15.4111 15.1184 15.2084 15.2274 15 15.3264V17C15 17.5523 14.5523 18 14 18H10C9.44772 18 9 17.5523 9 17V15.3264C8.7916 15.2274 8.58886 15.1184 8.39241 15M15.6076 15H8.39241\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconCircleQuestionmark\nexport function HelpCircleIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M12 16V16.01\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t\t<path d=\"M12 13C12 11.3608 14 11.9319 14 10C14 8.89543 13.1046 8 12 8C11.2597 8 10.6134 8.4022 10.2676 9\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconNewspaper\nexport function NewspaperIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M16 12V6C16 4.89543 15.1046 4 14 4H5C3.89543 4 3 4.89543 3 6V17.5C3 18.8807 4.11929 20 5.5 20H18.5M16 12V17.5C16 18.8807 17.1193 20 18.5 20M16 12H19C20.1046 12 21 12.8954 21 14V17.5C21 18.8807 19.8807 20 18.5 20M7 16H12M7 8H12V12H7V8Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconStar\nexport function StarIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M11.5288 2.29524C11.7179 1.90159 12.2821 1.90159 12.4712 2.29524L14.9458 7.44648C15.0219 7.60491 15.1735 7.71434 15.3487 7.73728L21.0456 8.4832C21.4809 8.5402 21.6552 9.07312 21.3368 9.37342L17.1693 13.303C17.0412 13.4238 16.9832 13.6009 17.0154 13.7735L18.0616 19.3857C18.1416 19.8146 17.6852 20.144 17.2993 19.9359L12.249 17.2133C12.0937 17.1296 11.9063 17.1296 11.751 17.2133L6.70073 19.9359C6.3148 20.144 5.85841 19.8146 5.93837 19.3857L6.98459 13.7735C7.01677 13.6009 6.95885 13.4238 6.83068 13.303L2.66324 9.37342C2.34476 9.07312 2.51909 8.5402 2.95444 8.4832L8.65127 7.73728C8.82648 7.71434 8.97811 7.60491 9.05422 7.44648L11.5288 2.29524Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n","import type { TimelineItemPart } from \"@helpway/types\";\nimport { t } from \"@helpway/widget-core\";\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { handleCodeBlockClick, linkifyText, renderMarkdown } from \"./content/simple-markdown\";\n\ninterface MessageBubbleProps {\n\ttext: string;\n\tsender: \"visitor\" | \"team\" | \"ai\";\n\tsenderName?: string;\n\tparts?: TimelineItemPart[] | null;\n\ttimestamp?: string;\n}\n\n/** Single message bubble — Intercom-style, renders text + image/file parts */\nexport function MessageBubble({ text, sender, senderName, parts, timestamp }: MessageBubbleProps) {\n\tconst senderClass = `hw-msg--${sender}`;\n\tconst bubbleRef = useRef<HTMLDivElement>(null);\n\n\tconst imageParts =\n\t\tparts?.filter((p): p is Extract<TimelineItemPart, { type: \"image\" }> => p.type === \"image\") ??\n\t\t[];\n\tconst fileParts =\n\t\tparts?.filter((p): p is Extract<TimelineItemPart, { type: \"file\" }> => p.type === \"file\") ?? [];\n\tconst hasText = text.length > 0;\n\n\tuseEffect(() => {\n\t\tconst bubble = bubbleRef.current;\n\t\tif (!bubble || (sender !== \"ai\" && sender !== \"team\")) return;\n\t\tconst handleClick = (event: Event) => {\n\t\t\thandleCodeBlockClick(event, bubble);\n\t\t};\n\t\tbubble.addEventListener(\"click\", handleClick);\n\t\treturn () => {\n\t\t\tbubble.removeEventListener(\"click\", handleClick);\n\t\t};\n\t}, [sender]);\n\n\treturn (\n\t\t<div className={`hw-msg ${senderClass}`}>\n\t\t\t<div className=\"hw-msg-body\">\n\t\t\t\t{/*\n\t\t\t\t * Team members keep the sender label ABOVE the bubble (real-person\n\t\t\t\t * context matters — visitor wants to know a human is replying).\n\t\t\t\t * AI messages only show the label in the meta row BELOW the bubble\n\t\t\t\t * to avoid double-branding (agent name twice on the same message).\n\t\t\t\t */}\n\t\t\t\t{sender === \"team\" && (\n\t\t\t\t\t<div className=\"hw-msg-sender\">{senderName ?? t(\"widget.support\")}</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Image attachments */}\n\t\t\t\t{imageParts.length > 0 && (\n\t\t\t\t\t<div className=\"hw-msg-images\">\n\t\t\t\t\t\t{imageParts.map((img, i) => (\n\t\t\t\t\t\t\t<PreviewableThumbnail key={i} src={img.url} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Text bubble.\n\t\t\t\t - AI + team messages → renderMarkdown (team composer uses Tiptap → markdown output).\n\t\t\t\t - Visitor messages → linkifyText (widget composer is plain text).\n\t\t\t\t renderMarkdown escapes HTML entities first (&, <, >), so raw HTML cannot be injected.\n\t\t\t\t See packages/widget-react/src/themed/content/simple-markdown.ts for the safety guarantee. */}\n\t\t\t\t{hasText && (\n\t\t\t\t\t<div className=\"hw-msg-bubble\" ref={bubbleRef}>\n\t\t\t\t\t\t{sender === \"ai\" || sender === \"team\" ? (\n\t\t\t\t\t\t\t<span dangerouslySetInnerHTML={{ __html: renderMarkdown(text) }} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<span dangerouslySetInnerHTML={{ __html: linkifyText(text) }} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* File attachments */}\n\t\t\t\t{fileParts.length > 0 && (\n\t\t\t\t\t<div className=\"hw-msg-files\">\n\t\t\t\t\t\t{fileParts.map((file, i) => (\n\t\t\t\t\t\t\t<FileCard key={i} file={file} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{timestamp && (\n\t\t\t\t\t<div className=\"hw-msg-meta\">\n\t\t\t\t\t\t<span className=\"hw-msg-time\">{timestamp}</span>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// ── Previewable thumbnail (image) ────────────────\n\nfunction PreviewableThumbnail({ src }: { src: string }) {\n\tconst [hover, setHover] = useState(false);\n\tconst ref = useRef<HTMLAnchorElement>(null);\n\n\treturn (\n\t\t<>\n\t\t\t<a\n\t\t\t\tref={ref}\n\t\t\t\thref={src}\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclassName=\"hw-msg-image-link\"\n\t\t\t\tonMouseEnter={() => setHover(true)}\n\t\t\t\tonMouseLeave={() => setHover(false)}\n\t\t\t>\n\t\t\t\t<img src={src} alt=\"\" className=\"hw-msg-image\" loading=\"lazy\" />\n\t\t\t</a>\n\t\t\t{hover && <AnchoredPreview src={src} anchorRef={ref} href={src} />}\n\t\t</>\n\t);\n}\n\n// ── File card with hover preview for previewable types ───\n\nconst PREVIEWABLE_EXTS = new Set([\"pdf\", \"csv\", \"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\"]);\n\nfunction FileCard({ file }: { file: Extract<TimelineItemPart, { type: \"file\" }> }) {\n\tconst [hover, setHover] = useState(false);\n\tconst ref = useRef<HTMLAnchorElement>(null);\n\tconst ext = file.fileName.split(\".\").pop()?.toLowerCase() ?? \"\";\n\tconst isPreviewable = PREVIEWABLE_EXTS.has(ext);\n\tconst isImage = file.mimeType.startsWith(\"image/\");\n\n\treturn (\n\t\t<>\n\t\t\t<a\n\t\t\t\tref={ref}\n\t\t\t\thref={file.url}\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclassName=\"hw-msg-file\"\n\t\t\t\tonMouseEnter={() => isPreviewable && setHover(true)}\n\t\t\t\tonMouseLeave={() => setHover(false)}\n\t\t\t>\n\t\t\t\t<span className=\"hw-msg-file-icon\">\n\t\t\t\t\t<FileTypeIcon ext={ext} />\n\t\t\t\t</span>\n\t\t\t\t<span className=\"hw-msg-file-info\">\n\t\t\t\t\t<span className=\"hw-msg-file-name\">{file.fileName}</span>\n\t\t\t\t\t<span className=\"hw-msg-file-size\">{formatFileSize(file.fileSize)}</span>\n\t\t\t\t</span>\n\t\t\t</a>\n\t\t\t{hover &&\n\t\t\t\tisPreviewable &&\n\t\t\t\t(isImage ? (\n\t\t\t\t\t<AnchoredPreview src={file.url} anchorRef={ref} href={file.url} />\n\t\t\t\t) : (\n\t\t\t\t\t<AnchoredDocPreview fileName={file.fileName} ext={ext} anchorRef={ref} href={file.url} />\n\t\t\t\t))}\n\t\t</>\n\t);\n}\n\n// ── Anchored preview — card popover above the element ──\n\nexport function AnchoredPreview({\n\tsrc,\n\tanchorRef,\n\thref,\n\tonOpen,\n}: {\n\tsrc: string;\n\tanchorRef: React.RefObject<HTMLElement | null>;\n\thref?: string;\n\tonOpen?: () => void;\n}) {\n\tconst [style, setStyle] = useState<React.CSSProperties>({ opacity: 0 });\n\tconst [portalTarget, setPortalTarget] = useState<Element | DocumentFragment | null>(null);\n\n\tuseLayoutEffect(() => {\n\t\tconst anchor = anchorRef.current;\n\t\tif (!anchor) return;\n\n\t\tconst rect = anchor.getBoundingClientRect();\n\t\tconst pw = 260;\n\t\tconst gap = 8;\n\t\tconst vw = window.innerWidth;\n\n\t\tlet left = rect.left + rect.width / 2 - pw / 2;\n\t\tif (left < 8) left = 8;\n\t\tif (left + pw > vw - 8) left = vw - pw - 8;\n\n\t\tconst estimatedH = 200;\n\t\tlet top = rect.top - estimatedH - gap;\n\t\tif (top < 8) top = rect.bottom + gap;\n\n\t\tsetStyle({ left, top, width: pw, opacity: 1 });\n\t\t// Portal into the same root as the anchor so shadow-DOM widgets keep\n\t\t// --hw-* CSS token inheritance and the preview participates in the\n\t\t// widget's z-index stack. Falls back to document.body when the widget\n\t\t// isn't shadow-encapsulated.\n\t\tconst root = anchor.getRootNode();\n\t\tsetPortalTarget(root instanceof ShadowRoot ? root : document.body);\n\t}, [anchorRef]);\n\n\tconst handleClick = () => {\n\t\tif (onOpen) onOpen();\n\t\telse if (href) window.open(href, \"_blank\");\n\t};\n\n\tif (!portalTarget) return null;\n\n\treturn createPortal(\n\t\t<div className=\"hw-hover-preview\" style={style} onClick={handleClick}>\n\t\t\t<img src={src} alt=\"\" className=\"hw-hover-preview-img\" />\n\t\t</div>,\n\t\tportalTarget,\n\t);\n}\n\n// ── Document preview popover (PDF, CSV) ──────────\n\nfunction AnchoredDocPreview({\n\tfileName,\n\text,\n\tanchorRef,\n\thref,\n}: {\n\tfileName: string;\n\text: string;\n\tanchorRef: React.RefObject<HTMLElement | null>;\n\thref: string;\n}) {\n\tconst [style, setStyle] = useState<React.CSSProperties>({ opacity: 0 });\n\tconst [portalTarget, setPortalTarget] = useState<Element | DocumentFragment | null>(null);\n\n\tuseLayoutEffect(() => {\n\t\tconst anchor = anchorRef.current;\n\t\tif (!anchor) return;\n\n\t\tconst rect = anchor.getBoundingClientRect();\n\t\tconst pw = 220;\n\t\tconst ph = 80;\n\t\tconst gap = 8;\n\t\tconst vw = window.innerWidth;\n\n\t\tlet left = rect.left + rect.width / 2 - pw / 2;\n\t\tif (left < 8) left = 8;\n\t\tif (left + pw > vw - 8) left = vw - pw - 8;\n\n\t\tlet top = rect.top - ph - gap;\n\t\tif (top < 8) top = rect.bottom + gap;\n\n\t\tsetStyle({ left, top, width: pw, opacity: 1 });\n\t\tconst root = anchor.getRootNode();\n\t\tsetPortalTarget(root instanceof ShadowRoot ? root : document.body);\n\t}, [anchorRef]);\n\n\tif (!portalTarget) return null;\n\n\treturn createPortal(\n\t\t<div\n\t\t\tclassName=\"hw-hover-preview hw-hover-preview--doc\"\n\t\t\tstyle={style}\n\t\t\tonClick={() => window.open(href, \"_blank\")}\n\t\t>\n\t\t\t<div className=\"hw-hover-preview-doc-icon\">\n\t\t\t\t<FileTypeIcon ext={ext} />\n\t\t\t</div>\n\t\t\t<div className=\"hw-hover-preview-doc-info\">\n\t\t\t\t<span className=\"hw-hover-preview-doc-name\">{fileName}</span>\n\t\t\t\t<span className=\"hw-hover-preview-doc-hint\">{t(\"widget.click_to_open\")}</span>\n\t\t\t</div>\n\t\t</div>,\n\t\tportalTarget,\n\t);\n}\n\n// ── Helpers ──────────────────────────────────────\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction FileTypeIcon({ ext }: { ext: string }) {\n\t// Color-coded by file type\n\tconst colors: Record<string, string> = {\n\t\tpdf: \"#ef4444\",\n\t\tcsv: \"#22c55e\",\n\t\tdoc: \"#3b82f6\",\n\t\tdocx: \"#3b82f6\",\n\t\txls: \"#22c55e\",\n\t\txlsx: \"#22c55e\",\n\t\ttxt: \"#6b7280\",\n\t\tzip: \"#f59e0b\",\n\t};\n\tconst color = colors[ext] ?? \"currentColor\";\n\n\treturn (\n\t\t<svg\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke={color}\n\t\t\tstrokeWidth={1.5}\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t>\n\t\t\t<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n\t\t\t<polyline points=\"14 2 14 8 20 8\" />\n\t\t\t{ext === \"pdf\" && (\n\t\t\t\t<text x=\"8\" y=\"18\" fontSize=\"6\" fill={color} stroke=\"none\" fontWeight=\"700\">\n\t\t\t\t\tPDF\n\t\t\t\t</text>\n\t\t\t)}\n\t\t\t{ext === \"csv\" && (\n\t\t\t\t<text x=\"7\" y=\"18\" fontSize=\"6\" fill={color} stroke=\"none\" fontWeight=\"700\">\n\t\t\t\t\tCSV\n\t\t\t\t</text>\n\t\t\t)}\n\t\t</svg>\n\t);\n}\n","import { useEffect, useRef } from \"react\";\n\nconst COPY_ICON = `<svg class=\"hw-code-copy-icon\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"M15 9V4.25C15 3.55964 14.4404 3 13.75 3H4.25C3.55964 3 3 3.55964 3 4.25V13.75C3 14.4404 3.55964 15 4.25 15H9M10.25 9H19.75C20.4404 9 21 9.55964 21 10.25V19.75C21 20.4404 20.4404 21 19.75 21H10.25C9.55964 21 9 20.4404 9 19.75V10.25C9 9.55964 9.55964 9 10.25 9Z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\nconst CHECK_ICON = `<svg class=\"hw-code-check-icon\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"M8 13L11 16L16 8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\nfunction inferCodeLanguage(code: string, lang?: string): string {\n\tif (lang) return lang;\n\tconst trimmed = code.trim();\n\tif (/^(npm|pnpm|yarn|bun|npx|curl|cd|mkdir|cp|mv|rm|export)\\b/m.test(trimmed)) return \"bash\";\n\tif (/\\b(import|export)\\b/.test(trimmed) && /<[A-Z_a-z][\\w.:-]*(\\s|>)/.test(trimmed)) return \"tsx\";\n\tif (/\\b(import|export|const|let|function|type|interface)\\b/.test(trimmed)) return \"ts\";\n\tif (/^\\s*[{[]/.test(trimmed)) return \"json\";\n\treturn \"code\";\n}\n\nexport function handleCodeBlockClick(e: Event, root: HTMLElement): void {\n\tconst target = e.target as HTMLElement | null;\n\tconst btn = target?.closest<HTMLButtonElement>(\".hw-code-copy\");\n\tif (!btn || !root.contains(btn)) return;\n\tconst block = btn.closest(\".hw-code\");\n\tconst code = block?.querySelector(\"pre code\");\n\tconst text = code?.textContent ?? \"\";\n\tif (!text) return;\n\tvoid navigator.clipboard?.writeText(text).then(\n\t\t() => flashCopied(btn),\n\t\t() => flashCopied(btn, true),\n\t);\n}\n\n/**\n * Lightweight Markdown → HTML renderer.\n * Zero dependencies. Handles common patterns:\n * headings, bold, italic, code, links, lists, blockquotes, images, hr.\n *\n * Security note: Content is served from Better i18n Content CMS which only\n * accepts authenticated writes (secret API key). The CMS sanitizes content\n * server-side. Additionally, our renderMarkdown escapes HTML entities before\n * processing markdown syntax, preventing injection of raw HTML tags.\n */\nexport function renderMarkdown(md: string): string {\n\t// Stash fenced code blocks BEFORE any other pass. Fence content must be\n\t// preserved verbatim: no bold, no autolink, no newline→<br> — otherwise\n\t// a curl command or JSON sample gets shredded. We also escape HTML inside\n\t// the block (the global escape below runs only on the remaining markdown).\n\tconst codeBlocks: string[] = [];\n\tconst codeBlockPlaceholder = (i: number) => `\\u0000CODEBLOCK${i}\\u0000`;\n\tconst body = md.replace(\n\t\t// Eat ALL newlines around the fence (zero-or-more both sides). The\n\t\t// replacement re-emits its own `\\n\\n` pair so the paragraph splitter\n\t\t// cleanly bookends the fence. Without this, `before\\n\\n` + `\\n\\n` from\n\t\t// us = 3 newlines, the extra one becomes <br /> and lands inside a <p>.\n\t\t/\\n*```(\\w+)?\\n?([\\s\\S]*?)```\\n*/g,\n\t\t(_match, lang: string | undefined, code: string) => {\n\t\t\tconst escaped = code.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n\t\t\tconst langLabel = inferCodeLanguage(code, lang);\n\t\t\tconst className = langLabel !== \"code\" ? ` class=\"language-${langLabel}\"` : \"\";\n\t\t\t// Render every fenced block with a header bar (language label + copy\n\t\t\t// button) so it reads like a proper code card, not a bare <pre>.\n\t\t\t// The actual copy action is wired up in MarkdownContent via event\n\t\t\t// delegation — we only need the markup + a stable attribute to key\n\t\t\t// off of.\n\t\t\tconst trimmed = escaped.replace(/\\n$/, \"\");\n\t\t\tcodeBlocks.push(\n\t\t\t\t`<div class=\"hw-code\" data-hw-code=\"1\"><div class=\"hw-code-header\"><span class=\"hw-code-lang\">${langLabel}</span><div class=\"hw-code-actions\"><button type=\"button\" class=\"hw-code-action hw-code-copy\" aria-label=\"Copy code\" title=\"Copy code\">${COPY_ICON}${CHECK_ICON}<span class=\"hw-code-copy-label\">Copy</span></button></div></div><pre><code${className}>${trimmed}</code></pre></div>`,\n\t\t\t);\n\t\t\t// Sandwich the placeholder in blank lines so the paragraph splitter\n\t\t\t// treats it as its own block. Otherwise a fence that follows a\n\t\t\t// paragraph without a separating blank line ends up inside a <p>\n\t\t\t// (invalid HTML, collapses the <pre>).\n\t\t\treturn `\\n\\n${codeBlockPlaceholder(codeBlocks.length - 1)}\\n\\n`;\n\t\t},\n\t);\n\n\tlet html = body\n\t\t// Escape HTML entities FIRST — prevents XSS from raw HTML in markdown\n\t\t.replace(/&/g, \"&amp;\")\n\t\t.replace(/</g, \"&lt;\")\n\t\t.replace(/>/g, \"&gt;\")\n\t\t// Headings (### h3, ## h2, # h1)\n\t\t.replace(/^### (.+)$/gm, \"<h3>$1</h3>\")\n\t\t.replace(/^## (.+)$/gm, \"<h2>$1</h2>\")\n\t\t.replace(/^# (.+)$/gm, \"<h1>$1</h1>\")\n\t\t// Horizontal rule\n\t\t.replace(/^---$/gm, \"<hr />\")\n\t\t// Bold + italic\n\t\t.replace(/\\*\\*\\*(.+?)\\*\\*\\*/g, \"<strong><em>$1</em></strong>\")\n\t\t// Bold\n\t\t.replace(/\\*\\*(.+?)\\*\\*/g, \"<strong>$1</strong>\")\n\t\t// Italic\n\t\t.replace(/\\*(.+?)\\*/g, \"<em>$1</em>\")\n\t\t// Inline code\n\t\t.replace(/`([^`]+)`/g, \"<code>$1</code>\")\n\t\t// Images\n\t\t.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<img src=\"$2\" alt=\"$1\" />')\n\t\t// Links (markdown format)\n\t\t.replace(\n\t\t\t/\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n\t\t\t'<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>',\n\t\t)\n\t\t// Auto-link bare URLs (not already inside an href or markdown link)\n\t\t.replace(\n\t\t\t/(?<!\")(?<!=)(https?:\\/\\/[^\\s<)]+)/g,\n\t\t\t'<a href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>',\n\t\t)\n\t\t// Blockquotes\n\t\t.replace(/^&gt; (.+)$/gm, \"<blockquote>$1</blockquote>\")\n\t\t// Unordered lists\n\t\t.replace(/^[*-] (.+)$/gm, \"<li>$1</li>\")\n\t\t// Paragraphs (double newline)\n\t\t.replace(/\\n\\n/g, \"</p><p>\")\n\t\t// Single newlines → br\n\t\t.replace(/\\n/g, \"<br />\");\n\n\t// Wrap consecutive <li> items in <ul>\n\thtml = html.replace(/((?:<li>.*?<\\/li>\\s*)+)/g, \"<ul>$1</ul>\");\n\n\t// Wrap in paragraph if not starting with a block element\n\tif (\n\t\t!html.startsWith(\"<h\") &&\n\t\t!html.startsWith(\"<ul\") &&\n\t\t!html.startsWith(\"<blockquote\") &&\n\t\t!html.startsWith(\"<hr\")\n\t) {\n\t\thtml = `<p>${html}</p>`;\n\t}\n\n\t// Re-inject code blocks now that surrounding paragraphs / <br> passes are\n\t// done. Placeholders used NUL sentinels so they can't collide with user\n\t// content or be accidentally wrapped by the block-element heuristics above.\n\tif (codeBlocks.length > 0) {\n\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: placeholders use NUL sentinels intentionally.\n\t\thtml = html.replace(/\\u0000CODEBLOCK(\\d+)\\u0000/g, (_m, idx: string) => {\n\t\t\tconst i = Number.parseInt(idx, 10);\n\t\t\treturn codeBlocks[i] ?? \"\";\n\t\t});\n\t\t// A code block that landed inside a <p> (because the preceding line had no\n\t\t// blank-line separator) becomes invalid nesting (<p><div><pre>). Unwrap\n\t\t// the outer <p> so the block stands on its own.\n\t\thtml = html.replace(/<p>(\\s*<div class=\"hw-code\"[\\s\\S]*?<\\/div>\\s*)<\\/p>/g, \"$1\");\n\t}\n\n\treturn html;\n}\n\n/**\n * Convert bare URLs in plain text to clickable links.\n * Used for visitor/team messages (not full markdown).\n * HTML-escaped for safety.\n */\nexport function linkifyText(text: string): string {\n\treturn text\n\t\t.replace(/&/g, \"&amp;\")\n\t\t.replace(/</g, \"&lt;\")\n\t\t.replace(/>/g, \"&gt;\")\n\t\t.replace(\n\t\t\t/(https?:\\/\\/[^\\s<]+)/g,\n\t\t\t'<a href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>',\n\t\t)\n\t\t.replace(/\\n/g, \"<br />\");\n}\n\n/**\n * Renders markdown or pre-rendered HTML content.\n * Prefers bodyHtml (server-sanitized by CMS) when available,\n * falls back to client-side markdown rendering (HTML-escaped).\n */\nexport function MarkdownContent({\n\tbodyHtml,\n\tbodyMarkdown,\n\tclassName,\n}: {\n\tbodyHtml?: string | null;\n\tbodyMarkdown?: string | null;\n\tclassName?: string;\n}) {\n\tconst rootRef = useRef<HTMLDivElement>(null);\n\tconst html = bodyHtml ?? (bodyMarkdown ? renderMarkdown(bodyMarkdown) : \"\");\n\n\t// Strip whitespace-only block elements after the HTML lands in the DOM.\n\t// PlateJS/Slate/ProseMirror CMS bodies emit <p>&nbsp;</p> or <div> </div>\n\t// to represent visual line breaks. CSS `:empty` doesn't match these (the\n\t// nbsp/space is a text node) and CSS has no text-content selector, so we\n\t// clean them up here. Runs once per html change.\n\tuseEffect(() => {\n\t\tconst root = rootRef.current;\n\t\tif (!root) return;\n\n\t\tconst isWhitespaceOnly = (el: Element): boolean => {\n\t\t\t// No element children OR only <br> children, AND text is whitespace/empty\n\t\t\tconst hasNonBrChild = Array.from(el.children).some(\n\t\t\t\t(c) => c.tagName !== \"BR\",\n\t\t\t);\n\t\t\tif (hasNonBrChild) return false;\n\t\t\tconst text = el.textContent ?? \"\";\n\t\t\treturn text.replace(/[\\s ]/g, \"\") === \"\";\n\t\t};\n\n\t\tconst removeEmpties = () => {\n\t\t\tconst candidates = root.querySelectorAll(\"p, div\");\n\t\t\tcandidates.forEach((el) => {\n\t\t\t\tif (isWhitespaceOnly(el)) el.remove();\n\t\t\t});\n\t\t};\n\t\tremoveEmpties();\n\t}, [html]);\n\n\t// Event-delegated copy handler for any `.hw-code-copy` button inside the\n\t// rendered tree. Using delegation instead of rendering each code block as\n\t// a React component keeps the markdown → HTML path zero-dep.\n\tuseEffect(() => {\n\t\tconst root = rootRef.current;\n\t\tif (!root) return;\n\t\tconst handler = (e: Event) => {\n\t\t\thandleCodeBlockClick(e, root);\n\t\t};\n\t\troot.addEventListener(\"click\", handler);\n\t\treturn () => {\n\t\t\troot.removeEventListener(\"click\", handler);\n\t\t};\n\t}, []);\n\n\tif (!html) return null;\n\n\treturn (\n\t\t<div\n\t\t\tref={rootRef}\n\t\t\tclassName={`hw-markdown ${className ?? \"\"}`}\n\t\t\t// Content is from authenticated CMS (server-sanitized bodyHtml)\n\t\t\t// or client-side rendered with HTML entity escaping (renderMarkdown).\n\t\t\t// biome-ignore lint/security/noDangerouslySetInnerHtml: trusted CMS content\n\t\t\tdangerouslySetInnerHTML={{ __html: html }}\n\t\t/>\n\t);\n}\n\nfunction flashCopied(btn: HTMLButtonElement, failed = false) {\n\tconst label = btn.querySelector(\".hw-code-copy-label\");\n\tif (!label) return;\n\tconst original = label.textContent ?? \"Copy\";\n\tlabel.textContent = failed ? \"Failed\" : \"Copied\";\n\tbtn.classList.add(failed ? \"hw-code-copy--failed\" : \"hw-code-copy--copied\");\n\tsetTimeout(() => {\n\t\tlabel.textContent = original;\n\t\tbtn.classList.remove(\"hw-code-copy--copied\", \"hw-code-copy--failed\");\n\t}, 1500);\n}\n","import type { TimelineItem } from \"@helpway/types\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\ninterface DebugEvent {\n\tid: string;\n\tt: number;\n\tkind: \"trpc\" | \"ws\" | \"store\" | \"error\";\n\tlabel: string;\n\tdetail?: string;\n}\n\nconst MAX_EVENTS = 60;\n\nfunction isDebugEnabled(): boolean {\n\tif (typeof window === \"undefined\") return false;\n\tif (typeof window.localStorage !== \"undefined\" && window.localStorage.getItem(\"hw:debug\") === \"1\") {\n\t\treturn true;\n\t}\n\tconst search = window.location?.search ?? \"\";\n\treturn search.includes(\"hwdebug=1\") || search.includes(\"debug=hw\");\n}\n\nfunction senderOf(item: TimelineItem): string {\n\tif (item.visitorId) return \"visitor\";\n\tif (item.aiAgentId) return \"ai\";\n\tif (item.userId) return \"team\";\n\treturn item.type;\n}\n\nexport function WidgetDebugOverlay() {\n\tconst [enabled, setEnabled] = useState(false);\n\tconst [open, setOpen] = useState(true);\n\tconst [events, setEvents] = useState<DebugEvent[]>([]);\n\tconst eventsRef = useRef<DebugEvent[]>([]);\n\n\t// Subscribe to each field individually — returning a fresh object from a\n\t// selector triggers an infinite re-render loop with zustand because each\n\t// render produces a new object reference.\n\tconst activeId = useWidgetStore((s) => s.activeConversationId);\n\tconst messagesMap = useWidgetStore((s) => s.messages);\n\tconst typingUsers = useWidgetStore((s) => s.typingUsers);\n\tconst aiProcessingMap = useWidgetStore((s) => s.aiProcessing);\n\tconst { store } = useWidgetContext();\n\n\tuseEffect(() => {\n\t\tsetEnabled(isDebugEnabled());\n\t}, []);\n\n\tconst pushEvent = useMemo(\n\t\t() => (ev: Omit<DebugEvent, \"id\" | \"t\">) => {\n\t\t\tconst e: DebugEvent = {\n\t\t\t\t...ev,\n\t\t\t\tid: `${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n\t\t\t\tt: Date.now(),\n\t\t\t};\n\t\t\teventsRef.current = [e, ...eventsRef.current].slice(0, MAX_EVENTS);\n\t\t\tsetEvents(eventsRef.current);\n\t\t},\n\t\t[],\n\t);\n\n\t// Intercept fetch to log tRPC calls — works with any tRPC proxy shape\n\t// because we observe at the network boundary, not the client object.\n\tuseEffect(() => {\n\t\tif (!enabled) return;\n\t\tif (typeof window === \"undefined\" || typeof window.fetch !== \"function\") return;\n\t\tconst originalFetch = window.fetch.bind(window);\n\t\tconst patched = (async (input: RequestInfo | URL, init?: RequestInit) => {\n\t\t\tconst url = typeof input === \"string\" ? input : input instanceof URL ? input.toString() : input.url;\n\t\t\tconst isTrpc = url.includes(\"/trpc/\");\n\t\t\tif (isTrpc) {\n\t\t\t\tconst method = init?.method ?? (typeof input !== \"string\" && !(input instanceof URL) ? input.method : \"GET\");\n\t\t\t\tconst label = url.split(\"/trpc/\")[1]?.split(\"?\")[0] ?? url;\n\t\t\t\tpushEvent({ kind: \"trpc\", label: `→ ${method} ${label}`, detail: shortJson(init?.body) });\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst res = await originalFetch(input, init);\n\t\t\t\tif (isTrpc) {\n\t\t\t\t\tconst label = url.split(\"/trpc/\")[1]?.split(\"?\")[0] ?? url;\n\t\t\t\t\tpushEvent({ kind: \"trpc\", label: `← ${res.status} ${label}` });\n\t\t\t\t}\n\t\t\t\treturn res;\n\t\t\t} catch (err) {\n\t\t\t\tif (isTrpc) {\n\t\t\t\t\tconst label = url.split(\"/trpc/\")[1]?.split(\"?\")[0] ?? url;\n\t\t\t\t\tpushEvent({ kind: \"error\", label: `✘ ${label}`, detail: err instanceof Error ? err.message : String(err) });\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}) as unknown as typeof window.fetch;\n\t\twindow.fetch = patched;\n\t\treturn () => {\n\t\t\twindow.fetch = originalFetch;\n\t\t};\n\t}, [enabled, pushEvent]);\n\n\t// Tap WebSocket events by wrapping the store's handleRealtimeEvent\n\tuseEffect(() => {\n\t\tif (!enabled) return;\n\t\tconst original = store.getState().handleRealtimeEvent;\n\t\tstore.setState({\n\t\t\thandleRealtimeEvent: (ev) => {\n\t\t\t\tpushEvent({ kind: \"ws\", label: ev.type, detail: shortJson(ev) });\n\t\t\t\toriginal(ev);\n\t\t\t},\n\t\t});\n\t\treturn () => {\n\t\t\tstore.setState({ handleRealtimeEvent: original });\n\t\t};\n\t}, [enabled, store, pushEvent]);\n\n\t// Emit a marker when messages array changes for the active conversation\n\tconst activeMessages = activeId ? messagesMap.get(activeId) ?? [] : [];\n\tconst lastMsgSignature = useMemo(\n\t\t() => activeMessages.map((m) => `${m.id}:${senderOf(m)}:${m.createdAt}`).join(\"|\"),\n\t\t[activeMessages],\n\t);\n\tconst prevSigRef = useRef(lastMsgSignature);\n\tuseEffect(() => {\n\t\tif (!enabled) return;\n\t\tif (prevSigRef.current !== lastMsgSignature) {\n\t\t\tprevSigRef.current = lastMsgSignature;\n\t\t\tpushEvent({\n\t\t\t\tkind: \"store\",\n\t\t\t\tlabel: `messages[${activeMessages.length}]`,\n\t\t\t\tdetail: activeMessages\n\t\t\t\t\t.map((m, i) => `${i}:${senderOf(m)}=${(m.text ?? \"\").slice(0, 24)}`)\n\t\t\t\t\t.join(\" | \"),\n\t\t\t});\n\t\t}\n\t}, [lastMsgSignature, activeMessages, enabled, pushEvent]);\n\n\tif (!enabled) return null;\n\n\tconst isTyping = activeId ? typingUsers.get(activeId) : false;\n\tconst isAi = activeId ? aiProcessingMap.get(activeId) : false;\n\n\treturn (\n\t\t<div style={styles.wrap}>\n\t\t\t<div style={styles.header}>\n\t\t\t\t<strong>hw debug</strong>\n\t\t\t\t<span style={styles.meta}>\n\t\t\t\t\t{\" \"}· conv {activeId ? activeId.slice(0, 10) : \"—\"} · items {activeMessages.length} · typing {isTyping ? \"Y\" : \"n\"} · ai {isAi ? \"Y\" : \"n\"}\n\t\t\t\t</span>\n\t\t\t\t<button type=\"button\" style={styles.btn} onClick={() => setOpen((v) => !v)}>{open ? \"hide\" : \"show\"}</button>\n\t\t\t\t<button type=\"button\" style={styles.btn} onClick={() => { eventsRef.current = []; setEvents([]); }}>clear</button>\n\t\t\t</div>\n\t\t\t{open && (\n\t\t\t\t<div style={styles.body}>\n\t\t\t\t\t<div style={styles.section}>\n\t\t\t\t\t\t<div style={styles.sectionTitle}>messages (active)</div>\n\t\t\t\t\t\t{activeMessages.length === 0 ? (\n\t\t\t\t\t\t\t<div style={styles.empty}>empty</div>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\tactiveMessages.map((m, i) => (\n\t\t\t\t\t\t\t\t<div key={m.id} style={styles.row}>\n\t\t\t\t\t\t\t\t\t<span style={{ ...styles.badge, background: colorFor(senderOf(m)) }}>{i}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.sender}>{senderOf(m)}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.ts}>{m.createdAt.slice(11, 23)}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.text}>{(m.text ?? \"\").slice(0, 60)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style={styles.section}>\n\t\t\t\t\t\t<div style={styles.sectionTitle}>events</div>\n\t\t\t\t\t\t{events.length === 0 ? (\n\t\t\t\t\t\t\t<div style={styles.empty}>no events yet — send a message</div>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\tevents.map((e) => (\n\t\t\t\t\t\t\t\t<div key={e.id} style={styles.row}>\n\t\t\t\t\t\t\t\t\t<span style={{ ...styles.badge, background: kindColor(e.kind) }}>{e.kind}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.ts}>{new Date(e.t).toISOString().slice(11, 23)}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.evLabel}>{e.label}</span>\n\t\t\t\t\t\t\t\t\t{e.detail && <span style={styles.detail}>{e.detail}</span>}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nfunction shortJson(v: unknown): string {\n\tif (v === undefined) return \"\";\n\ttry {\n\t\tconst s = JSON.stringify(v);\n\t\tif (!s) return \"\";\n\t\treturn s.length > 180 ? `${s.slice(0, 177)}…` : s;\n\t} catch {\n\t\treturn String(v);\n\t}\n}\n\nfunction colorFor(sender: string): string {\n\tswitch (sender) {\n\t\tcase \"visitor\":\n\t\t\treturn \"#1d4ed8\";\n\t\tcase \"ai\":\n\t\t\treturn \"#7c3aed\";\n\t\tcase \"team\":\n\t\t\treturn \"#16a34a\";\n\t\tdefault:\n\t\t\treturn \"#6b7280\";\n\t}\n}\n\nfunction kindColor(kind: DebugEvent[\"kind\"]): string {\n\tswitch (kind) {\n\t\tcase \"trpc\":\n\t\t\treturn \"#0ea5e9\";\n\t\tcase \"ws\":\n\t\t\treturn \"#f97316\";\n\t\tcase \"store\":\n\t\t\treturn \"#64748b\";\n\t\tcase \"error\":\n\t\t\treturn \"#dc2626\";\n\t}\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n\twrap: {\n\t\tposition: \"fixed\",\n\t\tright: 12,\n\t\tbottom: 12,\n\t\tzIndex: 2147483000,\n\t\twidth: 420,\n\t\tmaxHeight: \"70vh\",\n\t\tbackground: \"rgba(9,9,11,0.94)\",\n\t\tcolor: \"#e5e7eb\",\n\t\tborderRadius: 10,\n\t\tfontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n\t\tfontSize: 11,\n\t\tboxShadow: \"0 12px 30px rgba(0,0,0,0.35)\",\n\t\toverflow: \"hidden\",\n\t\tpointerEvents: \"auto\",\n\t},\n\theader: {\n\t\tdisplay: \"flex\",\n\t\talignItems: \"center\",\n\t\tgap: 6,\n\t\tpadding: \"6px 10px\",\n\t\tbackground: \"#18181b\",\n\t\tborderBottom: \"1px solid #27272a\",\n\t},\n\tmeta: { flex: 1, color: \"#a1a1aa\", fontSize: 10 },\n\tbtn: {\n\t\tbackground: \"#27272a\",\n\t\tcolor: \"#e4e4e7\",\n\t\tborder: \"1px solid #3f3f46\",\n\t\tborderRadius: 4,\n\t\tpadding: \"2px 8px\",\n\t\tcursor: \"pointer\",\n\t\tfontSize: 10,\n\t},\n\tbody: { display: \"flex\", flexDirection: \"column\", maxHeight: \"calc(70vh - 32px)\", overflow: \"auto\" },\n\tsection: { borderBottom: \"1px solid #27272a\", padding: \"6px 10px\" },\n\tsectionTitle: { color: \"#a1a1aa\", fontSize: 10, textTransform: \"uppercase\", letterSpacing: 0.6, marginBottom: 4 },\n\trow: {\n\t\tdisplay: \"grid\",\n\t\tgridTemplateColumns: \"32px 56px 72px 1fr\",\n\t\tgap: 6,\n\t\talignItems: \"baseline\",\n\t\tpadding: \"2px 0\",\n\t\tborderTop: \"1px dashed #27272a\",\n\t},\n\tbadge: {\n\t\tdisplay: \"inline-block\",\n\t\tborderRadius: 3,\n\t\tpadding: \"1px 4px\",\n\t\tcolor: \"white\",\n\t\tfontSize: 9,\n\t\ttextAlign: \"center\",\n\t},\n\tsender: { color: \"#d4d4d8\" },\n\tts: { color: \"#71717a\", fontSize: 10 },\n\ttext: { color: \"#e4e4e7\", whiteSpace: \"nowrap\", overflow: \"hidden\", textOverflow: \"ellipsis\" },\n\tevLabel: { color: \"#e4e4e7\" },\n\tdetail: { gridColumn: \"1 / -1\", color: \"#a1a1aa\", fontSize: 10, whiteSpace: \"pre-wrap\", wordBreak: \"break-all\" },\n\tempty: { color: \"#52525b\", fontStyle: \"italic\", fontSize: 10 },\n};\n","import { resolveLabel, t } from \"@helpway/widget-core\";\nimport type { WidgetContentTab } from \"@helpway/widget-core\";\nimport { useCallback, useEffect } from \"react\";\nimport { useContentTab } from \"../../hooks/use-content-tab\";\nimport type { ContentEntryItem } from \"../../hooks/use-content-tab\";\nimport { ContentDetailView } from \"./content-detail-view\";\nimport { ContentListView } from \"./content-list-view\";\nimport { GroupedContentTabView } from \"./grouped-content-tab-view\";\n\n/**\n * Content tab dispatcher:\n * - \"flat\" (default) → simple list → detail\n * - \"grouped\" → categories → items → detail\n */\nexport function ContentTabView({\n\ttab,\n\tshowDetail,\n\tdetailSlug,\n\tsubView,\n\tonSelectEntry,\n\tonSelectCategory,\n}: {\n\ttab: WidgetContentTab;\n\tshowDetail: boolean;\n\tdetailSlug: string | null;\n\tsubView?: string | null;\n\tonSelectEntry: (slug: string) => void;\n\tonSelectCategory?: (category: ContentEntryItem) => void;\n}) {\n\t// ── Grouped tab ──\n\tif (tab.tabType === \"grouped\" && tab.itemsModelSlug) {\n\t\treturn (\n\t\t\t<GroupedContentTabView\n\t\t\t\ttab={tab}\n\t\t\t\tsubView={subView ?? null}\n\t\t\t\tdetailSlug={detailSlug}\n\t\t\t\tonSelectCategory={onSelectCategory ?? (() => {})}\n\t\t\t\tonSelectEntry={onSelectEntry}\n\t\t\t/>\n\t\t);\n\t}\n\n\t// ── Flat tab (default) ──\n\treturn (\n\t\t<FlatContentTabView\n\t\t\ttab={tab}\n\t\t\tshowDetail={showDetail}\n\t\t\tdetailSlug={detailSlug}\n\t\t\tonSelectEntry={onSelectEntry}\n\t\t/>\n\t);\n}\n\n// ── Flat (original behavior) ─────────────────────────────\n\nfunction FlatContentTabView({\n\ttab,\n\tshowDetail,\n\tdetailSlug,\n\tonSelectEntry,\n}: {\n\ttab: WidgetContentTab;\n\tshowDetail: boolean;\n\tdetailSlug: string | null;\n\tonSelectEntry: (slug: string) => void;\n}) {\n\tconst {\n\t\tentries,\n\t\tdetail,\n\t\tisLoading,\n\t\tisLoadingDetail,\n\t\thasMore,\n\t\tfetchEntries,\n\t\tloadMore,\n\t\tfetchDetail,\n\t} = useContentTab(tab.id);\n\n\tuseEffect(() => {\n\t\tif (detailSlug) fetchDetail(detailSlug);\n\t}, [detailSlug, fetchDetail]);\n\n\tconst handleSearch = useCallback(\n\t\t(query: string) => {\n\t\t\tfetchEntries({ page: 1, search: query || undefined, reset: true });\n\t\t},\n\t\t[fetchEntries],\n\t);\n\n\tif (showDetail && detailSlug) {\n\t\treturn <ContentDetailView entry={detail} isLoading={isLoadingDetail} />;\n\t}\n\n\treturn (\n\t\t<ContentListView\n\t\t\tentries={entries}\n\t\t\tisLoading={isLoading}\n\t\t\thasMore={hasMore}\n\t\t\tonSelect={onSelectEntry}\n\t\t\tonLoadMore={loadMore}\n\t\t\tonSearch={handleSearch}\n\t\t\tsearchPlaceholder={`${t(\"widget.search\")} ${resolveLabel(tab.label).toLowerCase()}...`}\n\t\t\tdisplay={tab.display}\n\t\t/>\n\t);\n}\n","import type { WidgetContentTab } from \"@helpway/widget-core\";\nimport { CONTENT_CACHE_TTL, getLocale } from \"@helpway/widget-core\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\ninterface ContentEntryItem {\n\tslug: string;\n\ttitle: string;\n\tbody: string | null;\n\tpublishedAt: string | null;\n\tcustomFields: Record<string, string | null>;\n}\n\ninterface ContentEntryDetail {\n\tslug: string;\n\ttitle: string;\n\tbody: string | null;\n\tbodyHtml: string | null;\n\tpublishedAt: string | null;\n\tsourceLanguage: string;\n\tavailableLanguages: string[];\n\tcustomFields: Record<string, string | null>;\n}\n\nconst EMPTY_TABS: WidgetContentTab[] = [];\n\n// ── Cache key helpers ──\n\nfunction listKey(tabId: string, lang: string) {\n\treturn `flat:${tabId}:${lang}:list`;\n}\n\nfunction detailKey(tabId: string, lang: string, slug: string) {\n\treturn `flat:${tabId}:${lang}:detail:${slug}`;\n}\n\ninterface CachedList {\n\titems: ContentEntryItem[];\n\ttotal: number;\n\thasMore: boolean;\n\tpage: number;\n}\n\nfunction readCache<T>(cache: Map<string, { data: unknown; ts: number }>, key: string): T | null {\n\tconst entry = cache.get(key);\n\tif (!entry) return null;\n\tif (Date.now() - entry.ts > CONTENT_CACHE_TTL) return null;\n\treturn entry.data as T;\n}\n\n/**\n * Hook for fetching content from a dynamic content tab.\n * Content is cached in the Zustand store so tab switches don't re-fetch.\n */\nexport function useContentTab(tabId: string) {\n\tconst { client, store } = useWidgetContext();\n\tconst contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_TABS;\n\tconst tab = contentTabs.find((t) => t.id === tabId) ?? null;\n\n\tconst lang = getLocale();\n\tconst cache = store.getState().contentCache;\n\n\tconst [entries, setEntries] = useState<ContentEntryItem[]>(\n\t\t() => readCache<CachedList>(cache, listKey(tabId, lang))?.items ?? [],\n\t);\n\tconst [detail, setDetail] = useState<ContentEntryDetail | null>(null);\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [isLoadingDetail, setIsLoadingDetail] = useState(false);\n\tconst [hasMore, setHasMore] = useState(\n\t\t() => readCache<CachedList>(cache, listKey(tabId, lang))?.hasMore ?? false,\n\t);\n\tconst [total, setTotal] = useState(\n\t\t() => readCache<CachedList>(cache, listKey(tabId, lang))?.total ?? 0,\n\t);\n\tconst [page, setPage] = useState(\n\t\t() => readCache<CachedList>(cache, listKey(tabId, lang))?.page ?? 1,\n\t);\n\n\tconst fetchEntries = useCallback(\n\t\tasync (opts?: { page?: number; search?: string; reset?: boolean }) => {\n\t\t\tif (!tab) return;\n\t\t\tconst p = opts?.page ?? 1;\n\t\t\tconst reset = opts?.reset ?? p === 1;\n\n\t\t\tsetIsLoading(true);\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\t\ttabId,\n\t\t\t\t\tpage: p,\n\t\t\t\t\tlimit: 10,\n\t\t\t\t\tsearch: opts?.search,\n\t\t\t\t\tlanguage: getLocale(),\n\t\t\t\t});\n\n\t\t\t\tif (result.items) {\n\t\t\t\t\tsetEntries((prev) => {\n\t\t\t\t\t\tconst nextItems = reset ? result.items! : [...prev, ...result.items!];\n\t\t\t\t\t\tif (!opts?.search) {\n\t\t\t\t\t\t\tstore.getState().setContentCache(listKey(tabId, getLocale()), {\n\t\t\t\t\t\t\t\titems: nextItems,\n\t\t\t\t\t\t\t\ttotal: result.total,\n\t\t\t\t\t\t\t\thasMore: result.hasMore,\n\t\t\t\t\t\t\t\tpage: p,\n\t\t\t\t\t\t\t} satisfies CachedList);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nextItems;\n\t\t\t\t\t});\n\t\t\t\t\tsetHasMore(result.hasMore);\n\t\t\t\t\tsetTotal(result.total);\n\t\t\t\t\tsetPage(p);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useContentTab] fetch error:\", err);\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client, tabId, tab, store],\n\t);\n\n\tconst loadMore = useCallback(() => {\n\t\tif (!hasMore || isLoading) return;\n\t\tfetchEntries({ page: page + 1 });\n\t}, [fetchEntries, hasMore, isLoading, page]);\n\n\tconst fetchDetail = useCallback(\n\t\tasync (slug: string) => {\n\t\t\tif (!tab) return;\n\n\t\t\t// Check detail cache\n\t\t\tconst cached = readCache<ContentEntryDetail>(\n\t\t\t\tstore.getState().contentCache,\n\t\t\t\tdetailKey(tabId, getLocale(), slug),\n\t\t\t);\n\t\t\tif (cached) {\n\t\t\t\tsetDetail(cached);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetIsLoadingDetail(true);\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\t\ttabId,\n\t\t\t\t\tslug,\n\t\t\t\t\tlanguage: getLocale(),\n\t\t\t\t});\n\t\t\t\tif (result.entry) {\n\t\t\t\t\tconst entry = result.entry as ContentEntryDetail;\n\t\t\t\t\tsetDetail(entry);\n\t\t\t\t\tstore.getState().setContentCache(\n\t\t\t\t\t\tdetailKey(tabId, getLocale(), slug),\n\t\t\t\t\t\tentry,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useContentTab] detail error:\", err);\n\t\t\t} finally {\n\t\t\t\tsetIsLoadingDetail(false);\n\t\t\t}\n\t\t},\n\t\t[client, tabId, tab, store],\n\t);\n\n\tconst clearDetail = useCallback(() => {\n\t\tsetDetail(null);\n\t}, []);\n\n\t// Initial fetch — only if cache was empty\n\tuseEffect(() => {\n\t\tif (tab && entries.length === 0) {\n\t\t\tfetchEntries({ page: 1, reset: true });\n\t\t}\n\t}, [tab]); // eslint-disable-line react-hooks/exhaustive-deps\n\n\treturn {\n\t\ttab,\n\t\tentries,\n\t\tdetail,\n\t\tisLoading,\n\t\tisLoadingDetail,\n\t\thasMore,\n\t\ttotal,\n\t\tfetchEntries,\n\t\tloadMore,\n\t\tfetchDetail,\n\t\tclearDetail,\n\t};\n}\n\nexport type { ContentEntryItem, ContentEntryDetail, WidgetContentTab };\n","import { formatRelativeTime } from \"@helpway/widget-core\";\nimport type { ContentEntryDetail } from \"../../hooks/use-content-tab\";\nimport { MarkdownContent } from \"./simple-markdown\";\n\nexport function ContentDetailView({\n\tentry,\n\tisLoading,\n}: {\n\tentry: ContentEntryDetail | null;\n\tisLoading: boolean;\n}) {\n\tif (isLoading || !entry) {\n\t\treturn <ArticleSkeleton />;\n\t}\n\n\tconst badge = entry.customFields.version ?? entry.customFields.priority ?? entry.customFields.type ?? null;\n\n\treturn (\n\t\t<div className=\"hw-content-detail\">\n\t\t\t<div className=\"hw-content-detail-header\">\n\t\t\t\t<h1 className=\"hw-content-detail-title\">{entry.title}</h1>\n\t\t\t\t{(badge || entry.publishedAt) && (\n\t\t\t\t\t<div className=\"hw-content-detail-meta\">\n\t\t\t\t\t\t{badge && <span className=\"hw-content-entry-badge\">{badge}</span>}\n\t\t\t\t\t\t{entry.publishedAt && (\n\t\t\t\t\t\t\t<span className=\"hw-content-detail-date\">\n\t\t\t\t\t\t\t\t{formatRelativeTime(entry.publishedAt)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{(entry.body || entry.bodyHtml) && (\n\t\t\t\t<div className=\"hw-content-detail-body\">\n\t\t\t\t\t<MarkdownContent bodyHtml={entry.bodyHtml} bodyMarkdown={entry.body} />\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n/**\n * Article-shaped skeleton.\n *\n * Uses the real .hw-content-detail / .hw-content-detail-header / .hw-content-detail-body / .hw-markdown\n * wrapper classes so all padding, font metrics, and adjacency-spacing rules\n * apply identically to the skeleton — guaranteeing the content lands without\n * any reflow when it arrives.\n *\n * Layout maps 1:1 to the rendered changelog:\n * <h1>Title</h1>\n * <div class=\"meta\"> badge + date </div>\n * <h2>Section</h2>\n * <ul><li>Bullet 1, 2 lines</li></ul>\n * <ul><li>Bullet 2, 2 lines</li></ul>\n * ...\n */\nfunction ArticleSkeleton() {\n\tconst sections: { headerWidth: string; items: { l1: string; l2: string }[] }[] = [\n\t\t{\n\t\t\theaderWidth: \"30%\",\n\t\t\titems: [\n\t\t\t\t{ l1: \"98%\", l2: \"62%\" },\n\t\t\t\t{ l1: \"94%\", l2: \"48%\" },\n\t\t\t\t{ l1: \"96%\", l2: \"70%\" },\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\theaderWidth: \"26%\",\n\t\t\titems: [\n\t\t\t\t{ l1: \"92%\", l2: \"55%\" },\n\t\t\t\t{ l1: \"88%\", l2: \"40%\" },\n\t\t\t],\n\t\t},\n\t];\n\n\treturn (\n\t\t<div className=\"hw-content-detail\">\n\t\t\t<div className=\"hw-content-detail-header\">\n\t\t\t\t<h1 className=\"hw-content-detail-title\">\n\t\t\t\t\t<span className=\"hw-skeleton hw-skeleton-title\" />\n\t\t\t\t</h1>\n\t\t\t\t<div className=\"hw-content-detail-meta\">\n\t\t\t\t\t<span className=\"hw-skeleton hw-skeleton-badge\" />\n\t\t\t\t\t<span className=\"hw-skeleton hw-skeleton-date\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"hw-content-detail-body\">\n\t\t\t\t<div className=\"hw-markdown\">\n\t\t\t\t\t{sections.map((s, i) => (\n\t\t\t\t\t\t<SkeletonSection\n\t\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\t\theaderWidth={s.headerWidth}\n\t\t\t\t\t\t\titems={s.items}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction SkeletonSection({\n\theaderWidth,\n\titems,\n}: {\n\theaderWidth: string;\n\titems: { l1: string; l2: string }[];\n}) {\n\treturn (\n\t\t<>\n\t\t\t<h2>\n\t\t\t\t<span\n\t\t\t\t\tclassName=\"hw-skeleton hw-skeleton-h2\"\n\t\t\t\t\tstyle={{ display: \"block\", width: headerWidth }}\n\t\t\t\t/>\n\t\t\t</h2>\n\t\t\t{items.map((item, j) => (\n\t\t\t\t<ul key={j}>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<div className=\"hw-skeleton-bullet-lines\">\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclassName=\"hw-skeleton hw-skeleton-bullet-line\"\n\t\t\t\t\t\t\t\tstyle={{ display: \"block\", width: item.l1 }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclassName=\"hw-skeleton hw-skeleton-bullet-line\"\n\t\t\t\t\t\t\t\tstyle={{ display: \"block\", width: item.l2, marginTop: 8 }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t))}\n\t\t</>\n\t);\n}\n","import { formatRelativeTime, t } from \"@helpway/widget-core\";\nimport type { ContentTabDisplay } from \"@helpway/types\";\nimport { useCallback, useRef, useState } from \"react\";\nimport type { ContentEntryItem } from \"../../hooks/use-content-tab\";\n\n/**\n * Content entry list — Intercom-style clean card layout.\n * Search bar at top, card entries with title + description + chevron.\n */\nexport function ContentListView({\n\tentries,\n\tisLoading,\n\thasMore,\n\tonSelect,\n\tonLoadMore,\n\tonSearch,\n\tsearchPlaceholder,\n\tdisplay,\n}: {\n\tentries: ContentEntryItem[];\n\tisLoading: boolean;\n\thasMore: boolean;\n\tonSelect: (slug: string) => void;\n\tonLoadMore: () => void;\n\tonSearch?: (query: string) => void;\n\tsearchPlaceholder?: string;\n\tdisplay?: ContentTabDisplay;\n}) {\n\tconst [searchText, setSearchText] = useState(\"\");\n\tconst debounceRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n\tconst handleSearch = useCallback(\n\t\t(value: string) => {\n\t\t\tsetSearchText(value);\n\t\t\tif (!onSearch) return;\n\t\t\tclearTimeout(debounceRef.current);\n\t\t\tdebounceRef.current = setTimeout(() => {\n\t\t\t\tonSearch(value.trim());\n\t\t\t}, 300);\n\t\t},\n\t\t[onSearch],\n\t);\n\n\treturn (\n\t\t<div className=\"hw-content-list\">\n\t\t\t{/* Search */}\n\t\t\t{onSearch && (\n\t\t\t\t<div className=\"hw-content-search\">\n\t\t\t\t\t<div className=\"hw-content-search-box\">\n\t\t\t\t\t\t<svg className=\"hw-content-search-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t\t\t\t\t<circle cx=\"11\" cy=\"11\" r=\"8\" />\n\t\t\t\t\t\t\t<line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tclassName=\"hw-content-search-input\"\n\t\t\t\t\t\t\tplaceholder={searchPlaceholder ?? t(\"widget.search\")}\n\t\t\t\t\t\t\tvalue={searchText}\n\t\t\t\t\t\t\tonChange={(e) => handleSearch(e.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Loading */}\n\t\t\t{isLoading && entries.length === 0 && (\n\t\t\t\t<div className=\"hw-skeleton-content\">\n\t\t\t\t\t{[1, 2, 3].map((i) => (\n\t\t\t\t\t\t<div key={i} className=\"hw-skeleton-content-item\">\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: \"70%\", height: 14 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: \"90%\", height: 12 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: \"40%\", height: 10 }} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Empty */}\n\t\t\t{!isLoading && entries.length === 0 && (\n\t\t\t\t<div className=\"hw-content-empty\">\n\t\t\t\t\t<div className=\"hw-content-empty-title\">\n\t\t\t\t\t\t{searchText ? t(\"widget.no_results\") : t(\"widget.nothing_yet\")}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"hw-content-empty-desc\">\n\t\t\t\t\t\t{searchText ? t(\"widget.try_different\") : t(\"widget.check_back\")}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Entries */}\n\t\t\t{entries.length > 0 && (\n\t\t\t\t<div className=\"hw-content-entries\">\n\t\t\t\t\t{entries.map((entry) => (\n\t\t\t\t\t\t<ContentEntryCard key={entry.slug} entry={entry} onSelect={onSelect} display={display} />\n\t\t\t\t\t))}\n\t\t\t\t\t{hasMore && (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"hw-content-load-more\"\n\t\t\t\t\t\t\tonClick={onLoadMore}\n\t\t\t\t\t\t\tdisabled={isLoading}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{isLoading ? t(\"widget.loading\") : t(\"widget.load_more\")}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ── Entry Card — Intercom-style ──────────────────────────\n\nfunction truncateText(text: string | null, maxLen = 80): string {\n\tif (!text) return \"\";\n\tconst clean = text.replace(/[#*_`>\\[\\]!()-]/g, \"\").trim();\n\treturn clean.length > maxLen ? `${clean.slice(0, maxLen)}...` : clean;\n}\n\nfunction ContentEntryCard({\n\tentry,\n\tonSelect,\n\tdisplay,\n}: {\n\tentry: ContentEntryItem;\n\tonSelect: (slug: string) => void;\n\tdisplay?: ContentTabDisplay;\n}) {\n\tconst { customFields } = entry;\n\n\t// Use display mapping if configured, otherwise auto-detect from common field names\n\tconst badge = display?.badgeField\n\t\t? customFields[display.badgeField] ?? null\n\t\t: customFields.version ?? customFields.priority ?? customFields.type ?? null;\n\n\tconst subtitleValue = display?.subtitleField\n\t\t? (display.subtitleField === \"body\" ? entry.body : customFields[display.subtitleField]) ?? null\n\t\t: customFields.excerpt ?? customFields.summary ?? customFields.description ?? null;\n\n\tconst preview = subtitleValue ? truncateText(subtitleValue) : truncateText(entry.body);\n\n\treturn (\n\t\t<button type=\"button\" className=\"hw-content-entry\" onClick={() => onSelect(entry.slug)}>\n\t\t\t<div className=\"hw-content-entry-main\">\n\t\t\t\t<div className=\"hw-content-entry-text\">\n\t\t\t\t\t<span className=\"hw-content-entry-title\">{entry.title}</span>\n\t\t\t\t\t{preview && (\n\t\t\t\t\t\t<span className=\"hw-content-entry-desc\">{preview}</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{(badge || entry.publishedAt) && (\n\t\t\t\t\t\t<div className=\"hw-content-entry-meta\">\n\t\t\t\t\t\t\t{badge && <span className=\"hw-content-entry-badge\">{badge}</span>}\n\t\t\t\t\t\t\t{entry.publishedAt && (\n\t\t\t\t\t\t\t\t<span className=\"hw-content-entry-date\">{formatRelativeTime(entry.publishedAt)}</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<svg className=\"hw-content-entry-chevron\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t\t\t<polyline points=\"9 18 15 12 9 6\" />\n\t\t\t\t</svg>\n\t\t\t</div>\n\t\t</button>\n\t);\n}\n","import type { WidgetContentTab } from \"@helpway/widget-core\";\nimport { t } from \"@helpway/widget-core\";\nimport { useEffect, useRef } from \"react\";\nimport { useGroupedContentTab } from \"../../hooks/use-grouped-content-tab\";\nimport type { ContentEntryItem } from \"../../hooks/use-content-tab\";\nimport { ContentDetailView } from \"./content-detail-view\";\nimport { ContentListView } from \"./content-list-view\";\n\n/**\n * Grouped content tab — category → items → detail drill-down.\n *\n * Three views managed by parent (DefaultWidget):\n * - subView = null → show categories\n * - subView = \"content-category\" → show items for activeCategory\n * - subView = \"content-detail\" → show item detail\n */\nexport function GroupedContentTabView({\n\ttab,\n\tsubView,\n\tdetailSlug,\n\tonSelectCategory,\n\tonSelectEntry,\n}: {\n\ttab: WidgetContentTab;\n\tsubView: string | null;\n\tdetailSlug: string | null;\n\tonSelectCategory: (category: ContentEntryItem) => void;\n\tonSelectEntry: (slug: string) => void;\n}) {\n\tconst {\n\t\tcategories,\n\t\tisCategoriesLoading,\n\t\titems,\n\t\tisItemsLoading,\n\t\titemsHasMore,\n\t\tactiveCategory,\n\t\tdetail,\n\t\tisLoadingDetail,\n\t\tinitFetch,\n\t\tselectCategory,\n\t\tsearchCategories,\n\t\tloadMoreItems,\n\t\tsearchItems,\n\t\tfetchDetail,\n\t\tclearCategory,\n\t} = useGroupedContentTab(tab.id);\n\n\t// Init fetch categories on mount\n\tuseEffect(() => {\n\t\tinitFetch();\n\t}, [initFetch]);\n\n\t// Fetch detail when slug changes\n\tuseEffect(() => {\n\t\tif (detailSlug && subView === \"content-detail\") {\n\t\t\tfetchDetail(detailSlug);\n\t\t}\n\t}, [detailSlug, subView, fetchDetail]);\n\n\t// Clean up hook state when navigating back to category list\n\tconst prevSubView = useRef(subView);\n\tuseEffect(() => {\n\t\tif (prevSubView.current === \"content-category\" && subView === null) {\n\t\t\tclearCategory();\n\t\t}\n\t\tprevSubView.current = subView;\n\t}, [subView, clearCategory]);\n\n\t// ── Detail view ──\n\tif (subView === \"content-detail\" && detailSlug) {\n\t\treturn <ContentDetailView entry={detail} isLoading={isLoadingDetail} />;\n\t}\n\n\t// ── Items list (within a category) ──\n\tif (subView === \"content-category\" && activeCategory) {\n\t\treturn (\n\t\t\t<ContentListView\n\t\t\t\tentries={items}\n\t\t\t\tisLoading={isItemsLoading}\n\t\t\t\thasMore={itemsHasMore}\n\t\t\t\tonSelect={onSelectEntry}\n\t\t\t\tonLoadMore={loadMoreItems}\n\t\t\t\tonSearch={searchItems}\n\t\t\t\tsearchPlaceholder={t(\"widget.search\")}\n\t\t\t\tdisplay={tab.display}\n\t\t\t/>\n\t\t);\n\t}\n\n\t// ── Categories list (with search) ──\n\treturn (\n\t\t<ContentListView\n\t\t\tentries={categories}\n\t\t\tisLoading={isCategoriesLoading}\n\t\t\thasMore={false}\n\t\t\tonSelect={(slug) => {\n\t\t\t\tconst cat = categories.find((c) => c.slug === slug);\n\t\t\t\tif (cat) {\n\t\t\t\t\tselectCategory(cat);\n\t\t\t\t\tonSelectCategory(cat);\n\t\t\t\t}\n\t\t\t}}\n\t\t\tonLoadMore={() => {}}\n\t\t\tonSearch={searchCategories}\n\t\t\tsearchPlaceholder={t(\"widget.search\")}\n\t\t/>\n\t);\n}\n","import type { WidgetContentTab } from \"@helpway/widget-core\";\nimport { CONTENT_CACHE_TTL, getLocale } from \"@helpway/widget-core\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\nimport type { ContentEntryItem, ContentEntryDetail } from \"./use-content-tab\";\n\nconst EMPTY_TABS: WidgetContentTab[] = [];\n\n// ── Cache key helpers ──\n\nfunction categoriesKey(tabId: string, lang: string) {\n\treturn `grouped:${tabId}:${lang}:categories`;\n}\n\nfunction itemsKey(tabId: string, lang: string, groupSlug: string) {\n\treturn `grouped:${tabId}:${lang}:items:${groupSlug}`;\n}\n\nfunction detailKey(tabId: string, lang: string, slug: string) {\n\treturn `grouped:${tabId}:${lang}:detail:${slug}`;\n}\n\ninterface CachedItems {\n\titems: ContentEntryItem[];\n\thasMore: boolean;\n\tpage: number;\n}\n\nfunction readCache<T>(cache: Map<string, { data: unknown; ts: number }>, key: string): T | null {\n\tconst entry = cache.get(key);\n\tif (!entry) return null;\n\tif (Date.now() - entry.ts > CONTENT_CACHE_TTL) return null;\n\treturn entry.data as T;\n}\n\n/**\n * Hook for grouped content tabs (category → items drill-down).\n * Content is cached in the Zustand store so tab switches don't re-fetch.\n */\nexport function useGroupedContentTab(tabId: string) {\n\tconst { client, store } = useWidgetContext();\n\tconst contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_TABS;\n\tconst tab = contentTabs.find((t) => t.id === tabId) ?? null;\n\n\tconst lang = getLocale();\n\tconst cache = store.getState().contentCache;\n\n\t// ── Categories (top level) ──\n\tconst cachedCategories = readCache<ContentEntryItem[]>(cache, categoriesKey(tabId, lang));\n\tconst [categories, setCategories] = useState<ContentEntryItem[]>(cachedCategories ?? []);\n\tconst [isCategoriesLoading, setIsCategoriesLoading] = useState(false);\n\n\t// ── Items (within a category) ──\n\tconst [items, setItems] = useState<ContentEntryItem[]>([]);\n\tconst [isItemsLoading, setIsItemsLoading] = useState(false);\n\tconst [itemsHasMore, setItemsHasMore] = useState(false);\n\tconst itemsPageRef = useRef(1);\n\n\t// ── Detail (single item) ──\n\tconst [detail, setDetail] = useState<ContentEntryDetail | null>(null);\n\tconst [isLoadingDetail, setIsLoadingDetail] = useState(false);\n\n\t// ── Active category ──\n\tconst [activeCategory, setActiveCategory] = useState<ContentEntryItem | null>(null);\n\n\t// ── All categories (unfiltered, for client-side search) ──\n\tconst allCategoriesRef = useRef<ContentEntryItem[]>(cachedCategories ?? []);\n\n\t// ── Fetch categories ──\n\tconst fetchCategories = useCallback(async () => {\n\t\tif (!tab) return;\n\t\tsetIsCategoriesLoading(true);\n\t\ttry {\n\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\ttabId,\n\t\t\t\tpage: 1,\n\t\t\t\tlimit: 50,\n\t\t\t\tlanguage: getLocale(),\n\t\t\t});\n\t\t\tif (result.items) {\n\t\t\t\tallCategoriesRef.current = result.items;\n\t\t\t\tsetCategories(result.items);\n\t\t\t\tstore.getState().setContentCache(categoriesKey(tabId, getLocale()), result.items);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(\"[useGroupedContentTab] categories error:\", err);\n\t\t} finally {\n\t\t\tsetIsCategoriesLoading(false);\n\t\t}\n\t}, [client, tabId, tab, store]);\n\n\t// Init — only fetch if cache was empty\n\tconst initFetch = useCallback(() => {\n\t\tif (tab && categories.length === 0) {\n\t\t\tfetchCategories();\n\t\t}\n\t}, [fetchCategories, tab, categories.length]);\n\n\t// ── Fetch items for a category ──\n\tconst fetchItems = useCallback(\n\t\tasync (opts?: { page?: number; search?: string; reset?: boolean; groupSlug?: string }) => {\n\t\t\tif (!tab?.itemsModelSlug) return;\n\t\t\tconst p = opts?.page ?? 1;\n\t\t\tconst reset = opts?.reset ?? p === 1;\n\n\t\t\tsetIsItemsLoading(true);\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\t\ttabId,\n\t\t\t\t\tpage: p,\n\t\t\t\t\tlimit: 10,\n\t\t\t\t\tsearch: opts?.search,\n\t\t\t\t\tgroupSlug: opts?.groupSlug,\n\t\t\t\t\titemsModel: tab.itemsModelSlug,\n\t\t\t\t\tlanguage: getLocale(),\n\t\t\t\t});\n\t\t\t\tif (result.items) {\n\t\t\t\t\tsetItems((prev) => {\n\t\t\t\t\t\tconst nextItems = reset ? result.items! : [...prev, ...result.items!];\n\t\t\t\t\t\tif (!opts?.search && opts?.groupSlug) {\n\t\t\t\t\t\t\tstore.getState().setContentCache(\n\t\t\t\t\t\t\t\titemsKey(tabId, getLocale(), opts.groupSlug),\n\t\t\t\t\t\t\t\t{ items: nextItems, hasMore: result.hasMore, page: p } satisfies CachedItems,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nextItems;\n\t\t\t\t\t});\n\t\t\t\t\tsetItemsHasMore(result.hasMore);\n\t\t\t\t\titemsPageRef.current = p;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useGroupedContentTab] items error:\", err);\n\t\t\t} finally {\n\t\t\t\tsetIsItemsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client, tabId, tab, store],\n\t);\n\n\t// ── Select a category → load items from cache or fetch ──\n\tconst selectCategory = useCallback(\n\t\t(category: ContentEntryItem) => {\n\t\t\tsetActiveCategory(category);\n\t\t\tsetDetail(null);\n\n\t\t\tconst cached = readCache<CachedItems>(\n\t\t\t\tstore.getState().contentCache,\n\t\t\t\titemsKey(tabId, getLocale(), category.slug),\n\t\t\t);\n\t\t\tif (cached) {\n\t\t\t\tsetItems(cached.items);\n\t\t\t\tsetItemsHasMore(cached.hasMore);\n\t\t\t\titemsPageRef.current = cached.page;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetItems([]);\n\t\t\tfetchItems({ page: 1, reset: true, groupSlug: category.slug });\n\t\t},\n\t\t[fetchItems, store, tabId],\n\t);\n\n\t// ── Load more items ──\n\tconst loadMoreItems = useCallback(() => {\n\t\tif (!itemsHasMore || isItemsLoading || !activeCategory) return;\n\t\tfetchItems({\n\t\t\tpage: itemsPageRef.current + 1,\n\t\t\tgroupSlug: activeCategory.slug,\n\t\t});\n\t}, [fetchItems, itemsHasMore, isItemsLoading, activeCategory]);\n\n\t// ── Search items (cross-category) ──\n\tconst searchItems = useCallback(\n\t\t(query: string) => {\n\t\t\tsetItems([]);\n\t\t\tfetchItems({\n\t\t\t\tpage: 1,\n\t\t\t\treset: true,\n\t\t\t\tsearch: query || undefined,\n\t\t\t\tgroupSlug: query ? undefined : activeCategory?.slug,\n\t\t\t});\n\t\t},\n\t\t[fetchItems, activeCategory],\n\t);\n\n\t// ── Fetch item detail ──\n\tconst fetchDetail = useCallback(\n\t\tasync (slug: string) => {\n\t\t\tif (!tab?.itemsModelSlug) return;\n\n\t\t\tconst cached = readCache<ContentEntryDetail>(\n\t\t\t\tstore.getState().contentCache,\n\t\t\t\tdetailKey(tabId, getLocale(), slug),\n\t\t\t);\n\t\t\tif (cached) {\n\t\t\t\tsetDetail(cached);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetIsLoadingDetail(true);\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\t\ttabId,\n\t\t\t\t\tslug,\n\t\t\t\t\titemsModel: tab.itemsModelSlug,\n\t\t\t\t\tlanguage: getLocale(),\n\t\t\t\t});\n\t\t\t\tif (result.entry) {\n\t\t\t\t\tconst entry = result.entry as ContentEntryDetail;\n\t\t\t\t\tsetDetail(entry);\n\t\t\t\t\tstore.getState().setContentCache(\n\t\t\t\t\t\tdetailKey(tabId, getLocale(), slug),\n\t\t\t\t\t\tentry,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useGroupedContentTab] detail error:\", err);\n\t\t\t} finally {\n\t\t\t\tsetIsLoadingDetail(false);\n\t\t\t}\n\t\t},\n\t\t[client, tabId, tab, store],\n\t);\n\n\t// ── Search categories (client-side, instant) ──\n\tconst searchCategories = useCallback(\n\t\t(query: string) => {\n\t\t\tif (!query.trim()) {\n\t\t\t\tsetCategories(allCategoriesRef.current);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst q = query.toLowerCase();\n\t\t\tsetCategories(\n\t\t\t\tallCategoriesRef.current.filter((cat) =>\n\t\t\t\t\tcat.title.toLowerCase().includes(q) ||\n\t\t\t\t\t(cat.customFields.description ?? \"\").toLowerCase().includes(q),\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\t[],\n\t);\n\n\tconst clearDetail = useCallback(() => {\n\t\tsetDetail(null);\n\t}, []);\n\n\tconst clearCategory = useCallback(() => {\n\t\tsetActiveCategory(null);\n\t\tsetItems([]);\n\t\tsetDetail(null);\n\t}, []);\n\n\treturn {\n\t\ttab,\n\t\tcategories,\n\t\tisCategoriesLoading,\n\t\titems,\n\t\tisItemsLoading,\n\t\titemsHasMore,\n\t\tactiveCategory,\n\t\tdetail,\n\t\tisLoadingDetail,\n\t\tinitFetch,\n\t\tselectCategory,\n\t\tsearchCategories,\n\t\tloadMoreItems,\n\t\tsearchItems,\n\t\tfetchDetail,\n\t\tclearDetail,\n\t\tclearCategory,\n\t};\n}\n","import {\n\tBookIcon,\n\tHelpCircleIcon,\n\tLightbulbIcon,\n\tMegaphoneIcon,\n\tNewspaperIcon,\n\tStarIcon,\n} from \"../icons\";\n\n/**\n * Maps icon string keys to Central Icons components.\n * Dashboard lets users pick from this set when configuring a content tab.\n * Falls back to BookIcon for unknown keys.\n */\nconst ICON_MAP: Record<string, React.FC> = {\n\tbook: BookIcon,\n\tmegaphone: MegaphoneIcon,\n\tlightbulb: LightbulbIcon,\n\t\"help-circle\": HelpCircleIcon,\n\tnewspaper: NewspaperIcon,\n\tstar: StarIcon,\n};\n\nexport function ContentTabIconComponent({ icon }: { icon: string }) {\n\tconst Icon = ICON_MAP[icon] ?? BookIcon;\n\treturn <Icon />;\n}\n","import type { TimelineItem, TimelineItemPart } from \"@helpway/types\";\nimport { getInitials, getLocale, t } from \"@helpway/widget-core\";\nimport React, { useEffect, useRef } from \"react\";\nimport { useWidgetStore } from \"../provider\";\nimport { MessageBubble } from \"./message-bubble\";\n\nfunction parseParts(raw: TimelineItemPart[] | string | null): TimelineItemPart[] | null {\n\tif (!raw) return null;\n\tif (Array.isArray(raw)) return raw;\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\treturn Array.isArray(parsed) ? parsed : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\ninterface MessageListProps {\n\titems: TimelineItem[];\n\tvisitorName?: string;\n\tisTyping?: boolean;\n\tisAiProcessing?: boolean;\n\thasMore?: boolean;\n\tisLoadingMore?: boolean;\n\tonLoadMore?: () => void;\n\t/** Slot rendered after all messages but before typing indicators (e.g. email prompt) */\n\trenderAfterMessages?: React.ReactNode;\n}\n\n/** Timeline with date separators, typing indicator, infinite scroll, and AI processing state */\nexport function MessageList({\n\titems,\n\tvisitorName,\n\tisTyping,\n\tisAiProcessing,\n\thasMore,\n\tisLoadingMore,\n\tonLoadMore,\n\trenderAfterMessages,\n}: MessageListProps) {\n\tconst bottomRef = useRef<HTMLDivElement>(null);\n\tconst topRef = useRef<HTMLDivElement>(null);\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\tconst prevItemCountRef = useRef(items.length);\n\tconst isInitialLoadRef = useRef(true);\n\t// Single source of truth — agent name comes from dashboard config.\n\tconst agentName = useWidgetStore((s) => s.agentConfig?.name) ?? t(\"widget.helpway_ai\");\n\n\t// Auto-scroll to bottom on new messages (but NOT when loading older ones at top)\n\tuseEffect(() => {\n\t\tconst prevCount = prevItemCountRef.current;\n\t\tconst newCount = items.length;\n\t\tprevItemCountRef.current = newCount;\n\n\t\t// Initial load or new messages added at the end → scroll to bottom\n\t\tif (isInitialLoadRef.current || newCount > prevCount) {\n\t\t\t// Only scroll if the new items were appended (not prepended)\n\t\t\tconst lastItem = items[items.length - 1];\n\t\t\tconst prevLastItem = prevCount > 0 ? items[prevCount - 1] : null;\n\n\t\t\tif (isInitialLoadRef.current || !prevLastItem || lastItem?.id !== prevLastItem?.id) {\n\t\t\t\tbottomRef.current?.scrollIntoView({\n\t\t\t\t\tbehavior: isInitialLoadRef.current ? \"instant\" : \"smooth\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tisInitialLoadRef.current = false;\n\t\t}\n\t}, [items]);\n\n\t// Scroll to bottom when typing/AI indicators appear\n\tuseEffect(() => {\n\t\tif (isTyping || isAiProcessing) {\n\t\t\tbottomRef.current?.scrollIntoView({ behavior: \"smooth\" });\n\t\t}\n\t}, [isTyping, isAiProcessing]);\n\n\t// Infinite scroll — IntersectionObserver on the top sentinel\n\tuseEffect(() => {\n\t\tif (!hasMore || !onLoadMore || !topRef.current) return;\n\n\t\tconst observer = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tif (entries[0]?.isIntersecting && !isLoadingMore) {\n\t\t\t\t\t// Save scroll position before loading\n\t\t\t\t\tconst container = containerRef.current;\n\t\t\t\t\tconst prevScrollHeight = container?.scrollHeight ?? 0;\n\t\t\t\t\tconst prevScrollTop = container?.scrollTop ?? 0;\n\n\t\t\t\t\tonLoadMore();\n\n\t\t\t\t\t// Restore scroll position after DOM update (next frame)\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tif (container) {\n\t\t\t\t\t\t\tconst newScrollHeight = container.scrollHeight;\n\t\t\t\t\t\t\tcontainer.scrollTop = prevScrollTop + (newScrollHeight - prevScrollHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ root: containerRef.current, threshold: 0.1 },\n\t\t);\n\n\t\tobserver.observe(topRef.current);\n\t\treturn () => observer.disconnect();\n\t}, [hasMore, onLoadMore, isLoadingMore]);\n\n\tif (items.length === 0) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName=\"hw-messages\"\n\t\t\t\trole=\"log\"\n\t\t\t\taria-label={t(\"widget.aria_messages\")}\n\t\t\t\taria-live=\"polite\"\n\t\t\t>\n\t\t\t\t<div className=\"hw-empty\">\n\t\t\t\t\t<div className=\"hw-empty-icon\">\n\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n\t\t\t\t\t\t\t<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"hw-empty-text\">{t(\"widget.start_a_conversation\")}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tlet lastDateKey = \"\";\n\t// Stable \"today\" key (YYYY-MM-DD in local time) for separator gating.\n\t// We HIDE the separator for today entirely — matches Intercom/WhatsApp:\n\t// the date is implicit when \"now\", and showing it on every fresh\n\t// conversation creates a jarring vertical jump as the view fills in.\n\tconst todayKey = new Date().toLocaleDateString(\"en-CA\"); // en-CA is YYYY-MM-DD\n\tconst yesterday = new Date();\n\tyesterday.setDate(yesterday.getDate() - 1);\n\tconst yesterdayKey = yesterday.toLocaleDateString(\"en-CA\");\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tclassName=\"hw-messages\"\n\t\t\trole=\"log\"\n\t\t\taria-label={t(\"widget.aria_messages\")}\n\t\t\taria-live=\"polite\"\n\t\t>\n\t\t\t{/* Top sentinel for infinite scroll */}\n\t\t\t<div ref={topRef} className=\"hw-load-more-trigger\">\n\t\t\t\t{isLoadingMore && (\n\t\t\t\t\t<div className=\"hw-load-more-spinner\">\n\t\t\t\t\t\t<div />\n\t\t\t\t\t\t<div />\n\t\t\t\t\t\t<div />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{items.map((item) => {\n\t\t\t\tif (item.type === \"event\") {\n\t\t\t\t\treturn <EventCard key={(item as unknown as { _stableKey?: string })._stableKey ?? item.id} text={item.text ?? \"\"} />;\n\t\t\t\t}\n\n\t\t\t\t// Date separator — bucket by local YYYY-MM-DD; skip rendering\n\t\t\t\t// when the bucket is \"today\" so today's chats stay flush at the top.\n\t\t\t\tconst itemDate = new Date(item.createdAt);\n\t\t\t\tconst dateKey = itemDate.toLocaleDateString(\"en-CA\");\n\t\t\t\tconst isNewBucket = dateKey !== lastDateKey;\n\t\t\t\tif (isNewBucket) lastDateKey = dateKey;\n\t\t\t\tconst showDateSep = isNewBucket && dateKey !== todayKey;\n\t\t\t\tconst dateLabel =\n\t\t\t\t\tdateKey === yesterdayKey\n\t\t\t\t\t\t? t(\"widget.yesterday\")\n\t\t\t\t\t\t: itemDate.toLocaleDateString(getLocale(), {\n\t\t\t\t\t\t\t\tweekday: \"long\",\n\t\t\t\t\t\t\t\tmonth: \"short\",\n\t\t\t\t\t\t\t\tday: \"numeric\",\n\t\t\t\t\t\t\t});\n\n\t\t\t\t// Determine sender\n\t\t\t\tconst sender = item.visitorId ? \"visitor\" : item.aiAgentId ? \"ai\" : \"team\";\n\n\t\t\t\t// Show timestamp on the last message in a consecutive group from the same sender\n\t\t\t\tconst idx = items.indexOf(item);\n\t\t\t\tconst nextItem = items[idx + 1];\n\t\t\t\tconst nextSender = nextItem?.type === \"message\"\n\t\t\t\t\t? (nextItem.visitorId ? \"visitor\" : nextItem.aiAgentId ? \"ai\" : \"team\")\n\t\t\t\t\t: null;\n\t\t\t\tconst isLastInGroup = nextSender !== sender || nextItem?.type === \"event\";\n\t\t\t\tconst timeLabel = isLastInGroup\n\t\t\t\t\t? itemDate.toLocaleTimeString(getLocale(), { hour: \"2-digit\", minute: \"2-digit\" })\n\t\t\t\t\t: undefined;\n\n\t\t\t\treturn (\n\t\t\t\t\t<React.Fragment key={(item as unknown as { _stableKey?: string })._stableKey ?? item.id}>\n\t\t\t\t\t\t{showDateSep && (\n\t\t\t\t\t\t\t<div className=\"hw-date-sep\">\n\t\t\t\t\t\t\t\t<div className=\"hw-date-sep-line\" />\n\t\t\t\t\t\t\t\t<div className=\"hw-date-sep-text\">{dateLabel}</div>\n\t\t\t\t\t\t\t\t<div className=\"hw-date-sep-line\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<MessageBubble\n\t\t\t\t\t\t\ttext={item.text ?? \"\"}\n\t\t\t\t\t\t\tsender={sender}\n\t\t\t\t\t\t\tsenderName={sender === \"visitor\" ? visitorName : (item.userName ?? undefined)}\n\t\t\t\t\t\t\tparts={parseParts(item.parts)}\n\t\t\t\t\t\t\ttimestamp={timeLabel}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</React.Fragment>\n\t\t\t\t);\n\t\t\t})}\n\n\t\t\t{/* Slot for inline content after messages (e.g. email prompt) */}\n\t\t\t{renderAfterMessages}\n\n\t\t\t{/* AI processing indicator */}\n\t\t\t{isAiProcessing && (\n\t\t\t\t<div className=\"hw-typing\">\n\t\t\t\t\t<div className=\"hw-typing-label\">{agentName}</div>\n\t\t\t\t\t<div className=\"hw-typing-dots\">\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Typing indicator (team, not AI) */}\n\t\t\t{isTyping && !isAiProcessing && (\n\t\t\t\t<div className=\"hw-typing\">\n\t\t\t\t\t<div className=\"hw-typing-dots\">\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<div ref={bottomRef} />\n\t\t</div>\n\t);\n}\n\n// ── Event Card ────────────────────────────────────────\n\ninterface EventData {\n\taction: string;\n\tname: string;\n\timage?: string | null;\n}\n\nfunction parseEventData(text: string): EventData | null {\n\tif (!text.startsWith(\"{\")) return null;\n\ttry {\n\t\tconst data = JSON.parse(text);\n\t\tif (data.action && data.name) return data as EventData;\n\t} catch {\n\t\t/* plain text fallback */\n\t}\n\treturn null;\n}\n\nfunction EventCard({ text }: { text: string }) {\n\tconst data = parseEventData(text);\n\n\t// Structured event — rich card with avatar\n\tif (data) {\n\t\tconst message = data.action === \"joined\" ? t(\"widget.joined\") : t(\"widget.left\");\n\n\t\treturn (\n\t\t\t<div className=\"hw-event hw-event--card\">\n\t\t\t\t<div className=\"hw-event-avatar\">\n\t\t\t\t\t{data.image ? (\n\t\t\t\t\t\t<img src={data.image} alt=\"\" className=\"hw-event-avatar-img\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span>{getInitials(data.name)}</span>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hw-event-body\">\n\t\t\t\t\t<span className=\"hw-event-name\">{data.name}</span>{\" \"}\n\t\t\t\t\t<span className=\"hw-event-action\">{message}</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Plain text event (resolve, reopen, etc.)\n\treturn (\n\t\t<div className=\"hw-event\">\n\t\t\t<div className=\"hw-event-text\">{text}</div>\n\t\t</div>\n\t);\n}\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\":host {\\n all: initial;\\n font-family:\\n -apple-system,\\n BlinkMacSystemFont,\\n \\\"Segoe UI\\\",\\n Roboto,\\n \\\"Helvetica Neue\\\",\\n Arial,\\n sans-serif;\\n font-size: 14px;\\n line-height: 1.5;\\n color: #1a1a1a;\\n -webkit-font-smoothing: antialiased;\\n -moz-osx-font-smoothing: grayscale;\\n}\\n.hw-widget {\\n font-family:\\n -apple-system,\\n BlinkMacSystemFont,\\n \\\"Segoe UI\\\",\\n Roboto,\\n \\\"Helvetica Neue\\\",\\n Arial,\\n sans-serif;\\n font-size: 14px;\\n line-height: 1.5;\\n color: #1a1a1a;\\n -webkit-font-smoothing: antialiased;\\n -moz-osx-font-smoothing: grayscale;\\n}\\n.hw-widget *,\\n.hw-widget *::before,\\n.hw-widget *::after {\\n box-sizing: border-box;\\n margin: 0;\\n padding: 0;\\n}\\n:where(.hw-widget) {\\n --hw-primary: #171717;\\n --hw-primary-hover: #2a2a2a;\\n --hw-brand: #171717;\\n --hw-on-brand: #ffffff;\\n --hw-focus-border: #9ca3af;\\n --hw-focus-ring: rgba(0, 0, 0, 0.06);\\n --hw-accent: #6366f1;\\n --hw-bg: #ffffff;\\n --hw-bg-subtle: #fafafa;\\n --hw-bg-hover: #f5f5f5;\\n --hw-border: #f0f0f0;\\n --hw-border-md: #e5e5e5;\\n --hw-text: #111;\\n --hw-text-1: #111;\\n --hw-text-2: #666;\\n --hw-text-3: #999;\\n --hw-text-4: #bbb;\\n --hw-radius: 16px;\\n --hw-visitor-bubble-bg: #f0f0f0;\\n --hw-visitor-bubble-text: #1a1a1a;\\n --hw-font:\\n -apple-system,\\n BlinkMacSystemFont,\\n \\\"Segoe UI\\\",\\n Roboto,\\n \\\"Helvetica Neue\\\",\\n Arial,\\n sans-serif;\\n}\\n.hw-agent-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-agent-icon {\\n width: 100%;\\n height: 100%;\\n border-radius: inherit;\\n}\\n.hw-widget :focus-visible {\\n outline: 2px solid var(--hw-primary);\\n outline-offset: 2px;\\n}\\n.hw-widget :focus:not(:focus-visible) {\\n outline: none;\\n}\\n.hw-widget {\\n position: fixed;\\n bottom: 20px;\\n right: var(--hw-position-right, 20px);\\n left: var(--hw-position-left, auto);\\n z-index: 999999;\\n font-family: var(--hw-font);\\n}\\n.hw-bubble {\\n width: 48px;\\n height: 48px;\\n border-radius: 14px;\\n background: var(--hw-primary);\\n color: white;\\n border: none;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\\n transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s ease;\\n position: relative;\\n overflow: visible;\\n}\\n.hw-bubble--rounded {\\n border-radius: 14px;\\n}\\n.hw-bubble--square {\\n border-radius: 8px;\\n}\\n.hw-bubble--pill {\\n border-radius: 24px;\\n}\\n.hw-bubble--launcher-bubble,\\n.hw-bubble--launcher-help {\\n width: auto;\\n padding: 0 16px 0 12px;\\n gap: 8px;\\n border-radius: 24px;\\n}\\n.hw-bubble--launcher-bubble.hw-bubble--square,\\n.hw-bubble--launcher-help.hw-bubble--square {\\n border-radius: 8px;\\n}\\n.hw-bubble--launcher-bubble.hw-bubble--rounded,\\n.hw-bubble--launcher-help.hw-bubble--rounded {\\n border-radius: 14px;\\n}\\n.hw-bubble-label {\\n font-size: 14px;\\n font-weight: 600;\\n white-space: nowrap;\\n line-height: 1;\\n position: static;\\n opacity: 1;\\n transform: none;\\n}\\n.hw-bubble--launcher-bubble .hw-bubble-icon,\\n.hw-bubble--launcher-help .hw-bubble-icon {\\n position: static;\\n}\\n.hw-bubble:hover {\\n transform: scale(1.05);\\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);\\n}\\n.hw-bubble:active {\\n transform: scale(0.95);\\n}\\n.hw-bubble--open {\\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\\n}\\n.hw-bubble:focus-visible {\\n outline: 2px solid white;\\n outline-offset: 2px;\\n}\\n.hw-bubble-icon {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n position: absolute;\\n transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease;\\n}\\n.hw-bubble-icon svg {\\n width: 22px;\\n height: 22px;\\n}\\n.hw-bubble-icon--hidden {\\n transform: scale(0.3) rotate(90deg);\\n opacity: 0;\\n}\\n.hw-bubble-icon--bot {\\n}\\n.hw-bubble--avatar .hw-bubble-icon--bot {\\n width: 100%;\\n height: 100%;\\n}\\n.hw-bubble--avatar .hw-bubble-icon--bot .hw-agent-img {\\n width: 100%;\\n height: 100%;\\n border-radius: 0;\\n}\\n.hw-bubble-icon--close svg {\\n width: 22px;\\n height: 22px;\\n}\\n.hw-bubble-badge {\\n position: absolute;\\n top: -4px;\\n right: -4px;\\n min-width: 20px;\\n height: 20px;\\n border-radius: 10px;\\n background: var(--hw-primary);\\n color: white;\\n font-size: 11px;\\n font-weight: 700;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 0 5px;\\n border: 2px solid white;\\n animation: hw-badge-pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\\n}\\n@keyframes hw-badge-pop {\\n from {\\n transform: scale(0);\\n }\\n to {\\n transform: scale(1);\\n }\\n}\\n.hw-bubble-badge::after {\\n content: \\\"\\\";\\n position: absolute;\\n inset: -2px;\\n border-radius: inherit;\\n background: var(--hw-primary);\\n opacity: 0;\\n animation: hw-badge-pulse 2s ease-out infinite;\\n}\\n@keyframes hw-badge-pulse {\\n 0% {\\n opacity: 0.5;\\n transform: scale(1);\\n }\\n 100% {\\n opacity: 0;\\n transform: scale(1.8);\\n }\\n}\\n.hw-window {\\n position: absolute;\\n bottom: 72px;\\n right: var(--hw-window-right, 0);\\n left: var(--hw-window-left, auto);\\n width: 440px;\\n height: 640px;\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text);\\n border-radius: var(--hw-radius);\\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.04);\\n display: flex;\\n flex-direction: column;\\n overflow: hidden;\\n animation: hw-window-open 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);\\n transition: width 280ms cubic-bezier(0.4, 0, 0.2, 1), height 280ms cubic-bezier(0.4, 0, 0.2, 1);\\n}\\n.hw-window--reading {\\n width: min(720px, calc(100vw - 40px));\\n height: min(800px, calc(100vh - 100px));\\n}\\n@keyframes hw-window-open {\\n from {\\n opacity: 0;\\n transform: translateY(12px) scale(0.96);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n}\\n.hw-window--closing {\\n animation: hw-window-close 0.2s ease forwards;\\n}\\n@keyframes hw-window-close {\\n from {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n to {\\n opacity: 0;\\n transform: translateY(8px) scale(0.98);\\n }\\n}\\n.hw-content {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n overflow: hidden;\\n min-height: 0;\\n}\\n@media (prefers-reduced-motion: reduce) {\\n .hw-window,\\n .hw-window--closing,\\n .hw-content,\\n .hw-msg,\\n .hw-bubble-icon,\\n .hw-bubble-badge,\\n .hw-bubble-badge::after,\\n .hw-typing-dot,\\n .hw-loading-dot {\\n animation-duration: 0.01ms !important;\\n transition-duration: 0.01ms !important;\\n }\\n}\\n.hw-hero {\\n flex-shrink: 0;\\n background:\\n linear-gradient(\\n 160deg,\\n color-mix(in srgb, var(--hw-primary) 60%, black) 0%,\\n var(--hw-primary) 50%,\\n color-mix(in srgb, var(--hw-primary) 40%, black) 100%);\\n color: white;\\n padding: 20px 22px 40px;\\n}\\n.hw-hero-top {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n margin-bottom: 16px;\\n}\\n.hw-hero-close {\\n width: 30px;\\n height: 30px;\\n border-radius: 50%;\\n border: none;\\n background: rgba(255, 255, 255, 0.1);\\n color: rgba(255, 255, 255, 0.6);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n transition: background 0.15s, color 0.15s;\\n}\\n.hw-hero-close:hover {\\n background: rgba(255, 255, 255, 0.2);\\n color: white;\\n}\\n.hw-hero-close:active {\\n transform: scale(0.92);\\n transition:\\n transform 0.14s cubic-bezier(0.23, 1, 0.32, 1),\\n background 0.15s,\\n color 0.15s;\\n}\\n.hw-hero-close svg {\\n width: 20px;\\n height: 20px;\\n}\\n.hw-hero-bot-icon {\\n width: 36px;\\n height: 36px;\\n flex-shrink: 0;\\n color: white;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 10px;\\n overflow: hidden;\\n}\\n.hw-hero-bot-icon svg {\\n width: 32px;\\n height: 32px;\\n}\\n.hw-hero-greeting {\\n font-size: 26px;\\n font-weight: 700;\\n line-height: 1.15;\\n margin-bottom: 6px;\\n}\\n.hw-hero-greeting-name {\\n font-weight: 300;\\n}\\n.hw-hero-greeting-question {\\n font-weight: 700;\\n}\\n.hw-hero-subtitle {\\n font-size: 15px;\\n color: rgba(255, 255, 255, 0.5);\\n line-height: 1.35;\\n}\\n.hw-sheet {\\n flex: 1;\\n overflow-y: auto;\\n min-height: 0;\\n background: #ffffff;\\n border-radius: 20px 20px 0 0;\\n margin-top: -24px;\\n box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);\\n position: relative;\\n z-index: 1;\\n}\\n.hw-sheet-inner {\\n padding: 20px 16px;\\n display: flex;\\n flex-direction: column;\\n gap: 12px;\\n}\\n.hw-header {\\n display: flex;\\n align-items: center;\\n padding: 12px 16px;\\n background: var(--hw-primary);\\n color: white;\\n flex-shrink: 0;\\n gap: 10px;\\n}\\n.hw-header--sub {\\n justify-content: space-between;\\n background: transparent;\\n color: var(--hw-text);\\n border-bottom: 1px solid var(--hw-border);\\n}\\n.hw-header-back {\\n width: 28px;\\n height: 28px;\\n border-radius: 8px;\\n border: none;\\n background: transparent;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n transition: color 0.15s, background 0.15s;\\n flex-shrink: 0;\\n}\\n.hw-header-back svg {\\n width: 18px;\\n height: 18px;\\n}\\n.hw-header-back:hover {\\n color: var(--hw-text);\\n background: var(--hw-bg-subtle);\\n}\\n.hw-header-identity {\\n display: flex;\\n align-items: center;\\n gap: 10px;\\n flex: 1;\\n min-width: 0;\\n}\\n.hw-header-bot-icon {\\n width: 28px;\\n height: 28px;\\n flex-shrink: 0;\\n color: var(--hw-text);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 8px;\\n overflow: hidden;\\n}\\n.hw-header-bot-icon svg {\\n width: 24px;\\n height: 24px;\\n}\\n.hw-header-bot-icon--team {\\n background: var(--hw-brand, #0a0a0a);\\n color: var(--hw-on-brand, #fff);\\n}\\n.hw-header-agent-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-header-agent-initials {\\n font-size: 11px;\\n font-weight: 600;\\n line-height: 1;\\n}\\n.hw-header-info {\\n flex: 1;\\n min-width: 0;\\n}\\n.hw-header-name {\\n font-size: 14px;\\n font-weight: 600;\\n line-height: 1.3;\\n}\\n.hw-header-status {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n line-height: 1.3;\\n}\\n.hw-header-close {\\n width: 28px;\\n height: 28px;\\n border-radius: 8px;\\n border: none;\\n background: transparent;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n transition:\\n background-color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n transform 140ms cubic-bezier(0.23, 1, 0.32, 1);\\n flex-shrink: 0;\\n}\\n.hw-header-close svg {\\n width: 20px;\\n height: 20px;\\n}\\n.hw-header-close:hover {\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text);\\n}\\n.hw-header-close:active {\\n transform: scale(0.92);\\n}\\n.hw-header--centered {\\n justify-content: space-between;\\n background: transparent;\\n color: var(--hw-text);\\n border-bottom: 1px solid var(--hw-border);\\n}\\n.hw-header--centered .hw-header-title {\\n position: absolute;\\n left: 50%;\\n transform: translateX(-50%);\\n max-width: calc(100% - 88px);\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n text-align: center;\\n}\\n.hw-header-spacer {\\n width: 28px;\\n flex-shrink: 0;\\n}\\n.hw-header--messages {\\n justify-content: space-between;\\n background: transparent;\\n color: var(--hw-text);\\n border-bottom: 1px solid var(--hw-border);\\n}\\n.hw-header-title {\\n font-size: 16px;\\n font-weight: 600;\\n}\\n.hw-header-actions {\\n display: flex;\\n align-items: center;\\n gap: 6px;\\n}\\n.hw-header-action {\\n width: 28px;\\n height: 28px;\\n border-radius: 8px;\\n border: none;\\n background: transparent;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n transition:\\n background-color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n transform 140ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n.hw-header-action svg {\\n width: 16px;\\n height: 16px;\\n}\\n.hw-header-action:hover {\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text);\\n}\\n.hw-header-action:active {\\n transform: scale(0.94);\\n}\\n.hw-card {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n width: 100%;\\n padding: 14px 16px;\\n border-radius: 14px;\\n background: var(--hw-bg);\\n border: 1px solid rgba(0, 0, 0, 0.06);\\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.03);\\n cursor: pointer;\\n transition: box-shadow 180ms cubic-bezier(0.23, 1, 0.32, 1), transform 180ms cubic-bezier(0.23, 1, 0.32, 1);\\n text-align: left;\\n color: var(--hw-text);\\n font-family: inherit;\\n}\\n.hw-card:hover {\\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.05);\\n transform: translateY(-1px);\\n}\\n.hw-card:active {\\n transform: translateY(0) scale(0.99);\\n transition-duration: 120ms;\\n}\\n.hw-card-body {\\n flex: 1;\\n min-width: 0;\\n}\\n.hw-card-title {\\n font-size: 14px;\\n font-weight: 600;\\n line-height: 1.3;\\n color: var(--hw-text);\\n}\\n.hw-card-meta {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n line-height: 1.3;\\n margin-top: 1px;\\n}\\n.hw-card-arrow {\\n width: 32px;\\n height: 32px;\\n border-radius: 50%;\\n background: var(--hw-primary);\\n color: white;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n}\\n.hw-card-arrow svg {\\n width: 14px;\\n height: 14px;\\n}\\n.hw-msgs-tab {\\n flex: 1;\\n overflow-y: auto;\\n padding: 12px 16px;\\n display: flex;\\n flex-direction: column;\\n gap: 8px;\\n}\\n.hw-recent-card {\\n border-radius: 14px;\\n background: var(--hw-bg);\\n border: 1px solid rgba(0, 0, 0, 0.06);\\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.03);\\n overflow: hidden;\\n}\\n.hw-recent-header {\\n font-size: 12px;\\n font-weight: 600;\\n color: var(--hw-text-2);\\n padding: 12px 14px 0;\\n}\\n.hw-recent-row {\\n display: flex;\\n align-items: center;\\n gap: 10px;\\n width: 100%;\\n padding: 10px 14px;\\n border: none;\\n border-bottom: 1px solid var(--hw-border);\\n background: none;\\n cursor: pointer;\\n text-align: left;\\n font-family: inherit;\\n color: var(--hw-text);\\n transition: background-color 140ms cubic-bezier(0.23, 1, 0.32, 1), transform 140ms cubic-bezier(0.23, 1, 0.32, 1);\\n position: relative;\\n}\\n.hw-recent-row:hover {\\n background: rgba(0, 0, 0, 0.03);\\n}\\n.hw-recent-row:active {\\n transform: scale(0.995);\\n}\\n.hw-recent-row--last {\\n border-bottom: none;\\n}\\n.hw-recent-row .hw-conv-card-avatar {\\n width: 32px;\\n height: 32px;\\n border-radius: 8px;\\n}\\n.hw-recent-row .hw-conv-card-avatar svg {\\n width: 18px;\\n height: 18px;\\n}\\n.hw-recent-row .hw-conv-card-name {\\n font-size: 13px;\\n}\\n.hw-recent-row .hw-conv-card-preview {\\n font-size: 12px;\\n}\\n.hw-recent-row--unread .hw-conv-card-name {\\n color: var(--hw-text);\\n}\\n.hw-recent-row--unread .hw-conv-card-time {\\n color: var(--hw-accent);\\n font-weight: 500;\\n}\\n.hw-recent-row-badge {\\n min-width: 18px;\\n height: 18px;\\n border-radius: 9px;\\n background: var(--hw-primary);\\n color: white;\\n font-size: 11px;\\n font-weight: 600;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 0 5px;\\n flex-shrink: 0;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-recent-see-all {\\n display: block;\\n width: 100%;\\n padding: 10px 14px;\\n text-align: center;\\n font-size: 13px;\\n font-weight: 500;\\n color: var(--hw-text);\\n background: none;\\n border: none;\\n border-top: 1px solid var(--hw-border);\\n cursor: pointer;\\n font-family: inherit;\\n transition: background 0.1s;\\n}\\n.hw-recent-see-all:hover {\\n background: rgba(0, 0, 0, 0.02);\\n}\\n.hw-conv-card {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n gap: 4px;\\n width: 100%;\\n padding: 14px 16px;\\n border-radius: 14px;\\n background: var(--hw-bg);\\n border: 1px solid rgba(0, 0, 0, 0.06);\\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.03);\\n cursor: pointer;\\n transition: box-shadow 0.15s, transform 0.1s;\\n text-align: left;\\n font-family: inherit;\\n color: var(--hw-text);\\n}\\n.hw-conv-card:hover {\\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.04);\\n}\\n.hw-conv-card:active {\\n transform: scale(0.99);\\n}\\n.hw-conv-card-row {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n}\\n.hw-conv-card-avatar {\\n width: 36px;\\n height: 36px;\\n border-radius: 10px;\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text-3);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n overflow: hidden;\\n}\\n.hw-conv-card-avatar svg {\\n width: 20px;\\n height: 20px;\\n}\\n.hw-conv-card-avatar-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-conv-card-avatar--team {\\n background: var(--hw-brand, #0a0a0a);\\n color: var(--hw-on-brand, #fff);\\n}\\n.hw-conv-card-avatar-initials {\\n font-size: 12px;\\n font-weight: 600;\\n line-height: 1;\\n letter-spacing: 0.02em;\\n}\\n.hw-conv-card-content {\\n flex: 1;\\n min-width: 0;\\n}\\n.hw-conv-card-top {\\n display: flex;\\n align-items: baseline;\\n gap: 8px;\\n}\\n.hw-conv-card-name {\\n flex: 1;\\n font-size: 14px;\\n font-weight: 600;\\n color: var(--hw-text);\\n}\\n.hw-conv-card-time {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n flex-shrink: 0;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-conv-card-preview {\\n font-size: 13px;\\n color: var(--hw-text-2);\\n overflow: hidden;\\n text-overflow: ellipsis;\\n white-space: nowrap;\\n line-height: 1.4;\\n margin-top: 1px;\\n}\\n.hw-conv-card--unread .hw-conv-card-name {\\n color: var(--hw-text);\\n}\\n.hw-conv-card--unread .hw-conv-card-time {\\n color: var(--hw-accent);\\n font-weight: 500;\\n}\\n.hw-conv-card-badge {\\n position: absolute;\\n top: 12px;\\n right: 12px;\\n min-width: 18px;\\n height: 18px;\\n border-radius: 9px;\\n background: var(--hw-primary);\\n color: white;\\n font-size: 11px;\\n font-weight: 600;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 0 5px;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-empty-state {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 32px;\\n text-align: center;\\n}\\n.hw-empty-icon-wrap {\\n width: 48px;\\n height: 48px;\\n border-radius: 50%;\\n background: var(--hw-bg-subtle);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n margin-bottom: 16px;\\n color: var(--hw-text-3);\\n}\\n.hw-empty-icon-wrap svg {\\n width: 24px;\\n height: 24px;\\n}\\n.hw-empty-title {\\n font-size: 15px;\\n font-weight: 600;\\n color: var(--hw-text);\\n margin-bottom: 4px;\\n}\\n.hw-empty-desc {\\n font-size: 13px;\\n color: var(--hw-text-3);\\n margin-bottom: 20px;\\n}\\n.hw-empty-btn {\\n padding: 8px 20px;\\n border-radius: 10px;\\n background: var(--hw-primary);\\n color: white;\\n border: none;\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n font-family: inherit;\\n transition: background 0.15s;\\n}\\n.hw-empty-btn:hover {\\n background: var(--hw-primary-hover);\\n}\\n.hw-tabs {\\n display: flex;\\n border-top: 1px solid var(--hw-border);\\n flex-shrink: 0;\\n background: var(--hw-bg-subtle);\\n}\\n.hw-tabs-item {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n gap: 2px;\\n padding: 8px 0;\\n border: none;\\n background: none;\\n cursor: pointer;\\n font-family: inherit;\\n font-size: 11px;\\n font-weight: 500;\\n color: var(--hw-text-3);\\n transition: color 0.15s;\\n}\\n.hw-tabs-item svg {\\n width: 22px;\\n height: 22px;\\n}\\n.hw-tabs-item--active {\\n color: var(--hw-text);\\n}\\n.hw-tabs-item:hover {\\n color: var(--hw-text-2);\\n}\\n.hw-tabs-item:active {\\n transform: scale(0.94);\\n transition: transform 0.14s cubic-bezier(0.23, 1, 0.32, 1), color 0.15s;\\n}\\n.hw-tabs-icon-wrap {\\n position: relative;\\n display: inline-flex;\\n}\\n.hw-tabs-badge {\\n position: absolute;\\n top: -6px;\\n right: -10px;\\n min-width: 16px;\\n height: 16px;\\n border-radius: 8px;\\n background: var(--hw-primary);\\n color: white;\\n font-size: 10px;\\n font-weight: 700;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 0 4px;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-messages {\\n flex: 1;\\n overflow-y: auto;\\n overflow-x: hidden;\\n padding: 16px 20px;\\n background: var(--hw-bg-subtle);\\n display: flex;\\n flex-direction: column;\\n gap: 2px;\\n overscroll-behavior: contain;\\n min-width: 0;\\n scrollbar-color: rgba(0, 0, 0, 0.2) transparent;\\n scrollbar-width: thin;\\n}\\n.hw-messages::-webkit-scrollbar {\\n width: 10px;\\n height: 10px;\\n}\\n.hw-messages::-webkit-scrollbar-track {\\n background: transparent;\\n}\\n.hw-messages::-webkit-scrollbar-thumb {\\n background: rgba(0, 0, 0, 0.16);\\n background-clip: content-box;\\n border: 3px solid transparent;\\n border-radius: 999px;\\n}\\n.hw-messages::-webkit-scrollbar-thumb:hover {\\n background: rgba(0, 0, 0, 0.28);\\n background-clip: content-box;\\n}\\n.hw-widget[data-theme=dark] .hw-messages {\\n scrollbar-color: rgba(255, 255, 255, 0.26) transparent;\\n}\\n.hw-widget[data-theme=dark] .hw-messages::-webkit-scrollbar-thumb {\\n background: rgba(255, 255, 255, 0.2);\\n background-clip: content-box;\\n}\\n.hw-widget[data-theme=dark] .hw-messages::-webkit-scrollbar-thumb:hover {\\n background: rgba(255, 255, 255, 0.32);\\n background-clip: content-box;\\n}\\n.hw-empty {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 32px;\\n color: var(--hw-text-3);\\n text-align: center;\\n}\\n.hw-empty-icon {\\n width: 40px;\\n height: 40px;\\n margin-bottom: 12px;\\n opacity: 0.3;\\n}\\n.hw-empty-text {\\n font-size: 13px;\\n}\\n.hw-date-sep {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n padding: 12px 0;\\n}\\n.hw-date-sep-line {\\n flex: 1;\\n height: 1px;\\n background: var(--hw-border-md);\\n}\\n.hw-date-sep-text {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n font-weight: 500;\\n white-space: nowrap;\\n}\\n.hw-msg {\\n display: flex;\\n padding: 4px 0;\\n max-width: 75%;\\n min-width: 0;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n@keyframes hw-msg-appear {\\n from {\\n opacity: 0;\\n transform: translateY(6px);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n}\\n.hw-msg--visitor {\\n align-self: flex-end;\\n}\\n.hw-msg--team,\\n.hw-msg--ai {\\n align-self: flex-start;\\n}\\n.hw-msg--ai {\\n width: 100%;\\n max-width: 100%;\\n}\\n.hw-msg-body {\\n display: flex;\\n flex-direction: column;\\n min-width: 0;\\n max-width: 100%;\\n}\\n.hw-msg-bubble {\\n padding: 10px 14px;\\n border-radius: 18px;\\n font-size: 14px;\\n line-height: 1.45;\\n white-space: pre-wrap;\\n word-break: break-word;\\n overflow-wrap: anywhere;\\n max-width: 100%;\\n}\\n.hw-msg--visitor .hw-msg-bubble {\\n background: var(--hw-primary);\\n color: white;\\n border-bottom-right-radius: 4px;\\n}\\n.hw-msg--team .hw-msg-bubble {\\n background: var(--hw-visitor-bubble-bg);\\n color: var(--hw-visitor-bubble-text);\\n border-bottom-left-radius: 4px;\\n}\\n.hw-msg--ai .hw-msg-bubble {\\n background: var(--hw-visitor-bubble-bg);\\n color: var(--hw-text);\\n border-bottom-left-radius: 4px;\\n white-space: normal;\\n max-width: min(100%, 640px);\\n}\\n.hw-msg--ai .hw-msg-body {\\n width: 100%;\\n}\\n.hw-msg--ai .hw-msg-bubble:has(.hw-code),\\n.hw-msg--ai .hw-msg-bubble:has(pre) {\\n width: 100%;\\n}\\n.hw-msg--ai .hw-code {\\n width: 100%;\\n box-sizing: border-box;\\n}\\n.hw-msg-meta {\\n display: inline-flex;\\n align-items: center;\\n gap: 4px;\\n font-size: 11px;\\n color: var(--hw-text-3);\\n margin-top: 2px;\\n padding: 0 4px;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-msg-time {\\n white-space: nowrap;\\n}\\n.hw-msg--visitor .hw-msg-meta {\\n text-align: right;\\n}\\n.hw-msg--team .hw-msg-body,\\n.hw-msg--ai .hw-msg-body {\\n align-items: flex-start;\\n}\\n.hw-msg--visitor .hw-msg-body {\\n align-items: flex-end;\\n}\\n.hw-msg-sender {\\n font-size: 11px;\\n font-weight: 500;\\n color: var(--hw-text-3);\\n margin-bottom: 3px;\\n padding: 0 4px;\\n}\\n.hw-typing {\\n display: flex;\\n flex-direction: column;\\n gap: 3px;\\n padding: 8px 0;\\n width: fit-content;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n.hw-typing-label {\\n font-size: 11px;\\n font-weight: 500;\\n color: var(--hw-text-3);\\n padding: 0 4px;\\n}\\n.hw-typing-dots {\\n display: flex;\\n gap: 3px;\\n padding: 10px 14px;\\n width: fit-content;\\n background: var(--hw-visitor-bubble-bg);\\n border-radius: var(--hw-radius);\\n border-bottom-left-radius: 4px;\\n}\\n.hw-typing-dot {\\n width: 6px;\\n height: 6px;\\n border-radius: 50%;\\n background: var(--hw-text-3);\\n animation: hw-typing-bounce 1.4s infinite;\\n}\\n.hw-typing-dot:nth-child(2) {\\n animation-delay: 0.2s;\\n}\\n.hw-typing-dot:nth-child(3) {\\n animation-delay: 0.4s;\\n}\\n@keyframes hw-typing-bounce {\\n 0%, 60%, 100% {\\n transform: translateY(0);\\n }\\n 30% {\\n transform: translateY(-4px);\\n }\\n}\\n.hw-loading {\\n flex: 1;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.hw-loading-dots {\\n display: flex;\\n gap: 4px;\\n}\\n.hw-loading-dot {\\n width: 8px;\\n height: 8px;\\n border-radius: 50%;\\n background: var(--hw-text-4);\\n animation: hw-loading-pulse 1.4s infinite;\\n}\\n.hw-loading-dot:nth-child(2) {\\n animation-delay: 0.2s;\\n}\\n.hw-loading-dot:nth-child(3) {\\n animation-delay: 0.4s;\\n}\\n@keyframes hw-loading-pulse {\\n 0%, 60%, 100% {\\n opacity: 0.3;\\n transform: scale(0.8);\\n }\\n 30% {\\n opacity: 1;\\n transform: scale(1);\\n }\\n}\\n@keyframes hw-skeleton-shimmer {\\n 0% {\\n background-position: -200px 0;\\n }\\n 100% {\\n background-position: calc(200px + 100%) 0;\\n }\\n}\\n.hw-skeleton {\\n background:\\n linear-gradient(\\n 90deg,\\n var(--hw-bg-subtle) 25%,\\n rgba(0, 0, 0, 0.04) 50%,\\n var(--hw-bg-subtle) 75%);\\n background-size: 200px 100%;\\n animation: hw-skeleton-shimmer 1.5s ease-in-out infinite;\\n border-radius: 6px;\\n}\\n.hw-skeleton-messages {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n padding: 16px;\\n gap: 16px;\\n}\\n.hw-skeleton-msg {\\n display: flex;\\n gap: 10px;\\n align-items: flex-start;\\n}\\n.hw-skeleton-msg--right {\\n flex-direction: row-reverse;\\n}\\n.hw-skeleton-avatar {\\n width: 28px;\\n height: 28px;\\n border-radius: 8px;\\n flex-shrink: 0;\\n}\\n.hw-skeleton-bubble {\\n display: flex;\\n flex-direction: column;\\n gap: 6px;\\n}\\n.hw-skeleton-line {\\n height: 12px;\\n border-radius: 6px;\\n}\\n.hw-skeleton-convs {\\n display: flex;\\n flex-direction: column;\\n padding: 8px 0;\\n}\\n.hw-skeleton-conv {\\n display: flex;\\n gap: 10px;\\n align-items: center;\\n padding: 10px 16px;\\n}\\n.hw-skeleton-conv-avatar {\\n width: 36px;\\n height: 36px;\\n border-radius: 8px;\\n flex-shrink: 0;\\n}\\n.hw-skeleton-conv-lines {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n gap: 6px;\\n}\\n.hw-skeleton-content {\\n display: flex;\\n flex-direction: column;\\n padding: 12px 16px;\\n gap: 12px;\\n}\\n.hw-skeleton-content-item {\\n display: flex;\\n flex-direction: column;\\n gap: 6px;\\n padding: 12px;\\n border-radius: 10px;\\n background: var(--hw-bg);\\n}\\n.hw-skeleton-title {\\n height: 22px;\\n width: 65%;\\n border-radius: 6px;\\n}\\n.hw-skeleton-badge {\\n width: 42px;\\n height: 18px;\\n border-radius: 9px;\\n}\\n.hw-skeleton-date {\\n width: 60px;\\n height: 12px;\\n border-radius: 6px;\\n}\\n.hw-skeleton-h2 {\\n height: 16px;\\n border-radius: 6px;\\n}\\n.hw-skeleton-bullet {\\n padding-left: 20px;\\n display: flex;\\n flex-direction: column;\\n gap: 8px;\\n}\\n.hw-skeleton-bullet-line {\\n height: 14px;\\n border-radius: 7px;\\n}\\n.hw-email-card {\\n margin: 0 12px;\\n padding: 14px 16px 10px;\\n border: 1px solid var(--hw-border, rgba(0,0,0,0.08));\\n border-radius: 14px;\\n background: var(--hw-bg, #fff);\\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06), 0 4px 12px rgba(0, 0, 0, 0.03);\\n animation: hw-email-slide-in 0.25s ease-out;\\n}\\n@keyframes hw-email-slide-in {\\n from {\\n opacity: 0;\\n transform: translateY(8px);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n}\\n.hw-email-card-header {\\n display: flex;\\n align-items: flex-start;\\n gap: 10px;\\n margin-bottom: 12px;\\n}\\n.hw-email-card-icon {\\n flex-shrink: 0;\\n width: 32px;\\n height: 32px;\\n border-radius: 8px;\\n background: var(--hw-bg-hover, #f5f5f5);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n color: var(--hw-text, #1a1a1a);\\n}\\n.hw-email-card-title {\\n font-size: 13px;\\n font-weight: 600;\\n color: var(--hw-text, #1a1a1a);\\n line-height: 1.3;\\n margin: 0 0 2px;\\n}\\n.hw-email-card-subtitle {\\n font-size: 12px;\\n color: var(--hw-text-2, #888);\\n line-height: 1.4;\\n margin: 0;\\n}\\n.hw-email-card-input {\\n width: 100%;\\n padding: 9px 12px;\\n border-radius: 10px;\\n border: 1px solid var(--hw-border, rgba(0,0,0,0.1));\\n background: var(--hw-bg-subtle, #fafafa);\\n color: var(--hw-text, #1a1a1a);\\n font-size: 13px;\\n outline: none;\\n margin-bottom: 8px;\\n box-sizing: border-box;\\n transition: border-color 0.15s, box-shadow 0.15s;\\n}\\n.hw-email-card-input::placeholder {\\n color: var(--hw-text-3, #999);\\n}\\n.hw-email-card-input:focus {\\n border-color: var(--hw-focus-border, rgba(0,0,0,0.2));\\n box-shadow: 0 0 0 2px var(--hw-focus-ring, rgba(0,0,0,0.06));\\n}\\n.hw-email-card-input--error {\\n border-color: #ef4444;\\n}\\n.hw-email-card-submit {\\n width: 100%;\\n padding: 9px;\\n border-radius: 10px;\\n border: none;\\n background: var(--hw-brand, #0a0a0a);\\n color: var(--hw-on-brand, #fff);\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n transition: opacity 0.15s;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n gap: 6px;\\n}\\n.hw-email-card-submit:hover:not(:disabled) {\\n opacity: 0.88;\\n}\\n.hw-email-card-submit:disabled {\\n opacity: 0.5;\\n cursor: not-allowed;\\n}\\n.hw-email-card--success {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n gap: 6px;\\n padding: 10px 16px;\\n font-size: 13px;\\n color: var(--hw-text-2, #888);\\n animation: hw-email-slide-in 0.2s ease-out;\\n}\\n.hw-email-card--success svg {\\n flex-shrink: 0;\\n}\\n.hw-composer {\\n display: flex;\\n flex-direction: column;\\n padding: 12px 16px;\\n background: transparent;\\n flex-shrink: 0;\\n}\\n.hw-composer--compact {\\n padding: 8px 12px;\\n}\\n.hw-composer-box {\\n display: flex;\\n flex-direction: column;\\n border: 2px solid var(--hw-border-md);\\n border-radius: 16px;\\n overflow: hidden;\\n transition: border-color 0.2s;\\n background: var(--hw-bg);\\n}\\n.hw-composer-box:focus-within {\\n border-color: var(--hw-focus-border);\\n box-shadow: 0 0 0 3px var(--hw-focus-ring);\\n}\\n.hw-composer-input {\\n flex: 1;\\n resize: none;\\n border: none;\\n padding: 12px 16px 4px;\\n font-size: 14px;\\n font-family: inherit;\\n line-height: 1.4;\\n outline: none;\\n min-height: 40px;\\n max-height: 220px;\\n background: transparent;\\n color: var(--hw-text);\\n field-sizing: content;\\n}\\n.hw-composer-input:focus {\\n outline: none;\\n}\\n.hw-composer-input:focus-visible {\\n outline: none;\\n}\\n.hw-composer-input::placeholder {\\n color: var(--hw-text-4);\\n}\\n.hw-composer-toolbar {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n padding: 4px 10px 10px;\\n}\\n.hw-composer-toolbar-left {\\n display: flex;\\n align-items: center;\\n gap: 4px;\\n}\\n.hw-composer-send {\\n width: 32px;\\n height: 32px;\\n border-radius: 50%;\\n border: none;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n transition:\\n background-color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n transform 140ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n.hw-composer-send:active:not(:disabled) {\\n transform: scale(0.9);\\n}\\n.hw-composer-send--active {\\n background: var(--hw-primary);\\n color: white;\\n}\\n.hw-composer-send--inactive {\\n background: var(--hw-border);\\n color: var(--hw-text-4);\\n cursor: default;\\n}\\n.hw-composer-send svg {\\n width: 14px;\\n height: 14px;\\n}\\n.hw-composer-charcount {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n font-variant-numeric: tabular-nums;\\n opacity: 1;\\n transform: translateY(0);\\n transition:\\n color 180ms cubic-bezier(0.23, 1, 0.32, 1),\\n opacity 180ms cubic-bezier(0.23, 1, 0.32, 1),\\n transform 180ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n@starting-style {\\n .hw-composer-charcount {\\n opacity: 0;\\n transform: translateY(3px);\\n }\\n}\\n.hw-composer-charcount--over {\\n color: #ef4444;\\n font-weight: 600;\\n}\\n@media (prefers-reduced-motion: reduce) {\\n .hw-composer-charcount {\\n transform: none;\\n transition: color 160ms ease, opacity 160ms ease;\\n }\\n @starting-style {\\n .hw-composer-charcount {\\n transform: none;\\n }\\n }\\n}\\n.hw-composer-previews {\\n display: flex;\\n gap: 6px;\\n padding: 8px 10px 0;\\n overflow-x: auto;\\n scrollbar-width: none;\\n}\\n.hw-composer-previews::-webkit-scrollbar {\\n display: none;\\n}\\n.hw-composer-preview {\\n position: relative;\\n width: 48px;\\n height: 48px;\\n border-radius: 8px;\\n overflow: hidden;\\n flex-shrink: 0;\\n background: var(--hw-border);\\n cursor: pointer;\\n}\\n.hw-composer-preview--error {\\n outline: 2px solid #ef4444;\\n outline-offset: -2px;\\n}\\n.hw-composer-preview-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-composer-preview-file {\\n width: 100%;\\n height: 100%;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n background: var(--hw-bg-subtle);\\n}\\n.hw-composer-preview-ext {\\n font-size: 10px;\\n font-weight: 700;\\n color: var(--hw-text-3);\\n text-transform: uppercase;\\n}\\n.hw-composer-preview-loader {\\n position: absolute;\\n inset: 0;\\n background: rgba(0, 0, 0, 0.35);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.hw-composer-preview-loader::after {\\n content: \\\"\\\";\\n width: 16px;\\n height: 16px;\\n border: 2px solid rgba(255, 255, 255, 0.3);\\n border-top-color: white;\\n border-radius: 50%;\\n animation: hw-spin 0.6s linear infinite;\\n}\\n@keyframes hw-spin {\\n to {\\n transform: rotate(360deg);\\n }\\n}\\n.hw-composer-preview-badge {\\n position: absolute;\\n top: 2px;\\n right: 2px;\\n width: 16px;\\n height: 16px;\\n border-radius: 50%;\\n background: #ef4444;\\n color: white;\\n font-size: 10px;\\n font-weight: 700;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.hw-composer-preview-remove {\\n position: absolute;\\n top: 2px;\\n right: 2px;\\n width: 18px;\\n height: 18px;\\n border-radius: 50%;\\n border: none;\\n background: rgba(0, 0, 0, 0.55);\\n color: white;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n opacity: 0;\\n transition: opacity 0.15s;\\n}\\n.hw-composer-preview-remove svg {\\n width: 10px;\\n height: 10px;\\n}\\n.hw-composer-preview:hover .hw-composer-preview-remove {\\n opacity: 1;\\n}\\n.hw-composer-attach {\\n width: 28px;\\n height: 28px;\\n border: none;\\n background: none;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 6px;\\n opacity: 0.7;\\n transition: opacity 0.15s;\\n}\\n.hw-composer-attach:hover {\\n opacity: 1;\\n}\\n.hw-composer-attach svg {\\n width: 16px;\\n height: 16px;\\n}\\n.hw-msg-images {\\n display: flex;\\n flex-direction: column;\\n gap: 4px;\\n margin-bottom: 4px;\\n}\\n.hw-msg-image-link {\\n display: block;\\n border-radius: 14px;\\n overflow: hidden;\\n line-height: 0;\\n}\\n.hw-msg-image {\\n max-width: 140px;\\n max-height: 80px;\\n object-fit: cover;\\n border-radius: 8px;\\n outline: 1px solid rgba(0, 0, 0, 0.08);\\n outline-offset: -1px;\\n}\\n.hw-msg-files {\\n display: flex;\\n flex-direction: column;\\n gap: 4px;\\n margin-top: 4px;\\n}\\n.hw-msg-file {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 8px 12px;\\n border-radius: 10px;\\n background: var(--hw-bg-subtle);\\n text-decoration: none;\\n color: var(--hw-text);\\n transition: background 0.15s;\\n}\\n.hw-msg-file:hover {\\n background: var(--hw-border);\\n}\\n.hw-msg-file-icon {\\n flex-shrink: 0;\\n width: 20px;\\n height: 20px;\\n color: var(--hw-text-3);\\n}\\n.hw-msg-file-icon svg {\\n width: 100%;\\n height: 100%;\\n}\\n.hw-msg-file-info {\\n display: flex;\\n flex-direction: column;\\n min-width: 0;\\n}\\n.hw-msg-file-name {\\n font-size: 13px;\\n font-weight: 500;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.hw-msg-file-size {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n}\\n.hw-msg-image-link {\\n cursor: pointer;\\n border: none;\\n padding: 0;\\n background: none;\\n display: block;\\n line-height: 0;\\n}\\n.hw-hover-preview {\\n position: fixed;\\n z-index: 99998;\\n padding: 6px;\\n border-radius: 14px;\\n background: white;\\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.06);\\n cursor: pointer;\\n animation: hw-hover-in 0.15s ease-out;\\n}\\n@media (prefers-color-scheme: dark) {\\n .hw-hover-preview {\\n background: #1c1c1e;\\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08);\\n }\\n}\\n@keyframes hw-hover-in {\\n from {\\n opacity: 0;\\n transform: scale(0.96) translateY(4px);\\n }\\n to {\\n opacity: 1;\\n transform: scale(1) translateY(0);\\n }\\n}\\n.hw-hover-preview-img {\\n width: 100%;\\n max-height: 200px;\\n object-fit: contain;\\n border-radius: 10px;\\n display: block;\\n outline: 1px solid rgba(0, 0, 0, 0.08);\\n outline-offset: -1px;\\n}\\n.hw-hover-preview--doc {\\n display: flex;\\n align-items: center;\\n gap: 10px;\\n padding: 10px 14px;\\n}\\n.hw-hover-preview-doc-icon {\\n width: 28px;\\n height: 28px;\\n flex-shrink: 0;\\n}\\n.hw-hover-preview-doc-icon svg {\\n width: 100%;\\n height: 100%;\\n}\\n.hw-hover-preview-doc-info {\\n display: flex;\\n flex-direction: column;\\n min-width: 0;\\n}\\n.hw-hover-preview-doc-name {\\n font-size: 13px;\\n font-weight: 500;\\n color: var(--hw-text);\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.hw-hover-preview-doc-hint {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n}\\n.hw-event {\\n display: flex;\\n justify-content: center;\\n padding: 8px 16px;\\n}\\n.hw-event-text {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n text-align: center;\\n}\\n.hw-event--card {\\n justify-content: flex-start;\\n align-items: center;\\n gap: 10px;\\n background: var(--hw-bg-subtle);\\n padding: 10px 14px;\\n border-radius: 12px;\\n margin: 4px 16px;\\n}\\n.hw-event-avatar {\\n width: 32px;\\n height: 32px;\\n border-radius: 50%;\\n background: var(--hw-bg-hover, #e0e0e0);\\n color: var(--hw-text-2, #555);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n font-size: 11px;\\n font-weight: 600;\\n flex-shrink: 0;\\n overflow: hidden;\\n}\\n.hw-event-avatar-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-event-body {\\n font-size: 13px;\\n line-height: 1.3;\\n}\\n.hw-event-name {\\n font-weight: 600;\\n color: var(--hw-text);\\n}\\n.hw-event-action {\\n color: var(--hw-text-2);\\n}\\n.hw-resolved-banner {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 12px 16px;\\n border-top: 1px solid var(--hw-border);\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text-2);\\n font-size: 13px;\\n flex-shrink: 0;\\n}\\n.hw-new {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n background: var(--hw-bg-subtle);\\n}\\n.hw-new-body {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 32px 24px;\\n text-align: center;\\n}\\n.hw-new-welcome {\\n flex: 1;\\n padding: 16px 20px;\\n overflow-y: auto;\\n}\\n.hw-new-heading {\\n font-size: 17px;\\n font-weight: 600;\\n color: var(--hw-text);\\n margin-bottom: 6px;\\n}\\n.hw-new-desc {\\n font-size: 13px;\\n color: var(--hw-text-2);\\n margin-bottom: 24px;\\n}\\n.hw-powered {\\n text-align: center;\\n padding: 8px;\\n font-size: 11px;\\n color: var(--hw-text-4);\\n flex-shrink: 0;\\n}\\n.hw-powered a {\\n color: var(--hw-text-2);\\n text-decoration: none;\\n font-weight: 500;\\n}\\n.hw-powered a:hover {\\n color: var(--hw-text);\\n}\\n@media (max-width: 479px) {\\n .hw-widget {\\n bottom: 16px;\\n right: 16px;\\n left: auto;\\n }\\n .hw-window {\\n position: fixed;\\n top: 0;\\n left: 0;\\n right: 0;\\n bottom: 0;\\n width: 100%;\\n height: var(--hw-visible-height, 100%);\\n border-radius: 0;\\n animation: hw-mob-up 0.3s cubic-bezier(0.22, 1, 0.36, 1);\\n }\\n .hw-window--closing {\\n animation: hw-mob-down 0.2s ease forwards;\\n }\\n @keyframes hw-mob-up {\\n from {\\n opacity: 0;\\n transform: translateY(100%);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n }\\n @keyframes hw-mob-down {\\n from {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n to {\\n opacity: 0;\\n transform: translateY(100%);\\n }\\n }\\n .hw-hero {\\n padding-top: calc(20px + env(safe-area-inset-top, 0px));\\n }\\n .hw-header {\\n padding-top: env(safe-area-inset-top, 0px);\\n }\\n .hw-tabs {\\n padding-bottom: env(safe-area-inset-bottom, 0px);\\n }\\n .hw-composer {\\n padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));\\n }\\n .hw-powered {\\n padding-bottom: calc(5px + env(safe-area-inset-bottom, 0px));\\n }\\n .hw-header-close,\\n .hw-header-back,\\n .hw-header-action {\\n width: 34px;\\n height: 34px;\\n }\\n .hw-composer-send {\\n width: 40px;\\n height: 40px;\\n }\\n .hw-window ~ .hw-bubble {\\n display: none;\\n }\\n .hw-messages {\\n padding: 12px 14px;\\n }\\n .hw-msg {\\n max-width: 82%;\\n }\\n .hw-msg--ai {\\n max-width: 100%;\\n }\\n}\\n.hw-preview {\\n position: absolute;\\n bottom: calc(100% + 12px);\\n right: 0;\\n width: 300px;\\n max-width: calc(100vw - 40px);\\n background: var(--hw-bg);\\n border: 1px solid var(--hw-border);\\n border-radius: 16px;\\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06);\\n animation: hw-preview-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\\n overflow: hidden;\\n cursor: pointer;\\n transition: transform 0.15s, box-shadow 0.15s;\\n}\\n.hw-preview:hover {\\n transform: translateY(-2px);\\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15), 0 4px 12px rgba(0, 0, 0, 0.08);\\n}\\n.hw-preview--closing {\\n animation: hw-preview-out 0.2s ease forwards;\\n}\\n@keyframes hw-preview-in {\\n from {\\n opacity: 0;\\n transform: translateY(8px) scale(0.95);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n}\\n@keyframes hw-preview-out {\\n from {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n to {\\n opacity: 0;\\n transform: translateY(8px) scale(0.95);\\n }\\n}\\n.hw-preview-header {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 12px 14px 0;\\n}\\n.hw-preview-avatar {\\n width: 28px;\\n height: 28px;\\n border-radius: 50%;\\n background:\\n linear-gradient(\\n 135deg,\\n var(--hw-primary),\\n color-mix(in srgb, var(--hw-primary) 50%, black));\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n color: white;\\n flex-shrink: 0;\\n overflow: hidden;\\n}\\n.hw-preview-avatar svg {\\n width: 16px;\\n height: 16px;\\n}\\n.hw-preview-name {\\n font-size: 13px;\\n font-weight: 600;\\n color: var(--hw-text);\\n flex: 1;\\n}\\n.hw-preview-close {\\n width: 24px;\\n height: 24px;\\n border: none;\\n background: transparent;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 50%;\\n transition: background 0.15s, color 0.15s;\\n flex-shrink: 0;\\n}\\n.hw-preview-close:hover {\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text-2);\\n}\\n.hw-preview-close:active {\\n transform: scale(0.90);\\n transition:\\n transform 0.14s cubic-bezier(0.23, 1, 0.32, 1),\\n background 0.15s,\\n color 0.15s;\\n}\\n.hw-preview-close svg {\\n width: 12px;\\n height: 12px;\\n}\\n.hw-preview-body {\\n padding: 8px 14px 14px;\\n font-size: 14px;\\n line-height: 1.45;\\n color: var(--hw-text-2);\\n display: -webkit-box;\\n -webkit-line-clamp: 3;\\n -webkit-box-orient: vertical;\\n overflow: hidden;\\n}\\n.hw-content-search {\\n padding: 10px 16px;\\n}\\n.hw-content-search-box {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 8px 12px;\\n background: var(--hw-bg);\\n border: 1px solid var(--hw-border-md);\\n border-radius: 10px;\\n transition: border-color 0.15s, box-shadow 0.15s;\\n}\\n.hw-content-search-box:focus-within {\\n border-color: var(--hw-focus-border);\\n box-shadow: 0 0 0 3px var(--hw-focus-ring);\\n}\\n.hw-content-search-input {\\n flex: 1;\\n border: none !important;\\n outline: none !important;\\n box-shadow: none !important;\\n background: none;\\n font-size: 13px;\\n color: var(--hw-text-1);\\n font-family: inherit;\\n line-height: 1;\\n -webkit-appearance: none;\\n}\\n.hw-content-search-input:focus,\\n.hw-content-search-input:focus-visible {\\n outline: none !important;\\n box-shadow: none !important;\\n border: none !important;\\n}\\n.hw-content-search-input::placeholder {\\n color: var(--hw-text-3);\\n}\\n.hw-content-search-icon {\\n width: 15px;\\n height: 15px;\\n color: var(--hw-text-3);\\n flex-shrink: 0;\\n}\\n.hw-content-list {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n}\\n.hw-content-entries {\\n flex: 1;\\n overflow-y: auto;\\n overscroll-behavior: contain;\\n}\\n.hw-content-entry {\\n display: block;\\n width: 100%;\\n padding: 14px 16px;\\n border: none;\\n border-bottom: 1px solid var(--hw-border);\\n background: none;\\n cursor: pointer;\\n text-align: left;\\n transition: background-color 0.15s ease;\\n -webkit-tap-highlight-color: transparent;\\n}\\n.hw-content-entry:hover {\\n background: var(--hw-bg-hover);\\n}\\n.hw-content-entry:active {\\n background: var(--hw-border);\\n}\\n.hw-content-entry:last-child {\\n border-bottom: none;\\n}\\n.hw-content-entry-main {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n}\\n.hw-content-entry-text {\\n flex: 1;\\n min-width: 0;\\n display: flex;\\n flex-direction: column;\\n gap: 3px;\\n}\\n.hw-content-entry-title {\\n font-size: 14px;\\n font-weight: 600;\\n color: var(--hw-text-1);\\n line-height: 1.3;\\n}\\n.hw-content-entry-desc {\\n font-size: 13px;\\n color: var(--hw-text-2);\\n line-height: 1.4;\\n display: -webkit-box;\\n -webkit-line-clamp: 2;\\n -webkit-box-orient: vertical;\\n overflow: hidden;\\n}\\n.hw-content-entry-meta {\\n display: flex;\\n align-items: center;\\n gap: 6px;\\n margin-top: 2px;\\n}\\n.hw-content-entry-badge {\\n font-size: 11px;\\n font-weight: 500;\\n color: var(--hw-text-3);\\n background: var(--hw-bg-hover);\\n padding: 1px 6px;\\n border-radius: 4px;\\n}\\n.hw-content-entry-date {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n}\\n.hw-content-entry-chevron {\\n width: 16px;\\n height: 16px;\\n color: var(--hw-text-3);\\n flex-shrink: 0;\\n opacity: 0.5;\\n}\\n.hw-content-detail {\\n padding: 16px;\\n overflow-y: auto;\\n overscroll-behavior: contain;\\n height: 100%;\\n}\\n.hw-content-detail-header {\\n margin-bottom: 16px;\\n}\\n.hw-content-detail-title {\\n font-size: 17px;\\n font-weight: 700;\\n color: var(--hw-text-1);\\n margin: 0 0 6px;\\n line-height: 1.3;\\n display: flex;\\n align-items: center;\\n gap: 6px;\\n}\\n.hw-content-detail-meta {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n flex-wrap: wrap;\\n}\\n.hw-content-detail-date {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n}\\n.hw-content-detail-body {\\n font-size: 14px;\\n line-height: 1.6;\\n color: var(--hw-text-1);\\n}\\n.hw-markdown h1 {\\n font-size: 17px;\\n font-weight: 700;\\n margin: 0;\\n}\\n.hw-markdown h2 {\\n font-size: 15px;\\n font-weight: 600;\\n margin: 0;\\n}\\n.hw-markdown h3 {\\n font-size: 14px;\\n font-weight: 600;\\n margin: 0;\\n}\\n.hw-markdown p {\\n margin: 0;\\n}\\n.hw-markdown p:empty,\\n.hw-markdown div:empty,\\n.hw-markdown p:has(> br:only-child),\\n.hw-markdown div:has(> br:only-child) {\\n display: none;\\n}\\n.hw-markdown > * + * {\\n margin-top: 12px;\\n}\\n.hw-markdown > * + h1,\\n.hw-markdown > * + h2 {\\n margin-top: 20px;\\n}\\n.hw-markdown > * + h3 {\\n margin-top: 16px;\\n}\\n.hw-markdown > h1 + *,\\n.hw-markdown > h2 + *,\\n.hw-markdown > h3 + * {\\n margin-top: 8px;\\n}\\n.hw-markdown > *:first-child {\\n margin-top: 0;\\n}\\n.hw-markdown > *:last-child {\\n margin-bottom: 0;\\n}\\n.hw-markdown > br {\\n display: none;\\n}\\n.hw-markdown ul {\\n margin: 0;\\n padding-left: 20px;\\n}\\n.hw-markdown li {\\n margin: 4px 0;\\n}\\n.hw-markdown code {\\n font-family:\\n ui-monospace,\\n \\\"SF Mono\\\",\\n monospace;\\n font-size: 12px;\\n background: var(--hw-bg-hover);\\n padding: 1px 5px;\\n border-radius: 4px;\\n}\\n.hw-code {\\n margin: 10px 0;\\n border-radius: 10px;\\n overflow: hidden;\\n border: 1px solid var(--hw-border, rgba(0, 0, 0, 0.08));\\n background: var(--hw-bg-hover, #f5f5f4);\\n font-family:\\n ui-monospace,\\n \\\"SF Mono\\\",\\n \\\"Menlo\\\",\\n monospace;\\n}\\n.hw-code-header {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n gap: 10px;\\n padding: 7px 8px 7px 12px;\\n font-size: 11px;\\n color: var(--hw-text-2, #6b7280);\\n background: rgba(0, 0, 0, 0.03);\\n border-bottom: 1px solid var(--hw-border, rgba(0, 0, 0, 0.06));\\n}\\n.hw-code-lang {\\n text-transform: lowercase;\\n letter-spacing: 0.02em;\\n font-weight: 500;\\n}\\n.hw-code-actions {\\n display: inline-flex;\\n align-items: center;\\n gap: 1px;\\n}\\n.hw-code-action {\\n position: relative;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 22px;\\n height: 22px;\\n padding: 0;\\n font-family: inherit;\\n color: var(--hw-text-2, #6b7280);\\n background: transparent;\\n border: 1px solid transparent;\\n border-radius: 6px;\\n cursor: pointer;\\n opacity: 0.62;\\n transition:\\n background 120ms ease,\\n color 120ms ease,\\n opacity 120ms ease,\\n scale 120ms ease;\\n}\\n.hw-code-action:hover {\\n color: var(--hw-text, #111);\\n background: rgba(0, 0, 0, 0.06);\\n opacity: 1;\\n}\\n.hw-code-action:active {\\n scale: 0.96;\\n}\\n.hw-code-action svg {\\n width: 13px;\\n height: 13px;\\n}\\n.hw-code-copy-icon,\\n.hw-code-check-icon {\\n position: absolute;\\n inset: 50% auto auto 50%;\\n transition:\\n opacity 180ms cubic-bezier(0.2, 0, 0, 1),\\n scale 180ms cubic-bezier(0.2, 0, 0, 1),\\n filter 180ms cubic-bezier(0.2, 0, 0, 1);\\n translate: -50% -50%;\\n}\\n.hw-code-check-icon {\\n filter: blur(4px);\\n opacity: 0;\\n scale: 0.25;\\n}\\n.hw-code-copy--copied .hw-code-copy-icon {\\n filter: blur(4px);\\n opacity: 0;\\n scale: 0.25;\\n}\\n.hw-code-copy--copied .hw-code-check-icon {\\n filter: blur(0);\\n opacity: 1;\\n scale: 1;\\n}\\n.hw-code-copy-label {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n}\\n.hw-code-copy--copied {\\n color: #16a34a;\\n}\\n.hw-code-copy--failed {\\n color: #dc2626;\\n}\\n.hw-code pre {\\n margin: 0;\\n padding: 10px 12px;\\n background: transparent;\\n border-radius: 0;\\n overflow-x: auto;\\n max-width: 100%;\\n max-height: 320px;\\n scrollbar-color: rgba(0, 0, 0, 0.22) transparent;\\n scrollbar-width: thin;\\n}\\n.hw-code pre::-webkit-scrollbar {\\n width: 10px;\\n height: 10px;\\n}\\n.hw-code pre::-webkit-scrollbar-track {\\n background: transparent;\\n}\\n.hw-code pre::-webkit-scrollbar-thumb {\\n background: rgba(0, 0, 0, 0.18);\\n background-clip: content-box;\\n border: 3px solid transparent;\\n border-radius: 999px;\\n}\\n.hw-code pre::-webkit-scrollbar-thumb:hover {\\n background: rgba(0, 0, 0, 0.28);\\n background-clip: content-box;\\n}\\n.hw-code pre code {\\n display: block;\\n background: transparent;\\n padding: 0;\\n font-size: 12px;\\n line-height: 1.55;\\n white-space: pre;\\n color: var(--hw-text, #111);\\n}\\n@media (prefers-color-scheme: dark) {\\n .hw-code {\\n background: rgba(255, 255, 255, 0.04);\\n border-color: rgba(255, 255, 255, 0.08);\\n }\\n .hw-code-header {\\n background: rgba(255, 255, 255, 0.03);\\n border-bottom-color: rgba(255, 255, 255, 0.06);\\n }\\n .hw-code-action:hover,\\n .hw-code-action:focus-visible {\\n background: rgba(255, 255, 255, 0.08);\\n }\\n .hw-code pre {\\n scrollbar-color: rgba(255, 255, 255, 0.26) transparent;\\n }\\n .hw-code pre::-webkit-scrollbar-thumb {\\n background: rgba(255, 255, 255, 0.22);\\n background-clip: content-box;\\n }\\n .hw-code pre::-webkit-scrollbar-thumb:hover {\\n background: rgba(255, 255, 255, 0.32);\\n background-clip: content-box;\\n }\\n}\\n.hw-markdown pre {\\n margin: 8px 0;\\n padding: 10px 12px;\\n background: var(--hw-bg-hover);\\n border-radius: 8px;\\n overflow-x: auto;\\n max-width: 100%;\\n}\\n.hw-markdown pre code {\\n display: block;\\n background: transparent;\\n padding: 0;\\n border-radius: 0;\\n font-size: 12px;\\n line-height: 1.5;\\n white-space: pre;\\n word-break: normal;\\n color: inherit;\\n}\\n.hw-msg-bubble pre {\\n margin: 6px 0;\\n padding: 8px 10px;\\n background: rgba(0, 0, 0, 0.06);\\n border-radius: 6px;\\n overflow-x: auto;\\n max-width: 100%;\\n}\\n.hw-msg-bubble pre code {\\n background: transparent;\\n padding: 0;\\n font-size: 12px;\\n line-height: 1.5;\\n white-space: pre;\\n}\\n.hw-msg-bubble .hw-code pre {\\n margin: 0;\\n padding: 10px 12px;\\n background: transparent;\\n border-radius: 0;\\n}\\n.hw-msg-bubble .hw-code pre code {\\n background: transparent;\\n padding: 0;\\n font-size: 12px;\\n line-height: 1.55;\\n}\\n.hw-msg--team .hw-msg-bubble pre,\\n.hw-msg--visitor .hw-msg-bubble pre {\\n background: rgba(255, 255, 255, 0.12);\\n}\\n.hw-markdown blockquote {\\n margin: 0 0 12px;\\n padding: 8px 12px;\\n border-left: 3px solid var(--hw-border);\\n color: var(--hw-text-2);\\n font-style: italic;\\n}\\n.hw-markdown a {\\n color: var(--hw-primary);\\n text-decoration: underline;\\n text-underline-offset: 2px;\\n}\\n.hw-markdown img {\\n max-width: 100%;\\n border-radius: 8px;\\n margin: 8px 0;\\n outline: 1px solid rgba(0, 0, 0, 0.08);\\n outline-offset: -1px;\\n}\\n.hw-markdown hr {\\n border: none;\\n border-top: 1px solid var(--hw-border);\\n margin: 16px 0;\\n}\\n.hw-content-empty {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 40px 20px;\\n text-align: center;\\n}\\n.hw-content-empty-title {\\n font-size: 14px;\\n font-weight: 600;\\n color: var(--hw-text-1);\\n margin-bottom: 4px;\\n}\\n.hw-content-empty-desc {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n}\\n.hw-content-loading {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 40px 20px;\\n}\\n.hw-content-load-more {\\n display: block;\\n width: 100%;\\n padding: 10px;\\n border: none;\\n background: none;\\n color: var(--hw-primary);\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n text-align: center;\\n}\\n.hw-content-load-more:hover {\\n background: var(--hw-bg-hover);\\n}\\n.hw-content-load-more:disabled {\\n opacity: 0.5;\\n cursor: default;\\n}\\n@media (hover: none) {\\n .hw-composer-preview-remove {\\n opacity: 0.7;\\n }\\n}\\n.hw-composer--dragging .hw-composer-box {\\n border-color: var(--hw-primary);\\n background: color-mix(in srgb, var(--hw-primary) 4%, transparent);\\n}\\n.hw-composer-drop-overlay {\\n position: absolute;\\n inset: 0;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n background: color-mix(in srgb, var(--hw-bg) 90%, transparent);\\n border: 2px dashed var(--hw-primary);\\n border-radius: 12px;\\n z-index: 10;\\n pointer-events: none;\\n animation: hw-drop-pulse 1.5s ease-in-out infinite;\\n}\\n.hw-composer-drop-text {\\n font-size: 13px;\\n font-weight: 500;\\n color: var(--hw-primary);\\n}\\n@keyframes hw-drop-pulse {\\n 0%, 100% {\\n opacity: 0.8;\\n }\\n 50% {\\n opacity: 1;\\n }\\n}\\n.hw-disconnect {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n gap: 6px;\\n padding: 6px 12px;\\n background: #fef3c7;\\n color: #92400e;\\n font-size: 12px;\\n font-weight: 500;\\n flex-shrink: 0;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n.hw-disconnect-dot {\\n width: 6px;\\n height: 6px;\\n border-radius: 50%;\\n background: #f59e0b;\\n animation: hw-loading-pulse 1.4s infinite;\\n}\\n.hw-error-state {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 32px 24px;\\n text-align: center;\\n gap: 12px;\\n}\\n.hw-error-icon {\\n width: 48px;\\n height: 48px;\\n border-radius: 50%;\\n background: #fef2f2;\\n color: #ef4444;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.hw-error-icon svg {\\n width: 24px;\\n height: 24px;\\n}\\n.hw-error-title {\\n font-size: 15px;\\n font-weight: 600;\\n color: var(--hw-text);\\n}\\n.hw-error-desc {\\n font-size: 13px;\\n color: var(--hw-text-2);\\n}\\n.hw-error-btn {\\n padding: 8px 20px;\\n border: 1px solid var(--hw-border-md);\\n border-radius: 8px;\\n background: var(--hw-bg);\\n color: var(--hw-text);\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n transition: background 0.15s;\\n}\\n.hw-error-btn:hover {\\n background: var(--hw-bg-hover);\\n}\\n.hw-send-error {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 8px 12px;\\n background: #fef2f2;\\n color: #dc2626;\\n font-size: 12px;\\n font-weight: 500;\\n flex-shrink: 0;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n.hw-send-error-retry {\\n margin-left: auto;\\n padding: 2px 8px;\\n border: 1px solid #fca5a5;\\n border-radius: 4px;\\n background: none;\\n color: #dc2626;\\n font-size: 11px;\\n font-weight: 600;\\n cursor: pointer;\\n}\\n.hw-send-error-retry:hover {\\n background: #fee2e2;\\n}\\n.hw-resolved {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n gap: 12px;\\n padding: 16px 20px;\\n border-top: 1px solid var(--hw-border);\\n flex-shrink: 0;\\n}\\n.hw-resolved-text {\\n font-size: 13px;\\n color: var(--hw-text-3);\\n font-weight: 500;\\n}\\n.hw-resolved-actions {\\n display: flex;\\n gap: 8px;\\n}\\n.hw-resolved-reopen {\\n padding: 6px 16px;\\n border: 1px solid var(--hw-border-md);\\n border-radius: 8px;\\n background: var(--hw-bg);\\n color: var(--hw-text);\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n transition: background 0.15s;\\n}\\n.hw-resolved-reopen:hover {\\n background: var(--hw-bg-hover);\\n}\\n.hw-csat {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n gap: 8px;\\n}\\n.hw-csat-label {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n}\\n.hw-csat-buttons {\\n display: flex;\\n gap: 8px;\\n}\\n.hw-csat-btn {\\n width: 36px;\\n height: 36px;\\n border: 1px solid var(--hw-border-md);\\n border-radius: 8px;\\n background: var(--hw-bg);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n font-size: 18px;\\n transition:\\n transform 0.15s,\\n border-color 0.15s,\\n background 0.15s;\\n}\\n.hw-csat-btn:hover {\\n transform: scale(1.1);\\n border-color: var(--hw-text-3);\\n}\\n.hw-csat-btn--selected {\\n border-color: var(--hw-primary);\\n background: var(--hw-bg-hover);\\n transform: scale(1.15);\\n}\\n.hw-csat-thanks {\\n font-size: 12px;\\n color: #22c55e;\\n font-weight: 500;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n.hw-load-more-trigger {\\n display: flex;\\n justify-content: center;\\n min-height: 1px;\\n}\\n.hw-load-more-trigger:has(.hw-load-more-spinner) {\\n padding: 8px 0;\\n}\\n.hw-load-more-spinner {\\n display: flex;\\n gap: 3px;\\n}\\n.hw-load-more-spinner > div {\\n width: 5px;\\n height: 5px;\\n border-radius: 50%;\\n background: var(--hw-text-4);\\n animation: hw-loading-pulse 1.4s infinite;\\n}\\n.hw-load-more-spinner > div:nth-child(2) {\\n animation-delay: 0.2s;\\n}\\n.hw-load-more-spinner > div:nth-child(3) {\\n animation-delay: 0.4s;\\n}\\n.hw-drag-handle {\\n display: none;\\n}\\n@media (max-width: 479px) {\\n .hw-drag-handle {\\n display: flex;\\n justify-content: center;\\n padding: 8px 0 4px;\\n flex-shrink: 0;\\n }\\n .hw-drag-handle-pill {\\n width: 32px;\\n height: 4px;\\n border-radius: 2px;\\n background: var(--hw-text-4);\\n }\\n}\\n.hw-msg-bubble p {\\n margin: 0 0 8px;\\n}\\n.hw-msg-bubble p:last-child {\\n margin-bottom: 0;\\n}\\n.hw-msg-bubble strong {\\n font-weight: 600;\\n}\\n.hw-msg-bubble em {\\n font-style: italic;\\n}\\n.hw-msg-bubble a {\\n color: var(--hw-primary);\\n text-decoration: underline;\\n text-underline-offset: 2px;\\n word-break: break-all;\\n}\\n.hw-msg-bubble a:hover {\\n opacity: 0.8;\\n}\\n.hw-msg--visitor .hw-msg-bubble a {\\n color: rgba(255, 255, 255, 0.9);\\n}\\n.hw-msg--visitor .hw-msg-bubble a:hover {\\n color: white;\\n}\\n.hw-msg-bubble ul,\\n.hw-msg-bubble ol {\\n margin: 4px 0 8px;\\n padding-left: 20px;\\n}\\n.hw-msg-bubble li {\\n margin: 2px 0;\\n}\\n.hw-msg-bubble code {\\n padding: 1px 4px;\\n border-radius: 3px;\\n background: rgba(0, 0, 0, 0.06);\\n font-size: 0.9em;\\n font-family:\\n ui-monospace,\\n SFMono-Regular,\\n Menlo,\\n monospace;\\n}\\n.hw-msg-bubble pre {\\n margin: 4px 0 8px;\\n padding: 8px 10px;\\n border-radius: 6px;\\n background: rgba(0, 0, 0, 0.06);\\n overflow-x: auto;\\n font-size: 0.85em;\\n}\\n.hw-msg-bubble pre code {\\n padding: 0;\\n background: none;\\n}\\n.hw-msg-bubble blockquote {\\n margin: 4px 0 8px;\\n padding: 4px 0 4px 12px;\\n border-left: 3px solid var(--hw-border-md);\\n color: var(--hw-text-2);\\n}\\n.hw-widget[data-theme=dark] {\\n --hw-bg: #1c1c1e;\\n --hw-bg-subtle: #161618;\\n --hw-bg-hover: #2c2c2e;\\n --hw-border: rgba(255, 255, 255, 0.08);\\n --hw-border-md: rgba(255, 255, 255, 0.14);\\n --hw-text: #f5f5f5;\\n --hw-text-1: #f5f5f5;\\n --hw-text-2: #a1a1aa;\\n --hw-text-3: #71717a;\\n --hw-text-4: #52525b;\\n --hw-visitor-bubble-bg: #2c2c2e;\\n --hw-visitor-bubble-text: #f5f5f5;\\n --hw-focus-border: rgba(255, 255, 255, 0.28);\\n --hw-focus-ring: rgba(255, 255, 255, 0.08);\\n --hw-brand: #f5f5f5;\\n --hw-on-brand: #1c1c1e;\\n}\\n@media (prefers-color-scheme: dark) {\\n .hw-widget:not([data-theme=light]) .hw-messages {\\n scrollbar-color: rgba(255, 255, 255, 0.26) transparent;\\n }\\n .hw-widget:not([data-theme=light]) .hw-messages::-webkit-scrollbar-thumb {\\n background: rgba(255, 255, 255, 0.2);\\n background-clip: content-box;\\n }\\n .hw-widget:not([data-theme=light]) .hw-messages::-webkit-scrollbar-thumb:hover {\\n background: rgba(255, 255, 255, 0.32);\\n background-clip: content-box;\\n }\\n .hw-widget:not([data-theme=light]) {\\n --hw-bg: #1c1c1e;\\n --hw-bg-subtle: #161618;\\n --hw-bg-hover: #2c2c2e;\\n --hw-border: rgba(255, 255, 255, 0.08);\\n --hw-border-md: rgba(255, 255, 255, 0.14);\\n --hw-text: #f5f5f5;\\n --hw-text-1: #f5f5f5;\\n --hw-text-2: #a1a1aa;\\n --hw-text-3: #71717a;\\n --hw-text-4: #52525b;\\n --hw-visitor-bubble-bg: #2c2c2e;\\n --hw-visitor-bubble-text: #f5f5f5;\\n --hw-focus-border: rgba(255, 255, 255, 0.28);\\n --hw-focus-ring: rgba(255, 255, 255, 0.08);\\n --hw-brand: #f5f5f5;\\n --hw-on-brand: #1c1c1e;\\n }\\n}\\n@media (prefers-color-scheme: dark) {\\n .hw-widget:not([data-theme=light]) .hw-header {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n .hw-header-bot-icon {\\n background: var(--hw-bg-hover);\\n }\\n .hw-header-name,\\n .hw-header-title {\\n color: var(--hw-text);\\n }\\n .hw-header-status {\\n color: var(--hw-text-2);\\n }\\n .hw-header-close,\\n .hw-header-back {\\n color: var(--hw-text-2);\\n }\\n .hw-header-close:hover,\\n .hw-header-back:hover {\\n background: var(--hw-bg-hover);\\n color: var(--hw-text);\\n }\\n .hw-content-entry {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n .hw-content-entry:hover {\\n background: var(--hw-bg-hover);\\n border-color: var(--hw-border-md);\\n }\\n .hw-content-empty,\\n .hw-empty {\\n color: var(--hw-text-3);\\n }\\n .hw-conv-card {\\n border-color: var(--hw-border);\\n }\\n .hw-recent-row {\\n border-color: var(--hw-border);\\n }\\n .hw-composer-drop-overlay {\\n background: rgba(0, 0, 0, 0.6);\\n color: var(--hw-text);\\n }\\n .hw-composer--dragging .hw-composer-box {\\n border-color: var(--hw-focus-border);\\n box-shadow: 0 0 0 3px var(--hw-focus-ring);\\n }\\n .hw-hero {\\n background:\\n linear-gradient(\\n 160deg,\\n color-mix(in srgb, var(--hw-primary) 40%, black) 0%,\\n var(--hw-primary) 50%,\\n color-mix(in srgb, var(--hw-primary) 25%, black) 100%);\\n }\\n .hw-sheet {\\n background: var(--hw-bg);\\n }\\n .hw-card {\\n background: var(--hw-bg-hover);\\n border-color: var(--hw-border);\\n }\\n .hw-card:hover {\\n background: #333;\\n }\\n .hw-window {\\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.06);\\n }\\n .hw-bubble:focus-visible {\\n outline-color: var(--hw-text-3);\\n }\\n .hw-msg--visitor .hw-msg-bubble {\\n background: var(--hw-primary);\\n color: white;\\n }\\n .hw-msg-bubble code {\\n background: rgba(255, 255, 255, 0.08);\\n }\\n .hw-msg-bubble pre {\\n background: rgba(255, 255, 255, 0.08);\\n }\\n .hw-composer-box {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n .hw-composer-input {\\n color: var(--hw-text);\\n }\\n .hw-tabs {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n .hw-conv-card:hover,\\n .hw-recent-row:hover {\\n background: var(--hw-bg-hover);\\n }\\n .hw-disconnect {\\n background: #422006;\\n color: #fcd34d;\\n }\\n .hw-send-error {\\n background: #450a0a;\\n color: #fca5a5;\\n }\\n .hw-error-icon {\\n background: #450a0a;\\n color: #f87171;\\n }\\n .hw-resolved {\\n border-color: var(--hw-border);\\n }\\n .hw-resolved-reopen,\\n .hw-csat-btn {\\n background: var(--hw-bg-hover);\\n border-color: var(--hw-border-md);\\n color: var(--hw-text);\\n }\\n .hw-hover-preview {\\n background: #1c1c1e;\\n border-color: var(--hw-border);\\n }\\n .hw-content-search-box {\\n background: var(--hw-bg-hover);\\n border-color: var(--hw-border-md);\\n }\\n .hw-preview {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n}\\n\")","\"use client\";\n\n/**\n * `<HelpwayWidget />` — one-line drop-in React component that renders\n * the full Helpway widget natively in React.\n *\n * Since v0.2, this is a native React render (not a script tag injection).\n * The widget-core + widget-react code is bundled with your app, so widget\n * updates ship via `npm update @helpway/react` — no separate widget.js\n * deploy required. Bundle impact: ~120KB gzipped (shared with any other\n * helpway/react imports in your app, so subsequent uses are free).\n *\n * Power-user alternative: import `{ SupportProvider, DefaultWidget, useWidget, … }`\n * directly for programmatic control (render your own chat UI, expose\n * identify() via hook instead of global, etc.).\n *\n * @see https://helpway.ai/docs/quick-start for setup\n * @see https://helpway.ai/docs/react-sdk for the three integration layers\n * (drop-in, provider + hooks, fully headless)\n * @see https://helpway.ai/docs/customization for theming via `theme` prop\n * and the dashboard config\n * @see https://helpway.ai/docs/integration-notes for CSP, SSR, multi-tenant\n */\n\nimport type { WidgetTheme } from \"@helpway/widget-core\";\nimport { SupportProvider } from \"./provider\";\nimport { DefaultWidget } from \"./themed/default-widget\";\n// Auto-import CSS so consumers don't need a separate `import \"@helpway/react/styles.css\"` step.\n// Side-effect import — evaluated once per bundle, tree-shaker preserves it via `sideEffects: [\"*.css\"]`.\nimport \"./themed/styles.css\";\n\nexport interface HelpwayWidgetProps {\n\t/**\n\t * Public API key from the Helpway dashboard. Required.\n\t * Format: `pk_live_…` or `pk_test_…`.\n\t */\n\tapiKey: string;\n\t/**\n\t * Override the default API URL. Almost no one needs this —\n\t * exposed for staging / self-hosted setups.\n\t * @default \"https://api.helpway.ai\"\n\t */\n\tapiUrl?: string;\n\t/**\n\t * Widget locale (e.g. \"tr\", \"en\", \"de\"). Falls back to server-side\n\t * detection (Accept-Language + CF-IPCountry) then widget-core default.\n\t */\n\tlocale?: string;\n\t/**\n\t * Deep link: auto-open this conversation after bootstrap.\n\t * Usually sourced from `?hw_conv=` URL param for email CTAs.\n\t */\n\tinitialConversationId?: string;\n\t/**\n\t * Called once after the widget has bootstrapped and exposes\n\t * the full programmatic API object (also available as `window.Helpway`).\n\t */\n\tonReady?: (api: HelpwayPublicAPI) => void;\n\t/**\n\t * Hide the default floating launcher button. Use with\n\t * `customLauncherSelector` or `window.Helpway.open()` to trigger\n\t * the widget from your own UI.\n\t */\n\thideLauncher?: boolean;\n\t/**\n\t * CSS selector for a custom trigger element (e.g. `\"#support-btn\"`).\n\t * Clicking the matched element calls `Helpway.open()`. Combine with\n\t * `hideLauncher` to fully replace the default bubble.\n\t */\n\tcustomLauncherSelector?: string;\n\t/** Fires when the widget panel opens */\n\tonOpen?: () => void;\n\t/** Fires when the widget panel closes */\n\tonClose?: () => void;\n\t/** Fires when the unread count changes */\n\tonUnreadChange?: (count: number) => void;\n\t/**\n\t * Developer-side theme override. Most consumers should configure\n\t * appearance from the dashboard so changes apply without a redeploy\n\t * — see https://helpway.ai/docs/customization. Use this prop only\n\t * for runtime-resolved theming (multi-tenant brand colors, dark/\n\t * light sync with the host app, etc). Values map to CSS custom\n\t * properties on the widget host. See the `WidgetTheme` type for\n\t * the full set of supported keys.\n\t */\n\ttheme?: WidgetTheme;\n\t/**\n\t * @deprecated Legacy prop from the v0.1 script-loader era. If set,\n\t * the `/widget.js` suffix is stripped to derive `apiUrl`. New code\n\t * should use `apiUrl` instead.\n\t */\n\tsrc?: string;\n}\n\n// Re-export for consumers who use the onReady callback type.\n// `onReady` receives the programmatic methods object; the global\n// `window.Helpway` is the callable wrapper around it (HelpwayAPI).\nimport type { HelpwayMethods } from \"@helpway/widget-core\";\nexport type HelpwayPublicAPI = HelpwayMethods;\n\n/**\n * Render this once at the root of your app (e.g. in `_app.tsx`,\n * `layout.tsx`, or `main.tsx`). Unmounting cleanly tears down the\n * widget and its WebSocket connection — useful for route-scoped mounts.\n */\nexport function HelpwayWidget({\n\tapiKey,\n\tapiUrl,\n\tlocale,\n\tinitialConversationId,\n\tonReady,\n\thideLauncher,\n\tcustomLauncherSelector,\n\tonOpen,\n\tonClose,\n\tonUnreadChange,\n\ttheme,\n\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\tsrc,\n}: HelpwayWidgetProps) {\n\tconst resolvedApiUrl = apiUrl ?? (src ? src.replace(/\\/widget\\.js$/, \"\") : undefined);\n\n\treturn (\n\t\t<SupportProvider\n\t\t\tapiKey={apiKey}\n\t\t\tapiUrl={resolvedApiUrl}\n\t\t\tlocale={locale}\n\t\t\tinitialConversationId={initialConversationId}\n\t\t\tonReady={onReady}\n\t\t\tcustomLauncherSelector={customLauncherSelector}\n\t\t\tonOpen={onOpen}\n\t\t\tonClose={onClose}\n\t\t\tonUnreadChange={onUnreadChange}\n\t\t\ttheme={theme}\n\t\t>\n\t\t\t<DefaultWidget hideLauncher={hideLauncher} />\n\t\t</SupportProvider>\n\t);\n}\n","import { useEffect } from \"react\";\nimport type { RealtimeEvent } from \"@helpway/types\";\nimport { useWidgetContext } from \"../provider\";\n\n/**\n * Subscribe to raw WebSocket events.\n * For advanced usage — most apps should use useTimeline/usePresence instead.\n *\n * Usage:\n * ```tsx\n * useRealtime((event) => {\n * if (event.type === 'timelineItemCreated') { ... }\n * })\n * ```\n */\nexport function useRealtime(handler: (event: RealtimeEvent) => void) {\n\tconst { ws } = useWidgetContext();\n\n\tuseEffect(() => {\n\t\treturn ws.onEvent(handler);\n\t}, [ws, handler]);\n}\n"],"mappings":"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","names":["client","store","emitter","ws","identify","api","el","useCallback","useEffect","useRef","useState","useCallback","useState","useState","useCallback","useCallback","useRef","useState","useState","useRef","useCallback","store","useEffect","useState","useState","useEffect","useCallback","useRef","useRef","useCallback","useCallback","useEffect","useRef","useState","useState","useRef","useEffect","useCallback","useCallback","useRef","useState","jsx","jsx","jsx","jsx","jsx","useEffect","useRef","useState","useEffect","useRef","jsx","jsx","jsxs","useRef","useEffect","useState","jsx","jsxs","useRef","useCallback","useState","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useCallback","useEffect","useCallback","useEffect","useState","t","useState","useCallback","useEffect","Fragment","jsx","jsxs","useCallback","useRef","useState","jsx","jsxs","useEffect","useRef","useCallback","useRef","useState","EMPTY_TABS","detailKey","readCache","t","useState","useRef","useCallback","jsx","useEffect","useRef","jsx","useEffect","useCallback","jsx","useEffect","useRef","jsx","jsxs","useRef","useEffect","Fragment","jsx","jsxs","resolveLabel","useState","useRef","useEffect","useCallback","t","focusable","jsx","useEffect","useEffect"]}
1
+ {"version":3,"sources":["../../widget-core/src/client.ts","../../widget-core/src/visitor-id.ts","../../types/src/realtime-events.ts","../../widget-core/src/ws.ts","../../widget-core/src/store.ts","../../widget-core/src/api.ts","../../widget-core/src/theme.ts","../../widget-core/src/events.ts","../../widget-core/src/i18n.ts","../../widget-core/src/utils.ts","../src/provider.tsx","../src/themed/default-widget.tsx","../src/hooks/use-composer.ts","../src/hooks/use-conversations.ts","../src/hooks/use-i18n.ts","../src/hooks/use-presence.ts","../src/hooks/use-timeline.ts","../src/hooks/use-unread.ts","../src/hooks/use-widget.ts","../src/themed/composer.tsx","../src/themed/icons.tsx","../src/themed/message-bubble.tsx","../src/themed/content/simple-markdown.tsx","../src/themed/debug-overlay.tsx","../src/themed/content/content-tab-view.tsx","../src/hooks/use-content-tab.ts","../src/themed/content/content-detail-view.tsx","../src/themed/content/content-list-view.tsx","../src/themed/content/grouped-content-tab-view.tsx","../src/hooks/use-grouped-content-tab.ts","../src/themed/content/tab-icon.tsx","../src/themed/message-list.tsx","#style-inject:#style-inject","../src/themed/styles.css","../src/helpway-widget.tsx","../src/hooks/use-realtime.ts"],"sourcesContent":["import { createTRPCClient, httpBatchLink } from \"@trpc/client\";\nimport { getOrCreateVisitorId } from \"./visitor-id\";\n\n// The real AppRouter lives in apps/api/src/trpc/ but importing it pulls in CF Worker\n// source files. We type the client as `any` here — real type safety is in the\n// Zustand store (widget-react). The tRPC link config is the same at runtime.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type WidgetClient = any;\n\n/**\n * Create a tRPC vanilla client for widget API calls.\n *\n * Visitor identity uses a dual strategy:\n * 1. X-Visitor-Id header (localStorage-based) — always works, even cross-origin\n * 2. hw_visitor cookie (server-set) — additional persistence layer\n *\n * This ensures visitor identity survives 3rd-party cookie blocking\n * (Safari ITP, Firefox ETP, Chrome Privacy Sandbox).\n */\nexport function createWidgetClient(config: {\n\tapiUrl: string;\n\tapiKey: string;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n}): any {\n\treturn createTRPCClient({\n\t\tlinks: [\n\t\t\thttpBatchLink({\n\t\t\t\turl: `${config.apiUrl}/trpc`,\n\t\t\t\theaders() {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t\"X-Public-Key\": config.apiKey,\n\t\t\t\t\t\t\"X-Visitor-Id\": getOrCreateVisitorId(config.apiKey),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\tfetch(url, options) {\n\t\t\t\t\t// credentials: \"include\" sends cookies cross-origin (when not blocked)\n\t\t\t\t\treturn globalThis.fetch(url, { ...options, credentials: \"include\" });\n\t\t\t\t},\n\t\t\t}),\n\t\t],\n\t});\n}\n","/**\n * Per-site visitor identity storage (localStorage).\n *\n * Matches Intercom's `intercom-id-[app_id]` pattern — each publicKey gets\n * its own localStorage slot so a single browser visiting multiple Helpway\n * workspaces never bleeds identities across them.\n *\n * Storage key: `helpway:visitor:<publicKey-suffix>` (last 16 chars of the key,\n * which is always random — see `generatePublicKey` in apps/api/src/lib/id.ts).\n */\n\nconst PREFIX = \"helpway:visitor\";\nconst LEGACY_KEY = \"helpway:visitor-id\";\n\nfunction keyFor(publicKey: string): string {\n\t// Last 16 chars of publicKey — enough uniqueness (2^80 collision space for nanoid alphabet)\n\t// and keeps localStorage key short. Stable for a given site.\n\tconst suffix = publicKey.slice(-16);\n\treturn `${PREFIX}:${suffix}`;\n}\n\nfunction generateId(): string {\n\tconst ts = Date.now().toString(36);\n\tconst rand = Math.random().toString(36).slice(2, 10);\n\treturn `${ts}${rand}`;\n}\n\n/**\n * Get or create a persistent visitor ID scoped to `publicKey`.\n * Returns a stable per-site ID across page loads.\n */\nexport function getOrCreateVisitorId(publicKey: string): string {\n\ttry {\n\t\tconst storageKey = keyFor(publicKey);\n\t\tconst existing = localStorage.getItem(storageKey);\n\t\tif (existing) return existing;\n\n\t\t// One-time migration: if a legacy global key exists AND no per-site key\n\t\t// is set yet, seed this site with it. Keeps returning visitors identified\n\t\t// on their FIRST post-upgrade site load. Subsequent sites get fresh IDs.\n\t\tconst legacy = localStorage.getItem(LEGACY_KEY);\n\t\tif (legacy) {\n\t\t\tlocalStorage.setItem(storageKey, legacy);\n\t\t\tlocalStorage.removeItem(LEGACY_KEY);\n\t\t\treturn legacy;\n\t\t}\n\n\t\tconst id = generateId();\n\t\tlocalStorage.setItem(storageKey, id);\n\t\treturn id;\n\t} catch {\n\t\t// localStorage unavailable (SSR, private mode, quota exceeded)\n\t\treturn generateId();\n\t}\n}\n\n/** Sync the server-assigned canonical visitor ID back into localStorage. */\nexport function syncVisitorId(publicKey: string, serverVisitorId: string): void {\n\ttry {\n\t\tlocalStorage.setItem(keyFor(publicKey), serverVisitorId);\n\t} catch {\n\t\t// ignore\n\t}\n}\n\n/** Clear the visitor ID for a specific site (used by playground \"simulate anonymous\"). */\nexport function clearVisitorId(publicKey: string): void {\n\ttry {\n\t\tlocalStorage.removeItem(keyFor(publicKey));\n\t} catch {\n\t\t// ignore\n\t}\n}\n","import type { Conversation } from \"./conversation\";\nimport type { TimelineItem } from \"./timeline-item\";\n\n// ── Union of all realtime events ──────────────────────────\n\nexport type RealtimeEvent =\n\t| ConnectionEstablishedEvent\n\t| ConversationCreatedEvent\n\t| ConversationUpdatedEvent\n\t| TimelineItemCreatedEvent\n\t| TimelineItemUpdatedEvent\n\t| TimelineItemDeletedEvent\n\t| ConversationSeenEvent\n\t| ConversationTypingEvent\n\t| AiProcessingProgressEvent\n\t| AiProcessingCompletedEvent\n\t| VisitorPresenceChangedEvent\n\t| MemberUpdatedEvent;\n\n// ── Connection ────────────────────────────────────────────\n\nexport interface ConnectionEstablishedEvent {\n\ttype: \"connectionEstablished\";\n\tconnectionId: string;\n}\n\n// ── Conversation lifecycle ────────────────────────────────\n\nexport interface ConversationCreatedEvent {\n\ttype: \"conversationCreated\";\n\tconversation: Conversation;\n}\n\nexport interface ConversationUpdatedEvent {\n\ttype: \"conversationUpdated\";\n\tconversationId: string;\n\tupdates: Partial<Conversation>;\n}\n\n// ── Timeline items ────────────────────────────────────────\n\nexport interface TimelineItemCreatedEvent {\n\ttype: \"timelineItemCreated\";\n\tconversationId: string;\n\titem: TimelineItem;\n}\n\nexport interface TimelineItemUpdatedEvent {\n\ttype: \"timelineItemUpdated\";\n\tconversationId: string;\n\titem: TimelineItem;\n}\n\nexport interface TimelineItemDeletedEvent {\n\ttype: \"timelineItemDeleted\";\n\tconversationId: string;\n\titemId: string;\n}\n\n// ── Presence / read receipts ──────────────────────────────\n\nexport interface ConversationSeenEvent {\n\ttype: \"conversationSeen\";\n\tconversationId: string;\n\tuserId?: string;\n\tvisitorId?: string;\n\tlastSeenAt: string;\n}\n\nexport interface ConversationTypingEvent {\n\ttype: \"conversationTyping\";\n\tconversationId: string;\n\tuserId?: string;\n\tvisitorId?: string;\n\tisTyping: boolean;\n}\n\n// ── AI processing indicators ──────────────────────────────\n\nexport interface AiProcessingProgressEvent {\n\ttype: \"aiProcessingProgress\";\n\tconversationId: string;\n\tphase: \"thinking\" | \"searching\" | \"responding\";\n}\n\nexport interface AiProcessingCompletedEvent {\n\ttype: \"aiProcessingCompleted\";\n\tconversationId: string;\n\tstatus: \"success\" | \"error\" | \"skipped\";\n}\n\n// ── Visitor presence ─────────────────────────────────────\n\nexport interface VisitorPresenceChangedEvent {\n\ttype: \"visitorPresenceChanged\";\n\tvisitorId: string;\n\tstatus: \"online\" | \"offline\";\n}\n\n// ── Organization team ────────────────────────────────────\n\nexport interface MemberUpdatedEvent {\n\ttype: \"memberUpdated\";\n\taction: \"added\" | \"removed\" | \"roleChanged\";\n\tmemberId: string;\n}\n\n// ── Event type guard helper ───────────────────────────────\n\nexport function isRealtimeEvent(data: unknown): data is RealtimeEvent {\n\treturn (\n\t\ttypeof data === \"object\" &&\n\t\tdata !== null &&\n\t\t\"type\" in data &&\n\t\ttypeof (data as RealtimeEvent).type === \"string\"\n\t);\n}\n","import { type RealtimeEvent, isRealtimeEvent } from \"@helpway/types\";\n\nexport type EventHandler = (event: RealtimeEvent) => void;\n\ninterface WebSocketManagerConfig {\n\tapiUrl: string;\n\tvisitorId: string;\n\twebsiteId: string;\n}\n\n/**\n * WebSocket connection manager for ChatRoom Durable Object.\n * Handles connect, disconnect, auto-reconnect with exponential backoff,\n * ping/pong keep-alive, and event dispatching.\n *\n * Ping gating — visibility-aware:\n * Ping doubles as a presence heartbeat on the server (refreshes KV\n * presence key with a 150s TTL). When the tab is hidden we pause the\n * ping so a forgotten background tab naturally drops offline within\n * ~2.5 minutes. The socket itself stays open; only the heartbeat stops.\n */\nexport class WebSocketManager {\n\tprivate ws: WebSocket | null = null;\n\tprivate handlers = new Set<EventHandler>();\n\tprivate config: WebSocketManagerConfig;\n\tprivate reconnectAttempts = 0;\n\tprivate maxReconnectAttempts = 10;\n\tprivate reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate pingTimer: ReturnType<typeof setInterval> | null = null;\n\tprivate isDestroyed = false;\n\tprivate visibilityHandler: (() => void) | null = null;\n\n\tconstructor(config: WebSocketManagerConfig) {\n\t\tthis.config = config;\n\t\tthis.setupVisibilityListener();\n\t}\n\n\tprivate setupVisibilityListener(): void {\n\t\tif (typeof document === \"undefined\") return;\n\t\tthis.visibilityHandler = () => {\n\t\t\tif (document.visibilityState === \"hidden\") {\n\t\t\t\t// Tab backgrounded — stop heartbeat so KV TTL drops user offline.\n\t\t\t\tthis.stopPing();\n\t\t\t} else if (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\t\t// Tab visible again — resume heartbeat immediately to restore presence.\n\t\t\t\tthis.startPing();\n\t\t\t\tthis.send({ type: \"ping\" });\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener(\"visibilitychange\", this.visibilityHandler);\n\t}\n\n\t/** Update connection parameters (call before connect) */\n\tconfigure(params: Partial<WebSocketManagerConfig>): void {\n\t\tObject.assign(this.config, params);\n\t}\n\n\t/** Connect to the ChatRoom Durable Object WebSocket */\n\tconnect(): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) return;\n\t\t// Reset destroyed flag — allows reconnect after React StrictMode remount\n\t\tthis.isDestroyed = false;\n\n\t\tconst protocol = this.config.apiUrl.startsWith(\"https\") ? \"wss\" : \"ws\";\n\t\tconst base = this.config.apiUrl.replace(/^https?/, protocol);\n\t\tconst params = new URLSearchParams({\n\t\t\ttype: \"visitor\",\n\t\t\tid: this.config.visitorId,\n\t\t\twebsiteId: this.config.websiteId,\n\t\t});\n\n\t\tconst ws = new WebSocket(`${base}/ws?${params}`);\n\n\t\tws.onopen = () => {\n\t\t\tthis.reconnectAttempts = 0;\n\t\t\t// Only start heartbeat if the tab is visible — the visibility\n\t\t\t// listener resumes it automatically when the user returns.\n\t\t\tif (typeof document === \"undefined\" || document.visibilityState === \"visible\") {\n\t\t\t\tthis.startPing();\n\t\t\t}\n\t\t};\n\n\t\tws.onmessage = (event) => {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(event.data as string);\n\t\t\t\tif (data.type === \"pong\") return;\n\t\t\t\tif (isRealtimeEvent(data)) {\n\t\t\t\t\tfor (const handler of this.handlers) {\n\t\t\t\t\t\thandler(data);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Malformed message — ignore\n\t\t\t}\n\t\t};\n\n\t\tws.onclose = () => {\n\t\t\tthis.stopPing();\n\t\t\tthis.ws = null;\n\t\t\tif (!this.isDestroyed) {\n\t\t\t\tthis.scheduleReconnect();\n\t\t\t}\n\t\t};\n\n\t\tws.onerror = () => {\n\t\t\t// onclose will fire after onerror\n\t\t};\n\n\t\tthis.ws = ws;\n\t}\n\n\t/** Disconnect and stop reconnecting */\n\tdisconnect(): void {\n\t\tthis.isDestroyed = true;\n\t\tthis.stopPing();\n\t\tif (this.reconnectTimer) {\n\t\t\tclearTimeout(this.reconnectTimer);\n\t\t\tthis.reconnectTimer = null;\n\t\t}\n\t\tif (this.visibilityHandler && typeof document !== \"undefined\") {\n\t\t\tdocument.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n\t\t\tthis.visibilityHandler = null;\n\t\t}\n\t\tif (this.ws) {\n\t\t\tthis.ws.close(1000, \"Client disconnect\");\n\t\t\tthis.ws = null;\n\t\t}\n\t}\n\n\t/** Send a JSON message through the WebSocket */\n\tsend(data: Record<string, unknown>): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\tthis.ws.send(JSON.stringify(data));\n\t\t}\n\t}\n\n\t/** Send typing indicator */\n\tsendTyping(conversationId: string, isTyping: boolean): void {\n\t\tthis.send({ type: \"typing\", conversationId, isTyping });\n\t}\n\n\t/** Subscribe to realtime events */\n\tonEvent(handler: EventHandler): () => void {\n\t\tthis.handlers.add(handler);\n\t\treturn () => {\n\t\t\tthis.handlers.delete(handler);\n\t\t};\n\t}\n\n\t/** Check if connected */\n\tget isConnected(): boolean {\n\t\treturn this.ws?.readyState === WebSocket.OPEN;\n\t}\n\n\t// ── Private ──────────────────────────────────────────\n\n\tprivate scheduleReconnect(): void {\n\t\tif (this.reconnectAttempts >= this.maxReconnectAttempts) return;\n\n\t\tconst delay = Math.min(1000 * 2 ** this.reconnectAttempts, 30000);\n\t\tthis.reconnectAttempts++;\n\n\t\tthis.reconnectTimer = setTimeout(() => {\n\t\t\tthis.connect();\n\t\t}, delay);\n\t}\n\n\tprivate startPing(): void {\n\t\tthis.stopPing();\n\t\tthis.pingTimer = setInterval(() => {\n\t\t\tthis.send({ type: \"ping\" });\n\t\t}, 25000);\n\t}\n\n\tprivate stopPing(): void {\n\t\tif (this.pingTimer) {\n\t\t\tclearInterval(this.pingTimer);\n\t\t\tthis.pingTimer = null;\n\t\t}\n\t}\n}\n","import type { PublicVisitor, RealtimeEvent, TimelineItem } from \"@helpway/types\";\nimport { createStore } from \"zustand/vanilla\";\n\n// ── Agent Config (from bootstrap) ────────────────────────\n\nexport interface WidgetContentTab {\n\tid: string;\n\tlabel: string;\n\ticon: string;\n\tmodelSlug: string;\n\tdisplay?: {\n\t\tsubtitleField?: string;\n\t\tbadgeField?: string;\n\t\timageField?: string;\n\t\tdateField?: string;\n\t};\n\ttabType?: \"flat\" | \"grouped\";\n\titemsModelSlug?: string;\n\tgroupField?: string;\n}\n\nexport interface AgentConfig {\n\tid: string;\n\tname: string;\n\tavatarUrl: string | null;\n\tavatarPreset: string | null;\n\twelcomeMessage: string | null;\n\tsubtitleText: string | null;\n\tbrandColor: string;\n\twidgetPosition: \"bottom-right\" | \"bottom-left\";\n\tlauncherStyle: \"icon\" | \"bubble\" | \"help\";\n\t/** Custom image rendered inside the launcher bubble. NULL → fall back\n\t * to the chat-header chain (avatarUrl → avatarPreset → website logo). */\n\tlauncherIconUrl: string | null;\n\tbubbleStyle: \"rounded\" | \"square\" | \"pill\";\n\t/** Show/hide Messages tab in widget footer */\n\tshowMessagesTab: boolean;\n\t/** Require visitor to provide email before starting a conversation */\n\trequireVisitorEmail: boolean;\n\t/** Dynamic content tabs from Better i18n Content CMS integration */\n\tcontentTabs: WidgetContentTab[];\n}\n\n// ── Content Cache ──────────────────────────────────────────\n\nexport interface ContentCacheEntry {\n\tdata: unknown;\n\tts: number;\n}\n\nexport const CONTENT_CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\n// ── State Shape ──────────────────────────────────────────\n\nexport interface WidgetState {\n\t// Connection\n\tisReady: boolean;\n\tisConnecting: boolean;\n\n\t// Identity\n\tvisitor: PublicVisitor | null;\n\twebsite: { id: string; name: string; domain: string | null; logoUrl: string | null } | null;\n\n\t// Agent config (from bootstrap)\n\tagentConfig: AgentConfig | null;\n\n\t// Conversations\n\tconversations: ConversationSummary[];\n\tactiveConversationId: string | null;\n\n\t// Messages per conversation\n\tmessages: Map<string, TimelineItem[]>;\n\n\t// Presence\n\ttypingUsers: Map<string, boolean>; // conversationId → someone is typing\n\taiProcessing: Map<string, boolean>; // conversationId → AI is processing\n\n\t// UI state\n\tisOpen: boolean;\n\tisDismissed: boolean;\n\tview: \"home\" | \"conversation\" | \"new\";\n\n\t// Incoming message preview (shown when widget is closed)\n\tincomingPreview: {\n\t\ttext: string;\n\t\tconversationId: string;\n\t\ttimestamp: number;\n\t\tmessages?: Array<{ text: string }>;\n\t\tquickReplies?: {\n\t\t\tstepId: string;\n\t\t\tprompt: string | null;\n\t\t\toptions: Array<{ id: string; label: string }>;\n\t\t};\n\t} | null;\n\n\t// Pre-filled text for new conversation (set via global API)\n\tnewConversationPrefill: string | null;\n\n\t// Content cache (survives tab switches — keyed by request params)\n\tcontentCache: Map<string, ContentCacheEntry>;\n}\n\nexport interface ConversationSummary {\n\tid: string;\n\ttitle: string | null;\n\tstatus: string;\n\tlastMessageText: string | null;\n\tlastMessageAt: string | null;\n\tlastMessageSenderType: string | null;\n\tlastMessageSenderName: string | null;\n\tlastMessageSenderImage: string | null;\n\t/** Display-only fields for the assigned support user. NULL when no\n\t * human is assigned (AI agent is handling). UserId is intentionally\n\t * not exposed — only what the chat header needs to render. */\n\tassigneeName: string | null;\n\tassigneeImage: string | null;\n\tunreadCount: number;\n}\n\n// ── Actions ──────────────────────────────────────────────\n\nexport interface WidgetActions {\n\t// Lifecycle\n\tsetReady(\n\t\tvisitor: WidgetState[\"visitor\"],\n\t\twebsite: WidgetState[\"website\"],\n\t\tagentConfig?: AgentConfig | null,\n\t): void;\n\tsetConnecting(connecting: boolean): void;\n\n\t// Conversations\n\tsetConversations(conversations: ConversationSummary[]): void;\n\taddConversation(conversation: ConversationSummary): void;\n\tsetActiveConversation(id: string | null): void;\n\n\t// Messages\n\tsetMessages(conversationId: string, items: TimelineItem[]): void;\n\taddMessage(conversationId: string, item: TimelineItem): void;\n\t/**\n\t * Replace a message by ID (used by optimistic send — swaps\n\t * temp `optimistic-*` id for the server-confirmed item).\n\t */\n\treplaceMessage(conversationId: string, oldId: string, item: TimelineItem): void;\n\t/** Remove a message by ID (used for optimistic rollback on send failure) */\n\tremoveMessage(conversationId: string, id: string): void;\n\t/**\n\t * Move an optimistic conversation to its server-assigned ID.\n\t * Copies messages + updates activeConversationId + conversations list.\n\t */\n\tremapConversationId(oldId: string, newId: string): void;\n\n\t// Presence\n\tsetTyping(conversationId: string, isTyping: boolean): void;\n\tsetAiProcessing(conversationId: string, processing: boolean): void;\n\n\t// Identity\n\tupdateVisitorContact(contact: { id: string; name: string | null; email: string | null }): void;\n\n\t// Unread\n\tclearUnread(conversationId: string): void;\n\n\t// UI\n\tsetOpen(open: boolean): void;\n\tsetDismissed(dismissed: boolean): void;\n\tsetView(view: WidgetState[\"view\"]): void;\n\tsetNewConversationPrefill(text: string | null): void;\n\tdismissPreview(): void;\n\n\t// Content cache\n\tsetContentCache(key: string, data: unknown): void;\n\n\t// Realtime\n\thandleRealtimeEvent(event: RealtimeEvent): void;\n}\n\nexport type WidgetStore = WidgetState & WidgetActions;\n\n// ── Store Factory ────────────────────────────────────────\n\nexport function createWidgetStore() {\n\treturn createStore<WidgetStore>((set, get) => ({\n\t\t// Initial state\n\t\tisReady: false,\n\t\tisConnecting: true,\n\t\tvisitor: null,\n\t\twebsite: null,\n\t\tagentConfig: null,\n\t\tconversations: [],\n\t\tactiveConversationId: null,\n\t\tmessages: new Map(),\n\t\ttypingUsers: new Map(),\n\t\taiProcessing: new Map(),\n\t\tisOpen: false,\n\t\tisDismissed: false,\n\t\tview: \"home\",\n\t\tincomingPreview: null,\n\t\tnewConversationPrefill: null,\n\t\tcontentCache: new Map(),\n\n\t\t// ── Lifecycle ────────────────────────────────────\n\n\t\tsetReady(visitor, website, agentConfig) {\n\t\t\tset({\n\t\t\t\tisReady: true,\n\t\t\t\tisConnecting: false,\n\t\t\t\tvisitor,\n\t\t\t\twebsite,\n\t\t\t\tagentConfig: agentConfig ?? null,\n\t\t\t});\n\t\t},\n\n\t\tsetConnecting(connecting) {\n\t\t\tset({ isConnecting: connecting });\n\t\t},\n\n\t\t// ── Conversations ────────────────────────────────\n\n\t\tsetConversations(conversations) {\n\t\t\tset({ conversations });\n\t\t},\n\n\t\taddConversation(conversation) {\n\t\t\tset((state) => ({\n\t\t\t\tconversations: [conversation, ...state.conversations],\n\t\t\t}));\n\t\t},\n\n\t\tsetActiveConversation(id) {\n\t\t\tset({ activeConversationId: id, view: id ? \"conversation\" : \"home\" });\n\t\t},\n\n\t\t// ── Messages ─────────────────────────────────────\n\n\t\tsetMessages(conversationId, items) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.messages);\n\t\t\t\tnext.set(conversationId, items);\n\t\t\t\treturn { messages: next };\n\t\t\t});\n\t\t},\n\n\t\taddMessage(conversationId, item) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.messages);\n\t\t\t\tconst existing = next.get(conversationId) ?? [];\n\t\t\t\t// Deduplicate by ID — WS echoes may arrive twice (once from broadcast,\n\t\t\t\t// once from the mutation response path).\n\t\t\t\tif (existing.some((m) => m.id === item.id)) return state;\n\t\t\t\t// Agent welcome messages are always the opener of a conversation.\n\t\t\t\t// If the first existing item is a visitor message, prepend the welcome\n\t\t\t\t// so the greeting stays above — don't rely on createdAt (client clock\n\t\t\t\t// vs server clock drift can flip the order).\n\t\t\t\tconst isAgentWelcome = !!item.aiAgentId && !item.visitorId;\n\t\t\t\tconst firstIsVisitor = existing[0]?.visitorId != null;\n\t\t\t\tif (isAgentWelcome && firstIsVisitor) {\n\t\t\t\t\tnext.set(conversationId, [item, ...existing]);\n\t\t\t\t\treturn { messages: next };\n\t\t\t\t}\n\t\t\t\t// General case: insert chronologically. Sort only when the newcomer\n\t\t\t\t// is older than the current tail (rare — WS reorders).\n\t\t\t\tconst last = existing[existing.length - 1];\n\t\t\t\tconst isOutOfOrder = last && item.createdAt < last.createdAt;\n\t\t\t\tconst merged = [...existing, item];\n\t\t\t\tif (isOutOfOrder) {\n\t\t\t\t\tmerged.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n\t\t\t\t}\n\t\t\t\tnext.set(conversationId, merged);\n\t\t\t\treturn { messages: next };\n\t\t\t});\n\t\t},\n\n\t\treplaceMessage(conversationId, oldId, item) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.messages);\n\t\t\t\tconst existing = next.get(conversationId) ?? [];\n\t\t\t\t// Race with WS echo: if the real item already landed, just drop the optimistic\n\t\t\t\tif (existing.some((m) => m.id === item.id && m.id !== oldId)) {\n\t\t\t\t\tnext.set(\n\t\t\t\t\t\tconversationId,\n\t\t\t\t\t\texisting.filter((m) => m.id !== oldId),\n\t\t\t\t\t);\n\t\t\t\t\treturn { messages: next };\n\t\t\t\t}\n\t\t\t\t// Preserve the optimistic ID as _stableKey so the React key\n\t\t\t\t// stays constant across the optimistic → real ID swap.\n\t\t\t\tnext.set(\n\t\t\t\t\tconversationId,\n\t\t\t\t\texisting.map((m) =>\n\t\t\t\t\t\tm.id === oldId\n\t\t\t\t\t\t\t? { ...item, _stableKey: (m as unknown as { _stableKey?: string })._stableKey ?? oldId }\n\t\t\t\t\t\t\t: m,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn { messages: next };\n\t\t\t});\n\t\t},\n\n\t\tremoveMessage(conversationId, id) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.messages);\n\t\t\t\tconst existing = next.get(conversationId);\n\t\t\t\tif (!existing) return state;\n\t\t\t\tnext.set(\n\t\t\t\t\tconversationId,\n\t\t\t\t\texisting.filter((m) => m.id !== id),\n\t\t\t\t);\n\t\t\t\treturn { messages: next };\n\t\t\t});\n\t\t},\n\n\t\tremapConversationId(oldId, newId) {\n\t\t\tset((state) => {\n\t\t\t\t// Merge messages from tempId + newId — WS echo may have inserted\n\t\t\t\t// items under the real id BEFORE the createConversation mutation\n\t\t\t\t// resolved. Dedupe by id so we don't lose the WS-delivered items.\n\t\t\t\tconst nextMessages = new Map(state.messages);\n\t\t\t\tconst tempItems = nextMessages.get(oldId) ?? [];\n\t\t\t\tconst existingItems = nextMessages.get(newId) ?? [];\n\t\t\t\tconst tempRewritten = tempItems.map((m) => ({ ...m, conversationId: newId }));\n\t\t\t\tconst isAgentMsg = (m: TimelineItem) =>\n\t\t\t\t\t!!m.aiAgentId && !m.visitorId && !m.userId;\n\t\t\t\t// Prefer the seed welcome that came in via the temp conversation.\n\t\t\t\t// Keeping its DOM node stable is the whole point of openNewConversation\n\t\t\t\t// seeding; if we let the server-welcome (different id, same text)\n\t\t\t\t// take its slot, React unmounts the seed bubble and the animation\n\t\t\t\t// replays — exactly the \"git-gel\" the seed exists to prevent.\n\t\t\t\tconst seen = new Set<string>();\n\t\t\t\tconst merged: TimelineItem[] = [];\n\t\t\t\tlet keptAgentWelcome = false;\n\t\t\t\tfor (const m of tempRewritten) {\n\t\t\t\t\tif (seen.has(m.id)) continue;\n\t\t\t\t\tseen.add(m.id);\n\t\t\t\t\tmerged.push(m);\n\t\t\t\t\tif (isAgentMsg(m) && merged.length === 1) keptAgentWelcome = true;\n\t\t\t\t}\n\t\t\t\tfor (const m of existingItems) {\n\t\t\t\t\tif (seen.has(m.id)) continue;\n\t\t\t\t\t// Drop server's welcome echo if we already kept the seed welcome.\n\t\t\t\t\tif (isAgentMsg(m) && keptAgentWelcome) continue;\n\t\t\t\t\tseen.add(m.id);\n\t\t\t\t\tmerged.push(m);\n\t\t\t\t}\n\t\t\t\tnextMessages.delete(oldId);\n\t\t\t\tnextMessages.set(newId, merged);\n\n\t\t\t\t// Dedupe conversation list — WS conversationCreated may have\n\t\t\t\t// prepended newId already; in that case drop the temp entry.\n\t\t\t\tconst hasNewId = state.conversations.some((c) => c.id === newId);\n\t\t\t\tconst conversations = hasNewId\n\t\t\t\t\t? state.conversations.filter((c) => c.id !== oldId)\n\t\t\t\t\t: state.conversations.map((c) => (c.id === oldId ? { ...c, id: newId } : c));\n\n\t\t\t\treturn {\n\t\t\t\t\tmessages: nextMessages,\n\t\t\t\t\tconversations,\n\t\t\t\t\tactiveConversationId:\n\t\t\t\t\t\tstate.activeConversationId === oldId ? newId : state.activeConversationId,\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\n\t\t// ── Presence ─────────────────────────────────────\n\n\t\tsetTyping(conversationId, isTyping) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.typingUsers);\n\t\t\t\tnext.set(conversationId, isTyping);\n\t\t\t\treturn { typingUsers: next };\n\t\t\t});\n\t\t},\n\n\t\tsetAiProcessing(conversationId, processing) {\n\t\t\tset((state) => {\n\t\t\t\tconst next = new Map(state.aiProcessing);\n\t\t\t\tnext.set(conversationId, processing);\n\t\t\t\treturn { aiProcessing: next };\n\t\t\t});\n\t\t},\n\n\t\t// ── Identity ─────────────────────────────────────\n\n\t\tupdateVisitorContact(contact) {\n\t\t\tset((state) => ({\n\t\t\t\tvisitor: state.visitor ? { ...state.visitor, contact } : state.visitor,\n\t\t\t}));\n\t\t},\n\n\t\t// ── Unread ───────────────────────────────────────\n\n\t\tclearUnread(conversationId) {\n\t\t\tset((s) => ({\n\t\t\t\tconversations: s.conversations.map((c) =>\n\t\t\t\t\tc.id === conversationId ? { ...c, unreadCount: 0 } : c,\n\t\t\t\t),\n\t\t\t}));\n\t\t},\n\n\t\t// ── UI ───────────────────────────────────────────\n\n\t\tsetOpen(open) {\n\t\t\tset((s) => ({\n\t\t\t\tisOpen: open,\n\t\t\t\tincomingPreview: open ? null : s.incomingPreview,\n\t\t\t}));\n\t\t},\n\n\t\tsetDismissed(dismissed) {\n\t\t\tset({ isDismissed: dismissed });\n\t\t},\n\n\t\tsetView(view) {\n\t\t\tset({ view });\n\t\t},\n\n\t\tsetNewConversationPrefill(text) {\n\t\t\tset({ newConversationPrefill: text });\n\t\t},\n\n\t\tdismissPreview() {\n\t\t\tset({ incomingPreview: null });\n\t\t},\n\n\t\t// ── Content Cache ────────────────────────────────\n\n\t\tsetContentCache(key, data) {\n\t\t\tget().contentCache.set(key, { data, ts: Date.now() });\n\t\t},\n\n\t\t// ── Realtime Event Handler ───────────────────────\n\n\t\thandleRealtimeEvent(event) {\n\t\t\tconst state = get();\n\n\t\t\tswitch (event.type) {\n\t\t\t\tcase \"timelineItemCreated\": {\n\t\t\t\t\t// Only add public messages (widget shouldn't see private notes)\n\t\t\t\t\tif (event.item.visibility === \"public\") {\n\t\t\t\t\t\t// When the widget seeded a local welcome bubble (openNewConversation)\n\t\t\t\t\t\t// the server's createConversation path ALSO emits its own welcome\n\t\t\t\t\t\t// timeline item. The *only* duplicate we care about is the opener:\n\t\t\t\t\t\t// a timeline that holds exactly the seed welcome and nothing else,\n\t\t\t\t\t\t// where an agent-authored WS event with a different id would\n\t\t\t\t\t\t// double-render. If the visitor has already sent a message (list\n\t\t\t\t\t\t// length ≥ 2), every incoming agent item is a genuine AI reply and\n\t\t\t\t\t\t// MUST be rendered — otherwise the visitor never sees the answer.\n\t\t\t\t\t\tconst isAgentAuthored =\n\t\t\t\t\t\t\t!!event.item.aiAgentId &&\n\t\t\t\t\t\t\t!event.item.visitorId &&\n\t\t\t\t\t\t\t!event.item.userId;\n\t\t\t\t\t\tconst existing = state.messages.get(event.conversationId);\n\t\t\t\t\t\tconst seedId = existing?.[0]?.id;\n\t\t\t\t\t\tconst isSeedWelcomeEcho =\n\t\t\t\t\t\t\tisAgentAuthored &&\n\t\t\t\t\t\t\t!!existing &&\n\t\t\t\t\t\t\texisting.length === 1 &&\n\t\t\t\t\t\t\ttypeof seedId === \"string\" &&\n\t\t\t\t\t\t\tseedId.startsWith(\"seed-welcome-\") &&\n\t\t\t\t\t\t\tseedId !== event.item.id;\n\t\t\t\t\t\tif (isSeedWelcomeEcho) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.addMessage(event.conversationId, event.item);\n\t\t\t\t\t}\n\t\t\t\t\t// Clear typing/processing indicators as soon as the AI message arrives\n\t\t\t\t\t// (don't wait for aiProcessingCompleted which comes later after auto-title etc.)\n\t\t\t\t\tif (event.item.aiAgentId) {\n\t\t\t\t\t\tstate.setAiProcessing(event.conversationId, false);\n\t\t\t\t\t\tstate.setTyping(event.conversationId, false);\n\t\t\t\t\t}\n\t\t\t\t\t// Update conversation preview + unread count\n\t\t\t\t\tif (event.item.type === \"message\" && event.item.text) {\n\t\t\t\t\t\tconst isIncoming = !event.item.visitorId; // team or AI message\n\t\t\t\t\t\tconst currentState = get();\n\t\t\t\t\t\tconst isViewingThis =\n\t\t\t\t\t\t\tcurrentState.isOpen && currentState.activeConversationId === event.conversationId;\n\n\t\t\t\t\t\tset((s) => ({\n\t\t\t\t\t\t\tconversations: s.conversations.map((c) =>\n\t\t\t\t\t\t\t\tc.id === event.conversationId\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t...c,\n\t\t\t\t\t\t\t\t\t\t\tlastMessageText: event.item.text,\n\t\t\t\t\t\t\t\t\t\t\tlastMessageAt: event.item.createdAt,\n\t\t\t\t\t\t\t\t\t\t\t// Increment unread if incoming and not actively viewing\n\t\t\t\t\t\t\t\t\t\t\t...(isIncoming && !isViewingThis ? { unreadCount: c.unreadCount + 1 } : {}),\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: c,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t// Show preview bubble if widget is closed and message is incoming\n\t\t\t\t\t\t\t...(isIncoming && !currentState.isOpen\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tincomingPreview: {\n\t\t\t\t\t\t\t\t\t\t\ttext: event.item.text ?? \"\",\n\t\t\t\t\t\t\t\t\t\t\tconversationId: event.conversationId,\n\t\t\t\t\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t}));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"conversationUpdated\": {\n\t\t\t\t\tset((s) => ({\n\t\t\t\t\t\tconversations: s.conversations.map((c) =>\n\t\t\t\t\t\t\tc.id === event.conversationId ? { ...c, ...event.updates } : c,\n\t\t\t\t\t\t),\n\t\t\t\t\t}));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"conversationTyping\": {\n\t\t\t\t\t// Only show typing for non-visitor (team/AI typing)\n\t\t\t\t\tif (!event.visitorId) {\n\t\t\t\t\t\tstate.setTyping(event.conversationId, event.isTyping);\n\t\t\t\t\t\t// Auto-clear after 5 seconds\n\t\t\t\t\t\tif (event.isTyping) {\n\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\tstate.setTyping(event.conversationId, false);\n\t\t\t\t\t\t\t}, 5000);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"aiProcessingProgress\": {\n\t\t\t\t\t// Track AI processing separately for distinct UI indicator\n\t\t\t\t\tstate.setAiProcessing(event.conversationId, true);\n\t\t\t\t\tstate.setTyping(event.conversationId, true);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"aiProcessingCompleted\": {\n\t\t\t\t\tstate.setAiProcessing(event.conversationId, false);\n\t\t\t\t\tstate.setTyping(event.conversationId, false);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase \"conversationCreated\": {\n\t\t\t\t\t// Race-safe insert: WS may arrive before OR after the HTTP\n\t\t\t\t\t// createConversation response. If after, remapConversationId\n\t\t\t\t\t// already renamed tempId → realId, so the entry exists.\n\t\t\t\t\t// If before, we prepend here; the later remap call hits the\n\t\t\t\t\t// `hasNewId=true` branch and drops the temp entry.\n\t\t\t\t\tconst conv = event.conversation as unknown as {\n\t\t\t\t\t\tid: string;\n\t\t\t\t\t\ttitle: string | null;\n\t\t\t\t\t\tstatus: string;\n\t\t\t\t\t\tlastMessageText?: string | null;\n\t\t\t\t\t\tlastMessageAt?: string | null;\n\t\t\t\t\t\tlastMessageSenderType?: string | null;\n\t\t\t\t\t};\n\t\t\t\t\tconst alreadyPresent = state.conversations.some((c) => c.id === conv.id);\n\t\t\t\t\tif (alreadyPresent) break;\n\t\t\t\t\tstate.addConversation({\n\t\t\t\t\t\tid: conv.id,\n\t\t\t\t\t\ttitle: conv.title,\n\t\t\t\t\t\tstatus: conv.status,\n\t\t\t\t\t\tlastMessageText: conv.lastMessageText ?? null,\n\t\t\t\t\t\tlastMessageAt: conv.lastMessageAt ?? null,\n\t\t\t\t\t\tlastMessageSenderType: conv.lastMessageSenderType ?? null,\n\t\t\t\t\t\tlastMessageSenderName: null,\n\t\t\t\t\t\tlastMessageSenderImage: null,\n\t\t\t\t\t\tassigneeName: null,\n\t\t\t\t\t\tassigneeImage: null,\n\t\t\t\t\t\tunreadCount: 0,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t}));\n}\n","import type { StoreApi } from \"zustand/vanilla\";\nimport type { Listener, WidgetEventEmitter, WidgetEventName, WidgetEvents } from \"./events\";\nimport type { WidgetStore } from \"./store\";\nimport { clearVisitorId } from \"./visitor-id\";\n\n/**\n * The programmatic widget API — all the methods consumers can call\n * once the widget is mounted. Returned by `createHelpwayAPI()`.\n *\n * The global `window.Helpway` is the *callable* wrapper around this\n * (see `HelpwayAPI` and `installCallable`).\n */\nexport interface HelpwayMethods {\n\t/** Open the widget panel */\n\topen(): void;\n\t/** Close the widget panel */\n\tclose(): void;\n\t/** Toggle the widget panel open/closed */\n\ttoggle(): void;\n\t/** Dismiss the widget entirely (launcher + panel). Use for page-specific hiding. */\n\tdismiss(): void;\n\t/** Show the widget again after dismiss */\n\tshow(): void;\n\t/** Full reset: clear session, cookies, visitor identity */\n\tshutdown(): void;\n\t/** Identify the visitor (link to contact) */\n\tidentify(data: {\n\t\texternalId: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}): Promise<void>;\n\t/** Open a new conversation, optionally pre-filling the message */\n\tnewConversation(prefill?: string): void;\n\t/** Open a specific conversation by ID */\n\topenConversation(id: string): void;\n\t/** Get the current unread count */\n\treadonly unreadCount: number;\n\t/** Whether the widget panel is currently open */\n\treadonly isOpen: boolean;\n\t/** Subscribe to widget events */\n\ton<K extends WidgetEventName>(event: K, fn: Listener<WidgetEvents[K]>): void;\n\t/** Unsubscribe from widget events */\n\toff<K extends WidgetEventName>(event: K, fn: Listener<WidgetEvents[K]>): void;\n}\n\n/**\n * The global `window.Helpway` shape: callable (Intercom-style snippet API)\n * AND object (typed methods). Build one of these from a `HelpwayMethods`\n * via `installCallable()`.\n */\nexport interface HelpwayAPI extends HelpwayMethods {\n\t(command: string, ...args: unknown[]): unknown;\n}\n\n/**\n * Install a callable wrapper around any methods object onto `window.Helpway`,\n * draining any calls that the snippet stub queued before the widget mounted.\n * Returns the callable so callers can compare identities on cleanup.\n *\n * Generic in `T` so both the rich `HelpwayMethods` (from widget-react) and\n * the slimmer script-tag API (from widget-embed) can use the same plumbing.\n */\nexport function installCallable<T extends object>(\n\tmethods: T,\n): T & ((command: string, ...args: unknown[]) => unknown) {\n\tconst dispatch = (command: string, ...args: unknown[]): unknown => {\n\t\tconst fn = (methods as unknown as Record<string, unknown>)[command];\n\t\tif (typeof fn === \"function\") {\n\t\t\treturn (fn as (...a: unknown[]) => unknown)(...args);\n\t\t}\n\t\tconsole.warn(`[Helpway] Unknown command: ${command}`);\n\t\treturn undefined;\n\t};\n\tconst callable = Object.assign(dispatch, methods);\n\tconst previous = window.Helpway as { q?: unknown[][] } | undefined;\n\twindow.Helpway = callable as unknown as HelpwayAPI;\n\tconst queue = previous?.q;\n\tif (queue?.length) {\n\t\tfor (const entry of queue) {\n\t\t\ttry {\n\t\t\t\tdispatch(...(entry as [string, ...unknown[]]));\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[Helpway] queued call failed:\", err);\n\t\t\t}\n\t\t}\n\t}\n\treturn callable;\n}\n\nexport function createHelpwayAPI(deps: {\n\tstore: StoreApi<WidgetStore>;\n\temitter: WidgetEventEmitter;\n\tidentify: (data: {\n\t\texternalId: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}) => Promise<void>;\n\tapiKey: string;\n}): HelpwayMethods {\n\tconst { store, emitter, identify, apiKey } = deps;\n\n\treturn {\n\t\topen() {\n\t\t\tstore.getState().setOpen(true);\n\t\t\tstore.getState().setDismissed(false);\n\t\t},\n\n\t\tclose() {\n\t\t\tstore.getState().setOpen(false);\n\t\t},\n\n\t\ttoggle() {\n\t\t\tconst s = store.getState();\n\t\t\tif (s.isDismissed) {\n\t\t\t\ts.setDismissed(false);\n\t\t\t\ts.setOpen(true);\n\t\t\t\temitter.emit(\"show\");\n\t\t\t} else {\n\t\t\t\ts.setOpen(!s.isOpen);\n\t\t\t}\n\t\t},\n\n\t\tdismiss() {\n\t\t\tstore.getState().setOpen(false);\n\t\t\tstore.getState().setDismissed(true);\n\t\t\temitter.emit(\"dismiss\");\n\t\t},\n\n\t\tshow() {\n\t\t\tstore.getState().setDismissed(false);\n\t\t\temitter.emit(\"show\");\n\t\t},\n\n\t\tshutdown() {\n\t\t\tstore.getState().setOpen(false);\n\t\t\tstore.getState().setDismissed(false);\n\t\t\tclearVisitorId(apiKey);\n\t\t\tif (typeof document !== \"undefined\") {\n\t\t\t\tdocument.cookie = \"hw_visitor=; Path=/; Max-Age=0\";\n\t\t\t}\n\t\t},\n\n\t\tidentify,\n\n\t\tnewConversation(prefill?: string) {\n\t\t\tconst s = store.getState();\n\t\t\ts.setDismissed(false);\n\t\t\ts.setOpen(true);\n\t\t\ts.setNewConversationPrefill(prefill ?? \"\");\n\t\t},\n\n\t\topenConversation(id: string) {\n\t\t\tconst s = store.getState();\n\t\t\ts.setDismissed(false);\n\t\t\ts.setActiveConversation(id);\n\t\t\ts.setOpen(true);\n\t\t},\n\n\t\tget unreadCount() {\n\t\t\treturn store.getState().conversations.reduce((sum, c) => sum + c.unreadCount, 0);\n\t\t},\n\n\t\tget isOpen() {\n\t\t\treturn store.getState().isOpen;\n\t\t},\n\n\t\ton(event, fn) {\n\t\t\temitter.on(event, fn);\n\t\t},\n\n\t\toff(event, fn) {\n\t\t\temitter.off(event, fn);\n\t\t},\n\t};\n}\n","/**\n * Widget theming — typed surface over the CSS custom properties baked\n * into the default themed widget. Consumers pass a `WidgetTheme` object;\n * `applyTheme` writes the values onto the host element so the cascade\n * picks them up inside the Shadow DOM.\n *\n * Common cases (color, position, radius) get their own first-class\n * fields. Anything else can still be set via `cssVariables` — it's a\n * raw passthrough for custom var names we don't model yet.\n *\n * **Note for SDK consumers:** prefer dashboard-driven theming when you\n * can — changes go live without a redeploy. This API is for runtime-\n * resolved values (multi-tenant, dark/light sync with the host app).\n *\n * @see https://helpway.ai/docs/customization for the full reference,\n * the dashboard config UI, and the multi-tenant example.\n */\n\nexport type WidgetPosition = \"bottom-right\" | \"bottom-left\";\n\nexport interface WidgetTheme {\n\t/** Launcher background + accent color. Hover variant is auto-derived. */\n\tprimaryColor?: string;\n\t/** Text/icon color rendered ON TOP of `primaryColor`. Defaults to white. */\n\tonPrimaryColor?: string;\n\t/** Visitor (outgoing) message bubble background. Defaults to `primaryColor`. */\n\tbubbleColor?: string;\n\t/** Visitor message bubble text color. Defaults to `onPrimaryColor`. */\n\tbubbleTextColor?: string;\n\t/** Widget panel background color. */\n\tbackgroundColor?: string;\n\t/** Widget panel text color. */\n\ttextColor?: string;\n\t/** Border color used inside the panel. */\n\tborderColor?: string;\n\t/** Corner radius for the panel + cards (any valid CSS length). */\n\tradius?: string;\n\t/** Font family stack for everything inside the widget. */\n\tfontFamily?: string;\n\t/** Launcher + panel placement. Defaults to \"bottom-right\". */\n\tposition?: WidgetPosition;\n\t/**\n\t * Escape hatch: any CSS custom property not modeled above. Keys must\n\t * start with `--`. Wins over the typed fields above when both set.\n\t */\n\tcssVariables?: Record<`--${string}`, string>;\n}\n\n/** Validate a hex like `#aabbcc`. We're conservative on purpose. */\nfunction isValidHex(color: string): boolean {\n\treturn /^#[0-9a-fA-F]{6}$/.test(color);\n}\n\n/**\n * Lighten a #rrggbb hex by a fixed amount (used as the hover variant\n * of `primaryColor`). Non-hex inputs return unchanged so callers can\n * pass `oklch(...)`, `hsl(...)`, etc. and bring their own hover.\n */\nfunction lighten(hex: string): string {\n\tif (!isValidHex(hex)) return hex;\n\tconst r = Math.min(255, Number.parseInt(hex.slice(1, 3), 16) + 30);\n\tconst g = Math.min(255, Number.parseInt(hex.slice(3, 5), 16) + 30);\n\tconst b = Math.min(255, Number.parseInt(hex.slice(5, 7), 16) + 30);\n\tconst hex2 = (n: number) => n.toString(16).padStart(2, \"0\");\n\treturn `#${hex2(r)}${hex2(g)}${hex2(b)}`;\n}\n\n/** Map a single typed field onto its CSS variable(s). */\nfunction setVar(host: HTMLElement, name: string, value: string | undefined) {\n\tif (value == null || value === \"\") return;\n\thost.style.setProperty(name, value);\n}\n\n/**\n * Write a `WidgetTheme` onto the host element. Safe to call multiple\n * times — every call is incremental, only the keys you provide are\n * touched. Pass `undefined` for a field to leave the existing value alone;\n * call `clearTheme()` if you want to reset.\n */\nexport function applyTheme(host: HTMLElement, theme: WidgetTheme | undefined) {\n\tif (!host || !theme) return;\n\n\tif (theme.primaryColor) {\n\t\tsetVar(host, \"--hw-primary\", theme.primaryColor);\n\t\tsetVar(host, \"--hw-primary-hover\", lighten(theme.primaryColor));\n\t\tsetVar(host, \"--hw-brand\", theme.primaryColor);\n\t}\n\tsetVar(host, \"--hw-on-brand\", theme.onPrimaryColor);\n\tsetVar(host, \"--hw-visitor-bubble-bg\", theme.bubbleColor ?? theme.primaryColor);\n\tsetVar(host, \"--hw-visitor-bubble-text\", theme.bubbleTextColor ?? theme.onPrimaryColor);\n\tsetVar(host, \"--hw-bg\", theme.backgroundColor);\n\tsetVar(host, \"--hw-text\", theme.textColor);\n\tsetVar(host, \"--hw-border\", theme.borderColor);\n\tsetVar(host, \"--hw-radius\", theme.radius);\n\tsetVar(host, \"--hw-font\", theme.fontFamily);\n\n\tif (theme.position === \"bottom-left\") {\n\t\tsetVar(host, \"--hw-position-right\", \"auto\");\n\t\tsetVar(host, \"--hw-position-left\", \"20px\");\n\t\tsetVar(host, \"--hw-window-right\", \"auto\");\n\t\tsetVar(host, \"--hw-window-left\", \"0\");\n\t} else if (theme.position === \"bottom-right\") {\n\t\thost.style.removeProperty(\"--hw-position-right\");\n\t\thost.style.removeProperty(\"--hw-position-left\");\n\t\thost.style.removeProperty(\"--hw-window-right\");\n\t\thost.style.removeProperty(\"--hw-window-left\");\n\t}\n\n\tif (theme.cssVariables) {\n\t\tfor (const [key, value] of Object.entries(theme.cssVariables)) {\n\t\t\tif (key.startsWith(\"--\")) host.style.setProperty(key, value);\n\t\t}\n\t}\n}\n","export type Listener<T = unknown> = (data: T) => void;\n\nexport interface WidgetEvents {\n\topen: undefined;\n\tclose: undefined;\n\tdismiss: undefined;\n\tshow: undefined;\n\tunreadChange: number;\n\tmessageReceived: { conversationId: string; text: string; senderName: string | null };\n\tready: undefined;\n}\n\nexport type WidgetEventName = keyof WidgetEvents;\n\nexport class WidgetEventEmitter {\n\tprivate listeners = new Map<string, Set<Listener>>();\n\n\ton<K extends WidgetEventName>(event: K, fn: Listener<WidgetEvents[K]>): void {\n\t\tif (!this.listeners.has(event)) this.listeners.set(event, new Set());\n\t\tthis.listeners.get(event)!.add(fn as Listener);\n\t}\n\n\toff<K extends WidgetEventName>(event: K, fn: Listener<WidgetEvents[K]>): void {\n\t\tthis.listeners.get(event)?.delete(fn as Listener);\n\t}\n\n\temit<K extends WidgetEventName>(\n\t\tevent: K,\n\t\t...args: WidgetEvents[K] extends undefined ? [] : [WidgetEvents[K]]\n\t): void {\n\t\tconst data = args[0];\n\t\tthis.listeners.get(event)?.forEach((fn) => {\n\t\t\ttry {\n\t\t\t\tfn(data);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`[Helpway] Event handler error (${event}):`, err);\n\t\t\t}\n\t\t});\n\t}\n\n\tremoveAll(): void {\n\t\tthis.listeners.clear();\n\t}\n}\n","/**\n * Widget i18n — lightweight, zero-dependency translation system.\n *\n * Architecture:\n * - English strings bundled as fallback (zero-latency, always works)\n * - Other locales fetched from Better i18n CDN at runtime\n * - Locale detection: data-locale > identify metadata > navigator.language > \"en\"\n * - Simple key-value lookup with t(\"widget.key\") syntax\n *\n * CDN URL: https://cdn.better-i18n.com/helpway/widget/{locale}/translations.json\n */\n\n// ── Bundled English fallback strings ────────────────────────\n\nconst en: Record<string, string> = {\n\t// Navigation & tabs\n\t\"widget.home\": \"Home\",\n\t\"widget.messages\": \"Messages\",\n\t\"widget.help\": \"Help\",\n\n\t// Home screen\n\t\"widget.send_us_message\": \"Send us a message\",\n\t\"widget.reply_time\": \"We typically reply in a few minutes\",\n\t\"widget.recent_conversations\": \"Recent conversations\",\n\t\"widget.see_all\": \"See all conversations\",\n\n\t// Messages tab\n\t\"widget.no_messages\": \"No messages yet\",\n\t\"widget.no_messages_desc\": \"Start a conversation to get help\",\n\t\"widget.start_conversation\": \"Start a conversation\",\n\t\"widget.no_preview\": \"No messages yet\",\n\n\t// Conversation\n\t\"widget.new_conversation\": \"New conversation\",\n\t\"widget.resolved_text\": \"This conversation has been resolved\",\n\t\"widget.send_followup\": \"Send a follow-up\",\n\t\"widget.start_a_conversation\": \"Start a conversation\",\n\n\t// Composer\n\t\"widget.placeholder\": \"Send a message...\",\n\t\"widget.placeholder_new\": \"How can we help?\",\n\t\"widget.drop_files\": \"Drop files here\",\n\n\t// CSAT\n\t\"widget.csat_label\": \"How was your experience?\",\n\t\"widget.csat_thanks\": \"Thanks for your feedback!\",\n\n\t// Inline email collection (after AI reply)\n\t\"widget.email_title\": \"Stay in the loop\",\n\t\"widget.email_subtitle\": \"Get notified when we reply\",\n\t\"widget.email_placeholder\": \"you@email.com\",\n\t\"widget.email_continue\": \"Notify me\",\n\t\"widget.email_saved\": \"You'll be notified by email\",\n\t\"widget.email_dismiss\": \"No thanks\",\n\n\t// Errors\n\t\"widget.error_title\": \"Something went wrong\",\n\t\"widget.error_desc\": \"Failed to load. Please try again.\",\n\t\"widget.retry\": \"Retry\",\n\t\"widget.reconnecting\": \"Reconnecting...\",\n\t\"widget.send_error\": \"Message not sent\",\n\n\t// Date separators (today is implicit — never rendered)\n\t\"widget.yesterday\": \"Yesterday\",\n\n\t// Sender labels\n\t\"widget.helpway_ai\": \"Helpway AI\",\n\t\"widget.support\": \"Support\",\n\n\t// Events\n\t\"widget.joined\": \"joined the conversation\",\n\t\"widget.left\": \"left the conversation\",\n\n\t// Content/search\n\t\"widget.content\": \"Content\",\n\t\"widget.search\": \"Search...\",\n\t\"widget.no_results\": \"No results found\",\n\t\"widget.try_different\": \"Try a different search term\",\n\t\"widget.nothing_yet\": \"Nothing here yet\",\n\t\"widget.check_back\": \"Check back later for updates\",\n\t\"widget.load_more\": \"Load more\",\n\t\"widget.loading\": \"Loading...\",\n\n\t// Copy\n\t\"widget.copy\": \"Copy message\",\n\t\"widget.copied\": \"Copied\",\n\n\t// File upload\n\t\"widget.file_too_large\": \"File too large (max 10 MB)\",\n\t\"widget.click_to_open\": \"Click to open\",\n\t\"widget.caption_required\": \"Add a message to send with your attachment\",\n\n\t// Accessibility\n\t\"widget.aria_chat\": \"Support chat\",\n\t\"widget.aria_close\": \"Close\",\n\t\"widget.aria_back\": \"Back\",\n\t\"widget.aria_send\": \"Send message\",\n\t\"widget.aria_attach\": \"Attach file\",\n\t\"widget.aria_input\": \"Message input\",\n\t\"widget.aria_remove\": \"Remove\",\n\t\"widget.aria_dismiss\": \"Dismiss\",\n\t\"widget.aria_open\": \"Open support\",\n\t\"widget.aria_close_support\": \"Close support\",\n\t\"widget.aria_good\": \"Good\",\n\t\"widget.aria_bad\": \"Bad\",\n\t\"widget.aria_messages\": \"Messages\",\n\n\t// Time (relative)\n\t\"widget.time_now\": \"now\",\n\t\"widget.time_yesterday\": \"Yesterday\",\n\n\t// Powered by\n\t\"widget.powered_by\": \"Powered by\",\n\n\t// Hero / home screen\n\t\"widget.welcome_message\": \"Hi there 👋\\nHow can we help?\",\n\t\"widget.subtitle_text\": \"Usually replies in minutes\",\n};\n\n// ── State ───────────────────────────────────────────────────\n\nlet currentLocale = \"en\";\nlet translations: Record<string, string> = {};\nlet isLoaded = false;\nlet revision = 0; // Incremented on every translation change — React hook watches this\nconst listeners: Array<() => void> = [];\n\n// ── Public API ──────────────────────────────────────────────\n\n/**\n * Translate a key. Falls back to English bundled string, then to the key itself.\n *\n * Supports simple interpolation: t(\"widget.key\", { name: \"John\" })\n * Template: \"Hello {{name}}\" → \"Hello John\"\n */\nexport function t(key: string, params?: Record<string, string | number>): string {\n\tconst value = translations[key] ?? en[key] ?? key;\n\n\tif (!params) return value;\n\n\treturn value.replace(/\\{\\{(\\w+)\\}\\}/g, (_, k: string) => {\n\t\treturn params[k]?.toString() ?? `{{${k}}}`;\n\t});\n}\n\n/** Get the current locale code */\nexport function getLocale(): string {\n\treturn currentLocale;\n}\n\n/** Get current revision number — changes when translations are loaded/updated */\nexport function getI18nRevision(): number {\n\treturn revision;\n}\n\n/** Check if translations have been loaded */\nexport function isI18nReady(): boolean {\n\treturn isLoaded;\n}\n\n/** Subscribe to locale/translation changes. Returns unsubscribe fn. */\nexport function onLocaleChange(fn: () => void): () => void {\n\tlisteners.push(fn);\n\treturn () => {\n\t\tconst idx = listeners.indexOf(fn);\n\t\tif (idx >= 0) listeners.splice(idx, 1);\n\t};\n}\n\n// ── Initialization ──────────────────────────────────────────\n\n/**\n * Detect locale from available signals and fetch translations.\n *\n * Priority:\n * 1. Explicit `locale` param (from data-locale attribute)\n * 2. navigator.language (browser preference)\n * 3. \"en\" fallback\n */\nexport async function initI18n(options?: { locale?: string; cdnBase?: string }): Promise<void> {\n\tif (options?.cdnBase) {\n\t\tcdnBase = options.cdnBase;\n\t}\n\n\tconst detected =\n\t\toptions?.locale ?? (typeof navigator !== \"undefined\" ? navigator.language : \"en\");\n\n\t// Normalize: \"fr-FR\" → \"fr\", \"pt-BR\" → \"pt-BR\" (keep regional if meaningful)\n\tcurrentLocale = normalizeLocale(detected);\n\n\t// English is bundled — no fetch needed\n\tif (currentLocale === \"en\") {\n\t\tisLoaded = true;\n\t\tnotify();\n\t\treturn;\n\t}\n\n\t// Fetch from CDN\n\ttry {\n\t\tconst data = await fetchTranslations(currentLocale);\n\t\tif (data) {\n\t\t\t// Only pick widget.* keys from the full namespace bundle\n\t\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttranslations[`widget.${key}`] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (err) {\n\t\tconsole.warn(`[Helpway] Failed to fetch ${currentLocale} translations, using English`, err);\n\t}\n\n\tisLoaded = true;\n\tnotify();\n}\n\n/**\n * Update locale at runtime (e.g., after identify() provides metadata.locale).\n * Re-fetches translations if locale changed.\n */\nexport async function setLocale(locale: string): Promise<void> {\n\tconst normalized = normalizeLocale(locale);\n\tif (normalized === currentLocale) return;\n\n\tcurrentLocale = normalized;\n\ttranslations = {}; // Clear old translations\n\n\tif (normalized === \"en\") {\n\t\tnotify();\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst data = await fetchTranslations(normalized);\n\t\tif (data) {\n\t\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttranslations[`widget.${key}`] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Silent fallback to English\n\t}\n\n\tnotify();\n}\n\n// ── Internals ───────────────────────────────────────────────\n\nlet cdnBase = \"https://cdn.better-i18n.com/helpway/widget\";\n\nasync function fetchTranslations(locale: string): Promise<Record<string, string> | null> {\n\t// All namespaces live in a single translations.json — widget keys nested under \"widget\" key\n\tconst url = `${cdnBase}/${locale}/translations.json`;\n\n\tlet res = await fetch(url);\n\tif (!res.ok && locale.includes(\"-\")) {\n\t\t// Try base locale: \"pt-BR\" → \"pt\"\n\t\tconst base = locale.split(\"-\")[0];\n\t\tres = await fetch(`${cdnBase}/${base}/translations.json`);\n\t}\n\tif (!res.ok) return null;\n\n\tconst data: Record<string, unknown> = await res.json();\n\t// CDN structure is nested: { \"widget\": { \"home\": \"Ana Sayfa\", ... }, \"sidebar\": {...} }\n\tconst widgetNs = data.widget;\n\tif (widgetNs && typeof widgetNs === \"object\" && !Array.isArray(widgetNs)) {\n\t\tconst result: Record<string, string> = {};\n\t\tfor (const [k, v] of Object.entries(widgetNs)) {\n\t\t\tif (typeof v === \"string\") result[k] = v;\n\t\t}\n\t\treturn result;\n\t}\n\treturn null;\n}\n\nfunction normalizeLocale(input: string): string {\n\t// Keep regional variants that are commonly distinct: pt-BR, zh-CN, zh-TW\n\tconst regional = [\"pt-br\", \"zh-cn\", \"zh-tw\", \"zh-hk\"];\n\tconst lower = input.toLowerCase().replace(\"_\", \"-\");\n\n\tfor (const r of regional) {\n\t\tif (lower.startsWith(r)) return r;\n\t}\n\n\t// Otherwise just use base: \"fr-FR\" → \"fr\"\n\treturn lower.split(\"-\")[0] ?? \"en\";\n}\n\nfunction notify(): void {\n\trevision++;\n\tfor (const fn of listeners) {\n\t\ttry {\n\t\t\tfn();\n\t\t} catch {\n\t\t\t/* ignore */\n\t\t}\n\t}\n}\n","import { t, getLocale } from \"./i18n\";\n\n/**\n * Format a date as relative time string.\n * Uses i18n for \"now\" and \"Yesterday\". Locale-aware date formatting.\n */\nexport function formatRelativeTime(date: string | Date): string {\n\tconst now = Date.now();\n\tconst then = typeof date === \"string\" ? new Date(date).getTime() : date.getTime();\n\tconst diffMs = now - then;\n\tconst diffMin = Math.floor(diffMs / 60000);\n\tconst diffHour = Math.floor(diffMs / 3600000);\n\tconst diffDay = Math.floor(diffMs / 86400000);\n\n\tif (diffMin < 1) return t(\"widget.time_now\");\n\tif (diffMin < 60) return `${diffMin}m`;\n\tif (diffHour < 24) return `${diffHour}h`;\n\tif (diffDay === 1) return t(\"widget.time_yesterday\");\n\tif (diffDay < 7) return `${diffDay}d`;\n\n\tconst d = typeof date === \"string\" ? new Date(date) : date;\n\treturn d.toLocaleDateString(getLocale(), { month: \"short\", day: \"numeric\" });\n}\n\n/**\n * Format time for message bubbles (HH:MM).\n */\nexport function formatTime(date: string | Date): string {\n\tconst d = typeof date === \"string\" ? new Date(date) : date;\n\treturn d.toLocaleTimeString(undefined, { hour: \"2-digit\", minute: \"2-digit\" });\n}\n\n/**\n * Resolve a label that may be a translation key (\"widget.*\") or plain text.\n * When the key resolves to itself (missing), falls back to a humanized form\n * so the UI never leaks raw \"widget.changelog\" strings to the visitor.\n */\nexport function resolveLabel(label: string): string {\n\tif (!label.startsWith(\"widget.\")) return label;\n\tconst resolved = t(label);\n\tif (resolved === label) {\n\t\treturn label\n\t\t\t.replace(\"widget.\", \"\")\n\t\t\t.replace(/_/g, \" \")\n\t\t\t.replace(/^\\w/, (c) => c.toUpperCase());\n\t}\n\treturn resolved;\n}\n\n/**\n * Get initials from a name or email.\n */\nexport function getInitials(value: string): string {\n\tif (!value) return \"?\";\n\n\t// Email: take first letter\n\tif (value.includes(\"@\")) return (value[0] ?? \"?\").toUpperCase();\n\n\t// Name: take first letter of first two words\n\tconst parts = value.trim().split(/\\s+/);\n\tif (parts.length >= 2) {\n\t\treturn ((parts[0]?.[0] ?? \"\") + (parts[1]?.[0] ?? \"\")).toUpperCase();\n\t}\n\treturn (parts[0]?.[0] ?? \"?\").toUpperCase();\n}\n","\"use client\";\n\nimport {\n\tWebSocketManager,\n\tWidgetEventEmitter,\n\ttype HelpwayMethods,\n\ttype WidgetClient,\n\ttype WidgetStore,\n\ttype WidgetTheme,\n\tapplyTheme,\n\tcreateHelpwayAPI,\n\tcreateWidgetClient,\n\tcreateWidgetStore,\n\tinitI18n,\n\tinstallCallable,\n\tsetLocale,\n\tsyncVisitorId,\n} from \"@helpway/widget-core\";\nimport {\n\ttype ReactNode,\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { type StoreApi, useStore } from \"zustand\";\n\n// ── Context ──────────────────────────────────────────────\n\nexport interface IdentifyData {\n\texternalId: string;\n\temail?: string;\n\tname?: string;\n\timage?: string;\n\tmetadata?: Record<string, unknown>;\n}\n\ninterface WidgetContextValue {\n\tclient: WidgetClient;\n\tstore: StoreApi<WidgetStore>;\n\tws: WebSocketManager;\n\tidentify: (data: IdentifyData) => Promise<void>;\n\tapi: HelpwayMethods;\n\temitter: WidgetEventEmitter;\n\thasBootstrapError: boolean;\n\twsDisconnected: boolean;\n\tretryBootstrap: () => void;\n}\n\nconst WidgetContext = createContext<WidgetContextValue | null>(null);\n\nexport function useWidgetContext(): WidgetContextValue {\n\tconst ctx = useContext(WidgetContext);\n\tif (!ctx) {\n\t\tthrow new Error(\"useWidgetContext must be used within <SupportProvider>\");\n\t}\n\treturn ctx;\n}\n\n/** Use a slice of the widget store with auto re-render */\nexport function useWidgetStore<T>(selector: (state: WidgetStore) => T): T {\n\tconst { store } = useWidgetContext();\n\treturn useStore(store, selector);\n}\n\n/** Hook to identify the current visitor (link to customer contact) */\nexport function useIdentify() {\n\tconst { identify } = useWidgetContext();\n\treturn identify;\n}\n\n/** Raw tRPC client — used by interactive components that need to call\n * mutations not exposed via the public HelpwayMethods (e.g. workflow\n * quick-reply taps). The client is `any`-typed by design (see\n * packages/widget-core/src/client.ts) so callers must spell mutation\n * paths explicitly. */\nexport function useWidgetClient(): WidgetClient {\n\tconst { client } = useWidgetContext();\n\treturn client;\n}\n\n// ── Provider ─────────────────────────────────────────────\n\ninterface SupportProviderProps {\n\tapiKey: string;\n\tapiUrl?: string;\n\tlocale?: string;\n\tinitialConversationId?: string;\n\tonReady?: (api: HelpwayMethods) => void;\n\tcustomLauncherSelector?: string;\n\tonOpen?: () => void;\n\tonClose?: () => void;\n\tonUnreadChange?: (count: number) => void;\n\t/**\n\t * Developer-side theme override. Most consumers should configure\n\t * appearance in the Helpway dashboard (see\n\t * https://helpway.ai/docs/customization) so changes apply without\n\t * a redeploy. Use this prop only when you need the widget to inherit\n\t * a host-app theme that the dashboard can't see (e.g. a tenant-\n\t * specific brand color resolved at runtime). Values here are written\n\t * as CSS custom properties on the widget host and override the\n\t * dashboard config for this mount only.\n\t */\n\ttheme?: WidgetTheme;\n\tchildren: ReactNode;\n}\n\n/**\n * Root provider for the Helpway widget.\n * Creates tRPC client, WebSocket connection, and state store.\n *\n * Visitor identity is managed via server-side cookies (hw_visitor).\n * No localStorage or client-side ID management needed.\n */\nexport function SupportProvider({\n\tapiKey,\n\tapiUrl,\n\tlocale,\n\tinitialConversationId,\n\tonReady,\n\tcustomLauncherSelector,\n\tonOpen,\n\tonClose,\n\tonUnreadChange,\n\ttheme,\n\tchildren,\n}: SupportProviderProps) {\n\tconst initRef = useRef<{\n\t\tclient: WidgetClient;\n\t\tstore: StoreApi<WidgetStore>;\n\t\tws: WebSocketManager;\n\t\tidentify: (data: IdentifyData) => Promise<void>;\n\t\tapi: HelpwayMethods;\n\t\temitter: WidgetEventEmitter;\n\t} | null>(null);\n\tconst [hasBootstrapError, setHasBootstrapError] = useState(false);\n\tconst [wsDisconnected, setWsDisconnected] = useState(false);\n\tconst [bootstrapAttempt, setBootstrapAttempt] = useState(0);\n\n\tif (!initRef.current) {\n\t\tconst resolvedApiUrl = apiUrl ?? inferApiUrl();\n\n\t\tconst client = createWidgetClient({\n\t\t\tapiUrl: resolvedApiUrl,\n\t\t\tapiKey,\n\t\t});\n\n\t\tconst store = createWidgetStore();\n\t\tconst emitter = new WidgetEventEmitter();\n\n\t\tconst ws = new WebSocketManager({\n\t\t\tapiUrl: resolvedApiUrl,\n\t\t\tvisitorId: \"\",\n\t\t\twebsiteId: \"\",\n\t\t});\n\n\t\tconst identify = async (data: IdentifyData) => {\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.identify.mutate(data);\n\t\t\t\tif (result.contact) {\n\t\t\t\t\tstore.getState().updateVisitorContact({\n\t\t\t\t\t\tid: result.contact.id,\n\t\t\t\t\t\tname: result.contact.name ?? null,\n\t\t\t\t\t\temail: result.contact.email ?? null,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst metaLocale = data.metadata?.locale;\n\t\t\t\tif (typeof metaLocale === \"string\" && metaLocale.length > 0) {\n\t\t\t\t\tsetLocale(metaLocale);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[Helpway] identify failed:\", err);\n\t\t\t}\n\t\t};\n\n\t\tconst api = createHelpwayAPI({ store, emitter, identify, apiKey });\n\n\t\tinitRef.current = { client, store, ws, identify, api, emitter };\n\t}\n\n\tconst { client, store, ws, identify, api, emitter } = initRef.current;\n\n\tconst retryBootstrap = useCallback(() => {\n\t\tsetHasBootstrapError(false);\n\t\tsetBootstrapAttempt((n) => n + 1);\n\t}, []);\n\n\t// Bootstrap on mount (re-runs on retry)\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tasync function bootstrap() {\n\t\t\ttry {\n\t\t\t\tconst data = await client.widget.bootstrap.query();\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\t// Initialize i18n BEFORE setReady to avoid flash of English text.\n\t\t\t\t// Priority: explicit `locale` prop → server-side detection\n\t\t\t\t// (Accept-Language + CF-IPCountry) → widget-core bundled default.\n\t\t\t\tconst resolvedLocale =\n\t\t\t\t\tlocale ?? (data as { detectedLocale?: string | null }).detectedLocale ?? undefined;\n\t\t\t\tawait initI18n({\n\t\t\t\t\tlocale: resolvedLocale,\n\t\t\t\t\tcdnBase: (data.agentConfig as { i18nCdnBase?: string } | null)?.i18nCdnBase ?? undefined,\n\t\t\t\t});\n\n\t\t\t\tstore.getState().setReady(data.visitor, data.website, data.agentConfig);\n\t\t\t\tsetHasBootstrapError(false);\n\n\t\t\t\t// Sync server-assigned visitor ID to localStorage\n\t\t\t\t// Ensures client uses canonical ID on subsequent page loads\n\t\t\t\tif (data.visitor?.id) {\n\t\t\t\t\tsyncVisitorId(apiKey, data.visitor.id);\n\t\t\t\t}\n\n\t\t\t\tconst convData = await client.widget.listConversations.query();\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\tconst mapConversation = (c: {\n\t\t\t\t\tid: string;\n\t\t\t\t\ttitle: string | null;\n\t\t\t\t\tstatus: string;\n\t\t\t\t\tlastMessageText: string | null;\n\t\t\t\t\tlastMessageAt: string | null;\n\t\t\t\t\tlastMessageSenderType: string | null;\n\t\t\t\t\tlastMessageSenderName: string | null;\n\t\t\t\t\tlastMessageSenderImage: string | null;\n\t\t\t\t}) => ({\n\t\t\t\t\tid: c.id,\n\t\t\t\t\ttitle: c.title,\n\t\t\t\t\tstatus: c.status,\n\t\t\t\t\tlastMessageText: c.lastMessageText,\n\t\t\t\t\tlastMessageAt: c.lastMessageAt,\n\t\t\t\t\tlastMessageSenderType: c.lastMessageSenderType,\n\t\t\t\t\tlastMessageSenderName: c.lastMessageSenderName,\n\t\t\t\t\tlastMessageSenderImage: c.lastMessageSenderImage,\n\t\t\t\t\tunreadCount: 0,\n\t\t\t\t});\n\n\t\t\t\tstore.getState().setConversations(\n\t\t\t\t\tconvData.conversations.map(mapConversation),\n\t\t\t\t);\n\n\t\t\t\t// Connect WebSocket BEFORE the proactive check so the visitor-channel\n\t\t\t\t// subscription is live by the time the workflow orchestrator emits\n\t\t\t\t// timelineItemCreated. Without this, the greeting message is broadcast\n\t\t\t\t// to a not-yet-subscribed client and the launcher preview bubble never\n\t\t\t\t// appears (only the unread badge increments via REST).\n\t\t\t\tif (data.website?.id && data.visitor?.id) {\n\t\t\t\t\tws.configure({ websiteId: data.website.id, visitorId: data.visitor.id });\n\t\t\t\t\tws.connect();\n\t\t\t\t}\n\n\t\t\t\tif (convData.conversations.length === 0 && !initialConversationId) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst proactive = await client.widget.proactiveCheck.mutate();\n\t\t\t\t\t\tif (cancelled || !proactive.triggered) {\n\t\t\t\t\t\t\t// nothing to do\n\t\t\t\t\t\t} else if (proactive.ephemeral) {\n\t\t\t\t\t\t\t// Render the greeting + (optional) quick replies entirely\n\t\t\t\t\t\t\t// client-side. No server-side conversation exists yet — we\n\t\t\t\t\t\t\t// materialize on the visitor's first reply.\n\t\t\t\t\t\t\thandleEphemeralProactive(store, proactive.ephemeral);\n\t\t\t\t\t\t} else if (proactive.conversationId) {\n\t\t\t\t\t\t\t// Fallback path for complex workflows that needed the\n\t\t\t\t\t\t\t// orchestrator up-front (delays, AI agent before any\n\t\t\t\t\t\t\t// visitor input, etc).\n\t\t\t\t\t\t\tconst nowIso = new Date().toISOString();\n\t\t\t\t\t\t\tstore.getState().addConversation({\n\t\t\t\t\t\t\t\tid: proactive.conversationId,\n\t\t\t\t\t\t\t\ttitle: null,\n\t\t\t\t\t\t\t\tstatus: \"open\",\n\t\t\t\t\t\t\t\tlastMessageText: proactive.lastMessageText ?? null,\n\t\t\t\t\t\t\t\tlastMessageAt: proactive.lastMessageAt ?? nowIso,\n\t\t\t\t\t\t\t\tlastMessageSenderType: proactive.lastMessageSenderType ?? null,\n\t\t\t\t\t\t\t\tlastMessageSenderName: null,\n\t\t\t\t\t\t\t\tlastMessageSenderImage: null,\n\t\t\t\t\t\t\t\tassigneeName: null,\n\t\t\t\t\t\t\t\tassigneeImage: null,\n\t\t\t\t\t\t\t\tunreadCount: 1,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tif (proactive.lastMessageText && !store.getState().isOpen) {\n\t\t\t\t\t\t\t\tstore.setState({\n\t\t\t\t\t\t\t\t\tincomingPreview: {\n\t\t\t\t\t\t\t\t\t\ttext: proactive.lastMessageText,\n\t\t\t\t\t\t\t\t\t\tconversationId: proactive.conversationId,\n\t\t\t\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// proactive check is best-effort\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (typeof window !== \"undefined\") {\n\t\t\t\t\tclient.widget.updatePage\n\t\t\t\t\t\t.mutate({\n\t\t\t\t\t\t\turl: window.location.href,\n\t\t\t\t\t\t\ttitle: document.title || window.location.pathname,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch(() => {});\n\t\t\t\t}\n\n\t\t\t\tif (initialConversationId && !cancelled) {\n\t\t\t\t\tstore.getState().setActiveConversation(initialConversationId);\n\t\t\t\t\tstore.getState().setOpen(true);\n\t\t\t\t}\n\n\t\t\t\temitter.emit(\"ready\");\n\t\t\t\tonReady?.(initRef.current!.api);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[Helpway] Bootstrap failed:\", err);\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tstore.getState().setConnecting(false);\n\t\t\t\t\tsetHasBootstrapError(true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbootstrap();\n\n\t\t// Debounced markSeen — coalesces rapid events (AI may stream multiple\n\t\t// messages, plus the typing/processing events fire too).\n\t\tlet markSeenTimer: ReturnType<typeof setTimeout> | null = null;\n\t\tconst scheduleMarkSeen = (conversationId: string) => {\n\t\t\tif (markSeenTimer) clearTimeout(markSeenTimer);\n\t\t\tmarkSeenTimer = setTimeout(() => {\n\t\t\t\tclient.widget.markSeen.mutate({ conversationId }).catch(() => {});\n\t\t\t\tstore.getState().clearUnread(conversationId);\n\t\t\t}, 400);\n\t\t};\n\n\t\tconst unsub = ws.onEvent((event) => {\n\t\t\tstore.getState().handleRealtimeEvent(event);\n\n\t\t\tif (event.type === \"timelineItemCreated\") {\n\t\t\t\tconst item = event.item;\n\t\t\t\tconst isPublicIncoming = item?.visibility === \"public\" && !item.visitorId;\n\n\t\t\t\t// Emit messageReceived for public incoming messages\n\t\t\t\tif (isPublicIncoming && item?.text) {\n\t\t\t\t\temitter.emit(\"messageReceived\", {\n\t\t\t\t\t\tconversationId: event.conversationId,\n\t\t\t\t\t\ttext: item.text,\n\t\t\t\t\t\tsenderName: \"aiAgentId\" in item && item.aiAgentId ? \"AI\" : null,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (!isPublicIncoming) return;\n\t\t\t\tconst s = store.getState();\n\t\t\t\tconst isViewing = s.isOpen && s.activeConversationId === event.conversationId;\n\t\t\t\tif (isViewing) scheduleMarkSeen(event.conversationId);\n\t\t\t}\n\t\t});\n\n\t\t// Monitor WebSocket connection state\n\t\tconst wsCheck = setInterval(() => {\n\t\t\tsetWsDisconnected(!ws.isConnected);\n\t\t}, 3000);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\tunsub();\n\t\t\tclearInterval(wsCheck);\n\t\t\tif (markSeenTimer) clearTimeout(markSeenTimer);\n\t\t\tws.disconnect();\n\t\t};\n\t}, [client, store, ws, bootstrapAttempt]);\n\n\t// Re-initialize translations when locale prop changes after bootstrap\n\tuseEffect(() => {\n\t\tif (locale != null) {\n\t\t\tsetLocale(locale);\n\t\t}\n\t}, [locale]);\n\n\t// Wire up event callbacks: emit open/close events\n\tuseEffect(() => {\n\t\tconst unsub = store.subscribe((state, prev) => {\n\t\t\tif (state.isOpen && !prev.isOpen) {\n\t\t\t\temitter.emit(\"open\");\n\t\t\t\tonOpen?.();\n\t\t\t}\n\t\t\tif (!state.isOpen && prev.isOpen) {\n\t\t\t\temitter.emit(\"close\");\n\t\t\t\tonClose?.();\n\t\t\t}\n\t\t\tconst prevUnread = prev.conversations.reduce((s, c) => s + c.unreadCount, 0);\n\t\t\tconst nextUnread = state.conversations.reduce((s, c) => s + c.unreadCount, 0);\n\t\t\tif (nextUnread !== prevUnread) {\n\t\t\t\temitter.emit(\"unreadChange\", nextUnread);\n\t\t\t\tonUnreadChange?.(nextUnread);\n\t\t\t}\n\t\t});\n\t\treturn unsub;\n\t}, [store, emitter, onOpen, onClose, onUnreadChange]);\n\n\t// Custom launcher selector: attach click handler with MutationObserver fallback for SPAs\n\tuseEffect(() => {\n\t\tif (!customLauncherSelector) return;\n\t\tconst handler = (e: Event) => {\n\t\t\te.preventDefault();\n\t\t\tapi.toggle();\n\t\t};\n\n\t\tconst attach = () => {\n\t\t\tconst el = document.querySelector(customLauncherSelector);\n\t\t\tif (el) {\n\t\t\t\tel.addEventListener(\"click\", handler);\n\t\t\t\treturn el;\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\n\t\tlet el = attach();\n\t\tlet observer: MutationObserver | null = null;\n\n\t\tif (!el) {\n\t\t\tobserver = new MutationObserver(() => {\n\t\t\t\tel = attach();\n\t\t\t\tif (el) observer?.disconnect();\n\t\t\t});\n\t\t\tobserver.observe(document.body, { childList: true, subtree: true });\n\t\t}\n\n\t\treturn () => {\n\t\t\tel?.removeEventListener(\"click\", handler);\n\t\t\tobserver?.disconnect();\n\t\t};\n\t}, [customLauncherSelector, api]);\n\n\t// Sync window.Helpway with the current api instance on mount,\n\t// restore on unmount. Must live in an effect (not the init block)\n\t// so React StrictMode's double mount/unmount cycle doesn't leave\n\t// the global undefined: the effect re-runs on each mount and\n\t// re-installs the callable, while the init block only fires once\n\t// because initRef.current is preserved across remounts.\n\t//\n\t// IMPORTANT: window.Helpway is exposed as a CALLABLE function (Intercom-style)\n\t// so that `Helpway(\"identify\", payload)` works alongside `Helpway.identify(payload)`.\n\t// Earlier versions assigned the raw `api` object here, which clobbered the\n\t// callable installed by the widget-embed loader and made the documented\n\t// `Helpway(\"cmd\", ...)` form throw \"is not a function\" downstream.\n\t// Apply developer-side theme overrides. We target the host that the\n\t// widget script created (#helpway-widget) when running under the\n\t// embed loader; otherwise fall back to documentElement so the CSS\n\t// vars cascade into a Light-DOM React mount. See:\n\t// https://helpway.ai/docs/customization\n\tuseEffect(() => {\n\t\tif (!theme || typeof document === \"undefined\") return;\n\t\tconst target =\n\t\t\t(document.getElementById(\"helpway-widget\") as HTMLElement | null) ??\n\t\t\tdocument.documentElement;\n\t\tapplyTheme(target, theme);\n\t}, [theme]);\n\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\") return;\n\t\tconst callable = installCallable(api);\n\t\treturn () => {\n\t\t\tif (window.Helpway === callable) {\n\t\t\t\twindow.Helpway = undefined;\n\t\t\t}\n\t\t\temitter.removeAll();\n\t\t};\n\t}, [api, emitter]);\n\n\tconst ctxValue: WidgetContextValue = {\n\t\tclient,\n\t\tstore,\n\t\tws,\n\t\tidentify,\n\t\tapi,\n\t\temitter,\n\t\thasBootstrapError,\n\t\twsDisconnected,\n\t\tretryBootstrap,\n\t};\n\n\treturn <WidgetContext.Provider value={ctxValue}>{children}</WidgetContext.Provider>;\n}\n\n// ── Helpers ──────────────────────────────────────────────\n\n/**\n * Resolve the API origin when the consumer doesn't pass `apiUrl` explicitly.\n *\n * Order of precedence:\n * 1. CDN script-tag origin — when the widget loads via\n * `<script src=\"https://cdn.helpway.ai/widget.js\" data-key=\"...\">` we\n * derive the origin from the script's URL so the bootstrap call hits\n * the API that owns the public key.\n * 2. Production default — `https://api.helpway.ai`. Matches the JSDoc\n * contract on the `apiUrl` prop.\n *\n * Earlier versions fell back to `window.location.origin` after the script\n * lookup, which broke any framework integration without the script tag\n * (Next App Router, Vite SPA, etc.) — bootstrap hit the consumer's own\n * server and 404'd. The `https://api.helpway.ai` fallback removes that\n * footgun.\n */\n/**\n * Synthetic conversation id prefix used for ephemeral proactive workflows.\n * The send-message flow checks for this prefix and routes to\n * `materializeFromProactive` instead of `sendMessage`/`createConversation`,\n * which is the moment we actually persist the conversation.\n */\nexport const EPHEMERAL_CONV_PREFIX = \"eph-\";\n\ninterface EphemeralProactivePayload {\n\tworkflowId: string;\n\tpathId: string;\n\tmessages: Array<{ stepId: string; text: string; sender: \"ai\" }>;\n\tquickReplies?: {\n\t\tstepId: string;\n\t\tprompt: string;\n\t\toptions: Array<{ id: string; label: string; goToPathId: string }>;\n\t};\n}\n\nfunction handleEphemeralProactive(\n\tstore: StoreApi<WidgetStore>,\n\tpayload: EphemeralProactivePayload,\n) {\n\tconst synthId = `${EPHEMERAL_CONV_PREFIX}${payload.workflowId}`;\n\tconst now = Date.now();\n\tconst lastMessage = payload.messages[payload.messages.length - 1];\n\tconst previewText = lastMessage?.text ?? \"\";\n\n\t// Inject the greeting (and quick replies) as if they came from the\n\t// server. Stagger timestamps so order is preserved if the visitor\n\t// scrolls through them later.\n\tconst items = payload.messages.map((m, i) => ({\n\t\tid: `${synthId}-msg-${m.stepId}`,\n\t\tconversationId: synthId,\n\t\ttype: \"message\" as const,\n\t\ttext: m.text,\n\t\tvisibility: \"public\" as const,\n\t\tuserId: null,\n\t\tvisitorId: null,\n\t\taiAgentId: null,\n\t\tcreatedAt: new Date(now - (payload.messages.length - i) * 100).toISOString(),\n\t\teditedAt: null,\n\t\tdeletedAt: null,\n\t}));\n\n\tif (payload.quickReplies) {\n\t\tconst qrFallback =\n\t\t\tpayload.quickReplies.prompt ||\n\t\t\tpayload.quickReplies.options.map((o) => `• ${o.label}`).join(\"\\n\");\n\t\titems.push({\n\t\t\tid: `${synthId}-qr-${payload.quickReplies.stepId}`,\n\t\t\tconversationId: synthId,\n\t\t\ttype: \"message\",\n\t\t\ttext: qrFallback,\n\t\t\tvisibility: \"public\",\n\t\t\tuserId: null,\n\t\t\tvisitorId: null,\n\t\t\taiAgentId: null,\n\t\t\tcreatedAt: new Date(now).toISOString(),\n\t\t\teditedAt: null,\n\t\t\tdeletedAt: null,\n\t\t\tmetadata: {\n\t\t\t\tkind: \"quick_replies\" as const,\n\t\t\t\tprompt: payload.quickReplies.prompt ?? null,\n\t\t\t\toptions: payload.quickReplies.options.map((o) => ({ id: o.id, label: o.label })),\n\t\t\t\tstepId: payload.quickReplies.stepId,\n\t\t\t},\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: metadata is widely typed\n\t\t} as any);\n\t}\n\n\tconst s = store.getState();\n\ts.addConversation({\n\t\tid: synthId,\n\t\ttitle: null,\n\t\tstatus: \"open\",\n\t\tlastMessageText: previewText,\n\t\tlastMessageAt: new Date(now).toISOString(),\n\t\tlastMessageSenderType: \"ai\",\n\t\tlastMessageSenderName: null,\n\t\tlastMessageSenderImage: null,\n\t\tassigneeName: null,\n\t\tassigneeImage: null,\n\t\tunreadCount: items.length,\n\t});\n\t// biome-ignore lint/suspicious/noExplicitAny: synthetic items match TimelineItem shape\n\ts.setMessages(synthId, items as any);\n\n\tif (!s.isOpen && previewText) {\n\t\tstore.setState({\n\t\t\tincomingPreview: {\n\t\t\t\ttext: previewText,\n\t\t\t\tconversationId: synthId,\n\t\t\t\ttimestamp: now,\n\t\t\t\tmessages: payload.messages.map((m) => ({ text: m.text })),\n\t\t\t\t...(payload.quickReplies\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tquickReplies: {\n\t\t\t\t\t\t\t\tstepId: payload.quickReplies.stepId,\n\t\t\t\t\t\t\t\tprompt: payload.quickReplies.prompt ?? null,\n\t\t\t\t\t\t\t\toptions: payload.quickReplies.options.map((o) => ({\n\t\t\t\t\t\t\t\t\tid: o.id,\n\t\t\t\t\t\t\t\t\tlabel: o.label,\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t});\n\t}\n}\n\nfunction inferApiUrl(): string {\n\tif (typeof document !== \"undefined\") {\n\t\tconst script = document.querySelector(\"script[data-key][src]\");\n\t\tif (script) {\n\t\t\tconst src = script.getAttribute(\"src\");\n\t\t\tif (src) {\n\t\t\t\ttry {\n\t\t\t\t\tconst url = new URL(src);\n\t\t\t\t\treturn `${url.protocol}//${url.host}`;\n\t\t\t\t} catch {\n\t\t\t\t\t// Fall through to the production default.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn \"https://api.helpway.ai\";\n}\n","\"use client\";\n\nimport { formatRelativeTime, t } from \"@helpway/widget-core\";\nimport type { ConversationSummary, WidgetContentTab } from \"@helpway/widget-core\";\nimport type { TimelineItem } from \"@helpway/types\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n/** Resolve a label that might be a translation key (widget.*) or raw text */\nfunction resolveLabel(label: string): string {\n\tif (!label.startsWith(\"widget.\")) return label;\n\tconst resolved = t(label);\n\t// If t() returned the key itself (no translation found), humanize it\n\tif (resolved === label)\n\t\treturn label\n\t\t\t.replace(\"widget.\", \"\")\n\t\t\t.replace(/_/g, \" \")\n\t\t\t.replace(/^\\w/, (c) => c.toUpperCase());\n\treturn resolved;\n}\n\nimport { useComposer } from \"../hooks/use-composer\";\nimport { useConversations } from \"../hooks/use-conversations\";\nimport { useI18n } from \"../hooks/use-i18n\";\nimport { usePresence } from \"../hooks/use-presence\";\nimport { useTimeline } from \"../hooks/use-timeline\";\nimport { useUnread } from \"../hooks/use-unread\";\nimport { useWidget } from \"../hooks/use-widget\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\nimport { Composer } from \"./composer\";\nimport { WidgetDebugOverlay } from \"./debug-overlay\";\nimport { ContentTabView } from \"./content/content-tab-view\";\nimport { ContentTabIconComponent } from \"./content/tab-icon\";\nimport { HomeIcon, MessagesIcon, SendIcon, XIcon } from \"./icons\";\nimport { MessageBubble } from \"./message-bubble\";\nimport { MessageList } from \"./message-list\";\n\nimport type { SubView, Tab } from \"./default-widget/types\";\n\nconst EMPTY_CONTENT_TABS: WidgetContentTab[] = [];\n\n/**\n * Factory-default admin strings. If the admin never customized these\n * values, the widget falls back to t() so visitors see their locale's\n * translation from the CDN bundle instead of frozen English.\n *\n * Keep in sync with packages/api seed defaults + widget-core/src/i18n.ts.\n */\nconst DEFAULT_EN_WELCOME = \"Hi there 👋\\nHow can we help?\";\nconst DEFAULT_EN_SUBTITLE = \"Usually replies in minutes\";\n\n/**\n * Helpway brand mark — octagonal outer with stylized \"W\" inside. Used as\n * the widget's own fallback avatar when the customer hasn't configured a\n * custom avatar/preset and the host site didn't set a logo either. Keeps\n * unconfigured widgets looking intentional rather than generic.\n */\nfunction HelpwayMark({ className }: { className?: string }) {\n\treturn (\n\t\t<svg\n\t\t\tclassName={className}\n\t\t\twidth=\"100%\"\n\t\t\theight=\"100%\"\n\t\t\tviewBox=\"0 0 42 42\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<path\n\t\t\t\td=\"M28.7 0H12.8L0 12.8V28.7L12.8 41.5H28.7L41.5 28.7V12.8L28.7 0ZM15 28.9L6.80002 20.7L15 12.5C18.1 9.4 23.2 9.4 26.3 12.5L34.5 20.7L26.3 28.9C23.2 32 18.2 32 15 28.9Z\"\n\t\t\t\tfill=\"currentColor\"\n\t\t\t/>\n\t\t</svg>\n\t);\n}\n\n/**\n * WidgetLogo — chat-header avatar. Renders WHO is talking to the\n * visitor right now. Resolution chain:\n * 1. Active conversation's assigned support user (assigneeName +\n * assigneeImage from the widget API). When a human takes over a\n * conversation the visitor sees that human, not the AI agent.\n * 2. Agent uploaded image (agentConfig.avatarUrl)\n * 3. Agent icon preset (avatarPreset + brandColor)\n * 4. Website logo (website.logoUrl)\n * 5. Helpway brand mark (octagonal) as the true last-resort fallback\n *\n * The `forceAgent` escape hatch skips the assignee lookup — used by\n * surfaces that mean \"the agent\" specifically (welcome card, conversation\n * list rows where we want the persistent brand, etc.) rather than \"the\n * person currently helping you\".\n */\nfunction WidgetLogo({\n\tclassName,\n\tforceAgent = false,\n}: {\n\tclassName?: string;\n\tforceAgent?: boolean;\n}) {\n\tconst agentConfig = useWidgetStore((s) => s.agentConfig);\n\tconst logoUrl = useWidgetStore((s) => s.website?.logoUrl);\n\tconst activeId = useWidgetStore((s) => s.activeConversationId);\n\tconst assignee = useWidgetStore((s) => {\n\t\tif (forceAgent || !s.activeConversationId) return null;\n\t\tconst c = s.conversations.find((c) => c.id === s.activeConversationId);\n\t\treturn c?.assigneeName || c?.assigneeImage ? c : null;\n\t});\n\n\t// In the launcher bubble (forceAgent=true), uploaded images are\n\t// treated as brand logos — `contain` + padding so SVG/PNG marks\n\t// don't get cropped by the rounded bubble. In the chat-header\n\t// context, face-photo avatars keep `cover` behavior.\n\tconst logoClass = forceAgent ? \"hw-agent-img--logo\" : \"\";\n\n\t// Assigned human takes priority over the AI agent default — but only\n\t// when we actually have an active conversation we're rendering for.\n\tif (!forceAgent && activeId && assignee?.assigneeImage) {\n\t\treturn (\n\t\t\t<img\n\t\t\t\tsrc={assignee.assigneeImage}\n\t\t\t\talt={assignee.assigneeName ?? \"\"}\n\t\t\t\tclassName={`hw-agent-img ${className ?? \"\"}`}\n\t\t\t/>\n\t\t);\n\t}\n\n\t// Agent uploaded image\n\tif (agentConfig?.avatarUrl) {\n\t\treturn <img src={agentConfig.avatarUrl} alt=\"\" className={`hw-agent-img ${logoClass} ${className ?? \"\"}`} />;\n\t}\n\n\t// Agent icon preset\n\tif (agentConfig?.avatarPreset) {\n\t\tconst color = agentConfig.brandColor ?? \"#0a0a0a\";\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={`hw-agent-icon ${className ?? \"\"}`}\n\t\t\t\tstyle={{\n\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tjustifyContent: \"center\",\n\t\t\t\t\tborderRadius: 8,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<AgentPresetIcon presetId={agentConfig.avatarPreset} />\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Website logo — always a brand mark, never a face avatar. Apply\n\t// --logo class regardless of context so it stays uncropped in both\n\t// launcher bubble and chat-header circles.\n\tif (logoUrl) {\n\t\treturn <img src={logoUrl} alt=\"\" className={`hw-agent-img hw-agent-img--logo ${className ?? \"\"}`} />;\n\t}\n\n\treturn <HelpwayMark className={className} />;\n}\n\n/**\n * LauncherIcon — what the visitor sees on the always-visible bubble\n * BEFORE opening the widget. Brand-stable, doesn't change per\n * conversation. Resolution chain:\n * 1. Custom launcher icon (agentConfig.launcherIconUrl) — admin upload\n * 2. Agent avatar (avatarUrl) — same image as the chat header default\n * 3. Agent icon preset\n * 4. Website logo\n * 5. Helpway brand mark\n */\nfunction LauncherIcon({ className }: { className?: string }) {\n\tconst agentConfig = useWidgetStore((s) => s.agentConfig);\n\n\tif (agentConfig?.launcherIconUrl) {\n\t\t// Launcher icon is a brand mark, not a face avatar — use `contain`\n\t\t// + inner padding so SVG/PNG logos with their own padding rules\n\t\t// don't get cropped by the bubble's rounded corners.\n\t\treturn (\n\t\t\t<img\n\t\t\t\tsrc={agentConfig.launcherIconUrl}\n\t\t\t\talt=\"\"\n\t\t\t\tclassName={`hw-agent-img hw-agent-img--logo ${className ?? \"\"}`}\n\t\t\t/>\n\t\t);\n\t}\n\t// Fall back to the same chain the chat header uses, with `forceAgent`\n\t// so we never accidentally render a per-conversation assignee on the\n\t// launcher (which would flicker as the active conversation changed).\n\treturn <WidgetLogo className={className} forceAgent />;\n}\n\n/**\n * Exact SVG paths extracted from @central-icons-react at build time.\n * Pixel-perfect match with the dashboard picker. Using static trusted\n * strings (NOT user input) rendered via innerHTML — safe because content\n * is hardcoded SVG from our own icon library, never from external sources.\n */\nconst PRESET_SVG: Record<string, string> = {\n\t// Helpway brand mark — octagonal chamfer with stylized \"W\" inside.\n\t// First entry so it's the default preset for new orgs.\n\thelpway:\n\t\t'<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M16.4 0H7.31L0 7.31V16.4L7.31 23.71H16.4L23.71 16.4V7.31L16.4 0ZM8.57 16.51L3.89 11.83L8.57 7.14C10.34 5.37 13.26 5.37 15.03 7.14L19.71 11.83L15.03 16.51C13.26 18.29 10.4 18.29 8.57 16.51Z\" fill=\"white\"/>',\n\tatom: '<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M9.67904 3.29155C10.7467 1.56948 13.2537 1.56948 14.3214 3.29155L15.1308 4.59707C15.2462 4.7833 15.3634 4.9684 15.4823 5.15233C15.7005 5.1305 15.9185 5.10662 16.1363 5.08068L17.6626 4.89893C19.6747 4.65934 21.2396 6.61723 20.5571 8.52637L20.0401 9.97255C19.9664 10.1786 19.8947 10.3854 19.825 10.5927C19.9779 10.7493 20.1323 10.9045 20.2882 11.0583L21.3821 12.1371C22.8256 13.5609 22.2668 16.0039 20.3491 16.6605L18.895 17.1584C18.6876 17.2294 18.4809 17.3023 18.275 17.3772C18.2478 17.5943 18.2226 17.8117 18.1995 18.0294L18.0372 19.5565C17.823 21.572 15.5635 22.6577 13.8546 21.5695L12.5584 20.7442C12.3734 20.6264 12.1873 20.5103 12.0002 20.3961C11.8131 20.5103 11.627 20.6264 11.442 20.7442L10.1458 21.5695C8.4369 22.6577 6.17739 21.572 5.96321 19.5565L5.80094 18.0294C5.7778 17.8117 5.75263 17.5943 5.72541 17.3772C5.51949 17.3023 5.31282 17.2294 5.10542 17.1584L3.65133 16.6605C1.7336 16.0039 1.17475 13.5609 2.61829 12.1371L3.71216 11.0583C3.86807 10.9045 4.0225 10.7493 4.17541 10.5927C4.10567 10.3854 4.03395 10.1786 3.96028 9.97255L3.44329 8.52637C2.7608 6.61723 4.32567 4.65934 6.33777 4.89893L7.86408 5.08068C8.08191 5.10662 8.29993 5.1305 8.5181 5.15233C8.63698 4.9684 8.75417 4.7833 8.86963 4.59707L9.67904 3.29155ZM7.61407 6.4827L6.16966 6.31071C5.20357 6.19567 4.45578 7.13505 4.78207 8.04778L5.2716 9.41715C6.10452 8.48167 6.88648 7.5021 7.61407 6.4827ZM5.78854 10.961C7.04552 9.61105 8.19784 8.16742 9.23549 6.64268C11.076 6.78287 12.9244 6.78287 14.7649 6.64268C15.8026 8.16743 16.9549 9.61105 18.2119 10.961C17.6657 12.722 17.2545 14.522 16.9818 16.3454C15.2628 17.0169 13.5974 17.8181 12.0002 18.7422C10.403 17.8181 8.73761 17.0169 7.01863 16.3454C6.74592 14.522 6.3347 12.722 5.78854 10.961ZM4.65269 12.1275L3.61666 13.1494C2.92581 13.8308 3.19234 15.0006 4.11188 15.3154L5.48873 15.7868C5.27593 14.553 4.99684 13.3315 4.65269 12.1275ZM7.22343 17.9611L7.377 19.4062C7.47946 20.3704 8.56185 20.8926 9.38218 20.3703L10.6083 19.5895C9.51004 18.9865 8.38012 18.4429 7.22343 17.9611ZM13.3921 19.5895L14.6182 20.3703C15.4385 20.8926 16.5209 20.3704 16.6234 19.4062L16.777 17.9611C15.6203 18.4429 14.4903 18.9865 13.3921 19.5895ZM18.5117 15.7868L19.8885 15.3154C20.8081 15.0006 21.0746 13.8308 20.3837 13.1494L19.3477 12.1275C19.0035 13.3315 18.7245 14.553 18.5117 15.7868ZM18.7288 9.41715L19.2183 8.04778C19.5446 7.13505 18.7968 6.19567 17.8307 6.31071L16.3863 6.4827C17.1139 7.5021 17.8959 8.48167 18.7288 9.41715ZM13.8786 5.2756C12.6272 5.3429 11.3731 5.3429 10.1218 5.2756L10.8874 4.04072C11.3991 3.21542 12.6013 3.21542 13.113 4.04072L13.8786 5.2756Z\" fill=\"white\"/>',\n\tbrain:\n\t\t'<path d=\"M15 10C13.3431 10 12 8.65685 12 7\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9 14C10.6569 14 12 15.3431 12 17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12 3.53516L12 20.2422\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M21 14.5C21 15.9633 20.102 17.2168 18.8271 17.7396C18.2888 19.6221 16.5553 21 14.5 21C13.5749 21 12.7151 20.7209 12 20.2422C11.285 20.7209 10.4251 21 9.5 21C7.44468 21 5.71119 19.6221 5.17291 17.7396C3.89797 17.2168 3 15.9633 3 14.5C3 13.5207 3.40223 12.6353 4.05051 12C3.40223 11.3647 3 10.4793 3 9.5C3 7.69511 4.36618 6.20931 6.12085 6.0203C6.55779 4.28478 8.12886 3 10 3C10.7286 3 11.4117 3.19479 12 3.53513C12.5883 3.19479 13.2714 3 14 3C15.8711 3 17.4422 4.28478 17.8792 6.0203C19.6338 6.20931 21 7.69511 21 9.5C21 10.4793 20.5978 11.3647 19.9495 12C20.5978 12.6353 21 13.5207 21 14.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\trobot:\n\t\t'<path d=\"M12 4H7C5.89543 4 5 4.89543 5 6V11C5 12.1046 5.89543 13 7 13H17C18.1046 13 19 12.1046 19 11V6C19 4.89543 18.1046 4 17 4H12ZM12 4V2M6 15L4 17M6 15C6 18.3137 8.68629 21 12 21C15.3137 21 18 18.3137 18 15M6 15V13M18 15L20 17M18 15V13M9 8V9M15 8V9\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tsparkle:\n\t\t'<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M21 12.5C14.75 12.5 12 15.4028 12 22C12 15.4028 9.25 12.5 3 12.5C9.25 12.5 12 9.59722 12 3C12 9.59722 14.75 12.5 21 12.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linejoin=\"round\"/>',\n\tbolt: '<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M13.1981 20.0571C11.7326 20.0571 10.2936 19.5252 9.46756 18.3817L9.1762 19.7304L3.79688 22.5824L4.3776 19.7304L8.2951 2H13.0916L11.7059 8.24953C12.8251 7.02621 13.8643 6.57412 15.1967 6.57412C18.0746 6.57412 19.9931 8.46227 19.9931 11.9194C19.9931 15.483 17.7815 20.0571 13.1981 20.0571ZM15.0368 12.9301C15.0368 14.5788 13.8643 15.8287 12.3455 15.8287C11.4927 15.8287 10.72 15.5096 10.2137 14.9511L10.9598 11.6802C11.5194 11.1216 12.1589 10.8025 12.905 10.8025C14.0509 10.8025 15.0368 11.6536 15.0368 12.9301Z\" fill=\"white\"/>',\n\tagent:\n\t\t'<path d=\"M12 8.5V12M12 12H8C6.89543 12 6 12.8954 6 14V15.5M12 12H16C17.1046 12 18 12.8954 18 14V15.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"12\" cy=\"6\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"6\" cy=\"18\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"18\" cy=\"18\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/>',\n\tbubble:\n\t\t'<path d=\"M4.00195 6.00003C4.00195 4.89546 4.89738 4.00003 6.00195 4.00002L18.0019 4C19.1065 4 20.002 4.89543 20.002 6V16.0358C20.002 17.1403 19.1065 18.0358 18.002 18.0358L15.3757 18.0358C15.1427 18.0358 14.9171 18.1171 14.7377 18.2657L11.9977 20.5358L9.29398 18.2694C9.11393 18.1185 8.8865 18.0358 8.65157 18.0358H6.00195C4.89738 18.0358 4.00195 17.1403 4.00195 16.0358V6.00003Z\" fill=\"white\"/><path d=\"M13.2395 9.43518L12.5426 7.62334C12.4561 7.39842 12.24 7.25 11.999 7.25C11.758 7.25 11.5419 7.39842 11.4554 7.62334L10.7586 9.43518C10.657 9.69927 10.4483 9.90797 10.1842 10.0095L8.37236 10.7064C8.14744 10.7929 7.99902 11.009 7.99902 11.25C7.99902 11.491 8.14744 11.7071 8.37236 11.7936L10.1842 12.4905C10.4483 12.592 10.657 12.8007 10.7586 13.0648L11.4554 14.8767C11.5419 15.1016 11.758 15.25 11.999 15.25C12.24 15.25 12.4561 15.1016 12.5426 14.8767L13.2395 13.0648C13.3411 12.8007 13.5498 12.592 13.8138 12.4905L15.6257 11.7936C15.8506 11.7071 15.999 11.491 15.999 11.25C15.999 11.009 15.8506 10.7929 15.6257 10.7064L13.8138 10.0095C13.5498 9.90797 13.3411 9.69927 13.2395 9.43518Z\" fill=\"white\"/>',\n\tlightbulb:\n\t\t'<path d=\"M10 21H14M15.6076 15C17.6404 13.7751 19 11.5463 19 9C19 5.13401 15.866 2 12 2C8.13401 2 5 5.13401 5 9C5 11.5463 6.35958 13.7751 8.39241 15M15.6076 15C15.4111 15.1184 15.2084 15.2274 15 15.3264V17C15 17.5523 14.5523 18 14 18H10C9.44772 18 9 17.5523 9 17V15.3264C8.7916 15.2274 8.58886 15.1184 8.39241 15M15.6076 15H8.39241\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\twand: '<path d=\"M11.3908 12.6089L4 19.9996\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M18.3943 5.2792C18.5999 5.1944 18.8056 5.40008 18.7208 5.60565L17.1697 9.36581C17.1339 9.45248 17.1497 9.55186 17.2105 9.62323L19.8476 12.72C19.9918 12.8894 19.8597 13.1485 19.638 13.1314L15.5826 12.8182C15.4891 12.811 15.3994 12.8566 15.3503 12.9365L13.22 16.4015C13.1035 16.591 12.8163 16.5455 12.764 16.3293L11.8087 12.3756C11.7867 12.2844 11.7156 12.2133 11.6244 12.1913L7.67069 11.236C7.45453 11.1837 7.40903 10.8964 7.59847 10.78L11.0635 8.64965C11.1434 8.60055 11.189 8.51089 11.1818 8.41743L10.8686 4.36198C10.8515 4.14027 11.1106 4.00822 11.2799 4.15239L14.3768 6.78952C14.4481 6.8503 14.5475 6.86604 14.6342 6.83029L18.3943 5.2792Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tchip: '<path d=\"M8 5.5V4M12 5.5V4M16 5.5V4M8 20V18.5M12 20V18.5M16 20V18.5M8.75 15H15.25C15.6642 15 16 14.6642 16 14.25V9.75C16 9.33579 15.6642 9 15.25 9H8.75C8.33579 9 8 9.33579 8 9.75V14.25C8 14.6642 8.33579 15 8.75 15ZM6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6V18C4 19.1046 4.89543 20 6 20Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tcode: '<path d=\"M10 9.5L8.20711 11.2929C7.81658 11.6834 7.81658 12.3166 8.20711 12.7071L10 14.5M14 9.5L15.7929 11.2929C16.1834 11.6834 16.1834 12.3166 15.7929 12.7071L14 14.5M6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6V18C4 19.1046 4.89543 20 6 20Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tlightning:\n\t\t'<path d=\"M4.11593 12.2764L8.61593 3.27639C8.70063 3.107 8.87376 3 9.06315 3H17.121C17.5097 3 17.7497 3.42399 17.5498 3.75725L15.4585 7.24275C15.2585 7.57601 15.4986 8 15.8872 8H20.6909C21.1505 8 21.3666 8.56776 21.0235 8.87338L7.38117 21.0236C7.00034 21.3628 6.41568 20.981 6.57301 20.4959L8.79194 13.6543C8.8967 13.3312 8.6559 13 8.31633 13H4.56314C4.19145 13 3.94971 12.6088 4.11593 12.2764Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tvibe: '<path d=\"M18.9847 2.4329C18.9568 2.18651 18.7485 2.00025 18.5005 2C18.2525 1.99975 18.0438 2.18557 18.0154 2.43191C17.838 3.96993 16.9699 4.83801 15.4319 5.01541C15.1856 5.04382 14.9997 5.25253 15 5.5005C15.0003 5.74847 15.1865 5.9568 15.4329 5.9847C16.9491 6.15645 17.8774 7.01617 18.0141 8.55536C18.0365 8.80725 18.2477 9.00028 18.5005 9C18.7534 8.99971 18.9642 8.80621 18.986 8.55426C19.1173 7.03683 20.0368 6.11734 21.5543 5.98599C21.8062 5.96418 21.9997 5.75344 22 5.50055C22.0003 5.24766 21.8073 5.03648 21.5554 5.01411C20.0162 4.87738 19.1564 3.94911 18.9847 2.4329Z\" fill=\"white\"/><path d=\"M2 20C2 16.6863 4.68629 14 8 14H8.5\" fill=\"white\"/><path d=\"M11 20L12.6892 14.0879C12.8732 13.444 13.4617 13 14.1315 13H20.5417C21.2725 13 21.8001 13.6995 21.5994 14.4022L20.2072 19.2747C20.0846 19.704 19.6922 20 19.2457 20H11ZM11 20H7\" fill=\"white\"/><circle cx=\"8.75\" cy=\"7.5\" r=\"3.5\" stroke=\"white\" stroke-width=\"2\"/>',\n\tnetwork:\n\t\t'<path d=\"M12 6.8501L16 7.2501M17.75 10.0001L16.55 14.0001M13.5 14.3572L12 12.0001L10.4091 9.5001M6.25 14.0001L7.45 10.0001M8 16.7501L12 17.1501\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"18.5\" cy=\"7.5\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"5.5\" cy=\"16.5\" r=\"2.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"8.5\" cy=\"6.5\" r=\"3.5\" stroke=\"white\" stroke-width=\"2\"/><circle cx=\"15.5\" cy=\"17.5\" r=\"3.5\" stroke=\"white\" stroke-width=\"2\"/>',\n\tconsole:\n\t\t'<path d=\"M7.5 8L9.25 9.75L7.5 11.5M12 11.5H14M6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6V18C4 19.1046 4.89543 20 6 20Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tprompt:\n\t\t'<path d=\"M6 5H5C3.89543 5 3 5.89543 3 7V8\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M18 5H19C20.1046 5 21 5.89543 21 7V8\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M21 16V17C21 18.1046 20.1046 19 19 19H18\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 19H5C3.89543 19 3 18.1046 3 17V16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M8 10H16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M8 14H14\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tglobe:\n\t\t'<path d=\"M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M21 12H3\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12 21C10.067 21 8.5 16.9706 8.5 12C8.5 7.02944 10.067 3 12 3C13.933 3 15.5 7.02944 15.5 12C15.5 16.9706 13.933 21 12 21Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\ttarget:\n\t\t'<path d=\"M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M17 12C17 14.7614 14.7614 17 12 17C9.23858 17 7 14.7614 7 12C7 9.23858 9.23858 7 12 7C14.7614 7 17 9.23858 17 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M13 12C13 12.5523 12.5523 13 12 13C11.4477 13 11 12.5523 11 12C11 11.4477 11.4477 11 12 11C12.5523 11 13 11.4477 13 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tdiamond:\n\t\t'<path d=\"M8.28256 4C7.77978 4 7.29545 4.18937 6.926 4.53039L2.53016 8.58809C1.69548 9.35857 1.66929 10.6687 2.47251 11.4719L10.5864 19.5858C11.3674 20.3668 12.6338 20.3668 13.4148 19.5858L21.5287 11.4719C22.3319 10.6687 22.3057 9.35857 21.471 8.58809L17.0752 4.53039C16.7057 4.18937 16.2214 4 15.7186 4H8.28256Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9.5 8L7.5 10L9.5 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tstar: '<path d=\"M11.5288 2.29524C11.7179 1.90159 12.2821 1.90159 12.4712 2.29524L14.9458 7.44648C15.0219 7.60491 15.1735 7.71434 15.3487 7.73728L21.0456 8.4832C21.4809 8.5402 21.6552 9.07312 21.3368 9.37342L17.1693 13.303C17.0412 13.4238 16.9832 13.6009 17.0154 13.7735L18.0616 19.3857C18.1416 19.8146 17.6852 20.144 17.2993 19.9359L12.249 17.2133C12.0937 17.1296 11.9063 17.1296 11.751 17.2133L6.70073 19.9359C6.3148 20.144 5.85841 19.8146 5.93837 19.3857L6.98459 13.7735C7.01677 13.6009 6.95885 13.4238 6.83068 13.303L2.66324 9.37342C2.34476 9.07312 2.51909 8.5402 2.95444 8.4832L8.65127 7.73728C8.82648 7.71434 8.97811 7.60491 9.05422 7.44648L11.5288 2.29524Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\theart:\n\t\t'<path d=\"M21 10C21 15.75 12.75 20 12 20C11.25 20 3 15.75 3 10C3 6 5.5 4 8 4C10.5 4 12 5.5 12 5.5C12 5.5 13.5 4 16 4C18.5 4 21 6 21 10Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tshield:\n\t\t'<path d=\"M20 7.17737C20 6.32338 19.4578 5.56361 18.6502 5.286L12.6502 3.2235C12.2288 3.07866 11.7712 3.07866 11.3498 3.22349L5.34984 5.286C4.54224 5.56361 4 6.32338 4 7.17737V11.9123C4 16.8848 8 19 12 21.1579C16 19 20 16.8848 20 11.9123V7.17737Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\trocket:\n\t\t'<path d=\"M3 21H5C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19V21Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.00098 13H4.76717C3.98987 13 3.50976 12.152 3.90968 11.4855L5.41837 8.97101C5.77982 8.3686 6.43083 8 7.13336 8H11.251C13.7671 5.25513 16.4925 3.3474 20.0017 3.04278C20.5519 2.99502 21.006 3.44906 20.9582 3.99927C20.6536 7.50845 18.7459 10.2339 16.001 12.75V16.8676C16.001 17.5701 15.6324 18.2212 15.03 18.5826L12.5155 20.0913C11.849 20.4912 11.001 20.0111 11.001 19.2338V17L7.00098 13Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 13L11.25 8\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M16 12.75L11 17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tcrown:\n\t\t'<path d=\"M4.16831 17.4079L2 7L8 10L12 4L16 10L22 7L19.8317 17.4079C19.6385 18.3353 18.8211 19 17.8737 19H6.12628C5.17892 19 4.36153 18.3353 4.16831 17.4079Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\ttrophy:\n\t\t'<path d=\"M12.0039 17V14\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M18 5H19C20.1046 5 21 5.89543 21 7C21 8.65685 19.6569 10 18 10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 5C6 3.89543 6.89543 3 8 3H16C17.1046 3 18 3.89543 18 5V8C18 11.3137 15.3137 14 12 14C8.68629 14 6 11.3137 6 8V5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 19C7 17.8954 7.89543 17 9 17H15C16.1046 17 17 17.8954 17 19C17 20.1046 16.1046 21 15 21H9C7.89543 21 7 20.1046 7 19Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 5H5C3.89543 5 3 5.89543 3 7C3 8.65685 4.34315 10 6 10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tcompass:\n\t\t'<path d=\"M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M14.6558 8.73023L10.5513 9.84965C10.2097 9.94281 9.94281 10.2097 9.84965 10.5513L8.73023 14.6558C8.62843 15.0291 8.97092 15.3716 9.34417 15.2698L13.4487 14.1504C13.7903 14.0572 14.0572 13.7903 14.1504 13.4487L15.2698 9.34417C15.3716 8.97092 15.0291 8.62843 14.6558 8.73023Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tfire: '<path d=\"M19.5 13.8122C19.5 23.3907 4.5 23.4012 4.5 13.8122C4.5 6.61352 12 2.5 12 2.5C12 2.5 19.5 6.61352 19.5 13.8122Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M15.5 17.4061C15.5 22.1954 8.5 22.2006 8.5 17.4061C8.5 13.8068 12 11.75 12 11.75C12 11.75 15.5 13.8068 15.5 17.4061Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tkey: '<path d=\"M20.8002 9.8753L20.0194 10.5L20.0194 10.5L20.8002 9.8753ZM22.0002 11.3753L21.2194 12V12L22.0002 11.3753ZM22.0002 12.6247L21.2194 12V12L22.0002 12.6247ZM20.8002 14.1247L20.0194 13.5L20.0194 13.5L20.8002 14.1247ZM18 14.5L17.5528 15.3944C17.6916 15.4639 17.8448 15.5 18 15.5V14.5ZM16 13.5L16.4472 12.6056C16.1657 12.4648 15.8343 12.4648 15.5528 12.6056L16 13.5ZM14 14.5V15.5C14.1552 15.5 14.3084 15.4639 14.4472 15.3944L14 14.5ZM11.0141 9.01843L11.8165 8.42152L11.8165 8.42152L11.0141 9.01843ZM11.0141 14.9816L10.2118 14.3847V14.3847L11.0141 14.9816ZM6.5 12C6.5 11.7239 6.72386 11.5 7 11.5V13.5C7.82843 13.5 8.5 12.8284 8.5 12H6.5ZM7 11.5C7.27614 11.5 7.5 11.7239 7.5 12H5.5C5.5 12.8284 6.17157 13.5 7 13.5V11.5ZM7.5 12C7.5 12.2761 7.27614 12.5 7 12.5V10.5C6.17157 10.5 5.5 11.1716 5.5 12H7.5ZM7 12.5C6.72386 12.5 6.5 12.2761 6.5 12H8.5C8.5 11.1716 7.82843 10.5 7 10.5V12.5ZM6.5 13H7.5V11H6.5V13ZM7 16C4.79086 16 3 14.2091 3 12H1C1 15.3137 3.68629 18 7 18V16ZM3 12C3 9.79086 4.79086 8 7 8V6C3.68629 6 1 8.68629 1 12H3ZM20.0194 10.5L21.2194 12L22.7811 10.7506L21.5811 9.25061L20.0194 10.5ZM21.2194 12L20.0194 13.5L21.5811 14.7494L22.7811 13.2494L21.2194 12ZM20.0194 13.5H18V15.5H20.0194V13.5ZM18.4472 13.6056L16.4472 12.6056L15.5528 14.3944L17.5528 15.3944L18.4472 13.6056ZM15.5528 12.6056L13.5528 13.6056L14.4472 15.3944L16.4472 14.3944L15.5528 12.6056ZM11.9079 10.5H20.0194V8.5H11.9079V10.5ZM7 8C8.31459 8 9.48107 8.63311 10.2118 9.61533L11.8165 8.42152C10.7246 6.9539 8.97356 6 7 6V8ZM14 13.5H11.9079V15.5H14V13.5ZM10.2118 14.3847C9.48107 15.3669 8.31459 16 7 16V18C8.97356 18 10.7246 17.0461 11.8165 15.5785L10.2118 14.3847ZM11.9079 13.5C11.1751 13.5 10.5749 13.8967 10.2118 14.3847L11.8165 15.5785C11.8445 15.5408 11.8734 15.5183 11.8929 15.5074C11.9106 15.4976 11.9148 15.5 11.9079 15.5V13.5ZM20.0194 13.5L20.0194 13.5V15.5C20.6269 15.5 21.2016 15.2238 21.5811 14.7494L20.0194 13.5ZM11.9079 8.5C11.9148 8.5 11.9106 8.50239 11.8929 8.49258C11.8734 8.48172 11.8445 8.45923 11.8165 8.42152L10.2118 9.61533C10.5749 10.1033 11.1751 10.5 11.9079 10.5V8.5ZM21.2194 12V12L22.7811 13.2494C23.3655 12.519 23.3655 11.481 22.7811 10.7506L21.2194 12ZM21.5811 9.25061C21.2016 8.77618 20.6269 8.5 20.0194 8.5V10.5L20.0194 10.5L21.5811 9.25061Z\" fill=\"white\"/>',\n\tlock: '<path d=\"M5 12C5 10.8954 5.89543 10 7 10H17C18.1046 10 19 10.8954 19 12V19C19 20.1046 18.1046 21 17 21H7C5.89543 21 5 20.1046 5 19V12Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M16 9.5V7C16 4.79086 14.2091 3 12 3C9.79086 3 8 4.79086 8 7V9.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12 14V17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tbookmark:\n\t\t'<path d=\"M19 19.9948V5C19 3.89543 18.1046 3 17 3H7C5.89543 3 5 3.89543 5 5V19.9948C5 20.8047 5.91243 21.2787 6.57503 20.813L10.8499 17.8083C11.54 17.3233 12.46 17.3233 13.1501 17.8083L17.425 20.813C18.0876 21.2787 19 20.8047 19 19.9948Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tstore:\n\t\t'<path d=\"M4 10V18C4 19.1046 4.89543 20 6 20H18C19.1046 20 20 19.1046 20 18V10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M14.4996 4H9.49956L9.2133 8.00762C9.0978 9.62461 10.3785 11 11.9996 11C13.6207 11 14.9013 9.62461 14.7858 8.00763L14.4996 4Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9.50047 4H5.73506C4.73976 4 3.89592 4.73186 3.75516 5.71716L3.4699 7.71396C3.22214 9.44831 4.56792 11 6.31987 11C7.83025 11 9.08385 9.83276 9.19146 8.32621L9.50047 4Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M18.2654 4H14.5L14.809 8.32621C14.9166 9.83276 16.1702 11 17.6806 11C19.4326 11 20.7783 9.44831 20.5306 7.71396L20.2453 5.71716C20.1046 4.73186 19.2607 4 18.2654 4Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tbag: '<path d=\"M15.0001 8C15.0001 9.65685 13.6569 11 12.0001 11C10.3432 11 9.00008 9.65685 9.00008 8M4.88288 5.87524L4.13288 17.8752C4.06092 19.0266 4.97534 20 6.12899 20H17.8712C19.0248 20 19.9392 19.0266 19.8673 17.8752L19.1173 5.87524C19.0514 4.82117 18.1773 4 17.1212 4H6.87899C5.82286 4 4.94876 4.82117 4.88288 5.87524Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\t\"credit-card\":\n\t\t'<path d=\"M3 10V17C3 18.1046 3.89543 19 5 19H19C20.1046 19 21 18.1046 21 17V10M3 10V7C3 5.89543 3.89543 5 5 5H19C20.1046 5 21 5.89518 21 6.99975V10M3 10H21\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\treceipt:\n\t\t'<path d=\"M9 8H15M9 12H11M19 21V5C19 3.89543 18.1046 3 17 3H7C5.89543 3 5 3.89543 5 5V21L7.33333 19L9.66667 21L12 19L14.3333 21L16.6667 19L19 21Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tbank: '<path d=\"M11.1056 2.94723L3.68328 6.65838C3.26452 6.86776 3 7.29576 3 7.76395C3 8.44661 3.55341 9.00002 4.23607 9.00002H19.7639C20.4466 9.00002 21 8.44661 21 7.76395C21 7.29576 20.7355 6.86776 20.3167 6.65838L12.8944 2.94723C12.3314 2.6657 11.6686 2.6657 11.1056 2.94723Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19.6126 20H4.38749C3.70493 20 3.22296 19.3313 3.4388 18.6838L3.54421 18.3675C3.81644 17.5509 4.58072 17 5.44158 17H18.5585C19.4194 17 20.1837 17.5509 20.4559 18.3675L20.5613 18.6838C20.7772 19.3313 20.2952 20 19.6126 20Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19 9V17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M15 17V9\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5 9V17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9 17V9\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\twallet:\n\t\t'<path d=\"M3 8V7C3 5.89543 3.89543 5 5 5H19C20.1046 5 21 5.89543 21 7V8M3 8H21M3 8V11M21 8V11M21 11V17C21 18.1046 20.1046 19 19 19H5C3.89543 19 3 18.1046 3 17V11M21 11H15C15 12.1046 14.1046 13 13 13H11C9.89543 13 9 12.1046 9 11H3\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tpackage:\n\t\t'<path d=\"M9 4V7.5C9 8.32843 9.67157 9 10.5 9H13.5C14.3284 9 15 8.32843 15 7.5V4M14 16H16M4 6V18C4 19.1046 4.89543 20 6 20H18C19.1046 20 20 19.1046 20 18V6C20 4.89543 19.1046 4 18 4H6C4.89543 4 4 4.89543 4 6Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\ttruck:\n\t\t'<path d=\"M10 16.5C10 17.8807 8.88071 19 7.5 19C6.11929 19 5 17.8807 5 16.5C5 15.1193 6.11929 14 7.5 14C8.88071 14 10 15.1193 10 16.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19 16.5C19 17.8807 17.8807 19 16.5 19C15.1193 19 14 17.8807 14 16.5C14 15.1193 15.1193 14 16.5 14C17.8807 14 19 15.1193 19 16.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M10 16H14\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9 14V7H6.07037C5.40166 7 4.7772 7.3342 4.40627 7.8906L3.3359 9.49615C3.11688 9.82469 3 10.2107 3 10.6056V14.2857C3 15.2325 3.76751 16 4.71429 16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M9 9V7C9 5.89543 9.89543 5 11 5H19C20.1046 5 21 5.89543 21 7V14C21 15.1046 20.1046 16 19 16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tmegaphone:\n\t\t'<path d=\"M17.9961 14.0001C19.6529 14.0001 20.9961 12.657 20.9961 11.0001C20.9961 9.34325 19.6529 8.0001 17.9961 8.0001M12.8254 18.0001C12.4136 19.1653 11.3023 20.0001 9.99609 20.0001C8.33924 20.0001 6.99609 18.657 6.99609 17.0001V15.5001M6.99829 6.5001V15.5001M17.9961 5.73752V16.2627C17.9961 17.617 16.6784 18.5797 15.3882 18.1681L4.38819 14.6585C3.55899 14.394 2.99609 13.6235 2.99609 12.7532V9.24704C2.99609 8.37667 3.55899 7.60622 4.38819 7.34167L15.3882 3.83215C16.6784 3.42051 17.9961 4.38325 17.9961 5.73752Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\temail:\n\t\t'<path d=\"M20.782 6.09202L19.891 6.54601L19.891 6.54601L20.782 6.09202ZM19.908 5.21799L20.362 4.32698V4.32698L19.908 5.21799ZM4.09202 5.21799L3.63803 4.32698L3.63803 4.32698L4.09202 5.21799ZM3.21799 6.09202L2.32698 5.63803L2.32698 5.63803L3.21799 6.09202ZM3.21799 17.908L4.10899 17.454L4.10899 17.454L3.21799 17.908ZM4.09202 18.782L4.54601 17.891H4.54601L4.09202 18.782ZM19.908 18.782L20.362 19.673V19.673L19.908 18.782ZM20.782 17.908L19.891 17.454L19.891 17.454L20.782 17.908ZM21 8.2H20V15.8H21H22V8.2H21ZM21 8.2H22C22 7.65645 22.0008 7.18864 21.9694 6.80497C21.9371 6.40963 21.8658 6.01641 21.673 5.63803L20.782 6.09202L19.891 6.54601C19.9162 6.59545 19.9539 6.69617 19.9761 6.96784C19.9992 7.25117 20 7.62345 20 8.2H21ZM20.782 6.09202L21.673 5.63803C21.3854 5.07354 20.9265 4.6146 20.362 4.32698L19.908 5.21799L19.454 6.10899C19.6422 6.20487 19.7951 6.35785 19.891 6.54601L20.782 6.09202ZM17.8 5V6C18.3766 6 18.7488 6.00078 19.0322 6.02393C19.3038 6.04612 19.4045 6.0838 19.454 6.10899L19.908 5.21799L20.362 4.32698C19.9836 4.13419 19.5904 4.06287 19.195 4.03057C18.8114 3.99922 18.3436 4 17.8 4V5ZM6.2 5V6H17.8V5V4H6.2V5ZM6.2 5V4C5.65645 4 5.18864 3.99922 4.80497 4.03057C4.40963 4.06287 4.01641 4.13419 3.63803 4.32698L4.09202 5.21799L4.54601 6.10899C4.59545 6.0838 4.69617 6.04612 4.96784 6.02393C5.25117 6.00078 5.62345 6 6.2 6V5ZM3.21799 6.09202L4.10899 6.54601C4.20487 6.35785 4.35785 6.20487 4.54601 6.10899L4.09202 5.21799L3.63803 4.32698C3.07354 4.6146 2.6146 5.07354 2.32698 5.63803L3.21799 6.09202ZM3 8.2H4C4 7.62345 4.00078 7.25117 4.02393 6.96784C4.04612 6.69617 4.0838 6.59545 4.10899 6.54601L3.21799 6.09202L2.32698 5.63803C2.13419 6.01641 2.06287 6.40963 2.03057 6.80497C1.99922 7.18864 2 7.65645 2 8.2H3ZM3 15.8H4V8.2H3H2V15.8H3ZM3 15.8H2C2 16.3435 1.99922 16.8114 2.03057 17.195C2.06287 17.5904 2.13419 17.9836 2.32698 18.362L3.21799 17.908L4.10899 17.454C4.0838 17.4045 4.04612 17.3038 4.02393 17.0322C4.00078 16.7488 4 16.3765 4 15.8H3ZM4.09202 18.782L4.54601 17.891C4.35785 17.7951 4.20487 17.6421 4.10899 17.454L3.21799 17.908L2.32698 18.362C2.6146 18.9265 3.07354 19.3854 3.63803 19.673L4.09202 18.782ZM6.2 19V18C5.62345 18 5.25117 17.9992 4.96784 17.9761C4.69617 17.9539 4.59545 17.9162 4.54601 17.891L4.09202 18.782L3.63803 19.673C4.01641 19.8658 4.40963 19.9371 4.80497 19.9694C5.18864 20.0008 5.65645 20 6.2 20V19ZM17.8 19V18H6.2V19V20H17.8V19ZM17.8 19V20C18.3436 20 18.8114 20.0008 19.195 19.9694C19.5904 19.9371 19.9836 19.8658 20.362 19.673L19.908 18.782L19.454 17.891C19.4045 17.9162 19.3038 17.9539 19.0322 17.9761C18.7488 17.9992 18.3766 18 17.8 18V19ZM20.782 17.908L19.891 17.454C19.7951 17.6421 19.6422 17.7951 19.454 17.891L19.908 18.782L20.362 19.673C20.9265 19.3854 21.3854 18.9265 21.673 18.362L20.782 17.908ZM21 15.8H20C20 16.3765 19.9992 16.7488 19.9761 17.0322C19.9539 17.3038 19.9162 17.4045 19.891 17.454L20.782 17.908L21.673 18.362C21.8658 17.9836 21.9371 17.5904 21.9694 17.195C22.0008 16.8114 22 16.3435 22 15.8H21Z\" fill=\"white\"/><path d=\"M21 5.63635L13.2665 11.9638C12.5297 12.5666 11.4703 12.5666 10.7335 11.9638L3 5.63635\" fill=\"white\"/>',\n\tbell: '<path d=\"M4.69376 9.44981C5.15435 5.76511 8.28661 3 12 3C15.7134 3 18.8456 5.76511 19.3062 9.44981L19.969 14.7519C20.1182 15.9456 19.1874 17 17.9844 17H6.01555C4.81256 17 3.88178 15.9456 4.031 14.7519L4.69376 9.44981Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M16 17C16 19.2091 14.2091 21 12 21C9.79086 21 8 19.2091 8 17\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tpeople:\n\t\t'<path d=\"M15.5 6.5C15.5 8.433 13.933 10 12 10C10.067 10 8.5 8.433 8.5 6.5C8.5 4.567 10.067 3 12 3C13.933 3 15.5 4.567 15.5 6.5Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12.0011 13C8.60997 13 6.03711 15.0143 4.9836 17.8629C4.5748 18.9682 5.51944 20 6.69796 20H17.3043C18.4828 20 19.4274 18.9682 19.0186 17.8629C17.9651 15.0143 15.3923 13 12.0011 13Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tsupport:\n\t\t'<path d=\"M6 10H4.5C3.67157 10 3 10.6716 3 11.5V15C3 15.8284 3.67157 16.5 4.5 16.5H6V10Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M20 10H18.5V16.5H20C20.8284 16.5 21.5 15.8284 21.5 15V11.5C21.5 10.6716 20.8284 10 20 10Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19.5 10V9.75C19.5 6.02208 16.2541 3 12.25 3C8.24594 3 5 6.02208 5 9.75V10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M12 19V19.5C12 20.3284 12.6716 21 13.5 21H15.25C17.7353 21 19.75 18.9853 19.75 16.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\thandshake:\n\t\t'<path d=\"M11.8305 5.68856C9.57907 3.43715 5.92881 3.43715 3.6774 5.68856C1.57785 7.78811 1.40103 11.1544 3.42019 13.3313C5.71921 15.8101 8.14783 18.1408 10.7345 20.3519C11.4619 20.9737 12.5313 20.9737 13.2587 20.3519C15.8453 18.1408 18.2739 15.8101 20.573 13.3313C22.5921 11.1544 22.4153 7.78811 20.3158 5.68856C18.0644 3.43715 14.4141 3.43715 12.1627 5.68856L8.8146 9.03664C8.22881 9.62243 8.22881 10.5722 8.8146 11.158C9.98617 12.3295 11.8857 12.3295 13.0572 11.158L13.7643 10.4509C14.1549 10.0603 14.788 10.0603 15.1786 10.4509L18.7141 13.9864\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tpill: '<path d=\"M17.4541 10.0962C18.6109 8.31497 18.4083 5.90826 16.8462 4.34619C15.0513 2.55127 12.1411 2.55127 10.3462 4.34619L4.34619 10.3462C2.55127 12.1411 2.55127 15.0513 4.34619 16.8462C5.90826 18.4083 8.31497 18.6109 10.0962 17.4541\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 7.5L11 11\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M16.5 20.5L14.5 10.5\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"15.5\" cy=\"15.5\" r=\"5.5\" stroke=\"white\" stroke-width=\"2\"/>',\n\t\"heart-beat\":\n\t\t'<path d=\"M16 12H14.5L13 14L10.5 10L9.25 12H8M12 5.76835C18.1619 -0.481837 28.7252 11.1257 12 20.5C-4.72523 11.1257 5.83803 -0.481838 12 5.76835Z\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n\tbook: '<path d=\"M9 6C8.44772 6 8 6.44772 8 7C8 7.55228 8.44772 8 9 8V6ZM15 8C15.5523 8 16 7.55228 16 7C16 6.44772 15.5523 6 15 6V8ZM9 10C8.44772 10 8 10.4477 8 11C8 11.5523 8.44772 12 9 12V10ZM12 12C12.5523 12 13 11.5523 13 11C13 10.4477 12.5523 10 12 10V12ZM7 4H17V2H7V4ZM18 5V19H20V5H18ZM17 20H7V22H17V20ZM6 19V5H4V19H6ZM7 20C6.44771 20 6 19.5523 6 19H4C4 20.6569 5.34315 22 7 22V20ZM18 19C18 19.5523 17.5523 20 17 20V22C18.6569 22 20 20.6569 20 19H18ZM17 4C17.5523 4 18 4.44772 18 5H20C20 3.34315 18.6569 2 17 2V4ZM7 2C5.34315 2 4 3.34315 4 5H6C6 4.44772 6.44772 4 7 4V2ZM18 12V15H20V12H18ZM17 16H7V18H17V16ZM7 22H10V20H7V22ZM7 16C5.34315 16 4 17.3431 4 19H6C6 18.4477 6.44772 18 7 18V16ZM18 15C18 15.5523 17.5523 16 17 16V18C18.6569 18 20 16.6569 20 15H18ZM9 8H15V6H9V8ZM9 12H12V10H9V12Z\" fill=\"white\"/>',\n\tgraduate:\n\t\t'<path d=\"M23 9L12 14L1 9L12 4L23 9ZM23 9V16M5 11V15.3025C5 16.0398 5.40565 16.7173 6.05556 17.0655L11.0556 19.744C11.6455 20.0601 12.3545 20.0601 12.9444 19.744L17.9444 17.0655C18.5944 16.7173 19 16.0398 19 15.3025V11\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>',\n};\n\n/**\n * Renders preset icon SVG — uses trusted static SVG content extracted from\n * @central-icons-react at build time. Content is hardcoded (not user input),\n * so innerHTML usage is safe from XSS.\n */\nfunction AgentPresetIcon({ presetId }: { presetId: string }) {\n\tconst svgContent = PRESET_SVG[presetId] ?? PRESET_SVG.sparkle;\n\treturn (\n\t\t// biome-ignore lint: trusted static SVG content from our icon library\n\t\t<svg\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tstyle={{ width: \"55%\", height: \"55%\" }}\n\t\t\tdangerouslySetInnerHTML={{ __html: svgContent ?? \"\" }}\n\t\t/>\n\t);\n}\n\n/**\n * Unified support widget — Intercom-style with tab navigation.\n * Two tabs: Home + Messages. Sub-views: conversation + new conversation.\n */\nexport function DefaultWidget({ hideLauncher = false }: { hideLauncher?: boolean } = {}) {\n\tconst { isReady, website, agentConfig } = useWidget();\n\tuseI18n();\n\tconst { client, store, hasBootstrapError, wsDisconnected, retryBootstrap } = useWidgetContext();\n\tconst { conversations, create, isCreating, setActiveConversation } = useConversations();\n\tconst activeId = useWidgetStore((s) => s.activeConversationId);\n\tconst isDismissed = useWidgetStore((s) => s.isDismissed);\n\tconst { totalUnread } = useUnread();\n\n\tconst contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_CONTENT_TABS;\n\n\tconst visitorContact = useWidgetStore((s) => s.visitor?.contact);\n\n\t// DEV: email prompt debug\n\tif (process.env.NODE_ENV !== \"production\") {\n\t\tconsole.debug(\"[Widget]\", {\n\t\t\treqEmail: agentConfig?.requireVisitorEmail,\n\t\t\tcontact: visitorContact?.email ?? null,\n\t\t\tactiveId,\n\t\t});\n\t}\n\n\tconst storeIsOpen = useWidgetStore((s) => s.isOpen);\n\tconst [isClosing, setIsClosing] = useState(false);\n\tconst isOpen = storeIsOpen || isClosing;\n\tconst [activeTab, setActiveTab] = useState<Tab>(\"home\");\n\tconst [subView, setSubView] = useState<SubView>(null);\n\tconst [newText, setNewText] = useState(\"\");\n\tconst [contentDetailSlug, setContentDetailSlug] = useState<string | null>(null);\n\tconst [contentCategoryName, setContentCategoryName] = useState<string | null>(null);\n\n\t// Sync API-driven navigation: when store.activeConversationId changes externally\n\t// (via window.Helpway.openConversation), drive the local subView to match.\n\tconst prevActiveIdRef = useRef(activeId);\n\tuseEffect(() => {\n\t\tif (activeId && activeId !== prevActiveIdRef.current && subView !== \"conversation\") {\n\t\t\tsetSubView(\"conversation\");\n\t\t}\n\t\tprevActiveIdRef.current = activeId;\n\t}, [activeId, subView]);\n\n\t// Consume newConversationPrefill from global API (window.Helpway.newConversation)\n\tconst prefill = useWidgetStore((s) => s.newConversationPrefill);\n\tuseEffect(() => {\n\t\tif (prefill !== null) {\n\t\t\tif (prefill.length > 0) setNewText(prefill);\n\t\t\tsetSubView(\"new\");\n\t\t\tsetActiveTab(\"home\");\n\t\t\tstore.getState().setNewConversationPrefill(null);\n\t\t}\n\t}, [prefill, store]);\n\tconst closeTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n\t// Resolve welcome/subtitle here (used both by openNewConversation seed\n\t// and by the header). Hoisted above openNewConversation so the callback\n\t// captures a defined binding instead of hitting the TDZ at closure time.\n\tconst welcomeMsgRaw = agentConfig?.welcomeMessage;\n\tconst welcomeIsFactoryDefault =\n\t\t!welcomeMsgRaw || welcomeMsgRaw === DEFAULT_EN_WELCOME;\n\tconst welcomeMessage = welcomeMsgRaw?.startsWith(\"widget.\")\n\t\t? t(welcomeMsgRaw)\n\t\t: welcomeIsFactoryDefault\n\t\t\t? t(\"widget.welcome_message\")\n\t\t\t: welcomeMsgRaw;\n\n\tconst openConversation = useCallback(\n\t\t(id: string) => {\n\t\t\tsetActiveConversation(id);\n\t\t\tsetSubView(\"conversation\");\n\t\t},\n\t\t[setActiveConversation],\n\t);\n\n\tconst openNewConversation = useCallback(() => {\n\t\t// Seed a temp conversation + a stable welcome bubble and drop the user\n\t\t// straight into \"conversation\" view. This keeps the welcome bubble\n\t\t// mounted in the SAME React subtree across the first-send transition\n\t\t// (previously: \"new\" view → \"conversation\" view = unmount + remount =\n\t\t// CSS `hw-msg-appear` animation replays = the \"git-gel\" flash).\n\t\t//\n\t\t// useComposer notices the temp id and routes through createConversation\n\t\t// when the visitor sends their first message.\n\t\tconst agentId = agentConfig?.id;\n\t\tif (!agentId) {\n\t\t\t// No agent config yet — skip the seed and let the server decide.\n\t\t\t// The user can still compose; submit will call createConversation.\n\t\t\tsetSubView(\"new\");\n\t\t\treturn;\n\t\t}\n\t\tconst tempId = `temp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\t\tconst seedWelcome: TimelineItem = {\n\t\t\tid: `seed-welcome-${tempId}`,\n\t\t\tconversationId: tempId,\n\t\t\torganizationId: \"\",\n\t\t\ttype: \"message\",\n\t\t\tvisibility: \"public\",\n\t\t\ttext: welcomeMessage,\n\t\t\tparts: null,\n\t\t\tuserId: null,\n\t\t\tvisitorId: null,\n\t\t\taiAgentId: agentId,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t\teditedAt: null,\n\t\t\tdeletedAt: null,\n\t\t};\n\t\tstore.getState().setMessages(tempId, [seedWelcome]);\n\t\tsetActiveConversation(tempId);\n\t\tsetSubView(\"conversation\");\n\t}, [agentConfig?.id, store, setActiveConversation, welcomeMessage]);\n\n\tconst goBack = useCallback(() => {\n\t\tif (subView === \"content-detail\") {\n\t\t\t// If inside a grouped tab, go back to category items, not all the way to categories\n\t\t\tconst tabId = activeTab.startsWith(\"content:\") ? activeTab.slice(8) : null;\n\t\t\tconst activeContentTab = tabId ? contentTabs.find((t) => t.id === tabId) : null;\n\t\t\tif (activeContentTab?.tabType === \"grouped\" && contentCategoryName) {\n\t\t\t\tsetSubView(\"content-category\");\n\t\t\t\tsetContentDetailSlug(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetSubView(null);\n\t\t\tsetContentDetailSlug(null);\n\t\t\treturn;\n\t\t}\n\t\tif (subView === \"content-category\") {\n\t\t\tsetSubView(null);\n\t\t\tsetContentCategoryName(null);\n\t\t\treturn;\n\t\t}\n\t\t// Race-immune mark-seen: when leaving a conversation, the visitor has\n\t\t// effectively \"seen\" everything currently in it — including any AI reply\n\t\t// that may have arrived via WS milliseconds before they tapped back.\n\t\t// Without this, the WS event arriving AFTER setActiveConversation(null)\n\t\t// finds isViewing=false and increments unreadCount.\n\t\t// Skip temp-* IDs (server doesn't know about them yet).\n\t\tconst leavingId = store.getState().activeConversationId;\n\t\tif (leavingId && !leavingId.startsWith(\"temp-\")) {\n\t\t\tstore.getState().clearUnread(leavingId);\n\t\t\tclient.widget.markSeen.mutate({ conversationId: leavingId }).catch(() => {});\n\t\t}\n\t\tsetActiveConversation(null);\n\t\tsetSubView(null);\n\t}, [setActiveConversation, subView, activeTab, contentTabs, contentCategoryName, client, store]);\n\n\tconst switchTab = useCallback(\n\t\t(tab: Tab) => {\n\t\t\t// Save current tab state\n\t\t\ttabStateRef.current[activeTab] = { subView, activeId };\n\t\t\t// Restore target tab state (if any)\n\t\t\tconst saved = tabStateRef.current[tab];\n\t\t\tsetActiveTab(tab);\n\t\t\tsetSubView(saved?.subView ?? null);\n\t\t\tif (saved?.activeId != null) {\n\t\t\t\tsetActiveConversation(saved.activeId);\n\t\t\t} else if (!saved) {\n\t\t\t\tsetActiveConversation(null);\n\t\t\t}\n\t\t},\n\t\t[activeTab, subView, activeId, setActiveConversation],\n\t);\n\n\tconst setStoreOpen = useWidgetStore((s) => s.setOpen);\n\n\tconst handleBubbleClick = useCallback(() => {\n\t\tif (storeIsOpen) {\n\t\t\tconst leavingId = store.getState().activeConversationId;\n\t\t\tif (leavingId && !leavingId.startsWith(\"temp-\")) {\n\t\t\t\tstore.getState().clearUnread(leavingId);\n\t\t\t\tclient.widget.markSeen.mutate({ conversationId: leavingId }).catch(() => {});\n\t\t\t}\n\t\t\tsetIsClosing(true);\n\t\t\tcloseTimerRef.current = setTimeout(() => {\n\t\t\t\tsetIsClosing(false);\n\t\t\t\tsetStoreOpen(false);\n\t\t\t}, 200);\n\t\t} else {\n\t\t\tsetIsClosing(false);\n\t\t\tsetSubView(null);\n\t\t\tsetActiveTab(\"home\");\n\t\t\tsetStoreOpen(true);\n\t\t}\n\t}, [storeIsOpen, setStoreOpen, client, store]);\n\n\tconst handleClose = useCallback(() => {\n\t\tconst leavingId = store.getState().activeConversationId;\n\t\tif (leavingId && !leavingId.startsWith(\"temp-\")) {\n\t\t\tstore.getState().clearUnread(leavingId);\n\t\t\tclient.widget.markSeen.mutate({ conversationId: leavingId }).catch(() => {});\n\t\t}\n\t\tsetIsClosing(true);\n\t\tcloseTimerRef.current = setTimeout(() => {\n\t\t\tsetIsClosing(false);\n\t\t\tsetStoreOpen(false);\n\t\t}, 200);\n\t}, [setStoreOpen, client, store]);\n\n\tconst handleNewConversation = useCallback(async () => {\n\t\tconst trimmed = newText.trim();\n\t\tif (!trimmed || isCreating) return;\n\t\tconst conv = await create(trimmed);\n\t\tif (conv) {\n\t\t\tsetNewText(\"\");\n\t\t\tsetSubView(\"conversation\");\n\t\t}\n\t}, [newText, isCreating, create]);\n\n\tconst windowRef = useRef<HTMLDivElement>(null);\n\tconst bubbleRef = useRef<HTMLButtonElement>(null);\n\tconst tabStateRef = useRef<{ [tab: string]: { subView: SubView; activeId: string | null } }>({});\n\tconst touchStartY = useRef(0);\n\tconst touchDeltaY = useRef(0);\n\n\tconst handleTouchStart = useCallback((e: React.TouchEvent) => {\n\t\ttouchStartY.current = e.touches[0]?.clientY ?? 0;\n\t\ttouchDeltaY.current = 0;\n\t}, []);\n\n\tconst handleTouchMove = useCallback((e: React.TouchEvent) => {\n\t\tconst delta = (e.touches[0]?.clientY ?? 0) - touchStartY.current;\n\t\ttouchDeltaY.current = delta;\n\t\tif (delta > 0 && windowRef.current) {\n\t\t\twindowRef.current.style.transform = `translateY(${Math.min(delta, 200)}px)`;\n\t\t\twindowRef.current.style.opacity = `${Math.max(1 - delta / 400, 0.5)}`;\n\t\t}\n\t}, []);\n\n\tconst handleTouchEnd = useCallback(() => {\n\t\tif (windowRef.current) {\n\t\t\twindowRef.current.style.transform = \"\";\n\t\t\twindowRef.current.style.opacity = \"\";\n\t\t}\n\t\tif (touchDeltaY.current > 80) {\n\t\t\thandleClose();\n\t\t}\n\t}, [handleClose]);\n\n\t// iOS virtual keyboard — `height: 100%` in CSS refers to the LAYOUT\n\t// viewport, which doesn't shrink when the keyboard opens on iOS Safari.\n\t// The result: composer gets pushed below the visible area and visitors\n\t// can't see what they're typing. visualViewport.height is the one\n\t// reliable API that reflects post-keyboard space. We write it to a CSS\n\t// custom property the mobile @media block consumes.\n\tuseEffect(() => {\n\t\tif (!isOpen || !windowRef.current) return;\n\t\tconst vv = window.visualViewport;\n\t\tif (!vv) return;\n\t\tconst win = windowRef.current;\n\t\tconst applyHeight = () => {\n\t\t\twin.style.setProperty(\"--hw-visible-height\", `${vv.height}px`);\n\t\t};\n\t\tapplyHeight();\n\t\tvv.addEventListener(\"resize\", applyHeight);\n\t\tvv.addEventListener(\"scroll\", applyHeight);\n\t\treturn () => {\n\t\t\tvv.removeEventListener(\"resize\", applyHeight);\n\t\t\tvv.removeEventListener(\"scroll\", applyHeight);\n\t\t\twin.style.removeProperty(\"--hw-visible-height\");\n\t\t};\n\t}, [isOpen]);\n\n\t// Escape to close / back — listener attached to the widget window, NOT\n\t// document. Two reasons: (1) widget lives inside a shadow DOM; document\n\t// listeners fire for host-page key events too, which would close the\n\t// widget when a visitor presses ESC in the host site's own search box.\n\t// (2) WCAG 2.1 AA requires focus-scoped escape behavior for dialogs.\n\tuseEffect(() => {\n\t\tif (!isOpen || !windowRef.current) return;\n\t\tconst win = windowRef.current;\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (e.key === \"Escape\") {\n\t\t\t\tif (subView) {\n\t\t\t\t\tgoBack();\n\t\t\t\t} else {\n\t\t\t\t\thandleClose();\n\t\t\t\t\tsetTimeout(() => bubbleRef.current?.focus(), 220);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\twin.addEventListener(\"keydown\", handleKeyDown);\n\t\treturn () => win.removeEventListener(\"keydown\", handleKeyDown);\n\t}, [isOpen, subView, handleClose, goBack]);\n\n\t// Focus trap — same rationale: listen on the widget window so only\n\t// keydowns inside the widget are trapped. `document.activeElement`\n\t// returns the shadow HOST when focus is inside a shadow root; to find\n\t// the actually-focused element we walk into the shadow root.\n\tuseEffect(() => {\n\t\tif (!isOpen || !windowRef.current) return;\n\t\tconst win = windowRef.current;\n\t\tconst getFocusable = () =>\n\t\t\twin.querySelectorAll<HTMLElement>(\n\t\t\t\t'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n\t\t\t);\n\t\tconst getActive = (): Element | null => {\n\t\t\t// Prefer the shadow root's activeElement so focus tracking works\n\t\t\t// even when the widget is mounted inside a closed/open shadow DOM.\n\t\t\tconst root = win.getRootNode();\n\t\t\tif (root instanceof ShadowRoot) return root.activeElement;\n\t\t\treturn document.activeElement;\n\t\t};\n\t\tconst handleTab = (e: KeyboardEvent) => {\n\t\t\tif (e.key !== \"Tab\") return;\n\t\t\tconst focusable = getFocusable();\n\t\t\tif (focusable.length === 0) return;\n\t\t\tconst first = focusable[0];\n\t\t\tconst last = focusable[focusable.length - 1];\n\t\t\tconst active = getActive();\n\t\t\tif (e.shiftKey && active === first) {\n\t\t\t\te.preventDefault();\n\t\t\t\tlast?.focus();\n\t\t\t} else if (!e.shiftKey && active === last) {\n\t\t\t\te.preventDefault();\n\t\t\t\tfirst?.focus();\n\t\t\t}\n\t\t};\n\t\twin.addEventListener(\"keydown\", handleTab);\n\t\tconst focusable = getFocusable();\n\t\tif (focusable.length > 0) focusable[0]?.focus();\n\t\treturn () => win.removeEventListener(\"keydown\", handleTab);\n\t}, [isOpen]);\n\n\tconst showTabBar = subView === null;\n\tconst activeConvSummary = useWidgetStore((s) => {\n\t\tconst id = s.activeConversationId;\n\t\treturn id ? s.conversations.find((c) => c.id === id) : null;\n\t});\n\t// Header name resolution mirrors WidgetLogo's avatar resolution:\n\t// 1. Assigned support user (sticky once a human takes over)\n\t// 2. Last team-side sender (in case there's no formal assignment\n\t// but a teammate jumped in for one message)\n\t// 3. AI agent name / website name\n\tconst assigneeName = activeConvSummary?.assigneeName;\n\tconst hasTeamAgent =\n\t\tactiveConvSummary?.lastMessageSenderType === \"team\" &&\n\t\tactiveConvSummary?.lastMessageSenderName;\n\tconst headerName = assigneeName\n\t\t? assigneeName\n\t\t: hasTeamAgent\n\t\t\t? activeConvSummary.lastMessageSenderName!\n\t\t\t: (agentConfig?.name ?? website?.name ?? \"Support\");\n\tconst companyName = agentConfig?.name ?? website?.name ?? \"Support\";\n\tconst subtitleMsg = agentConfig?.subtitleText;\n\tconst subtitleIsFactoryDefault =\n\t\t!subtitleMsg || subtitleMsg === DEFAULT_EN_SUBTITLE;\n\tconst subtitleText = subtitleMsg?.startsWith(\"widget.\")\n\t\t? t(subtitleMsg)\n\t\t: subtitleIsFactoryDefault\n\t\t\t? t(\"widget.subtitle_text\")\n\t\t\t: subtitleMsg;\n\tconst brandColor = agentConfig?.brandColor ?? \"#0a0a0a\";\n\tconst widgetPosition = agentConfig?.widgetPosition ?? \"bottom-right\";\n\tconst launcherStyle = agentConfig?.launcherStyle ?? \"icon\";\n\tconst bubbleStyle = agentConfig?.bubbleStyle ?? \"rounded\";\n\n\treturn (\n\t\t<div\n\t\t\tclassName=\"hw-widget\"\n\t\t\tstyle={\n\t\t\t\t{\n\t\t\t\t\t\"--hw-primary\": brandColor,\n\t\t\t\t\t\"--hw-position-right\": widgetPosition === \"bottom-right\" ? \"20px\" : \"auto\",\n\t\t\t\t\t\"--hw-position-left\": widgetPosition === \"bottom-left\" ? \"20px\" : \"auto\",\n\t\t\t\t\t\"--hw-window-right\": widgetPosition === \"bottom-right\" ? \"0\" : \"auto\",\n\t\t\t\t\t\"--hw-window-left\": widgetPosition === \"bottom-left\" ? \"0\" : \"auto\",\n\t\t\t\t} as React.CSSProperties\n\t\t\t}\n\t\t>\n\t\t\t{isOpen && !isReady && !hasBootstrapError && (\n\t\t\t\t<div className={`hw-window ${isClosing ? \"hw-window--closing\" : \"\"}`}>\n\t\t\t\t\t<div className=\"hw-skeleton-loading\">\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 120 }} />\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 200 }} />\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 160 }} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{isOpen && hasBootstrapError && (\n\t\t\t\t<div className={`hw-window ${isClosing ? \"hw-window--closing\" : \"\"}`}>\n\t\t\t\t\t<div className=\"hw-bootstrap-error\">\n\t\t\t\t\t\t<div className=\"hw-bootstrap-error-text\">{t(\"widget.error_desc\")}</div>\n\t\t\t\t\t\t<button type=\"button\" className=\"hw-bootstrap-error-retry\" onClick={retryBootstrap}>\n\t\t\t\t\t\t\t{t(\"widget.retry\")}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{isOpen && isReady && (\n\t\t\t\t<div\n\t\t\t\t\tref={windowRef}\n\t\t\t\t\tclassName={`hw-window ${isClosing ? \"hw-window--closing\" : \"\"} ${\n\t\t\t\t\t\tsubView === \"content-detail\" ? \"hw-window--reading\" : \"\"\n\t\t\t\t\t}`}\n\t\t\t\t\trole=\"dialog\"\n\t\t\t\t\taria-label={t(\"widget.aria_chat\")}\n\t\t\t\t\taria-modal=\"true\"\n\t\t\t\t\tonTouchStart={handleTouchStart}\n\t\t\t\t\tonTouchMove={handleTouchMove}\n\t\t\t\t\tonTouchEnd={handleTouchEnd}\n\t\t\t\t>\n\t\t\t\t\t{/* Drag handle for mobile swipe-down */}\n\t\t\t\t\t<div className=\"hw-drag-handle\">\n\t\t\t\t\t\t<div className=\"hw-drag-handle-pill\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t{/* WebSocket disconnect banner */}\n\t\t\t\t\t{wsDisconnected && (\n\t\t\t\t\t\t<div className=\"hw-disconnect\">\n\t\t\t\t\t\t\t<div className=\"hw-disconnect-dot\" />\n\t\t\t\t\t\t\t{t(\"widget.reconnecting\")}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t{/* ── Sub-view header: content-detail/content-category gets centered title ── */}\n\t\t\t\t\t{(subView === \"content-detail\" || subView === \"content-category\") &&\n\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\tconst tabId = activeTab.replace(\"content:\", \"\");\n\t\t\t\t\t\t\tconst contentTab = contentTabs.find((t) => t.id === tabId);\n\t\t\t\t\t\t\t// Show category name when viewing items within a category\n\t\t\t\t\t\t\tconst headerTitle =\n\t\t\t\t\t\t\t\tsubView === \"content-category\" && contentCategoryName\n\t\t\t\t\t\t\t\t\t? contentCategoryName\n\t\t\t\t\t\t\t\t\t: contentTab?.label\n\t\t\t\t\t\t\t\t\t\t? resolveLabel(contentTab.label)\n\t\t\t\t\t\t\t\t\t\t: t(\"widget.content\");\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div className=\"hw-header hw-header--centered\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"hw-header-back\"\n\t\t\t\t\t\t\t\t\t\tonClick={goBack}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_back\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M15 18l-6-6 6-6\" />\n\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-title\">{headerTitle}</div>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"hw-header-close\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})()}\n\t\t\t\t\t{subView !== null && subView !== \"content-detail\" && subView !== \"content-category\" && (\n\t\t\t\t\t\t<div className=\"hw-header hw-header--sub\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-header-back\"\n\t\t\t\t\t\t\t\tonClick={goBack}\n\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_back\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<path d=\"M15 18l-6-6 6-6\" />\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<div className=\"hw-header-identity\">\n\t\t\t\t\t\t\t\t<div className={`hw-header-bot-icon${hasTeamAgent ? \" hw-header-bot-icon--team\" : \"\"}`}>\n\t\t\t\t\t\t\t\t\t{hasTeamAgent && activeConvSummary?.lastMessageSenderImage ? (\n\t\t\t\t\t\t\t\t\t\t<img src={activeConvSummary.lastMessageSenderImage} alt={headerName} className=\"hw-header-agent-img\" />\n\t\t\t\t\t\t\t\t\t) : hasTeamAgent ? (\n\t\t\t\t\t\t\t\t\t\t<span className=\"hw-header-agent-initials\">\n\t\t\t\t\t\t\t\t\t\t\t{headerName.split(\" \").map((w: string) => w[0]).join(\"\").slice(0, 2).toUpperCase()}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<WidgetLogo />\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"hw-header-info\">\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-name\">{headerName}</div>\n\t\t\t\t\t\t\t\t\t{/* Keep the subtitle identical in both \"new\" and \"conversation\"\n\t\t\t\t\t\t\t\t\t sub-views — otherwise the header reads \"New conversation\"\n\t\t\t\t\t\t\t\t\t while composing and snaps to \"Usually replies in minutes\"\n\t\t\t\t\t\t\t\t\t the moment you send, which feels like the whole header\n\t\t\t\t\t\t\t\t\t rebuilt. */}\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-status\">{subtitleText}</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-header-close\"\n\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Home: hero header with gradient + sheet overlay ── */}\n\t\t\t\t\t{subView === null && activeTab === \"home\" && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<div className=\"hw-hero\">\n\t\t\t\t\t\t\t\t<div className=\"hw-hero-top\">\n\t\t\t\t\t\t\t\t\t<div className=\"hw-hero-bot-icon\">\n\t\t\t\t\t\t\t\t\t\t<WidgetLogo />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"hw-hero-close\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"hw-hero-greeting\">\n\t\t\t\t\t\t\t\t\t{welcomeMessage.split(\"\\n\").map((line, i) => (\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\t\t\t\t\t\tclassName={i === 0 ? \"hw-hero-greeting-name\" : \"hw-hero-greeting-question\"}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{i > 0 && <br />}\n\t\t\t\t\t\t\t\t\t\t\t{line}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"hw-hero-subtitle\">{subtitleText}</div>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{/* Sheet — overlaps hero, Intercom-style white drawer */}\n\t\t\t\t\t\t\t<div className=\"hw-sheet\">\n\t\t\t\t\t\t\t\t<div className=\"hw-sheet-inner\">\n\t\t\t\t\t\t\t\t\t<button type=\"button\" className=\"hw-card\" onClick={openNewConversation}>\n\t\t\t\t\t\t\t\t\t\t<div className=\"hw-card-body\">\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"hw-card-title\">{t(\"widget.send_us_message\")}</div>\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"hw-card-meta\">{t(\"widget.reply_time\")}</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div className=\"hw-card-arrow\">\n\t\t\t\t\t\t\t\t\t\t\t<SendIcon />\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<HomeView\n\t\t\t\t\t\t\t\t\t\tconversations={conversations}\n\t\t\t\t\t\t\t\t\t\tonSelect={openConversation}\n\t\t\t\t\t\t\t\t\t\tonMessagesClick={() => switchTab(\"messages\")}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Messages tab header ── */}\n\t\t\t\t\t{subView === null && activeTab === \"messages\" && (\n\t\t\t\t\t\t<div className=\"hw-header hw-header--centered\">\n\t\t\t\t\t\t\t<div className=\"hw-header-spacer\" />\n\t\t\t\t\t\t\t<div className=\"hw-header-title\">{t(\"widget.messages\")}</div>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-header-close\"\n\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Content tab header (list view, not detail) ── */}\n\t\t\t\t\t{subView === null &&\n\t\t\t\t\t\tactiveTab.startsWith(\"content:\") &&\n\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\tconst tabId = activeTab.replace(\"content:\", \"\");\n\t\t\t\t\t\t\tconst contentTab = contentTabs.find((t) => t.id === tabId);\n\t\t\t\t\t\t\tif (!contentTab) return null;\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div className=\"hw-header hw-header--centered\">\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-spacer\" />\n\t\t\t\t\t\t\t\t\t<div className=\"hw-header-title\">{resolveLabel(contentTab.label)}</div>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"hw-header-close\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\t\t\t\t\t\taria-label={t(\"widget.aria_close\")}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})()}\n\n\t\t\t\t\t{/* ── Content (non-home views) ── */}\n\t\t\t\t\t{(subView !== null || activeTab !== \"home\") && (\n\t\t\t\t\t\t<div className=\"hw-content\">\n\t\t\t\t\t\t\t{subView === null && activeTab === \"messages\" && (\n\t\t\t\t\t\t\t\t<MessagesView\n\t\t\t\t\t\t\t\t\tconversations={conversations}\n\t\t\t\t\t\t\t\t\tonSelect={openConversation}\n\t\t\t\t\t\t\t\t\tonNewClick={openNewConversation}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{subView === \"new\" && (\n\t\t\t\t\t\t\t\t<NewConversationView\n\t\t\t\t\t\t\t\t\ttext={newText}\n\t\t\t\t\t\t\t\t\tonTextChange={setNewText}\n\t\t\t\t\t\t\t\t\tonSubmit={handleNewConversation}\n\t\t\t\t\t\t\t\t\tisSubmitting={isCreating}\n\t\t\t\t\t\t\t\t\twelcomeMessage={welcomeMessage}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{subView === \"conversation\" && activeId && (\n\t\t\t\t\t\t\t\t<ConversationView conversationId={activeId} />\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{/* ── Content tab views ── */}\n\t\t\t\t\t\t\t{activeTab.startsWith(\"content:\") &&\n\t\t\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\t\t\tconst tabId = activeTab.replace(\"content:\", \"\");\n\t\t\t\t\t\t\t\t\tconst contentTab = contentTabs.find((t) => t.id === tabId);\n\t\t\t\t\t\t\t\t\tif (!contentTab) return null;\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<ContentTabView\n\t\t\t\t\t\t\t\t\t\t\ttab={contentTab}\n\t\t\t\t\t\t\t\t\t\t\tshowDetail={subView === \"content-detail\"}\n\t\t\t\t\t\t\t\t\t\t\tdetailSlug={contentDetailSlug}\n\t\t\t\t\t\t\t\t\t\t\tsubView={subView}\n\t\t\t\t\t\t\t\t\t\t\tonSelectEntry={(slug) => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetContentDetailSlug(slug);\n\t\t\t\t\t\t\t\t\t\t\t\tsetSubView(\"content-detail\");\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonSelectCategory={(cat) => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetContentCategoryName(cat.title);\n\t\t\t\t\t\t\t\t\t\t\t\tsetSubView(\"content-category\");\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t})()}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Tab Bar ── */}\n\t\t\t\t\t{showTabBar && (\n\t\t\t\t\t\t<TabBar\n\t\t\t\t\t\t\tactiveTab={activeTab}\n\t\t\t\t\t\t\tonTabChange={switchTab}\n\t\t\t\t\t\t\tunreadCount={totalUnread}\n\t\t\t\t\t\t\tcontentTabs={contentTabs}\n\t\t\t\t\t\t\tshowMessagesTab={agentConfig?.showMessagesTab ?? true}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* ── Footer ── */}\n\t\t\t\t\t<div className=\"hw-powered\">\n\t\t\t\t\t\t{t(\"widget.powered_by\")}{\" \"}\n\t\t\t\t\t\t<a href=\"https://helpway.ai\" target=\"_blank\" rel=\"noopener noreferrer\">\n\t\t\t\t\t\t\tHelpway\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Message Preview — shown when widget is closed and not dismissed */}\n\t\t\t{!isOpen && !isDismissed && !hideLauncher && <MessagePreview onOpen={handleBubbleClick} />}\n\n\t\t\t{/* Dev-only debug overlay — activates via ?hwdebug=1 or localStorage hw:debug=1 */}\n\t\t\t<WidgetDebugOverlay />\n\n\t\t\t{/* Bubble — hidden when dismissed; when hideLauncher is set, still show while open (close button) */}\n\t\t\t{!isDismissed && (!hideLauncher || isOpen) && (\n\t\t\t\t<button\n\t\t\t\t\tref={bubbleRef}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={[\n\t\t\t\t\t\t\"hw-bubble\",\n\t\t\t\t\t\t`hw-bubble--${bubbleStyle}`,\n\t\t\t\t\t\tlauncherStyle !== \"icon\" ? `hw-bubble--launcher-${launcherStyle}` : \"\",\n\t\t\t\t\t\tisOpen ? \"hw-bubble--open\" : \"\",\n\t\t\t\t\t\t(agentConfig?.launcherIconUrl || agentConfig?.avatarUrl || website?.logoUrl) ? \"hw-bubble--avatar\" : \"\",\n\t\t\t\t\t]\n\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t.join(\" \")}\n\t\t\t\t\tonClick={handleBubbleClick}\n\t\t\t\t\taria-label={isOpen ? t(\"widget.aria_close_support\") : t(\"widget.aria_open\")}\n\t\t\t\t\taria-expanded={isOpen}\n\t\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName={`hw-bubble-icon hw-bubble-icon--bot ${isOpen ? \"hw-bubble-icon--hidden\" : \"\"}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<LauncherIcon />\n\t\t\t\t\t</span>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName={`hw-bubble-icon hw-bubble-icon--close ${!isOpen ? \"hw-bubble-icon--hidden\" : \"\"}`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<XIcon size={24} />\n\t\t\t\t\t</span>\n\t\t\t\t\t{launcherStyle !== \"icon\" && !isOpen && (\n\t\t\t\t\t\t<span className=\"hw-bubble-label\">\n\t\t\t\t\t\t\t{launcherStyle === \"help\" ? t(\"widget.help\") : companyName}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{!isOpen && totalUnread > 0 && <div className=\"hw-bubble-badge\">{totalUnread}</div>}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ── Tab Bar ─────────────────────────────────────────────\n\nfunction TabBar({\n\tactiveTab,\n\tonTabChange,\n\tunreadCount,\n\tcontentTabs,\n\tshowMessagesTab = true,\n}: {\n\tactiveTab: Tab;\n\tonTabChange: (tab: Tab) => void;\n\tunreadCount: number;\n\tcontentTabs: WidgetContentTab[];\n\tshowMessagesTab?: boolean;\n}) {\n\treturn (\n\t\t<div className=\"hw-tabs\" role=\"tablist\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={`hw-tabs-item ${activeTab === \"home\" ? \"hw-tabs-item--active\" : \"\"}`}\n\t\t\t\tonClick={() => onTabChange(\"home\")}\n\t\t\t\trole=\"tab\"\n\t\t\t\taria-selected={activeTab === \"home\"}\n\t\t\t>\n\t\t\t\t<HomeIcon />\n\t\t\t\t<span>{t(\"widget.home\")}</span>\n\t\t\t</button>\n\t\t\t{showMessagesTab && (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={`hw-tabs-item ${activeTab === \"messages\" ? \"hw-tabs-item--active\" : \"\"}`}\n\t\t\t\t\tonClick={() => onTabChange(\"messages\")}\n\t\t\t\t\trole=\"tab\"\n\t\t\t\t\taria-selected={activeTab === \"messages\"}\n\t\t\t\t>\n\t\t\t\t\t<span className=\"hw-tabs-icon-wrap\">\n\t\t\t\t\t\t<MessagesIcon />\n\t\t\t\t\t\t{unreadCount > 0 && (\n\t\t\t\t\t\t\t<span className=\"hw-tabs-badge\">{unreadCount > 99 ? \"99+\" : unreadCount}</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</span>\n\t\t\t\t\t<span>{t(\"widget.messages\")}</span>\n\t\t\t\t</button>\n\t\t\t)}\n\t\t\t{/* Dynamic content tabs from Better i18n Content CMS */}\n\t\t\t{contentTabs.map((tab) => (\n\t\t\t\t<button\n\t\t\t\t\tkey={tab.id}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={`hw-tabs-item ${activeTab === `content:${tab.id}` ? \"hw-tabs-item--active\" : \"\"}`}\n\t\t\t\t\tonClick={() => onTabChange(`content:${tab.id}`)}\n\t\t\t\t\trole=\"tab\"\n\t\t\t\t\taria-selected={activeTab === `content:${tab.id}`}\n\t\t\t\t>\n\t\t\t\t\t<ContentTabIconComponent icon={tab.icon} />\n\t\t\t\t\t<span>{resolveLabel(tab.label)}</span>\n\t\t\t\t</button>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\n// ── Home Tab ────────────────────────────────────────────\n\nfunction HomeView({\n\tconversations,\n\tonSelect,\n\tonMessagesClick,\n}: {\n\tconversations: ConversationSummary[];\n\tonSelect: (id: string) => void;\n\tonMessagesClick: () => void;\n}) {\n\tconst recent = conversations.slice(0, 3);\n\tif (recent.length === 0) return null;\n\n\treturn (\n\t\t<div className=\"hw-recent-card\">\n\t\t\t<div className=\"hw-recent-header\">{t(\"widget.recent_conversations\")}</div>\n\t\t\t{recent.map((conv, i) => (\n\t\t\t\t<ConversationRow\n\t\t\t\t\tkey={conv.id}\n\t\t\t\t\tconversation={conv}\n\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\tisLast={i === recent.length - 1}\n\t\t\t\t/>\n\t\t\t))}\n\t\t\t{conversations.length > 3 && (\n\t\t\t\t<button type=\"button\" className=\"hw-recent-see-all\" onClick={onMessagesClick}>\n\t\t\t\t\t{t(\"widget.see_all\")}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ── Messages Tab ────────────────────────────────────────\n\nfunction MessagesView({\n\tconversations,\n\tonSelect,\n\tonNewClick,\n}: {\n\tconversations: ConversationSummary[];\n\tonSelect: (id: string) => void;\n\tonNewClick: () => void;\n}) {\n\tif (conversations.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"hw-empty-state\">\n\t\t\t\t<div className=\"hw-empty-icon-wrap\">\n\t\t\t\t\t<MessagesIcon />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hw-empty-title\">{t(\"widget.no_messages\")}</div>\n\t\t\t\t<div className=\"hw-empty-desc\">{t(\"widget.no_messages_desc\")}</div>\n\t\t\t\t<button type=\"button\" className=\"hw-empty-btn\" onClick={onNewClick}>\n\t\t\t\t\t{t(\"widget.start_conversation\")}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"hw-msgs-tab\">\n\t\t\t{conversations.map((conv) => (\n\t\t\t\t<ConversationCard key={conv.id} conversation={conv} onSelect={onSelect} />\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\n// ── Shared conversation body (avatar + name + time + preview) ──\n\nfunction ConvCardBody({ conv }: { conv: ConversationSummary }) {\n\tconst agentName = useWidgetStore((s) => s.agentConfig?.name) ?? \"Support\";\n\tconst isTeam = conv.lastMessageSenderType === \"team\" && conv.lastMessageSenderName;\n\tconst displayName = isTeam ? conv.lastMessageSenderName! : agentName;\n\tconst preview = conv.lastMessageText ?? t(\"widget.no_preview\");\n\treturn (\n\t\t<>\n\t\t\t<div className={`hw-conv-card-avatar${isTeam ? \" hw-conv-card-avatar--team\" : \"\"}`}>\n\t\t\t\t{isTeam ? (\n\t\t\t\t\tconv.lastMessageSenderImage ? (\n\t\t\t\t\t\t<img src={conv.lastMessageSenderImage} alt={displayName} className=\"hw-conv-card-avatar-img\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span className=\"hw-conv-card-avatar-initials\">\n\t\t\t\t\t\t\t{displayName.split(\" \").map((w) => w[0]).join(\"\").slice(0, 2).toUpperCase()}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)\n\t\t\t\t) : (\n\t\t\t\t\t<WidgetLogo />\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<div className=\"hw-conv-card-content\">\n\t\t\t\t<div className=\"hw-conv-card-top\">\n\t\t\t\t\t<span className=\"hw-conv-card-name\">{displayName}</span>\n\t\t\t\t\t{conv.lastMessageAt && (\n\t\t\t\t\t\t<span className=\"hw-conv-card-time\">{formatRelativeTime(conv.lastMessageAt)}</span>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hw-conv-card-preview\">{preview}</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n\n// ── Conversation Card (Intercom-style, Messages tab) ─────\n\nfunction ConversationCard({\n\tconversation: conv,\n\tonSelect,\n}: {\n\tconversation: ConversationSummary;\n\tonSelect: (id: string) => void;\n}) {\n\tconst hasUnread = conv.unreadCount > 0;\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={`hw-conv-card ${hasUnread ? \"hw-conv-card--unread\" : \"\"}`}\n\t\t\tonClick={() => onSelect(conv.id)}\n\t\t>\n\t\t\t<div className=\"hw-conv-card-row\">\n\t\t\t\t<ConvCardBody conv={conv} />\n\t\t\t</div>\n\t\t\t{hasUnread && <div className=\"hw-conv-card-badge\">{conv.unreadCount}</div>}\n\t\t</button>\n\t);\n}\n\n// ── Conversation Row (inside Home tab grouped card) ───────\n\nfunction ConversationRow({\n\tconversation: conv,\n\tonSelect,\n\tisLast,\n}: {\n\tconversation: ConversationSummary;\n\tonSelect: (id: string) => void;\n\tisLast: boolean;\n}) {\n\tconst hasUnread = conv.unreadCount > 0;\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={`hw-recent-row ${hasUnread ? \"hw-recent-row--unread\" : \"\"} ${isLast ? \"hw-recent-row--last\" : \"\"}`}\n\t\t\tonClick={() => onSelect(conv.id)}\n\t\t>\n\t\t\t<ConvCardBody conv={conv} />\n\t\t\t{hasUnread && <div className=\"hw-recent-row-badge\">{conv.unreadCount}</div>}\n\t\t</button>\n\t);\n}\n\n// ── Inline Email Prompt (post-first-reply) ─────────────\n\nfunction InlineEmailPrompt({ conversationId }: { conversationId?: string }) {\n\tconst { client, store } = useWidgetContext();\n\tconst updateContact = useWidgetStore((s) => s.updateVisitorContact);\n\tconst [email, setEmail] = useState(\"\");\n\tconst [isSubmitting, setIsSubmitting] = useState(false);\n\tconst [isSuccess, setIsSuccess] = useState(false);\n\tconst [hasError, setHasError] = useState(false);\n\n\tconst handleSubmit = async () => {\n\t\tconst trimmed = email.trim();\n\t\tif (!trimmed || !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(trimmed)) {\n\t\t\tsetHasError(true);\n\t\t\treturn;\n\t\t}\n\t\tsetHasError(false);\n\n\t\tconst previousContact = store.getState().visitor?.contact ?? null;\n\t\tconst optimisticContactId = previousContact?.id ?? `optimistic-contact-${Date.now()}`;\n\t\tupdateContact({\n\t\t\tid: optimisticContactId,\n\t\t\tname: previousContact?.name ?? null,\n\t\t\temail: trimmed,\n\t\t});\n\t\tsetIsSuccess(true);\n\t\tsetIsSubmitting(true);\n\t\ttry {\n\t\t\tconst result = await client.widget.collectEmail.mutate({\n\t\t\t\temail: trimmed,\n\t\t\t\t...(conversationId ? { conversationId } : {}),\n\t\t\t});\n\t\t\tif (result.contact) {\n\t\t\t\tupdateContact({\n\t\t\t\t\tid: result.contact.id,\n\t\t\t\t\tname: result.contact.name,\n\t\t\t\t\temail: result.contact.email,\n\t\t\t\t});\n\t\t\t}\n\t\t\t// needsEmail will become false via optimistic contact update\n\t\t} catch {\n\t\t\tif (previousContact) {\n\t\t\t\tupdateContact(previousContact);\n\t\t\t} else {\n\t\t\t\tupdateContact({ id: \"\", name: null, email: null });\n\t\t\t}\n\t\t\tsetIsSuccess(false);\n\t\t} finally {\n\t\t\tsetIsSubmitting(false);\n\t\t}\n\t};\n\n\tif (isSuccess) {\n\t\treturn (\n\t\t\t<div className=\"hw-email-card hw-email-card--success\">\n\t\t\t\t<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#22c55e\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t\t\t<polyline points=\"20 6 9 17 4 12\" />\n\t\t\t\t</svg>\n\t\t\t\t{t(\"widget.email_saved\")}\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"hw-email-card\">\n\t\t\t<div className=\"hw-email-card-header\">\n\t\t\t\t<div className=\"hw-email-card-icon\">\n\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t\t\t\t<rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" />\n\t\t\t\t\t\t<path d=\"M22 7l-10 7L2 7\" />\n\t\t\t\t\t</svg>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<p className=\"hw-email-card-title\">{t(\"widget.email_title\")}</p>\n\t\t\t\t\t<p className=\"hw-email-card-subtitle\">{t(\"widget.email_subtitle\")}</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<input\n\t\t\t\ttype=\"email\"\n\t\t\t\tclassName={`hw-email-card-input${hasError ? \" hw-email-card-input--error\" : \"\"}`}\n\t\t\t\tvalue={email}\n\t\t\t\tonChange={(e) => { setEmail(e.target.value); setHasError(false); }}\n\t\t\t\tonKeyDown={(e) => { if (e.key === \"Enter\") handleSubmit(); }}\n\t\t\t\tplaceholder={t(\"widget.email_placeholder\")}\n\t\t\t/>\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"hw-email-card-submit\"\n\t\t\t\tonClick={handleSubmit}\n\t\t\t\tdisabled={isSubmitting || !email.trim()}\n\t\t\t>\n\t\t\t\t{isSubmitting ? (\n\t\t\t\t\t<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n\t\t\t\t\t\t<circle cx=\"12\" cy=\"12\" r=\"10\" strokeDasharray=\"32\" strokeDashoffset=\"32\">\n\t\t\t\t\t\t\t<animate attributeName=\"stroke-dashoffset\" values=\"32;0\" dur=\"1s\" repeatCount=\"indefinite\" />\n\t\t\t\t\t\t</circle>\n\t\t\t\t\t</svg>\n\t\t\t\t) : t(\"widget.email_continue\")}\n\t\t\t</button>\n\n\t\t</div>\n\t);\n}\n\n// ── New Conversation ────────────────────────────────────\n\nfunction NewConversationView({\n\ttext,\n\tonTextChange,\n\tonSubmit,\n\tisSubmitting,\n\twelcomeMessage,\n}: {\n\ttext: string;\n\tonTextChange: (t: string) => void;\n\tonSubmit: () => void;\n\tisSubmitting: boolean;\n\twelcomeMessage: string;\n}) {\n\t// Stable timestamp so the bubble doesn't tick/re-render while the user types.\n\treturn (\n\t\t<div className=\"hw-new\">\n\t\t\t{/* Use the same MessageBubble that renders inside ConversationView so\n\t\t\t the welcome message looks IDENTICAL before and after the first send\n\t\t\t — same markdown rendering (line breaks preserved), same styles,\n\t\t\t same meta row. Without this the \"new\" view uses a raw string render\n\t\t\t and the user sees the bubble visually change the moment the\n\t\t\t conversation is created. */}\n\t\t\t<div className=\"hw-new-welcome\">\n\t\t\t\t<MessageBubble\n\t\t\t\t\ttext={welcomeMessage}\n\t\t\t\t\tsender=\"ai\"\n\t\t\t\t\tparts={null}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<Composer\n\t\t\t\ttext={text}\n\t\t\t\tonTextChange={onTextChange}\n\t\t\t\tonSubmit={onSubmit}\n\t\t\t\tisSubmitting={isSubmitting}\n\t\t\t\tplaceholder={t(\"widget.placeholder_new\")}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\n// ── Conversation View ───────────────────────────────────\n\nfunction ConversationView({ conversationId }: { conversationId: string }) {\n\tconst { items, isLoading, hasMore, loadMore } = useTimeline(conversationId);\n\tconst {\n\t\ttext,\n\t\tsetText,\n\t\tsubmit,\n\t\tisSubmitting,\n\t\tattachments,\n\t\taddFiles,\n\t\tremoveAttachment,\n\t\tsendError,\n\t\tclearSendError,\n\t\temailGateConvId,\n\t} = useComposer(conversationId);\n\tconst { isTyping, isAiProcessing, setTyping } = usePresence(conversationId);\n\tconst agentConfig = useWidgetStore((s) => s.agentConfig);\n\tconst visitorContact = useWidgetStore((s) => s.visitor?.contact);\n\n\tconst isResolved = useWidgetStore((s) => {\n\t\tconst conv = s.conversations.find((c) => c.id === conversationId);\n\t\treturn conv?.status === \"resolved\";\n\t});\n\n\t// Email prompt gate (BETTER-227 — Intercom pattern).\n\t// Show ONLY after:\n\t// (1) visitor sent at least one real message (not the welcome bubble), AND\n\t// (2) AI has replied at least once (so the visitor has seen value from the widget)\n\t// Prevents the \"Get notified when we reply\" card from appearing on widget open\n\t// before the visitor has even typed. Matches Intercom's post-first-response flow.\n\tconst hasVisitorMessage = items.some(\n\t\t(it) => it.type === \"message\" && Boolean((it as { visitorId?: string | null }).visitorId),\n\t);\n\tconst hasAiReply = items.some(\n\t\t(it) => it.type === \"message\" && Boolean((it as { aiAgentId?: string | null }).aiAgentId),\n\t);\n\t// Email is satisfied if EITHER the contact has one (fully identified\n\t// visitor) OR the visitor itself has one (collected via the gate but\n\t// not yet linked to a Contact row). Without the visitor.email fallback,\n\t// the gate re-shows on every refresh until a Contact is created.\n\tconst visitorOwnEmail = useWidgetStore((s) => s.visitor?.email);\n\tconst hasEmail = !!visitorContact?.email || !!visitorOwnEmail;\n\tconst needsEmailPostReply =\n\t\t!!agentConfig?.requireVisitorEmail &&\n\t\t!hasEmail &&\n\t\thasVisitorMessage &&\n\t\thasAiReply;\n\tconst needsEmail = needsEmailPostReply || !!emailGateConvId;\n\n\tif (isLoading && items.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"hw-messages\">\n\t\t\t\t<div className=\"hw-skeleton-messages\">\n\t\t\t\t\t{/* AI message skeleton */}\n\t\t\t\t\t<div className=\"hw-skeleton-msg\">\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-avatar\" />\n\t\t\t\t\t\t<div className=\"hw-skeleton-bubble\">\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 140 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 200 }} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{/* Visitor message skeleton */}\n\t\t\t\t\t<div className=\"hw-skeleton-msg hw-skeleton-msg--right\">\n\t\t\t\t\t\t<div className=\"hw-skeleton-bubble\" style={{ alignItems: \"flex-end\" }}>\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 160 }} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{/* AI reply skeleton */}\n\t\t\t\t\t<div className=\"hw-skeleton-msg\">\n\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-avatar\" />\n\t\t\t\t\t\t<div className=\"hw-skeleton-bubble\">\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 180 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 120 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: 80 }} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<MessageList\n\t\t\t\titems={items}\n\t\t\t\tisTyping={isTyping}\n\t\t\t\tisAiProcessing={isAiProcessing}\n\t\t\t\thasMore={hasMore}\n\t\t\t\tisLoadingMore={isLoading}\n\t\t\t\tonLoadMore={loadMore}\n\t\t\t/>\n\t\t\t{isResolved ? (\n\t\t\t\t<ResolvedBanner conversationId={conversationId} />\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t{needsEmail && <InlineEmailPrompt conversationId={emailGateConvId ?? undefined} />}\n\t\t\t\t\t{sendError && (\n\t\t\t\t\t\t<div className=\"hw-send-error\">\n\t\t\t\t\t\t\t{sendError}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-send-error-retry\"\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tclearSendError();\n\t\t\t\t\t\t\t\t\tsubmit();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{t(\"widget.retry\")}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t<Composer\n\t\t\t\t\t\ttext={text}\n\t\t\t\t\t\tonTextChange={setText}\n\t\t\t\t\t\tonSubmit={submit}\n\t\t\t\t\t\tonTyping={setTyping}\n\t\t\t\t\t\tisSubmitting={isSubmitting}\n\t\t\t\t\t\tattachments={attachments}\n\t\t\t\t\t\tonAddFiles={addFiles}\n\t\t\t\t\t\tonRemoveAttachment={removeAttachment}\n\t\t\t\t\t\tdisabled={needsEmail}\n\t\t\t\t\t/>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</>\n\t);\n}\n\n// ── Resolved Banner with CSAT ───────────────────────────\n\nfunction ResolvedBanner({ conversationId }: { conversationId: string }) {\n\tconst { client } = useWidgetContext();\n\tconst [csatRating, setCsatRating] = useState<\"good\" | \"bad\" | null>(null);\n\tconst [csatSubmitted, setCsatSubmitted] = useState(false);\n\n\tconst handleReopen = async () => {\n\t\ttry {\n\t\t\tawait client.widget.sendMessage.mutate({ conversationId, text: t(\"widget.send_followup\") });\n\t\t\t// Store update will be applied via WebSocket event from server\n\t\t} catch (err) {\n\t\t\tconsole.error(\"Failed to reopen:\", err);\n\t\t}\n\t};\n\n\tconst handleCsat = (rating: \"good\" | \"bad\") => {\n\t\tsetCsatRating(rating);\n\t\tsetCsatSubmitted(true);\n\t\t// Send CSAT via API (fire and forget)\n\t\tclient.widget.sendCsat.mutate({ conversationId, rating }).catch(() => {});\n\t};\n\n\treturn (\n\t\t<div className=\"hw-resolved\">\n\t\t\t<div className=\"hw-resolved-text\">{t(\"widget.resolved_text\")}</div>\n\t\t\t{!csatSubmitted ? (\n\t\t\t\t<div className=\"hw-csat\">\n\t\t\t\t\t<div className=\"hw-csat-label\">{t(\"widget.csat_label\")}</div>\n\t\t\t\t\t<div className=\"hw-csat-buttons\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={`hw-csat-btn ${csatRating === \"good\" ? \"hw-csat-btn--selected\" : \"\"}`}\n\t\t\t\t\t\t\tonClick={() => handleCsat(\"good\")}\n\t\t\t\t\t\t\taria-label={t(\"widget.aria_good\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t👍\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={`hw-csat-btn ${csatRating === \"bad\" ? \"hw-csat-btn--selected\" : \"\"}`}\n\t\t\t\t\t\t\tonClick={() => handleCsat(\"bad\")}\n\t\t\t\t\t\t\taria-label={t(\"widget.aria_bad\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t👎\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"hw-csat-thanks\">{t(\"widget.csat_thanks\")}</div>\n\t\t\t)}\n\t\t\t<div className=\"hw-resolved-actions\">\n\t\t\t\t<button type=\"button\" className=\"hw-resolved-reopen\" onClick={handleReopen}>\n\t\t\t\t\t{t(\"widget.send_followup\")}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// ── Message Preview Bubble ─────────────────────\n\nfunction MessagePreview({ onOpen }: { onOpen: () => void }) {\n\tconst preview = useWidgetStore((s) => s.incomingPreview);\n\tconst dismissPreview = useWidgetStore((s) => s.dismissPreview);\n\tconst setActiveConversation = useWidgetStore((s) => s.setActiveConversation);\n\tconst agentName = useWidgetStore((s) => s.agentConfig?.name) ?? \"Support\";\n\tconst [closing, setClosing] = useState(false);\n\n\t// Auto-dismiss after 8 seconds (skip when quick replies are present —\n\t// visitor needs time to read and decide)\n\tuseEffect(() => {\n\t\tif (!preview || preview.quickReplies) return;\n\t\tconst timer = setTimeout(() => {\n\t\t\tsetClosing(true);\n\t\t\tsetTimeout(() => dismissPreview(), 200);\n\t\t}, 8000);\n\t\treturn () => clearTimeout(timer);\n\t}, [preview, dismissPreview]);\n\n\tif (!preview) return null;\n\n\tconst handleClose = (e: React.MouseEvent) => {\n\t\te.stopPropagation();\n\t\tsetClosing(true);\n\t\tsetTimeout(() => {\n\t\t\tdismissPreview();\n\t\t\tsetClosing(false);\n\t\t}, 200);\n\t};\n\n\tconst handleClick = () => {\n\t\t// Bubble click is an explicit \"I want to read this\" — open the\n\t\t// widget AND jump straight to the conversation that pinged. Without\n\t\t// the setActiveConversation, the visitor lands on the home screen\n\t\t// and has to find the unread row themselves.\n\t\tconst targetConvId = preview.conversationId;\n\t\tdismissPreview();\n\t\tsetActiveConversation(targetConvId);\n\t\tonOpen();\n\t};\n\n\tconst messages = preview.messages?.length ? preview.messages : [{ text: preview.text }];\n\tconst hasQr = preview.quickReplies && preview.quickReplies.options.length > 0;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={`hw-preview ${closing ? \"hw-preview--closing\" : \"\"}`}\n\t\t\tonClick={handleClick}\n\t\t\trole=\"button\"\n\t\t\ttabIndex={0}\n\t\t>\n\t\t\t<div className=\"hw-preview-header\">\n\t\t\t\t<div className=\"hw-preview-avatar\">\n\t\t\t\t\t<WidgetLogo />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hw-preview-name\">{agentName}</div>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"hw-preview-close\"\n\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\taria-label={t(\"widget.aria_dismiss\")}\n\t\t\t\t>\n\t\t\t\t\t<XIcon size={20} />\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t{messages.map((m, i) => (\n\t\t\t\t<div key={i} className=\"hw-preview-body\">{m.text}</div>\n\t\t\t))}\n\n\t\t\t{hasQr && (\n\t\t\t\t<>\n\t\t\t\t\t{preview.quickReplies!.prompt && (\n\t\t\t\t\t\t<div className=\"hw-preview-body\">{preview.quickReplies!.prompt}</div>\n\t\t\t\t\t)}\n\t\t\t\t\t<div className=\"hw-preview-quick-replies\">\n\t\t\t\t\t\t{preview.quickReplies!.options.map((opt) => (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tkey={opt.id}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"hw-preview-qr-btn\"\n\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\tdismissPreview();\n\t\t\t\t\t\t\t\t\tsetActiveConversation(preview.conversationId);\n\t\t\t\t\t\t\t\t\tonOpen();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{opt.label}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import type { TimelineItem } from \"@helpway/types\";\nimport { t } from \"@helpway/widget-core\";\nimport { useCallback, useState } from \"react\";\nimport { useWidgetContext } from \"../provider\";\n\nexport interface PendingAttachment {\n\tid: string;\n\tfile: File;\n\tpreviewUrl: string | null; // blob URL for images\n\tisUploading: boolean;\n\terror: string | null;\n\t/** Resolved after upload — the part to include in sendMessage */\n\tpart:\n\t\t| { type: \"image\"; url: string; mimeType: string }\n\t\t| { type: \"file\"; url: string; fileName: string; fileSize: number; mimeType: string }\n\t\t| null;\n}\n\nconst MAX_ATTACHMENTS = 10;\nconst MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB\n\n/**\n * Composer state — text input + attachments + submit for a conversation.\n */\nexport function useComposer(conversationId: string | null) {\n\tconst { client, ws, store } = useWidgetContext();\n\tconst [text, setText] = useState(\"\");\n\tconst [isSubmitting, setIsSubmitting] = useState(false);\n\tconst [attachments, setAttachments] = useState<PendingAttachment[]>([]);\n\tconst [sendError, setSendError] = useState<string | null>(null);\n\tconst [emailGateConvId, setEmailGateConvId] = useState<string | null>(null);\n\n\tconst addFiles = useCallback(\n\t\tasync (files: File[]) => {\n\t\t\tif (!conversationId) return;\n\n\t\t\tconst remaining = MAX_ATTACHMENTS - attachments.length;\n\t\t\tconst toAdd = files.slice(0, remaining);\n\t\t\tif (toAdd.length === 0) return;\n\n\t\t\t// Create pending entries\n\t\t\tconst pending: PendingAttachment[] = toAdd.map((file) => ({\n\t\t\t\tid: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n\t\t\t\tfile,\n\t\t\t\tpreviewUrl: file.type.startsWith(\"image/\") ? URL.createObjectURL(file) : null,\n\t\t\t\tisUploading: true,\n\t\t\t\terror: null,\n\t\t\t\tpart: null,\n\t\t\t}));\n\n\t\t\tsetAttachments((prev) => [...prev, ...pending]);\n\n\t\t\t// Upload each file\n\t\t\tfor (const item of pending) {\n\t\t\t\ttry {\n\t\t\t\t\tif (item.file.size > MAX_FILE_SIZE) {\n\t\t\t\t\t\tthrow new Error(t(\"widget.file_too_large\"));\n\t\t\t\t\t}\n\n\t\t\t\t\t// Read file as base64\n\t\t\t\t\tconst base64 = await fileToBase64(item.file);\n\n\t\t\t\t\t// For temp conversations (before first send) skip the\n\t\t\t\t\t// conversationId — server scopes the R2 key to the visitor\n\t\t\t\t\t// and the file is attached to the timeline item by\n\t\t\t\t\t// createConversation when submit fires.\n\t\t\t\t\tconst convIdForUpload = conversationId.startsWith(\"temp-\")\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: conversationId;\n\t\t\t\t\tconst result = await client.widget.uploadAttachment.mutate({\n\t\t\t\t\t\t...(convIdForUpload ? { conversationId: convIdForUpload } : {}),\n\t\t\t\t\t\tbase64,\n\t\t\t\t\t\tmimeType: item.file.type || \"application/octet-stream\",\n\t\t\t\t\t\tfileName: item.file.name,\n\t\t\t\t\t});\n\n\t\t\t\t\tsetAttachments((prev) =>\n\t\t\t\t\t\tprev.map((a) =>\n\t\t\t\t\t\t\ta.id === item.id ? { ...a, isUploading: false, part: result.part } : a,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst message = err instanceof Error ? err.message : \"Upload failed\";\n\t\t\t\t\tsetAttachments((prev) =>\n\t\t\t\t\t\tprev.map((a) => (a.id === item.id ? { ...a, isUploading: false, error: message } : a)),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[conversationId, attachments.length, client],\n\t);\n\n\tconst removeAttachment = useCallback((id: string) => {\n\t\tsetAttachments((prev) => {\n\t\t\tconst item = prev.find((a) => a.id === id);\n\t\t\tif (item?.previewUrl) URL.revokeObjectURL(item.previewUrl);\n\t\t\treturn prev.filter((a) => a.id !== id);\n\t\t});\n\t}, []);\n\n\tconst submit = useCallback(async () => {\n\t\tconst trimmed = text.trim();\n\t\tconst readyParts = attachments.filter((a) => a.part !== null).map((a) => a.part!);\n\t\tconst hasText = trimmed.length > 0;\n\t\tconst hasAttachments = readyParts.length > 0;\n\n\t\tif (!conversationId || isSubmitting) return;\n\n\t\t// Policy 2026-04-19: every outgoing message must have a text body.\n\t\t// An attachment on its own renders as an empty bubble in the\n\t\t// dashboard and leaves the AI with no caption to reason about.\n\t\t// Surface a soft inline error instead of silently no-op'ing so\n\t\t// the visitor understands *why* the send didn't go through.\n\t\tif (!hasText) {\n\t\t\tif (hasAttachments) {\n\t\t\t\tsetSendError(t(\"widget.caption_required\"));\n\t\t\t\tsetTimeout(() => setSendError(null), 4000);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Don't send while uploads are in progress\n\t\tconst stillUploading = attachments.some((a) => a.isUploading);\n\t\tif (stillUploading) return;\n\n\t\t// ── OPTIMISTIC: message appears in the widget INSTANTLY ──\n\t\t// The user sees their message the moment they hit send; the mutation\n\t\t// runs in the background. On success we swap the optimistic placeholder\n\t\t// for the server-confirmed item (preserving scroll + bubble position).\n\t\t// On failure we remove the placeholder and restore the composer text.\n\t\tconst optimisticId = `optimistic-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\t\tconst now = new Date().toISOString();\n\t\tconst currentVisitorId = store.getState().visitor?.id ?? null;\n\t\tconst optimisticItem: TimelineItem = {\n\t\t\tid: optimisticId,\n\t\t\tconversationId,\n\t\t\torganizationId: \"\",\n\t\t\ttype: \"message\",\n\t\t\tvisibility: \"public\",\n\t\t\ttext: hasText ? trimmed : null,\n\t\t\tparts:\n\t\t\t\thasText || hasAttachments\n\t\t\t\t\t? ([\n\t\t\t\t\t\t\t...(hasText ? [{ type: \"text\" as const, text: trimmed }] : []),\n\t\t\t\t\t\t\t...readyParts,\n\t\t\t\t\t\t] as TimelineItem[\"parts\"])\n\t\t\t\t\t: null,\n\t\t\tuserId: null,\n\t\t\tvisitorId: currentVisitorId,\n\t\t\taiAgentId: null,\n\t\t\tcreatedAt: now,\n\t\t\teditedAt: null,\n\t\t\tdeletedAt: null,\n\t\t};\n\n\t\t// Flush UI immediately\n\t\tconst attachmentsSnapshot = attachments;\n\t\tconst textSnapshot = text;\n\t\tstore.getState().addMessage(conversationId, optimisticItem);\n\t\tsetText(\"\");\n\t\tsetAttachments([]);\n\t\tws.sendTyping(conversationId, false);\n\t\tsetIsSubmitting(true);\n\t\ttry {\n\t\t\t// Temp conversation IDs (seeded by openNewConversation) don't exist on\n\t\t\t// the server yet. On the first send we have to call createConversation\n\t\t\t// instead — the API allocates the real ID and returns the visitor item.\n\t\t\t// The welcome item from the response is DROPPED because the widget is\n\t\t\t// already showing a seed welcome bubble; keeping the same bubble\n\t\t\t// instance across this transition is what prevents the \"git-gel\" flash.\n\t\t\tconst isTempConversation = conversationId.startsWith(\"temp-\");\n\t\t\t// Ephemeral proactive conversation — only exists in the widget\n\t\t\t// store, server hasn't seen it yet. First reply triggers\n\t\t\t// materialization (creates conversation + writes greeting +\n\t\t\t// visitor message in one go).\n\t\t\tconst isEphemeralConversation = conversationId.startsWith(\"eph-\");\n\t\t\tif (isEphemeralConversation) {\n\t\t\t\tconst workflowId = conversationId.slice(\"eph-\".length);\n\t\t\t\tconst result = await client.widget.materializeFromProactive.mutate({\n\t\t\t\t\tworkflowId,\n\t\t\t\t\t...(hasText ? { text: trimmed } : {}),\n\t\t\t\t});\n\t\t\t\t// Pull the real conversation onto the synthetic id so all the\n\t\t\t\t// in-flight optimistic state (visitor bubble, scroll position,\n\t\t\t\t// active id) carries over without a flash.\n\t\t\t\tstore.getState().remapConversationId(conversationId, result.conversationId);\n\t\t\t\t// Hydrate canonical timeline from server — replaces synthetic\n\t\t\t\t// greeting ids with real ULIDs and surfaces the persisted\n\t\t\t\t// visitor message. We keep the optimistic placeholder in the\n\t\t\t\t// store so the visitor sees their bubble immediately; the\n\t\t\t\t// canonical setMessages dedupes by id, but our optimistic id\n\t\t\t\t// won't collide so it'll be shadowed cleanly.\n\t\t\t\ttry {\n\t\t\t\t\tconst timeline = await client.widget.getTimeline.query({\n\t\t\t\t\t\tconversationId: result.conversationId,\n\t\t\t\t\t\tlimit: 50,\n\t\t\t\t\t});\n\t\t\t\t\tif (timeline?.items) {\n\t\t\t\t\t\tstore\n\t\t\t\t\t\t\t.getState()\n\t\t\t\t\t\t\t.setMessages(result.conversationId, timeline.items as TimelineItem[]);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Best-effort: optimistic state is still on screen, next\n\t\t\t\t\t// WS event or refresh will hydrate.\n\t\t\t\t}\n\t\t\t} else if (isTempConversation) {\n\t\t\t\tconst result = await client.widget.createConversation.mutate({\n\t\t\t\t\t...(hasText ? { text: trimmed } : {}),\n\t\t\t\t\t...(hasAttachments ? { parts: readyParts } : {}),\n\t\t\t\t});\n\t\t\t\tconst conv = result.conversation;\n\t\t\t\t// Move the temp conversation's messages (seed welcome + optimistic\n\t\t\t\t// visitor) onto the server-assigned id. remapConversationId merges\n\t\t\t\t// with any existing items under the real id (WS races are fine).\n\t\t\t\tstore.getState().remapConversationId(conversationId, conv.id);\n\t\t\t\tif (result.item) {\n\t\t\t\t\tstore\n\t\t\t\t\t\t.getState()\n\t\t\t\t\t\t.replaceMessage(conv.id, optimisticId, result.item as TimelineItem);\n\t\t\t\t}\n\t\t\t\tif (result.requireEmail) {\n\t\t\t\t\tsetEmailGateConvId(conv.id);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst result = await client.widget.sendMessage.mutate({\n\t\t\t\t\tconversationId,\n\t\t\t\t\t...(hasText ? { text: trimmed } : {}),\n\t\t\t\t\t...(hasAttachments ? { parts: readyParts } : {}),\n\t\t\t\t});\n\n\t\t\t\t// Replace optimistic placeholder with server-confirmed item.\n\t\t\t\t// If the WS echo already landed with the real id, replaceMessage\n\t\t\t\t// just drops the placeholder (race-safe, see store implementation).\n\t\t\t\tstore.getState().replaceMessage(conversationId, optimisticId, result.item as TimelineItem);\n\t\t\t}\n\n\t\t\t// Clean up blob URLs for uploaded attachments\n\t\t\tfor (const a of attachmentsSnapshot) {\n\t\t\t\tif (a.previewUrl) URL.revokeObjectURL(a.previewUrl);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(\"[useComposer] Send failed:\", err);\n\t\t\t// Roll back: remove placeholder, restore text + attachments so user can retry\n\t\t\tstore.getState().removeMessage(conversationId, optimisticId);\n\t\t\tsetText(textSnapshot);\n\t\t\tsetAttachments(attachmentsSnapshot);\n\t\t\tsetSendError(err instanceof Error ? err.message : t(\"widget.send_error\"));\n\t\t\t// Auto-clear after 5 seconds\n\t\t\tsetTimeout(() => setSendError(null), 5000);\n\t\t} finally {\n\t\t\tsetIsSubmitting(false);\n\t\t}\n\t}, [text, attachments, conversationId, isSubmitting, client, ws, store]);\n\n\tconst clearSendError = useCallback(() => setSendError(null), []);\n\n\treturn {\n\t\ttext,\n\t\tsetText,\n\t\tsubmit,\n\t\tisSubmitting,\n\t\tattachments,\n\t\taddFiles,\n\t\tremoveAttachment,\n\t\tsendError,\n\t\tclearSendError,\n\t\temailGateConvId,\n\t};\n}\n\n// ── Helpers ─────────────────────────────────────\n\nfunction fileToBase64(file: File): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst reader = new FileReader();\n\t\treader.onload = () => {\n\t\t\t// result is \"data:<mime>;base64,<data>\" — strip the prefix\n\t\t\tconst result = reader.result as string;\n\t\t\tconst base64 = result.split(\",\")[1];\n\t\t\tif (!base64) return reject(new Error(\"Failed to encode file\"));\n\t\t\tresolve(base64);\n\t\t};\n\t\treader.onerror = () => reject(new Error(\"Failed to read file\"));\n\t\treader.readAsDataURL(file);\n\t});\n}\n","import type { TimelineItem } from \"@helpway/types\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\n/**\n * Conversation list + create new conversation.\n */\nexport function useConversations() {\n\tconst { client, store } = useWidgetContext();\n\tconst conversations = useWidgetStore((s) => s.conversations);\n\tconst setActiveConversation = useWidgetStore((s) => s.setActiveConversation);\n\tconst [isCreating, setIsCreating] = useState(false);\n\n\tconst clientRef = useRef(client);\n\tconst storeRef = useRef(store);\n\tclientRef.current = client;\n\tstoreRef.current = store;\n\n\tconst create = useCallback(async (text: string) => {\n\t\tsetIsCreating(true);\n\n\t\t// OPTIMISTIC: show the visitor's message + open the conversation view\n\t\t// BEFORE the server roundtrip completes. The conversation gets a temp\n\t\t// id (`temp-<random>`) that's remapped to the server id on success.\n\t\t// Welcome message + any AI reply flow in via the same path the API\n\t\t// returns them — either by replacing the temp conv or via WS.\n\t\tconst tempConversationId = `temp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\t\tconst now = new Date().toISOString();\n\t\tconst optimisticMessageId = `optimistic-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n\t\tconst currentVisitorId = storeRef.current.getState().visitor?.id ?? null;\n\n\t\tconst optimisticMsg: TimelineItem = {\n\t\t\tid: optimisticMessageId,\n\t\t\tconversationId: tempConversationId,\n\t\t\torganizationId: \"\",\n\t\t\ttype: \"message\",\n\t\t\tvisibility: \"public\",\n\t\t\ttext,\n\t\t\tparts: null,\n\t\t\tuserId: null,\n\t\t\tvisitorId: currentVisitorId,\n\t\t\taiAgentId: null,\n\t\t\tcreatedAt: now,\n\t\t\teditedAt: null,\n\t\t\tdeletedAt: null,\n\t\t};\n\n\t\t// Flush UI immediately: fake conversation + message + switch view\n\t\tconst store = storeRef.current.getState();\n\t\tstore.addConversation({\n\t\t\tid: tempConversationId,\n\t\t\ttitle: null,\n\t\t\tstatus: \"open\",\n\t\t\tlastMessageText: text,\n\t\t\tlastMessageAt: now,\n\t\t\tlastMessageSenderType: \"visitor\",\n\t\t\tlastMessageSenderName: null,\n\t\t\tlastMessageSenderImage: null,\n\t\t\tassigneeName: null,\n\t\t\tassigneeImage: null,\n\t\t\tunreadCount: 0,\n\t\t});\n\t\tstore.setMessages(tempConversationId, [optimisticMsg]);\n\t\tstore.setActiveConversation(tempConversationId);\n\n\t\ttry {\n\t\t\tconst result = await clientRef.current.widget.createConversation.mutate({ text });\n\t\t\tconst conv = result.conversation;\n\n\t\t\t// Remap temp ID → real ID (rewrites conversations list + messages map + active ref).\n\t\t\t// The optimistic message's id becomes stale (conversationId changed) — replaceMessage\n\t\t\t// with the server-confirmed item.\n\t\t\tstoreRef.current.getState().remapConversationId(tempConversationId, conv.id);\n\t\t\tif (result.item) {\n\t\t\t\tstoreRef.current\n\t\t\t\t\t.getState()\n\t\t\t\t\t.replaceMessage(conv.id, optimisticMessageId, result.item as TimelineItem);\n\t\t\t}\n\t\t\t// Insert welcome message if the agent sent one.\n\t\t\t// The welcome is ALWAYS the very first item in a new conversation, so\n\t\t\t// we place it at index 0 deterministically — never trust createdAt sort,\n\t\t\t// because client-clock (optimistic visitor) vs server-clock (welcome)\n\t\t\t// can be off by enough to re-order the pair. Dedup by id so a WS echo\n\t\t\t// doesn't double-insert.\n\t\t\tif (result.welcomeItem) {\n\t\t\t\tconst welcome = result.welcomeItem as TimelineItem;\n\t\t\t\tconst existing = storeRef.current.getState().messages.get(conv.id) ?? [];\n\t\t\t\tconst withoutWelcome = existing.filter((m) => m.id !== welcome.id);\n\t\t\t\tstoreRef.current.getState().setMessages(conv.id, [welcome, ...withoutWelcome]);\n\t\t\t}\n\t\t\treturn conv;\n\t\t} catch (err) {\n\t\t\t// Roll back: remove the fake conversation + message; let the caller surface the error\n\t\t\tstoreRef.current.getState().removeMessage(tempConversationId, optimisticMessageId);\n\t\t\tconst convs = storeRef.current\n\t\t\t\t.getState()\n\t\t\t\t.conversations.filter((c) => c.id !== tempConversationId);\n\t\t\tstoreRef.current.setState({ conversations: convs, activeConversationId: null });\n\t\t\tthrow err;\n\t\t} finally {\n\t\t\tsetIsCreating(false);\n\t\t}\n\t}, []);\n\n\treturn { conversations, create, isCreating, setActiveConversation };\n}\n","import { useEffect, useState } from \"react\";\nimport { onLocaleChange, getI18nRevision } from \"@helpway/widget-core\";\n\n/**\n * React hook that triggers re-render when widget translations load or locale changes.\n * Place this in the top-level widget component so all children get fresh t() values.\n *\n * Returns the current i18n revision number (for debugging).\n */\nexport function useI18n(): number {\n\tconst [rev, setRev] = useState(() => getI18nRevision());\n\n\tuseEffect(() => {\n\t\t// Subscribe to locale/translation changes\n\t\treturn onLocaleChange(() => {\n\t\t\tsetRev(getI18nRevision());\n\t\t});\n\t}, []);\n\n\treturn rev;\n}\n","import { useCallback, useRef } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\n/**\n * Typing presence — show \"is typing\" + send own typing status.\n *\n * Debounced: only sends WS event when typing state *changes*.\n * While typing, auto-stops after 3 seconds of inactivity.\n *\n * Usage:\n * ```tsx\n * const { isTyping, setTyping } = usePresence(conversationId)\n * ```\n */\nexport function usePresence(conversationId: string | null) {\n\tconst { ws } = useWidgetContext();\n\tconst isTyping = useWidgetStore((s) =>\n\t\tconversationId ? (s.typingUsers.get(conversationId) ?? false) : false,\n\t);\n\tconst isAiProcessing = useWidgetStore((s) =>\n\t\tconversationId ? (s.aiProcessing.get(conversationId) ?? false) : false,\n\t);\n\tconst typingTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\tconst isSendingTyping = useRef(false);\n\n\tconst setTyping = useCallback(\n\t\t(typing: boolean) => {\n\t\t\tif (!conversationId) return;\n\n\t\t\t// Clear any pending auto-stop\n\t\t\tif (typingTimer.current) clearTimeout(typingTimer.current);\n\n\t\t\tif (typing) {\n\t\t\t\t// Only send \"typing: true\" if we haven't already\n\t\t\t\tif (!isSendingTyping.current) {\n\t\t\t\t\tisSendingTyping.current = true;\n\t\t\t\t\tws.sendTyping(conversationId, true);\n\t\t\t\t}\n\t\t\t\t// Auto-stop after 3 seconds of inactivity\n\t\t\t\ttypingTimer.current = setTimeout(() => {\n\t\t\t\t\tisSendingTyping.current = false;\n\t\t\t\t\tws.sendTyping(conversationId, false);\n\t\t\t\t}, 3000);\n\t\t\t} else {\n\t\t\t\t// Immediately send stop\n\t\t\t\tif (isSendingTyping.current) {\n\t\t\t\t\tisSendingTyping.current = false;\n\t\t\t\t\tws.sendTyping(conversationId, false);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[conversationId, ws],\n\t);\n\n\treturn { isTyping, isAiProcessing, setTyping };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\nimport type { TimelineItem } from \"@helpway/types\";\n\nconst EMPTY_ITEMS: TimelineItem[] = [];\n\n/**\n * Timeline items for a conversation + real-time updates.\n */\nexport function useTimeline(conversationId: string | null) {\n\tconst { client, store } = useWidgetContext();\n\tconst messages = useWidgetStore((s) =>\n\t\tconversationId ? s.messages.get(conversationId) ?? EMPTY_ITEMS : EMPTY_ITEMS,\n\t);\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [hasMore, setHasMore] = useState(false);\n\tconst cursorRef = useRef<string | undefined>(undefined);\n\n\t// Stable refs to avoid effect re-triggers\n\tconst clientRef = useRef(client);\n\tconst storeRef = useRef(store);\n\tclientRef.current = client;\n\tstoreRef.current = store;\n\n\t// Load initial timeline when conversation changes\n\tuseEffect(() => {\n\t\tif (!conversationId) return;\n\n\t\t// Skip server fetch for optimistic temp IDs — they don't exist server-side.\n\t\t// useConversations.create() owns the seed for these; once remap fires this\n\t\t// effect re-runs with the real id and the fetch happens then.\n\t\tif (conversationId.startsWith(\"temp-\")) return;\n\n\t\tlet cancelled = false;\n\n\t\t// If createConversation already seeded the messages store (welcome + first\n\t\t// visitor message), the server has nothing new to tell us — skip the fetch.\n\t\t// Overwriting the seed with the server payload causes a full array-identity\n\t\t// flip, a brief key-swap for the optimistic→server id transition, and\n\t\t// restarts CSS enter animations — the \"mesajlar gidip tekrar geliyor\" flash.\n\t\t// New items still flow in via WS.addMessage, which dedupes by id.\n\t\tconst existingMessages = storeRef.current.getState().messages.get(conversationId);\n\t\tconst hasSeed = !!existingMessages && existingMessages.length > 0;\n\t\tif (hasSeed) {\n\t\t\tstoreRef.current.getState().clearUnread(conversationId);\n\t\t\tclientRef.current.widget.markSeen\n\t\t\t\t.mutate({ conversationId })\n\t\t\t\t.catch(() => {});\n\t\t\treturn () => {\n\t\t\t\tcancelled = true;\n\t\t\t};\n\t\t}\n\n\t\tsetIsLoading(true);\n\t\tasync function load() {\n\t\t\ttry {\n\t\t\t\tconst data = await clientRef.current.widget.getTimeline.query({\n\t\t\t\t\tconversationId: conversationId!,\n\t\t\t\t\tlimit: 50,\n\t\t\t\t});\n\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\t// Only overwrite if API returned items — don't wipe seed messages with empty response\n\t\t\t\tif (data.items.length > 0) {\n\t\t\t\t\tstoreRef.current.getState().setMessages(conversationId!, data.items as TimelineItem[]);\n\t\t\t\t}\n\t\t\t\tsetHasMore(data.hasMore);\n\t\t\t\tcursorRef.current = data.nextCursor ?? undefined;\n\n\t\t\t\t// Mark as seen + clear local unread count\n\t\t\t\tstoreRef.current.getState().clearUnread(conversationId!);\n\t\t\t\tclientRef.current.widget.markSeen.mutate({ conversationId: conversationId! }).catch(() => {});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useTimeline] Failed to load:\", err);\n\t\t\t} finally {\n\t\t\t\tif (!cancelled) setIsLoading(false);\n\t\t\t}\n\t\t}\n\n\t\tload();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [conversationId]); // Only re-run when conversationId changes\n\n\tconst loadMore = useCallback(async () => {\n\t\tif (!conversationId || !hasMore || isLoading) return;\n\n\t\tsetIsLoading(true);\n\t\ttry {\n\t\t\tconst data = await clientRef.current.widget.getTimeline.query({\n\t\t\t\tconversationId,\n\t\t\t\tcursor: cursorRef.current,\n\t\t\t\tlimit: 50,\n\t\t\t});\n\n\t\t\tconst existing = storeRef.current.getState().messages.get(conversationId) ?? [];\n\t\t\tstoreRef.current.getState().setMessages(conversationId, [...data.items as TimelineItem[], ...existing]);\n\t\t\tsetHasMore(data.hasMore);\n\t\t\tcursorRef.current = data.nextCursor ?? undefined;\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [conversationId, hasMore, isLoading]);\n\n\treturn { items: messages, isLoading, hasMore, loadMore };\n}\n","import { useWidgetStore } from \"../provider\";\n\n/**\n * Total unread count across all conversations.\n *\n * Usage:\n * ```tsx\n * const { totalUnread } = useUnread()\n * ```\n */\nexport function useUnread() {\n\tconst totalUnread = useWidgetStore((s) =>\n\t\ts.conversations.reduce((sum, c) => sum + c.unreadCount, 0),\n\t);\n\n\treturn { totalUnread };\n}\n","import { useWidgetContext, useWidgetStore } from \"../provider\";\n\n/**\n * Core widget state — connection status, visitor identity, website info.\n *\n * Usage:\n * ```tsx\n * const { isReady, visitor, website, identify } = useWidget()\n * ```\n */\nexport function useWidget() {\n\tconst { client } = useWidgetContext();\n\tconst isReady = useWidgetStore((s) => s.isReady);\n\tconst isConnecting = useWidgetStore((s) => s.isConnecting);\n\tconst visitor = useWidgetStore((s) => s.visitor);\n\tconst website = useWidgetStore((s) => s.website);\n\tconst agentConfig = useWidgetStore((s) => s.agentConfig);\n\n\tasync function identify(data: {\n\t\texternalId: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}) {\n\t\treturn client.widget.identify.mutate(data);\n\t}\n\n\treturn { isReady, isConnecting, visitor, website, agentConfig, identify };\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { t } from \"@helpway/widget-core\";\nimport type { PendingAttachment } from \"../hooks/use-composer\";\nimport { SendIcon, PaperclipIcon, XIcon } from \"./icons\";\nimport { AnchoredPreview } from \"./message-bubble\";\n\nconst MAX_CHARS = 5000;\nconst CHAR_WARN_THRESHOLD = 4800;\n\nconst ACCEPTED_TYPES = [\n\t\"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\", \"image/svg+xml\",\n\t\"application/pdf\", \"text/plain\", \"text/csv\", \"application/zip\",\n\t\"application/msword\",\n\t\"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n\t\"application/vnd.ms-excel\",\n\t\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n].join(\",\");\n\ninterface ComposerProps {\n\ttext: string;\n\tonTextChange: (text: string) => void;\n\tonSubmit: () => void;\n\tonTyping?: (isTyping: boolean) => void;\n\tisSubmitting?: boolean;\n\tplaceholder?: string;\n\t/** Compact mode — single-line input without footer row */\n\tcompact?: boolean;\n\t/** Pending attachments to preview */\n\tattachments?: PendingAttachment[];\n\t/** Called when files are added (paste, drop, or file picker) */\n\tonAddFiles?: (files: File[]) => void;\n\t/** Called to remove a pending attachment */\n\tonRemoveAttachment?: (id: string) => void;\n\t/** Disable entire composer (e.g. email required before sending) */\n\tdisabled?: boolean;\n}\n\n/** Widget composer — auto-resize, Enter-to-send, paste/drop attachments */\nexport function Composer({\n\ttext,\n\tonTextChange,\n\tonSubmit,\n\tonTyping,\n\tisSubmitting,\n\tplaceholder,\n\tcompact,\n\tattachments,\n\tonAddFiles,\n\tonRemoveAttachment,\n\tdisabled,\n}: ComposerProps) {\n\tconst ref = useRef<HTMLTextAreaElement>(null);\n\tconst fileInputRef = useRef<HTMLInputElement>(null);\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent) => {\n\t\t\tif (e.key === \"Enter\" && !e.shiftKey) {\n\t\t\t\te.preventDefault();\n\t\t\t\tonSubmit();\n\t\t\t}\n\t\t},\n\t\t[onSubmit],\n\t);\n\n\tconst handleChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\t\tconst value = e.target.value;\n\t\t\tif (value.length > MAX_CHARS) return; // Hard cap\n\t\t\tonTextChange(value);\n\t\t\tonTyping?.(value.length > 0);\n\n\t\t\t// Auto-resize (kept in sync with .hw-composer-input max-height in\n\t\t\t// styles.css — both at 220px / ~10 lines before internal scroll).\n\t\t\tconst el = ref.current;\n\t\t\tif (el) {\n\t\t\t\tel.style.height = \"auto\";\n\t\t\t\tel.style.height = `${Math.min(el.scrollHeight, 220)}px`;\n\t\t\t}\n\t\t},\n\t\t[onTextChange, onTyping],\n\t);\n\n\t// ── Clipboard paste ──────────────────────────\n\tconst handlePaste = useCallback(\n\t\t(e: React.ClipboardEvent) => {\n\t\t\tif (!onAddFiles) return;\n\t\t\tconst files = extractFiles(e.clipboardData);\n\t\t\tif (files.length > 0) {\n\t\t\t\te.preventDefault();\n\t\t\t\tonAddFiles(files);\n\t\t\t}\n\t\t},\n\t\t[onAddFiles],\n\t);\n\n\t// ── Drag & drop ──────────────────────────────\n\tconst [isDragging, setIsDragging] = useState(false);\n\tconst dragCountRef = useRef(0);\n\n\tconst handleDragEnter = useCallback((e: React.DragEvent) => {\n\t\te.preventDefault();\n\t\tdragCountRef.current++;\n\t\tif (dragCountRef.current === 1) setIsDragging(true);\n\t}, []);\n\n\tconst handleDragLeave = useCallback((e: React.DragEvent) => {\n\t\te.preventDefault();\n\t\tdragCountRef.current--;\n\t\tif (dragCountRef.current === 0) setIsDragging(false);\n\t}, []);\n\n\tconst handleDragOver = useCallback((e: React.DragEvent) => {\n\t\te.preventDefault();\n\t\te.dataTransfer.dropEffect = \"copy\";\n\t}, []);\n\n\tconst handleDrop = useCallback(\n\t\t(e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\tdragCountRef.current = 0;\n\t\t\tsetIsDragging(false);\n\t\t\tif (!onAddFiles) return;\n\t\t\tconst files = extractFiles(e.dataTransfer);\n\t\t\tif (files.length > 0) onAddFiles(files);\n\t\t},\n\t\t[onAddFiles],\n\t);\n\n\t// ── File picker ──────────────────────────────\n\tconst handleFileClick = useCallback(() => {\n\t\tfileInputRef.current?.click();\n\t}, []);\n\n\tconst handleFileChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\tif (!onAddFiles || !e.target.files) return;\n\t\t\tonAddFiles(Array.from(e.target.files));\n\t\t\te.target.value = \"\"; // reset so same file can be picked again\n\t\t},\n\t\t[onAddFiles],\n\t);\n\n\tconst hasText = text.trim().length > 0;\n\tconst hasAttachments = attachments && attachments.some((a) => a.part !== null);\n\tconst stillUploading = attachments?.some((a) => a.isUploading) ?? false;\n\t// Button stays clickable whenever there's *something* to send — the\n\t// actual text-required guard lives in `useComposer.submit` and\n\t// surfaces as an inline error if the visitor tries to send an\n\t// attachment without a caption. Feels less sticky than a disabled\n\t// arrow the user can't interpret.\n\tconst canSend = (hasText || hasAttachments) && !stillUploading;\n\tconst showCharCount = text.length >= CHAR_WARN_THRESHOLD;\n\tconst isOverLimit = text.length > MAX_CHARS;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={`hw-composer ${compact ? \"hw-composer--compact\" : \"\"} ${isDragging ? \"hw-composer--dragging\" : \"\"}`}\n\t\t\tonDragEnter={handleDragEnter}\n\t\t\tonDragLeave={handleDragLeave}\n\t\t\tonDragOver={handleDragOver}\n\t\t\tonDrop={handleDrop}\n\t\t>\n\t\t\t<div className=\"hw-composer-box\" style={{ position: \"relative\" }}>\n\t\t\t\t{/* Drag overlay */}\n\t\t\t\t{isDragging && (\n\t\t\t\t\t<div className=\"hw-composer-drop-overlay\">\n\t\t\t\t\t\t<span className=\"hw-composer-drop-text\">{t(\"widget.drop_files\")}</span>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{/* Attachment previews */}\n\t\t\t\t{attachments && attachments.length > 0 && (\n\t\t\t\t\t<div className=\"hw-composer-previews\">\n\t\t\t\t\t\t{attachments.map((a) => (\n\t\t\t\t\t\t\t<PreviewThumb\n\t\t\t\t\t\t\t\tkey={a.id}\n\t\t\t\t\t\t\t\tattachment={a}\n\t\t\t\t\t\t\t\tonRemove={onRemoveAttachment ? () => onRemoveAttachment(a.id) : undefined}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t<textarea\n\t\t\t\t\tref={ref}\n\t\t\t\t\tclassName=\"hw-composer-input\"\n\t\t\t\t\tvalue={text}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\tonPaste={handlePaste}\n\t\t\t\t\tplaceholder={placeholder ?? t(\"widget.placeholder\")}\n\t\t\t\t\trows={1}\n\t\t\t\t\tdisabled={disabled || isSubmitting}\n\t\t\t\t\taria-label={t(\"widget.aria_input\")}\n\t\t\t\t/>\n\t\t\t\t<div className=\"hw-composer-toolbar\">\n\t\t\t\t\t<div className=\"hw-composer-toolbar-left\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"hw-composer-attach\"\n\t\t\t\t\t\t\tonClick={handleFileClick}\n\t\t\t\t\t\t\tdisabled={disabled || isSubmitting}\n\t\t\t\t\t\t\taria-label={t(\"widget.aria_attach\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<PaperclipIcon />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tref={fileInputRef}\n\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\taccept={ACCEPTED_TYPES}\n\t\t\t\t\t\t\tmultiple\n\t\t\t\t\t\t\thidden\n\t\t\t\t\t\t\tonChange={handleFileChange}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{showCharCount && (\n\t\t\t\t\t\t\t<span className={`hw-composer-charcount ${isOverLimit ? \"hw-composer-charcount--over\" : \"\"}`}>\n\t\t\t\t\t\t\t\t{MAX_CHARS - text.length}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName={`hw-composer-send ${canSend && !isOverLimit && !disabled ? \"hw-composer-send--active\" : \"hw-composer-send--inactive\"}`}\n\t\t\t\t\t\tonClick={onSubmit}\n\t\t\t\t\t\tdisabled={disabled || !canSend || isSubmitting || isOverLimit}\n\t\t\t\t\t\taria-label={t(\"widget.aria_send\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t<SendIcon />\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// ── Preview thumbnail with hover ─────────────────\n\nfunction PreviewThumb({ attachment: a, onRemove }: { attachment: PendingAttachment; onRemove?: () => void }) {\n\tconst [hover, setHover] = useState(false);\n\tconst ref = useRef<HTMLDivElement>(null);\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={`hw-composer-preview ${a.error ? \"hw-composer-preview--error\" : \"\"}`}\n\t\t\tonMouseEnter={() => setHover(true)}\n\t\t\tonMouseLeave={() => setHover(false)}\n\t\t>\n\t\t\t{a.previewUrl ? (\n\t\t\t\t<img src={a.previewUrl} alt={a.file.name} className=\"hw-composer-preview-img\" />\n\t\t\t) : (\n\t\t\t\t<div className=\"hw-composer-preview-file\">\n\t\t\t\t\t<span className=\"hw-composer-preview-ext\">\n\t\t\t\t\t\t{a.file.name.split(\".\").pop()?.toUpperCase() ?? \"FILE\"}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{a.isUploading && <div className=\"hw-composer-preview-loader\" />}\n\t\t\t{a.error && <div className=\"hw-composer-preview-badge\" title={a.error}>!</div>}\n\t\t\t{onRemove && (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"hw-composer-preview-remove\"\n\t\t\t\t\tonClick={onRemove}\n\t\t\t\t\taria-label={t(\"widget.aria_remove\")}\n\t\t\t\t>\n\t\t\t\t\t<XIcon />\n\t\t\t\t</button>\n\t\t\t)}\n\t\t\t{/* Hover preview for images */}\n\t\t\t{hover && a.previewUrl && !a.isUploading && (\n\t\t\t\t<AnchoredPreview src={a.previewUrl} anchorRef={ref} />\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ── Helpers ──────────────────────────────────────\n\nfunction extractFiles(data: DataTransfer): File[] {\n\tconst files: File[] = [];\n\tif (data.files) {\n\t\tfor (let i = 0; i < data.files.length; i++) {\n\t\t\tconst file = data.files[i];\n\t\t\tif (file) files.push(file);\n\t\t}\n\t}\n\treturn files;\n}\n","// AUTO-GENERATED — DO NOT EDIT.\n// Run `bun scripts/sync-icons.ts` to regenerate from\n// @central-icons-react/round-outlined-radius-2-stroke-2 (devDep, not shipped).\n//\n// To add or rename an icon: edit MANIFEST in scripts/sync-icons.ts, re-run.\n\nimport type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement> & { size?: number | string };\n\n// IconBubble2\nexport function MessageIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M5.00195 4H19.002C20.1065 4 21.002 4.89543 21.002 6V16C21.002 17.1046 20.1065 18 19.002 18H12.002L7.00195 21V18H5.00195C3.89738 18 3.00195 17.1046 3.00195 16V6C3.00195 4.89543 3.89738 4 5.00195 4Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"square\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconCrossMedium\nexport function XIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M6.5 6.5L17.5 17.5M17.5 6.5L6.5 17.5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconArrowLeft\nexport function ArrowLeftIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M10 6L4 12L10 18\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M5 12H20\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconChevronRight\nexport function ChevronRightIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M9 4L15.5858 10.5858C16.3668 11.3668 16.3668 12.6331 15.5858 13.4142L9 20\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconSparklesSoft\nexport function SparklesIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M19 13C14.0987 13.4243 11.4243 16.0987 11 21C10.5578 16.0225 7.89737 13.5547 3 13C7.97478 12.4262 10.4262 9.97478 11 5C11.5547 9.89737 14.0225 12.5578 19 13Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M18.8864 2.34512C18.8642 2.14869 18.6981 2.0002 18.5004 2C18.3027 1.9998 18.1363 2.14794 18.1137 2.34433C18.0082 3.25861 17.7367 3.88584 17.3113 4.31127C16.8858 4.7367 16.2586 5.00822 15.3443 5.11367C15.1479 5.13632 14.9998 5.30271 15 5.5004C15.0002 5.69809 15.1487 5.86417 15.3451 5.88642C16.2439 5.98823 16.8855 6.25969 17.3217 6.68804C17.7556 7.11407 18.0322 7.74041 18.1126 8.64552C18.1305 8.84634 18.2988 9.00023 18.5004 9C18.702 8.99977 18.8701 8.84551 18.8874 8.64465C18.9645 7.75483 19.2409 7.11438 19.6776 6.67764C20.1144 6.24091 20.7548 5.96446 21.6446 5.88744C21.8455 5.87005 21.9998 5.70205 22 5.50044C22.0002 5.29883 21.8463 5.13048 21.6455 5.11264C20.7404 5.03224 20.1141 4.75557 19.688 4.3217C19.2597 3.88545 18.9882 3.24394 18.8864 2.34512Z\" fill=\"currentColor\" />\n\t\t</svg>\n\t);\n}\n\n// IconPaperPlaneTopRight\nexport function SendIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M9.61946 10.8613L20.9997 4.55422M9.04735 10.9043L4.10061 5.68812C3.49632 5.05091 3.94803 4 4.82621 4H20.2513C21.0247 4 21.5054 4.84039 21.1132 5.50702L13.1902 18.9762C12.7433 19.7358 11.6035 19.5879 11.3654 18.7393L9.28458 11.3223C9.24066 11.1658 9.15923 11.0223 9.04735 10.9043Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconPaperclip1\nexport function PaperclipIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M6 11V15C6 18.3137 8.68629 21 12 21C15.3137 21 18 18.3137 18 15V7C18 4.79086 16.2091 3 14 3C11.7909 3 10 4.79086 10 7V15C10 16.1046 10.8954 17 12 17C13.1046 17 14 16.1046 14 15V7\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconArrowUp\nexport function ArrowUpIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M12 5V20\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M6 10L12 4L18 10\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconHome\nexport function HomeIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M4 9.77313C4 9.2136 4 8.93383 4.07063 8.67517C4.1332 8.446 4.23609 8.22982 4.3745 8.03675C4.53071 7.81882 4.74784 7.6424 5.1821 7.28957L9.9821 3.38956C10.7014 2.80513 11.0611 2.51291 11.4609 2.40099C11.8135 2.30229 12.1865 2.30229 12.5391 2.40099C12.9389 2.51291 13.2986 2.80513 14.0179 3.38957L18.8179 7.28957C19.2522 7.6424 19.4693 7.81882 19.6255 8.03675C19.7639 8.22982 19.8668 8.446 19.9294 8.67517C20 8.93383 20 9.2136 20 9.77313V16.8C20 17.9201 20 18.4802 19.782 18.908C19.5903 19.2843 19.2843 19.5903 18.908 19.782C18.4802 20 17.9201 20 16.8 20H7.2C6.07989 20 5.51984 20 5.09202 19.782C4.71569 19.5903 4.40973 19.2843 4.21799 18.908C4 18.4802 4 17.9201 4 16.8V9.77313Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconBubbleDots\nexport function MessagesIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M4.00195 6.00003C4.00195 4.89546 4.89738 4.00003 6.00195 4.00002L18.0019 4C19.1065 4 20.002 4.89543 20.002 6V16.0358C20.002 17.1403 19.1065 18.0358 18.002 18.0358L15.3757 18.0358C15.1427 18.0358 14.9171 18.1171 14.7377 18.2657L11.9977 20.5358L9.29398 18.2694C9.11393 18.1185 8.8865 18.0358 8.65157 18.0358H6.00195C4.89738 18.0358 4.00195 17.1403 4.00195 16.0358V6.00003Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M6.875 11.25C6.875 11.7332 7.26675 12.125 7.75 12.125C8.23325 12.125 8.625 11.7332 8.625 11.25C8.625 10.7668 8.23325 10.375 7.75 10.375C7.26675 10.375 6.875 10.7668 6.875 11.25ZM11.125 11.25C11.125 11.7332 11.5168 12.125 12 12.125C12.4832 12.125 12.875 11.7332 12.875 11.25C12.875 10.7668 12.4832 10.375 12 10.375C11.5168 10.375 11.125 10.7668 11.125 11.25ZM15.375 11.25C15.375 11.7332 15.7668 12.125 16.25 12.125C16.7332 12.125 17.125 11.7332 17.125 11.25C17.125 10.7668 16.7332 10.375 16.25 10.375C15.7668 10.375 15.375 10.7668 15.375 11.25Z\" fill=\"currentColor\" stroke=\"currentColor\" strokeWidth=\"0.75\" strokeLinecap=\"square\" />\n\t\t</svg>\n\t);\n}\n\n// IconMagnifyingGlass\nexport function SearchIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M11 18C14.866 18 18 14.866 18 11C18 7.13401 14.866 4 11 4C7.13401 4 4 7.13401 4 11C4 14.866 7.13401 18 11 18Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t\t<path d=\"M20 20L16.05 16.05\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconBubblePlus\nexport function NewChatIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M11.9998 8L11.9998 11M11.9998 11V14M11.9998 11H8.99976M11.9998 11H14.9998M11.9977 20.5358L14.7377 18.2657C14.9171 18.1171 15.1427 18.0358 15.3757 18.0358L18.002 18.0358C19.1065 18.0357 20.002 17.1403 20.002 16.0358V6C20.002 4.89543 19.1065 4 18.0019 4L6.00195 4.00002C4.89738 4.00002 4.00195 4.89545 4.00195 6.00002V16.0358C4.00195 17.1403 4.89738 18.0358 6.00195 18.0358H8.65157C8.8865 18.0358 9.11393 18.1185 9.29398 18.2694L11.9977 20.5358Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconAppleIntelligence\nexport function BotIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path fillRule=\"evenodd\" clipRule=\"evenodd\" d=\"M9.67904 3.29155C10.7467 1.56948 13.2537 1.56948 14.3214 3.29155L15.1308 4.59707C15.2462 4.7833 15.3634 4.9684 15.4823 5.15233C15.7005 5.1305 15.9185 5.10662 16.1363 5.08068L17.6626 4.89893C19.6747 4.65934 21.2396 6.61723 20.5571 8.52637L20.0401 9.97255C19.9664 10.1786 19.8947 10.3854 19.825 10.5927C19.9779 10.7493 20.1323 10.9045 20.2882 11.0583L21.3821 12.1371C22.8256 13.5609 22.2668 16.0039 20.3491 16.6605L18.895 17.1584C18.6876 17.2294 18.4809 17.3023 18.275 17.3772C18.2478 17.5943 18.2226 17.8117 18.1995 18.0294L18.0372 19.5565C17.823 21.572 15.5635 22.6577 13.8546 21.5695L12.5584 20.7442C12.3734 20.6264 12.1873 20.5103 12.0002 20.3961C11.8131 20.5103 11.627 20.6264 11.442 20.7442L10.1458 21.5695C8.4369 22.6577 6.17739 21.572 5.96321 19.5565L5.80094 18.0294C5.7778 17.8117 5.75263 17.5943 5.72541 17.3772C5.51949 17.3023 5.31282 17.2294 5.10542 17.1584L3.65133 16.6605C1.7336 16.0039 1.17475 13.5609 2.61829 12.1371L3.71216 11.0583C3.86807 10.9045 4.0225 10.7493 4.17541 10.5927C4.10567 10.3854 4.03395 10.1786 3.96028 9.97255L3.44329 8.52637C2.7608 6.61723 4.32567 4.65934 6.33777 4.89893L7.86408 5.08068C8.08191 5.10662 8.29993 5.1305 8.5181 5.15233C8.63698 4.9684 8.75417 4.7833 8.86963 4.59707L9.67904 3.29155ZM7.61407 6.4827L6.16966 6.31071C5.20357 6.19567 4.45578 7.13505 4.78207 8.04778L5.2716 9.41715C6.10452 8.48167 6.88648 7.5021 7.61407 6.4827ZM5.78854 10.961C7.04552 9.61105 8.19784 8.16742 9.23549 6.64268C11.076 6.78287 12.9244 6.78287 14.7649 6.64268C15.8026 8.16743 16.9549 9.61105 18.2119 10.961C17.6657 12.722 17.2545 14.522 16.9818 16.3454C15.2628 17.0169 13.5974 17.8181 12.0002 18.7422C10.403 17.8181 8.73761 17.0169 7.01863 16.3454C6.74592 14.522 6.3347 12.722 5.78854 10.961ZM4.65269 12.1275L3.61666 13.1494C2.92581 13.8308 3.19234 15.0006 4.11188 15.3154L5.48873 15.7868C5.27593 14.553 4.99684 13.3315 4.65269 12.1275ZM7.22343 17.9611L7.377 19.4062C7.47946 20.3704 8.56185 20.8926 9.38218 20.3703L10.6083 19.5895C9.51004 18.9865 8.38012 18.4429 7.22343 17.9611ZM13.3921 19.5895L14.6182 20.3703C15.4385 20.8926 16.5209 20.3704 16.6234 19.4062L16.777 17.9611C15.6203 18.4429 14.4903 18.9865 13.3921 19.5895ZM18.5117 15.7868L19.8885 15.3154C20.8081 15.0006 21.0746 13.8308 20.3837 13.1494L19.3477 12.1275C19.0035 13.3315 18.7245 14.553 18.5117 15.7868ZM18.7288 9.41715L19.2183 8.04778C19.5446 7.13505 18.7968 6.19567 17.8307 6.31071L16.3863 6.4827C17.1139 7.5021 17.8959 8.48167 18.7288 9.41715ZM13.8786 5.2756C12.6272 5.3429 11.3731 5.3429 10.1218 5.2756L10.8874 4.04072C11.3991 3.21542 12.6013 3.21542 13.113 4.04072L13.8786 5.2756Z\" fill=\"currentColor\" />\n\t\t</svg>\n\t);\n}\n\n// IconBook\nexport function BookIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M9 6C8.44772 6 8 6.44772 8 7C8 7.55228 8.44772 8 9 8V6ZM15 8C15.5523 8 16 7.55228 16 7C16 6.44772 15.5523 6 15 6V8ZM9 10C8.44772 10 8 10.4477 8 11C8 11.5523 8.44772 12 9 12V10ZM12 12C12.5523 12 13 11.5523 13 11C13 10.4477 12.5523 10 12 10V12ZM7 4H17V2H7V4ZM18 5V19H20V5H18ZM17 20H7V22H17V20ZM6 19V5H4V19H6ZM7 20C6.44771 20 6 19.5523 6 19H4C4 20.6569 5.34315 22 7 22V20ZM18 19C18 19.5523 17.5523 20 17 20V22C18.6569 22 20 20.6569 20 19H18ZM17 4C17.5523 4 18 4.44772 18 5H20C20 3.34315 18.6569 2 17 2V4ZM7 2C5.34315 2 4 3.34315 4 5H6C6 4.44772 6.44772 4 7 4V2ZM18 12V15H20V12H18ZM17 16H7V18H17V16ZM7 22H10V20H7V22ZM7 16C5.34315 16 4 17.3431 4 19H6C6 18.4477 6.44772 18 7 18V16ZM18 15C18 15.5523 17.5523 16 17 16V18C18.6569 18 20 16.6569 20 15H18ZM9 8H15V6H9V8ZM9 12H12V10H9V12Z\" fill=\"currentColor\" />\n\t\t</svg>\n\t);\n}\n\n// IconMegaphone\nexport function MegaphoneIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M17.9961 14.0001C19.6529 14.0001 20.9961 12.657 20.9961 11.0001C20.9961 9.34325 19.6529 8.0001 17.9961 8.0001M12.8254 18.0001C12.4136 19.1653 11.3023 20.0001 9.99609 20.0001C8.33924 20.0001 6.99609 18.657 6.99609 17.0001V15.5001M6.99829 6.5001V15.5001M17.9961 5.73752V16.2627C17.9961 17.617 16.6784 18.5797 15.3882 18.1681L4.38819 14.6585C3.55899 14.394 2.99609 13.6235 2.99609 12.7532V9.24704C2.99609 8.37667 3.55899 7.60622 4.38819 7.34167L15.3882 3.83215C16.6784 3.42051 17.9961 4.38325 17.9961 5.73752Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconLightBulb\nexport function LightbulbIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M10 21H14M15.6076 15C17.6404 13.7751 19 11.5463 19 9C19 5.13401 15.866 2 12 2C8.13401 2 5 5.13401 5 9C5 11.5463 6.35958 13.7751 8.39241 15M15.6076 15C15.4111 15.1184 15.2084 15.2274 15 15.3264V17C15 17.5523 14.5523 18 14 18H10C9.44772 18 9 17.5523 9 17V15.3264C8.7916 15.2274 8.58886 15.1184 8.39241 15M15.6076 15H8.39241\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconCircleQuestionmark\nexport function HelpCircleIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t\t<path d=\"M12 16V16.01\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n\t\t\t<path d=\"M12 13C12 11.3608 14 11.9319 14 10C14 8.89543 13.1046 8 12 8C11.2597 8 10.6134 8.4022 10.2676 9\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconNewspaper\nexport function NewspaperIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M16 12V6C16 4.89543 15.1046 4 14 4H5C3.89543 4 3 4.89543 3 6V17.5C3 18.8807 4.11929 20 5.5 20H18.5M16 12V17.5C16 18.8807 17.1193 20 18.5 20M16 12H19C20.1046 12 21 12.8954 21 14V17.5C21 18.8807 19.8807 20 18.5 20M7 16H12M7 8H12V12H7V8Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n\n// IconStar\nexport function StarIcon({ size = 24, ...props }: IconProps) {\n\treturn (\n\t\t<svg\n\t\t\twidth={typeof size === \"number\" ? `${size}px` : size}\n\t\t\theight={typeof size === \"number\" ? `${size}px` : size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\taria-hidden={true}\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path d=\"M11.5288 2.29524C11.7179 1.90159 12.2821 1.90159 12.4712 2.29524L14.9458 7.44648C15.0219 7.60491 15.1735 7.71434 15.3487 7.73728L21.0456 8.4832C21.4809 8.5402 21.6552 9.07312 21.3368 9.37342L17.1693 13.303C17.0412 13.4238 16.9832 13.6009 17.0154 13.7735L18.0616 19.3857C18.1416 19.8146 17.6852 20.144 17.2993 19.9359L12.249 17.2133C12.0937 17.1296 11.9063 17.1296 11.751 17.2133L6.70073 19.9359C6.3148 20.144 5.85841 19.8146 5.93837 19.3857L6.98459 13.7735C7.01677 13.6009 6.95885 13.4238 6.83068 13.303L2.66324 9.37342C2.34476 9.07312 2.51909 8.5402 2.95444 8.4832L8.65127 7.73728C8.82648 7.71434 8.97811 7.60491 9.05422 7.44648L11.5288 2.29524Z\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n\t\t</svg>\n\t);\n}\n","import type { TimelineItemMetadata, TimelineItemPart } from \"@helpway/types\";\nimport { t } from \"@helpway/widget-core\";\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { handleCodeBlockClick, linkifyText, renderMarkdown } from \"./content/simple-markdown\";\n\ninterface MessageBubbleProps {\n\ttext: string;\n\tsender: \"visitor\" | \"team\" | \"ai\";\n\tsenderName?: string;\n\tparts?: TimelineItemPart[] | null;\n\ttimestamp?: string;\n\t/** Variant payload for interactive messages (quick replies, …). */\n\tmetadata?: TimelineItemMetadata | null;\n\t/** Called when the visitor taps a quick-reply option. */\n\tonQuickReplyTap?: (optionId: string, stepId: string) => void;\n}\n\n/** Single message bubble — Intercom-style, renders text + image/file parts */\nexport function MessageBubble({\n\ttext,\n\tsender,\n\tsenderName,\n\tparts,\n\ttimestamp,\n\tmetadata,\n\tonQuickReplyTap,\n}: MessageBubbleProps) {\n\tconst senderClass = `hw-msg--${sender}`;\n\tconst bubbleRef = useRef<HTMLDivElement>(null);\n\n\tconst imageParts =\n\t\tparts?.filter((p): p is Extract<TimelineItemPart, { type: \"image\" }> => p.type === \"image\") ??\n\t\t[];\n\tconst fileParts =\n\t\tparts?.filter((p): p is Extract<TimelineItemPart, { type: \"file\" }> => p.type === \"file\") ?? [];\n\tconst hasText = text.length > 0;\n\n\tuseEffect(() => {\n\t\tconst bubble = bubbleRef.current;\n\t\tif (!bubble || (sender !== \"ai\" && sender !== \"team\")) return;\n\t\tconst handleClick = (event: Event) => {\n\t\t\thandleCodeBlockClick(event, bubble);\n\t\t};\n\t\tbubble.addEventListener(\"click\", handleClick);\n\t\treturn () => {\n\t\t\tbubble.removeEventListener(\"click\", handleClick);\n\t\t};\n\t}, [sender]);\n\n\treturn (\n\t\t<div className={`hw-msg ${senderClass}`}>\n\t\t\t<div className=\"hw-msg-body\">\n\t\t\t\t{/*\n\t\t\t\t * Team members keep the sender label ABOVE the bubble (real-person\n\t\t\t\t * context matters — visitor wants to know a human is replying).\n\t\t\t\t * AI messages only show the label in the meta row BELOW the bubble\n\t\t\t\t * to avoid double-branding (agent name twice on the same message).\n\t\t\t\t */}\n\t\t\t\t{sender === \"team\" && (\n\t\t\t\t\t<div className=\"hw-msg-sender\">{senderName ?? t(\"widget.support\")}</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Image attachments */}\n\t\t\t\t{imageParts.length > 0 && (\n\t\t\t\t\t<div className=\"hw-msg-images\">\n\t\t\t\t\t\t{imageParts.map((img, i) => (\n\t\t\t\t\t\t\t<PreviewableThumbnail key={i} src={img.url} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Text bubble.\n\t\t\t\t - AI + team messages → renderMarkdown (team composer uses Tiptap → markdown output).\n\t\t\t\t - Visitor messages → linkifyText (widget composer is plain text).\n\t\t\t\t renderMarkdown escapes HTML entities first (&, <, >), so raw HTML cannot be injected.\n\t\t\t\t See packages/widget-react/src/themed/content/simple-markdown.ts for the safety guarantee. */}\n\t\t\t\t{hasText && (\n\t\t\t\t\t<div className=\"hw-msg-bubble\" ref={bubbleRef}>\n\t\t\t\t\t\t{sender === \"ai\" || sender === \"team\" ? (\n\t\t\t\t\t\t\t<span dangerouslySetInnerHTML={{ __html: renderMarkdown(text) }} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<span dangerouslySetInnerHTML={{ __html: linkifyText(text) }} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* File attachments */}\n\t\t\t\t{fileParts.length > 0 && (\n\t\t\t\t\t<div className=\"hw-msg-files\">\n\t\t\t\t\t\t{fileParts.map((file, i) => (\n\t\t\t\t\t\t\t<FileCard key={i} file={file} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Quick reply buttons — workflow is paused awaiting visitor input.\n\t\t\t\t Disabled when metadata.cancelled is set (visitor typed instead). */}\n\t\t\t\t{metadata?.kind === \"quick_replies\" && (\n\t\t\t\t\t<QuickReplyButtons metadata={metadata} onTap={onQuickReplyTap} />\n\t\t\t\t)}\n\n\t\t\t\t{timestamp && (\n\t\t\t\t\t<div className=\"hw-msg-meta\">\n\t\t\t\t\t\t<span className=\"hw-msg-time\">{timestamp}</span>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// ── Quick reply buttons (interactive workflow) ────────\n\nfunction QuickReplyButtons({\n\tmetadata,\n\tonTap,\n}: {\n\tmetadata: Extract<TimelineItemMetadata, { kind: \"quick_replies\" }>;\n\tonTap?: (optionId: string, stepId: string) => void;\n}) {\n\tconst [tappedId, setTappedId] = useState<string | null>(null);\n\tconst isLocked = metadata.cancelled || tappedId !== null;\n\n\tconst handleTap = (optionId: string) => {\n\t\tif (isLocked) return;\n\t\tsetTappedId(optionId);\n\t\tonTap?.(optionId, metadata.stepId);\n\t};\n\n\treturn (\n\t\t<div\n\t\t\tclassName=\"hw-quick-replies\"\n\t\t\tdata-cancelled={metadata.cancelled ? \"true\" : undefined}\n\t\t>\n\t\t\t{metadata.options.map((opt) => {\n\t\t\t\tconst isTapped = tappedId === opt.id;\n\t\t\t\treturn (\n\t\t\t\t\t<button\n\t\t\t\t\t\tkey={opt.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"hw-quick-reply-btn\"\n\t\t\t\t\t\tdata-tapped={isTapped ? \"true\" : undefined}\n\t\t\t\t\t\tdisabled={isLocked}\n\t\t\t\t\t\tonClick={() => handleTap(opt.id)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{opt.label}\n\t\t\t\t\t</button>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n\n// ── Previewable thumbnail (image) ────────────────\n\nfunction PreviewableThumbnail({ src }: { src: string }) {\n\tconst [hover, setHover] = useState(false);\n\tconst ref = useRef<HTMLAnchorElement>(null);\n\n\treturn (\n\t\t<>\n\t\t\t<a\n\t\t\t\tref={ref}\n\t\t\t\thref={src}\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclassName=\"hw-msg-image-link\"\n\t\t\t\tonMouseEnter={() => setHover(true)}\n\t\t\t\tonMouseLeave={() => setHover(false)}\n\t\t\t>\n\t\t\t\t<img src={src} alt=\"\" className=\"hw-msg-image\" loading=\"lazy\" />\n\t\t\t</a>\n\t\t\t{hover && <AnchoredPreview src={src} anchorRef={ref} href={src} />}\n\t\t</>\n\t);\n}\n\n// ── File card with hover preview for previewable types ───\n\nconst PREVIEWABLE_EXTS = new Set([\"pdf\", \"csv\", \"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\"]);\n\nfunction FileCard({ file }: { file: Extract<TimelineItemPart, { type: \"file\" }> }) {\n\tconst [hover, setHover] = useState(false);\n\tconst ref = useRef<HTMLAnchorElement>(null);\n\tconst ext = file.fileName.split(\".\").pop()?.toLowerCase() ?? \"\";\n\tconst isPreviewable = PREVIEWABLE_EXTS.has(ext);\n\tconst isImage = file.mimeType.startsWith(\"image/\");\n\n\treturn (\n\t\t<>\n\t\t\t<a\n\t\t\t\tref={ref}\n\t\t\t\thref={file.url}\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclassName=\"hw-msg-file\"\n\t\t\t\tonMouseEnter={() => isPreviewable && setHover(true)}\n\t\t\t\tonMouseLeave={() => setHover(false)}\n\t\t\t>\n\t\t\t\t<span className=\"hw-msg-file-icon\">\n\t\t\t\t\t<FileTypeIcon ext={ext} />\n\t\t\t\t</span>\n\t\t\t\t<span className=\"hw-msg-file-info\">\n\t\t\t\t\t<span className=\"hw-msg-file-name\">{file.fileName}</span>\n\t\t\t\t\t<span className=\"hw-msg-file-size\">{formatFileSize(file.fileSize)}</span>\n\t\t\t\t</span>\n\t\t\t</a>\n\t\t\t{hover &&\n\t\t\t\tisPreviewable &&\n\t\t\t\t(isImage ? (\n\t\t\t\t\t<AnchoredPreview src={file.url} anchorRef={ref} href={file.url} />\n\t\t\t\t) : (\n\t\t\t\t\t<AnchoredDocPreview fileName={file.fileName} ext={ext} anchorRef={ref} href={file.url} />\n\t\t\t\t))}\n\t\t</>\n\t);\n}\n\n// ── Anchored preview — card popover above the element ──\n\nexport function AnchoredPreview({\n\tsrc,\n\tanchorRef,\n\thref,\n\tonOpen,\n}: {\n\tsrc: string;\n\tanchorRef: React.RefObject<HTMLElement | null>;\n\thref?: string;\n\tonOpen?: () => void;\n}) {\n\tconst [style, setStyle] = useState<React.CSSProperties>({ opacity: 0 });\n\tconst [portalTarget, setPortalTarget] = useState<Element | DocumentFragment | null>(null);\n\n\tuseLayoutEffect(() => {\n\t\tconst anchor = anchorRef.current;\n\t\tif (!anchor) return;\n\n\t\tconst rect = anchor.getBoundingClientRect();\n\t\tconst pw = 260;\n\t\tconst gap = 8;\n\t\tconst vw = window.innerWidth;\n\n\t\tlet left = rect.left + rect.width / 2 - pw / 2;\n\t\tif (left < 8) left = 8;\n\t\tif (left + pw > vw - 8) left = vw - pw - 8;\n\n\t\tconst estimatedH = 200;\n\t\tlet top = rect.top - estimatedH - gap;\n\t\tif (top < 8) top = rect.bottom + gap;\n\n\t\tsetStyle({ left, top, width: pw, opacity: 1 });\n\t\t// Portal into the same root as the anchor so shadow-DOM widgets keep\n\t\t// --hw-* CSS token inheritance and the preview participates in the\n\t\t// widget's z-index stack. Falls back to document.body when the widget\n\t\t// isn't shadow-encapsulated.\n\t\tconst root = anchor.getRootNode();\n\t\tsetPortalTarget(root instanceof ShadowRoot ? root : document.body);\n\t}, [anchorRef]);\n\n\tconst handleClick = () => {\n\t\tif (onOpen) onOpen();\n\t\telse if (href) window.open(href, \"_blank\");\n\t};\n\n\tif (!portalTarget) return null;\n\n\treturn createPortal(\n\t\t<div className=\"hw-hover-preview\" style={style} onClick={handleClick}>\n\t\t\t<img src={src} alt=\"\" className=\"hw-hover-preview-img\" />\n\t\t</div>,\n\t\tportalTarget,\n\t);\n}\n\n// ── Document preview popover (PDF, CSV) ──────────\n\nfunction AnchoredDocPreview({\n\tfileName,\n\text,\n\tanchorRef,\n\thref,\n}: {\n\tfileName: string;\n\text: string;\n\tanchorRef: React.RefObject<HTMLElement | null>;\n\thref: string;\n}) {\n\tconst [style, setStyle] = useState<React.CSSProperties>({ opacity: 0 });\n\tconst [portalTarget, setPortalTarget] = useState<Element | DocumentFragment | null>(null);\n\n\tuseLayoutEffect(() => {\n\t\tconst anchor = anchorRef.current;\n\t\tif (!anchor) return;\n\n\t\tconst rect = anchor.getBoundingClientRect();\n\t\tconst pw = 220;\n\t\tconst ph = 80;\n\t\tconst gap = 8;\n\t\tconst vw = window.innerWidth;\n\n\t\tlet left = rect.left + rect.width / 2 - pw / 2;\n\t\tif (left < 8) left = 8;\n\t\tif (left + pw > vw - 8) left = vw - pw - 8;\n\n\t\tlet top = rect.top - ph - gap;\n\t\tif (top < 8) top = rect.bottom + gap;\n\n\t\tsetStyle({ left, top, width: pw, opacity: 1 });\n\t\tconst root = anchor.getRootNode();\n\t\tsetPortalTarget(root instanceof ShadowRoot ? root : document.body);\n\t}, [anchorRef]);\n\n\tif (!portalTarget) return null;\n\n\treturn createPortal(\n\t\t<div\n\t\t\tclassName=\"hw-hover-preview hw-hover-preview--doc\"\n\t\t\tstyle={style}\n\t\t\tonClick={() => window.open(href, \"_blank\")}\n\t\t>\n\t\t\t<div className=\"hw-hover-preview-doc-icon\">\n\t\t\t\t<FileTypeIcon ext={ext} />\n\t\t\t</div>\n\t\t\t<div className=\"hw-hover-preview-doc-info\">\n\t\t\t\t<span className=\"hw-hover-preview-doc-name\">{fileName}</span>\n\t\t\t\t<span className=\"hw-hover-preview-doc-hint\">{t(\"widget.click_to_open\")}</span>\n\t\t\t</div>\n\t\t</div>,\n\t\tportalTarget,\n\t);\n}\n\n// ── Helpers ──────────────────────────────────────\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction FileTypeIcon({ ext }: { ext: string }) {\n\t// Color-coded by file type\n\tconst colors: Record<string, string> = {\n\t\tpdf: \"#ef4444\",\n\t\tcsv: \"#22c55e\",\n\t\tdoc: \"#3b82f6\",\n\t\tdocx: \"#3b82f6\",\n\t\txls: \"#22c55e\",\n\t\txlsx: \"#22c55e\",\n\t\ttxt: \"#6b7280\",\n\t\tzip: \"#f59e0b\",\n\t};\n\tconst color = colors[ext] ?? \"currentColor\";\n\n\treturn (\n\t\t<svg\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke={color}\n\t\t\tstrokeWidth={1.5}\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t>\n\t\t\t<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n\t\t\t<polyline points=\"14 2 14 8 20 8\" />\n\t\t\t{ext === \"pdf\" && (\n\t\t\t\t<text x=\"8\" y=\"18\" fontSize=\"6\" fill={color} stroke=\"none\" fontWeight=\"700\">\n\t\t\t\t\tPDF\n\t\t\t\t</text>\n\t\t\t)}\n\t\t\t{ext === \"csv\" && (\n\t\t\t\t<text x=\"7\" y=\"18\" fontSize=\"6\" fill={color} stroke=\"none\" fontWeight=\"700\">\n\t\t\t\t\tCSV\n\t\t\t\t</text>\n\t\t\t)}\n\t\t</svg>\n\t);\n}\n","import { useEffect, useRef } from \"react\";\n\nconst COPY_ICON = `<svg class=\"hw-code-copy-icon\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"M15 9V4.25C15 3.55964 14.4404 3 13.75 3H4.25C3.55964 3 3 3.55964 3 4.25V13.75C3 14.4404 3.55964 15 4.25 15H9M10.25 9H19.75C20.4404 9 21 9.55964 21 10.25V19.75C21 20.4404 20.4404 21 19.75 21H10.25C9.55964 21 9 20.4404 9 19.75V10.25C9 9.55964 9.55964 9 10.25 9Z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\nconst CHECK_ICON = `<svg class=\"hw-code-check-icon\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"M8 13L11 16L16 8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\nfunction inferCodeLanguage(code: string, lang?: string): string {\n\tif (lang) return lang;\n\tconst trimmed = code.trim();\n\tif (/^(npm|pnpm|yarn|bun|npx|curl|cd|mkdir|cp|mv|rm|export)\\b/m.test(trimmed)) return \"bash\";\n\tif (/\\b(import|export)\\b/.test(trimmed) && /<[A-Z_a-z][\\w.:-]*(\\s|>)/.test(trimmed)) return \"tsx\";\n\tif (/\\b(import|export|const|let|function|type|interface)\\b/.test(trimmed)) return \"ts\";\n\tif (/^\\s*[{[]/.test(trimmed)) return \"json\";\n\treturn \"code\";\n}\n\nexport function handleCodeBlockClick(e: Event, root: HTMLElement): void {\n\tconst target = e.target as HTMLElement | null;\n\tconst btn = target?.closest<HTMLButtonElement>(\".hw-code-copy\");\n\tif (!btn || !root.contains(btn)) return;\n\tconst block = btn.closest(\".hw-code\");\n\tconst code = block?.querySelector(\"pre code\");\n\tconst text = code?.textContent ?? \"\";\n\tif (!text) return;\n\tvoid navigator.clipboard?.writeText(text).then(\n\t\t() => flashCopied(btn),\n\t\t() => flashCopied(btn, true),\n\t);\n}\n\n/**\n * Lightweight Markdown → HTML renderer.\n * Zero dependencies. Handles common patterns:\n * headings, bold, italic, code, links, lists, blockquotes, images, hr.\n *\n * Security note: Content is served from Better i18n Content CMS which only\n * accepts authenticated writes (secret API key). The CMS sanitizes content\n * server-side. Additionally, our renderMarkdown escapes HTML entities before\n * processing markdown syntax, preventing injection of raw HTML tags.\n */\nexport function renderMarkdown(md: string): string {\n\t// Stash fenced code blocks BEFORE any other pass. Fence content must be\n\t// preserved verbatim: no bold, no autolink, no newline→<br> — otherwise\n\t// a curl command or JSON sample gets shredded. We also escape HTML inside\n\t// the block (the global escape below runs only on the remaining markdown).\n\tconst codeBlocks: string[] = [];\n\tconst codeBlockPlaceholder = (i: number) => `\\u0000CODEBLOCK${i}\\u0000`;\n\tconst body = md.replace(\n\t\t// Eat ALL newlines around the fence (zero-or-more both sides). The\n\t\t// replacement re-emits its own `\\n\\n` pair so the paragraph splitter\n\t\t// cleanly bookends the fence. Without this, `before\\n\\n` + `\\n\\n` from\n\t\t// us = 3 newlines, the extra one becomes <br /> and lands inside a <p>.\n\t\t/\\n*```(\\w+)?\\n?([\\s\\S]*?)```\\n*/g,\n\t\t(_match, lang: string | undefined, code: string) => {\n\t\t\tconst escaped = code.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n\t\t\tconst langLabel = inferCodeLanguage(code, lang);\n\t\t\tconst className = langLabel !== \"code\" ? ` class=\"language-${langLabel}\"` : \"\";\n\t\t\t// Render every fenced block with a header bar (language label + copy\n\t\t\t// button) so it reads like a proper code card, not a bare <pre>.\n\t\t\t// The actual copy action is wired up in MarkdownContent via event\n\t\t\t// delegation — we only need the markup + a stable attribute to key\n\t\t\t// off of.\n\t\t\tconst trimmed = escaped.replace(/\\n$/, \"\");\n\t\t\tcodeBlocks.push(\n\t\t\t\t`<div class=\"hw-code\" data-hw-code=\"1\"><div class=\"hw-code-header\"><span class=\"hw-code-lang\">${langLabel}</span><div class=\"hw-code-actions\"><button type=\"button\" class=\"hw-code-action hw-code-copy\" aria-label=\"Copy code\" title=\"Copy code\">${COPY_ICON}${CHECK_ICON}<span class=\"hw-code-copy-label\">Copy</span></button></div></div><pre><code${className}>${trimmed}</code></pre></div>`,\n\t\t\t);\n\t\t\t// Sandwich the placeholder in blank lines so the paragraph splitter\n\t\t\t// treats it as its own block. Otherwise a fence that follows a\n\t\t\t// paragraph without a separating blank line ends up inside a <p>\n\t\t\t// (invalid HTML, collapses the <pre>).\n\t\t\treturn `\\n\\n${codeBlockPlaceholder(codeBlocks.length - 1)}\\n\\n`;\n\t\t},\n\t);\n\n\tlet html = body\n\t\t// Escape HTML entities FIRST — prevents XSS from raw HTML in markdown\n\t\t.replace(/&/g, \"&amp;\")\n\t\t.replace(/</g, \"&lt;\")\n\t\t.replace(/>/g, \"&gt;\")\n\t\t// Headings (### h3, ## h2, # h1)\n\t\t.replace(/^### (.+)$/gm, \"<h3>$1</h3>\")\n\t\t.replace(/^## (.+)$/gm, \"<h2>$1</h2>\")\n\t\t.replace(/^# (.+)$/gm, \"<h1>$1</h1>\")\n\t\t// Horizontal rule\n\t\t.replace(/^---$/gm, \"<hr />\")\n\t\t// Bold + italic\n\t\t.replace(/\\*\\*\\*(.+?)\\*\\*\\*/g, \"<strong><em>$1</em></strong>\")\n\t\t// Bold\n\t\t.replace(/\\*\\*(.+?)\\*\\*/g, \"<strong>$1</strong>\")\n\t\t// Italic\n\t\t.replace(/\\*(.+?)\\*/g, \"<em>$1</em>\")\n\t\t// Inline code\n\t\t.replace(/`([^`]+)`/g, \"<code>$1</code>\")\n\t\t// Images\n\t\t.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<img src=\"$2\" alt=\"$1\" />')\n\t\t// Links (markdown format)\n\t\t.replace(\n\t\t\t/\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n\t\t\t'<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>',\n\t\t)\n\t\t// Auto-link bare URLs (not already inside an href or markdown link)\n\t\t.replace(\n\t\t\t/(?<!\")(?<!=)(https?:\\/\\/[^\\s<)]+)/g,\n\t\t\t'<a href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>',\n\t\t)\n\t\t// Blockquotes\n\t\t.replace(/^&gt; (.+)$/gm, \"<blockquote>$1</blockquote>\")\n\t\t// Unordered lists\n\t\t.replace(/^[*-] (.+)$/gm, \"<li>$1</li>\")\n\t\t// Paragraphs (double newline)\n\t\t.replace(/\\n\\n/g, \"</p><p>\")\n\t\t// Single newlines → br\n\t\t.replace(/\\n/g, \"<br />\");\n\n\t// Wrap consecutive <li> items in <ul>\n\thtml = html.replace(/((?:<li>.*?<\\/li>\\s*)+)/g, \"<ul>$1</ul>\");\n\n\t// Wrap in paragraph if not starting with a block element\n\tif (\n\t\t!html.startsWith(\"<h\") &&\n\t\t!html.startsWith(\"<ul\") &&\n\t\t!html.startsWith(\"<blockquote\") &&\n\t\t!html.startsWith(\"<hr\")\n\t) {\n\t\thtml = `<p>${html}</p>`;\n\t}\n\n\t// Re-inject code blocks now that surrounding paragraphs / <br> passes are\n\t// done. Placeholders used NUL sentinels so they can't collide with user\n\t// content or be accidentally wrapped by the block-element heuristics above.\n\tif (codeBlocks.length > 0) {\n\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: placeholders use NUL sentinels intentionally.\n\t\thtml = html.replace(/\\u0000CODEBLOCK(\\d+)\\u0000/g, (_m, idx: string) => {\n\t\t\tconst i = Number.parseInt(idx, 10);\n\t\t\treturn codeBlocks[i] ?? \"\";\n\t\t});\n\t\t// A code block that landed inside a <p> (because the preceding line had no\n\t\t// blank-line separator) becomes invalid nesting (<p><div><pre>). Unwrap\n\t\t// the outer <p> so the block stands on its own.\n\t\thtml = html.replace(/<p>(\\s*<div class=\"hw-code\"[\\s\\S]*?<\\/div>\\s*)<\\/p>/g, \"$1\");\n\t}\n\n\treturn html;\n}\n\n/**\n * Convert bare URLs in plain text to clickable links.\n * Used for visitor/team messages (not full markdown).\n * HTML-escaped for safety.\n */\nexport function linkifyText(text: string): string {\n\treturn text\n\t\t.replace(/&/g, \"&amp;\")\n\t\t.replace(/</g, \"&lt;\")\n\t\t.replace(/>/g, \"&gt;\")\n\t\t.replace(\n\t\t\t/(https?:\\/\\/[^\\s<]+)/g,\n\t\t\t'<a href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>',\n\t\t)\n\t\t.replace(/\\n/g, \"<br />\");\n}\n\n/**\n * Renders markdown or pre-rendered HTML content.\n * Prefers bodyHtml (server-sanitized by CMS) when available,\n * falls back to client-side markdown rendering (HTML-escaped).\n */\nexport function MarkdownContent({\n\tbodyHtml,\n\tbodyMarkdown,\n\tclassName,\n}: {\n\tbodyHtml?: string | null;\n\tbodyMarkdown?: string | null;\n\tclassName?: string;\n}) {\n\tconst rootRef = useRef<HTMLDivElement>(null);\n\tconst html = bodyHtml ?? (bodyMarkdown ? renderMarkdown(bodyMarkdown) : \"\");\n\n\t// Strip whitespace-only block elements after the HTML lands in the DOM.\n\t// PlateJS/Slate/ProseMirror CMS bodies emit <p>&nbsp;</p> or <div> </div>\n\t// to represent visual line breaks. CSS `:empty` doesn't match these (the\n\t// nbsp/space is a text node) and CSS has no text-content selector, so we\n\t// clean them up here. Runs once per html change.\n\tuseEffect(() => {\n\t\tconst root = rootRef.current;\n\t\tif (!root) return;\n\n\t\tconst isWhitespaceOnly = (el: Element): boolean => {\n\t\t\t// No element children OR only <br> children, AND text is whitespace/empty\n\t\t\tconst hasNonBrChild = Array.from(el.children).some(\n\t\t\t\t(c) => c.tagName !== \"BR\",\n\t\t\t);\n\t\t\tif (hasNonBrChild) return false;\n\t\t\tconst text = el.textContent ?? \"\";\n\t\t\treturn text.replace(/[\\s ]/g, \"\") === \"\";\n\t\t};\n\n\t\tconst removeEmpties = () => {\n\t\t\tconst candidates = root.querySelectorAll(\"p, div\");\n\t\t\tcandidates.forEach((el) => {\n\t\t\t\tif (isWhitespaceOnly(el)) el.remove();\n\t\t\t});\n\t\t};\n\t\tremoveEmpties();\n\t}, [html]);\n\n\t// Event-delegated copy handler for any `.hw-code-copy` button inside the\n\t// rendered tree. Using delegation instead of rendering each code block as\n\t// a React component keeps the markdown → HTML path zero-dep.\n\tuseEffect(() => {\n\t\tconst root = rootRef.current;\n\t\tif (!root) return;\n\t\tconst handler = (e: Event) => {\n\t\t\thandleCodeBlockClick(e, root);\n\t\t};\n\t\troot.addEventListener(\"click\", handler);\n\t\treturn () => {\n\t\t\troot.removeEventListener(\"click\", handler);\n\t\t};\n\t}, []);\n\n\tif (!html) return null;\n\n\treturn (\n\t\t<div\n\t\t\tref={rootRef}\n\t\t\tclassName={`hw-markdown ${className ?? \"\"}`}\n\t\t\t// Content is from authenticated CMS (server-sanitized bodyHtml)\n\t\t\t// or client-side rendered with HTML entity escaping (renderMarkdown).\n\t\t\t// biome-ignore lint/security/noDangerouslySetInnerHtml: trusted CMS content\n\t\t\tdangerouslySetInnerHTML={{ __html: html }}\n\t\t/>\n\t);\n}\n\nfunction flashCopied(btn: HTMLButtonElement, failed = false) {\n\tconst label = btn.querySelector(\".hw-code-copy-label\");\n\tif (!label) return;\n\tconst original = label.textContent ?? \"Copy\";\n\tlabel.textContent = failed ? \"Failed\" : \"Copied\";\n\tbtn.classList.add(failed ? \"hw-code-copy--failed\" : \"hw-code-copy--copied\");\n\tsetTimeout(() => {\n\t\tlabel.textContent = original;\n\t\tbtn.classList.remove(\"hw-code-copy--copied\", \"hw-code-copy--failed\");\n\t}, 1500);\n}\n","import type { TimelineItem } from \"@helpway/types\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\ninterface DebugEvent {\n\tid: string;\n\tt: number;\n\tkind: \"trpc\" | \"ws\" | \"store\" | \"error\";\n\tlabel: string;\n\tdetail?: string;\n}\n\nconst MAX_EVENTS = 60;\n\nfunction isDebugEnabled(): boolean {\n\tif (typeof window === \"undefined\") return false;\n\tif (typeof window.localStorage !== \"undefined\" && window.localStorage.getItem(\"hw:debug\") === \"1\") {\n\t\treturn true;\n\t}\n\tconst search = window.location?.search ?? \"\";\n\treturn search.includes(\"hwdebug=1\") || search.includes(\"debug=hw\");\n}\n\nfunction senderOf(item: TimelineItem): string {\n\tif (item.visitorId) return \"visitor\";\n\tif (item.aiAgentId) return \"ai\";\n\tif (item.userId) return \"team\";\n\treturn item.type;\n}\n\nexport function WidgetDebugOverlay() {\n\tconst [enabled, setEnabled] = useState(false);\n\tconst [open, setOpen] = useState(true);\n\tconst [events, setEvents] = useState<DebugEvent[]>([]);\n\tconst eventsRef = useRef<DebugEvent[]>([]);\n\n\t// Subscribe to each field individually — returning a fresh object from a\n\t// selector triggers an infinite re-render loop with zustand because each\n\t// render produces a new object reference.\n\tconst activeId = useWidgetStore((s) => s.activeConversationId);\n\tconst messagesMap = useWidgetStore((s) => s.messages);\n\tconst typingUsers = useWidgetStore((s) => s.typingUsers);\n\tconst aiProcessingMap = useWidgetStore((s) => s.aiProcessing);\n\tconst { store } = useWidgetContext();\n\n\tuseEffect(() => {\n\t\tsetEnabled(isDebugEnabled());\n\t}, []);\n\n\tconst pushEvent = useMemo(\n\t\t() => (ev: Omit<DebugEvent, \"id\" | \"t\">) => {\n\t\t\tconst e: DebugEvent = {\n\t\t\t\t...ev,\n\t\t\t\tid: `${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n\t\t\t\tt: Date.now(),\n\t\t\t};\n\t\t\teventsRef.current = [e, ...eventsRef.current].slice(0, MAX_EVENTS);\n\t\t\tsetEvents(eventsRef.current);\n\t\t},\n\t\t[],\n\t);\n\n\t// Intercept fetch to log tRPC calls — works with any tRPC proxy shape\n\t// because we observe at the network boundary, not the client object.\n\tuseEffect(() => {\n\t\tif (!enabled) return;\n\t\tif (typeof window === \"undefined\" || typeof window.fetch !== \"function\") return;\n\t\tconst originalFetch = window.fetch.bind(window);\n\t\tconst patched = (async (input: RequestInfo | URL, init?: RequestInit) => {\n\t\t\tconst url = typeof input === \"string\" ? input : input instanceof URL ? input.toString() : input.url;\n\t\t\tconst isTrpc = url.includes(\"/trpc/\");\n\t\t\tif (isTrpc) {\n\t\t\t\tconst method = init?.method ?? (typeof input !== \"string\" && !(input instanceof URL) ? input.method : \"GET\");\n\t\t\t\tconst label = url.split(\"/trpc/\")[1]?.split(\"?\")[0] ?? url;\n\t\t\t\tpushEvent({ kind: \"trpc\", label: `→ ${method} ${label}`, detail: shortJson(init?.body) });\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst res = await originalFetch(input, init);\n\t\t\t\tif (isTrpc) {\n\t\t\t\t\tconst label = url.split(\"/trpc/\")[1]?.split(\"?\")[0] ?? url;\n\t\t\t\t\tpushEvent({ kind: \"trpc\", label: `← ${res.status} ${label}` });\n\t\t\t\t}\n\t\t\t\treturn res;\n\t\t\t} catch (err) {\n\t\t\t\tif (isTrpc) {\n\t\t\t\t\tconst label = url.split(\"/trpc/\")[1]?.split(\"?\")[0] ?? url;\n\t\t\t\t\tpushEvent({ kind: \"error\", label: `✘ ${label}`, detail: err instanceof Error ? err.message : String(err) });\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}) as unknown as typeof window.fetch;\n\t\twindow.fetch = patched;\n\t\treturn () => {\n\t\t\twindow.fetch = originalFetch;\n\t\t};\n\t}, [enabled, pushEvent]);\n\n\t// Tap WebSocket events by wrapping the store's handleRealtimeEvent\n\tuseEffect(() => {\n\t\tif (!enabled) return;\n\t\tconst original = store.getState().handleRealtimeEvent;\n\t\tstore.setState({\n\t\t\thandleRealtimeEvent: (ev) => {\n\t\t\t\tpushEvent({ kind: \"ws\", label: ev.type, detail: shortJson(ev) });\n\t\t\t\toriginal(ev);\n\t\t\t},\n\t\t});\n\t\treturn () => {\n\t\t\tstore.setState({ handleRealtimeEvent: original });\n\t\t};\n\t}, [enabled, store, pushEvent]);\n\n\t// Emit a marker when messages array changes for the active conversation\n\tconst activeMessages = activeId ? messagesMap.get(activeId) ?? [] : [];\n\tconst lastMsgSignature = useMemo(\n\t\t() => activeMessages.map((m) => `${m.id}:${senderOf(m)}:${m.createdAt}`).join(\"|\"),\n\t\t[activeMessages],\n\t);\n\tconst prevSigRef = useRef(lastMsgSignature);\n\tuseEffect(() => {\n\t\tif (!enabled) return;\n\t\tif (prevSigRef.current !== lastMsgSignature) {\n\t\t\tprevSigRef.current = lastMsgSignature;\n\t\t\tpushEvent({\n\t\t\t\tkind: \"store\",\n\t\t\t\tlabel: `messages[${activeMessages.length}]`,\n\t\t\t\tdetail: activeMessages\n\t\t\t\t\t.map((m, i) => `${i}:${senderOf(m)}=${(m.text ?? \"\").slice(0, 24)}`)\n\t\t\t\t\t.join(\" | \"),\n\t\t\t});\n\t\t}\n\t}, [lastMsgSignature, activeMessages, enabled, pushEvent]);\n\n\tif (!enabled) return null;\n\n\tconst isTyping = activeId ? typingUsers.get(activeId) : false;\n\tconst isAi = activeId ? aiProcessingMap.get(activeId) : false;\n\n\treturn (\n\t\t<div style={styles.wrap}>\n\t\t\t<div style={styles.header}>\n\t\t\t\t<strong>hw debug</strong>\n\t\t\t\t<span style={styles.meta}>\n\t\t\t\t\t{\" \"}· conv {activeId ? activeId.slice(0, 10) : \"—\"} · items {activeMessages.length} · typing {isTyping ? \"Y\" : \"n\"} · ai {isAi ? \"Y\" : \"n\"}\n\t\t\t\t</span>\n\t\t\t\t<button type=\"button\" style={styles.btn} onClick={() => setOpen((v) => !v)}>{open ? \"hide\" : \"show\"}</button>\n\t\t\t\t<button type=\"button\" style={styles.btn} onClick={() => { eventsRef.current = []; setEvents([]); }}>clear</button>\n\t\t\t</div>\n\t\t\t{open && (\n\t\t\t\t<div style={styles.body}>\n\t\t\t\t\t<div style={styles.section}>\n\t\t\t\t\t\t<div style={styles.sectionTitle}>messages (active)</div>\n\t\t\t\t\t\t{activeMessages.length === 0 ? (\n\t\t\t\t\t\t\t<div style={styles.empty}>empty</div>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\tactiveMessages.map((m, i) => (\n\t\t\t\t\t\t\t\t<div key={m.id} style={styles.row}>\n\t\t\t\t\t\t\t\t\t<span style={{ ...styles.badge, background: colorFor(senderOf(m)) }}>{i}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.sender}>{senderOf(m)}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.ts}>{m.createdAt.slice(11, 23)}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.text}>{(m.text ?? \"\").slice(0, 60)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style={styles.section}>\n\t\t\t\t\t\t<div style={styles.sectionTitle}>events</div>\n\t\t\t\t\t\t{events.length === 0 ? (\n\t\t\t\t\t\t\t<div style={styles.empty}>no events yet — send a message</div>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\tevents.map((e) => (\n\t\t\t\t\t\t\t\t<div key={e.id} style={styles.row}>\n\t\t\t\t\t\t\t\t\t<span style={{ ...styles.badge, background: kindColor(e.kind) }}>{e.kind}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.ts}>{new Date(e.t).toISOString().slice(11, 23)}</span>\n\t\t\t\t\t\t\t\t\t<span style={styles.evLabel}>{e.label}</span>\n\t\t\t\t\t\t\t\t\t{e.detail && <span style={styles.detail}>{e.detail}</span>}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nfunction shortJson(v: unknown): string {\n\tif (v === undefined) return \"\";\n\ttry {\n\t\tconst s = JSON.stringify(v);\n\t\tif (!s) return \"\";\n\t\treturn s.length > 180 ? `${s.slice(0, 177)}…` : s;\n\t} catch {\n\t\treturn String(v);\n\t}\n}\n\nfunction colorFor(sender: string): string {\n\tswitch (sender) {\n\t\tcase \"visitor\":\n\t\t\treturn \"#1d4ed8\";\n\t\tcase \"ai\":\n\t\t\treturn \"#7c3aed\";\n\t\tcase \"team\":\n\t\t\treturn \"#16a34a\";\n\t\tdefault:\n\t\t\treturn \"#6b7280\";\n\t}\n}\n\nfunction kindColor(kind: DebugEvent[\"kind\"]): string {\n\tswitch (kind) {\n\t\tcase \"trpc\":\n\t\t\treturn \"#0ea5e9\";\n\t\tcase \"ws\":\n\t\t\treturn \"#f97316\";\n\t\tcase \"store\":\n\t\t\treturn \"#64748b\";\n\t\tcase \"error\":\n\t\t\treturn \"#dc2626\";\n\t}\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n\twrap: {\n\t\tposition: \"fixed\",\n\t\tright: 12,\n\t\tbottom: 12,\n\t\tzIndex: 2147483000,\n\t\twidth: 420,\n\t\tmaxHeight: \"70vh\",\n\t\tbackground: \"rgba(9,9,11,0.94)\",\n\t\tcolor: \"#e5e7eb\",\n\t\tborderRadius: 10,\n\t\tfontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n\t\tfontSize: 11,\n\t\tboxShadow: \"0 12px 30px rgba(0,0,0,0.35)\",\n\t\toverflow: \"hidden\",\n\t\tpointerEvents: \"auto\",\n\t},\n\theader: {\n\t\tdisplay: \"flex\",\n\t\talignItems: \"center\",\n\t\tgap: 6,\n\t\tpadding: \"6px 10px\",\n\t\tbackground: \"#18181b\",\n\t\tborderBottom: \"1px solid #27272a\",\n\t},\n\tmeta: { flex: 1, color: \"#a1a1aa\", fontSize: 10 },\n\tbtn: {\n\t\tbackground: \"#27272a\",\n\t\tcolor: \"#e4e4e7\",\n\t\tborder: \"1px solid #3f3f46\",\n\t\tborderRadius: 4,\n\t\tpadding: \"2px 8px\",\n\t\tcursor: \"pointer\",\n\t\tfontSize: 10,\n\t},\n\tbody: { display: \"flex\", flexDirection: \"column\", maxHeight: \"calc(70vh - 32px)\", overflow: \"auto\" },\n\tsection: { borderBottom: \"1px solid #27272a\", padding: \"6px 10px\" },\n\tsectionTitle: { color: \"#a1a1aa\", fontSize: 10, textTransform: \"uppercase\", letterSpacing: 0.6, marginBottom: 4 },\n\trow: {\n\t\tdisplay: \"grid\",\n\t\tgridTemplateColumns: \"32px 56px 72px 1fr\",\n\t\tgap: 6,\n\t\talignItems: \"baseline\",\n\t\tpadding: \"2px 0\",\n\t\tborderTop: \"1px dashed #27272a\",\n\t},\n\tbadge: {\n\t\tdisplay: \"inline-block\",\n\t\tborderRadius: 3,\n\t\tpadding: \"1px 4px\",\n\t\tcolor: \"white\",\n\t\tfontSize: 9,\n\t\ttextAlign: \"center\",\n\t},\n\tsender: { color: \"#d4d4d8\" },\n\tts: { color: \"#71717a\", fontSize: 10 },\n\ttext: { color: \"#e4e4e7\", whiteSpace: \"nowrap\", overflow: \"hidden\", textOverflow: \"ellipsis\" },\n\tevLabel: { color: \"#e4e4e7\" },\n\tdetail: { gridColumn: \"1 / -1\", color: \"#a1a1aa\", fontSize: 10, whiteSpace: \"pre-wrap\", wordBreak: \"break-all\" },\n\tempty: { color: \"#52525b\", fontStyle: \"italic\", fontSize: 10 },\n};\n","import { resolveLabel, t } from \"@helpway/widget-core\";\nimport type { WidgetContentTab } from \"@helpway/widget-core\";\nimport { useCallback, useEffect } from \"react\";\nimport { useContentTab } from \"../../hooks/use-content-tab\";\nimport type { ContentEntryItem } from \"../../hooks/use-content-tab\";\nimport { ContentDetailView } from \"./content-detail-view\";\nimport { ContentListView } from \"./content-list-view\";\nimport { GroupedContentTabView } from \"./grouped-content-tab-view\";\n\n/**\n * Content tab dispatcher:\n * - \"flat\" (default) → simple list → detail\n * - \"grouped\" → categories → items → detail\n */\nexport function ContentTabView({\n\ttab,\n\tshowDetail,\n\tdetailSlug,\n\tsubView,\n\tonSelectEntry,\n\tonSelectCategory,\n}: {\n\ttab: WidgetContentTab;\n\tshowDetail: boolean;\n\tdetailSlug: string | null;\n\tsubView?: string | null;\n\tonSelectEntry: (slug: string) => void;\n\tonSelectCategory?: (category: ContentEntryItem) => void;\n}) {\n\t// ── Grouped tab ──\n\tif (tab.tabType === \"grouped\" && tab.itemsModelSlug) {\n\t\treturn (\n\t\t\t<GroupedContentTabView\n\t\t\t\ttab={tab}\n\t\t\t\tsubView={subView ?? null}\n\t\t\t\tdetailSlug={detailSlug}\n\t\t\t\tonSelectCategory={onSelectCategory ?? (() => {})}\n\t\t\t\tonSelectEntry={onSelectEntry}\n\t\t\t/>\n\t\t);\n\t}\n\n\t// ── Flat tab (default) ──\n\treturn (\n\t\t<FlatContentTabView\n\t\t\ttab={tab}\n\t\t\tshowDetail={showDetail}\n\t\t\tdetailSlug={detailSlug}\n\t\t\tonSelectEntry={onSelectEntry}\n\t\t/>\n\t);\n}\n\n// ── Flat (original behavior) ─────────────────────────────\n\nfunction FlatContentTabView({\n\ttab,\n\tshowDetail,\n\tdetailSlug,\n\tonSelectEntry,\n}: {\n\ttab: WidgetContentTab;\n\tshowDetail: boolean;\n\tdetailSlug: string | null;\n\tonSelectEntry: (slug: string) => void;\n}) {\n\tconst {\n\t\tentries,\n\t\tdetail,\n\t\tisLoading,\n\t\tisLoadingDetail,\n\t\thasMore,\n\t\tfetchEntries,\n\t\tloadMore,\n\t\tfetchDetail,\n\t} = useContentTab(tab.id);\n\n\tuseEffect(() => {\n\t\tif (detailSlug) fetchDetail(detailSlug);\n\t}, [detailSlug, fetchDetail]);\n\n\tconst handleSearch = useCallback(\n\t\t(query: string) => {\n\t\t\tfetchEntries({ page: 1, search: query || undefined, reset: true });\n\t\t},\n\t\t[fetchEntries],\n\t);\n\n\tif (showDetail && detailSlug) {\n\t\treturn <ContentDetailView entry={detail} isLoading={isLoadingDetail} />;\n\t}\n\n\treturn (\n\t\t<ContentListView\n\t\t\tentries={entries}\n\t\t\tisLoading={isLoading}\n\t\t\thasMore={hasMore}\n\t\t\tonSelect={onSelectEntry}\n\t\t\tonLoadMore={loadMore}\n\t\t\tonSearch={handleSearch}\n\t\t\tsearchPlaceholder={`${t(\"widget.search\")} ${resolveLabel(tab.label).toLowerCase()}...`}\n\t\t\tdisplay={tab.display}\n\t\t/>\n\t);\n}\n","import type { WidgetContentTab } from \"@helpway/widget-core\";\nimport { CONTENT_CACHE_TTL, getLocale } from \"@helpway/widget-core\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\n\ninterface ContentEntryItem {\n\tslug: string;\n\ttitle: string;\n\tbody: string | null;\n\tpublishedAt: string | null;\n\tcustomFields: Record<string, string | null>;\n}\n\ninterface ContentEntryDetail {\n\tslug: string;\n\ttitle: string;\n\tbody: string | null;\n\tbodyHtml: string | null;\n\tpublishedAt: string | null;\n\tsourceLanguage: string;\n\tavailableLanguages: string[];\n\tcustomFields: Record<string, string | null>;\n}\n\nconst EMPTY_TABS: WidgetContentTab[] = [];\n\n// ── Cache key helpers ──\n\nfunction listKey(tabId: string, lang: string) {\n\treturn `flat:${tabId}:${lang}:list`;\n}\n\nfunction detailKey(tabId: string, lang: string, slug: string) {\n\treturn `flat:${tabId}:${lang}:detail:${slug}`;\n}\n\ninterface CachedList {\n\titems: ContentEntryItem[];\n\ttotal: number;\n\thasMore: boolean;\n\tpage: number;\n}\n\nfunction readCache<T>(cache: Map<string, { data: unknown; ts: number }>, key: string): T | null {\n\tconst entry = cache.get(key);\n\tif (!entry) return null;\n\tif (Date.now() - entry.ts > CONTENT_CACHE_TTL) return null;\n\treturn entry.data as T;\n}\n\n/**\n * Hook for fetching content from a dynamic content tab.\n * Content is cached in the Zustand store so tab switches don't re-fetch.\n */\nexport function useContentTab(tabId: string) {\n\tconst { client, store } = useWidgetContext();\n\tconst contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_TABS;\n\tconst tab = contentTabs.find((t) => t.id === tabId) ?? null;\n\n\tconst lang = getLocale();\n\tconst cache = store.getState().contentCache;\n\n\tconst [entries, setEntries] = useState<ContentEntryItem[]>(\n\t\t() => readCache<CachedList>(cache, listKey(tabId, lang))?.items ?? [],\n\t);\n\tconst [detail, setDetail] = useState<ContentEntryDetail | null>(null);\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [isLoadingDetail, setIsLoadingDetail] = useState(false);\n\tconst [hasMore, setHasMore] = useState(\n\t\t() => readCache<CachedList>(cache, listKey(tabId, lang))?.hasMore ?? false,\n\t);\n\tconst [total, setTotal] = useState(\n\t\t() => readCache<CachedList>(cache, listKey(tabId, lang))?.total ?? 0,\n\t);\n\tconst [page, setPage] = useState(\n\t\t() => readCache<CachedList>(cache, listKey(tabId, lang))?.page ?? 1,\n\t);\n\n\tconst fetchEntries = useCallback(\n\t\tasync (opts?: { page?: number; search?: string; reset?: boolean }) => {\n\t\t\tif (!tab) return;\n\t\t\tconst p = opts?.page ?? 1;\n\t\t\tconst reset = opts?.reset ?? p === 1;\n\n\t\t\tsetIsLoading(true);\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\t\ttabId,\n\t\t\t\t\tpage: p,\n\t\t\t\t\tlimit: 10,\n\t\t\t\t\tsearch: opts?.search,\n\t\t\t\t\tlanguage: getLocale(),\n\t\t\t\t});\n\n\t\t\t\tif (result.items) {\n\t\t\t\t\tsetEntries((prev) => {\n\t\t\t\t\t\tconst nextItems = reset ? result.items! : [...prev, ...result.items!];\n\t\t\t\t\t\tif (!opts?.search) {\n\t\t\t\t\t\t\tstore.getState().setContentCache(listKey(tabId, getLocale()), {\n\t\t\t\t\t\t\t\titems: nextItems,\n\t\t\t\t\t\t\t\ttotal: result.total,\n\t\t\t\t\t\t\t\thasMore: result.hasMore,\n\t\t\t\t\t\t\t\tpage: p,\n\t\t\t\t\t\t\t} satisfies CachedList);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nextItems;\n\t\t\t\t\t});\n\t\t\t\t\tsetHasMore(result.hasMore);\n\t\t\t\t\tsetTotal(result.total);\n\t\t\t\t\tsetPage(p);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useContentTab] fetch error:\", err);\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client, tabId, tab, store],\n\t);\n\n\tconst loadMore = useCallback(() => {\n\t\tif (!hasMore || isLoading) return;\n\t\tfetchEntries({ page: page + 1 });\n\t}, [fetchEntries, hasMore, isLoading, page]);\n\n\tconst fetchDetail = useCallback(\n\t\tasync (slug: string) => {\n\t\t\tif (!tab) return;\n\n\t\t\t// Check detail cache\n\t\t\tconst cached = readCache<ContentEntryDetail>(\n\t\t\t\tstore.getState().contentCache,\n\t\t\t\tdetailKey(tabId, getLocale(), slug),\n\t\t\t);\n\t\t\tif (cached) {\n\t\t\t\tsetDetail(cached);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetIsLoadingDetail(true);\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\t\ttabId,\n\t\t\t\t\tslug,\n\t\t\t\t\tlanguage: getLocale(),\n\t\t\t\t});\n\t\t\t\tif (result.entry) {\n\t\t\t\t\tconst entry = result.entry as ContentEntryDetail;\n\t\t\t\t\tsetDetail(entry);\n\t\t\t\t\tstore.getState().setContentCache(\n\t\t\t\t\t\tdetailKey(tabId, getLocale(), slug),\n\t\t\t\t\t\tentry,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useContentTab] detail error:\", err);\n\t\t\t} finally {\n\t\t\t\tsetIsLoadingDetail(false);\n\t\t\t}\n\t\t},\n\t\t[client, tabId, tab, store],\n\t);\n\n\tconst clearDetail = useCallback(() => {\n\t\tsetDetail(null);\n\t}, []);\n\n\t// Initial fetch — only if cache was empty\n\tuseEffect(() => {\n\t\tif (tab && entries.length === 0) {\n\t\t\tfetchEntries({ page: 1, reset: true });\n\t\t}\n\t}, [tab]); // eslint-disable-line react-hooks/exhaustive-deps\n\n\treturn {\n\t\ttab,\n\t\tentries,\n\t\tdetail,\n\t\tisLoading,\n\t\tisLoadingDetail,\n\t\thasMore,\n\t\ttotal,\n\t\tfetchEntries,\n\t\tloadMore,\n\t\tfetchDetail,\n\t\tclearDetail,\n\t};\n}\n\nexport type { ContentEntryItem, ContentEntryDetail, WidgetContentTab };\n","import { formatRelativeTime } from \"@helpway/widget-core\";\nimport type { ContentEntryDetail } from \"../../hooks/use-content-tab\";\nimport { MarkdownContent } from \"./simple-markdown\";\n\nexport function ContentDetailView({\n\tentry,\n\tisLoading,\n}: {\n\tentry: ContentEntryDetail | null;\n\tisLoading: boolean;\n}) {\n\tif (isLoading || !entry) {\n\t\treturn <ArticleSkeleton />;\n\t}\n\n\tconst badge = entry.customFields.version ?? entry.customFields.priority ?? entry.customFields.type ?? null;\n\n\treturn (\n\t\t<div className=\"hw-content-detail\">\n\t\t\t<div className=\"hw-content-detail-header\">\n\t\t\t\t<h1 className=\"hw-content-detail-title\">{entry.title}</h1>\n\t\t\t\t{(badge || entry.publishedAt) && (\n\t\t\t\t\t<div className=\"hw-content-detail-meta\">\n\t\t\t\t\t\t{badge && <span className=\"hw-content-entry-badge\">{badge}</span>}\n\t\t\t\t\t\t{entry.publishedAt && (\n\t\t\t\t\t\t\t<span className=\"hw-content-detail-date\">\n\t\t\t\t\t\t\t\t{formatRelativeTime(entry.publishedAt)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{(entry.body || entry.bodyHtml) && (\n\t\t\t\t<div className=\"hw-content-detail-body\">\n\t\t\t\t\t<MarkdownContent bodyHtml={entry.bodyHtml} bodyMarkdown={entry.body} />\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n/**\n * Article-shaped skeleton.\n *\n * Uses the real .hw-content-detail / .hw-content-detail-header / .hw-content-detail-body / .hw-markdown\n * wrapper classes so all padding, font metrics, and adjacency-spacing rules\n * apply identically to the skeleton — guaranteeing the content lands without\n * any reflow when it arrives.\n *\n * Layout maps 1:1 to the rendered changelog:\n * <h1>Title</h1>\n * <div class=\"meta\"> badge + date </div>\n * <h2>Section</h2>\n * <ul><li>Bullet 1, 2 lines</li></ul>\n * <ul><li>Bullet 2, 2 lines</li></ul>\n * ...\n */\nfunction ArticleSkeleton() {\n\tconst sections: { headerWidth: string; items: { l1: string; l2: string }[] }[] = [\n\t\t{\n\t\t\theaderWidth: \"30%\",\n\t\t\titems: [\n\t\t\t\t{ l1: \"98%\", l2: \"62%\" },\n\t\t\t\t{ l1: \"94%\", l2: \"48%\" },\n\t\t\t\t{ l1: \"96%\", l2: \"70%\" },\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\theaderWidth: \"26%\",\n\t\t\titems: [\n\t\t\t\t{ l1: \"92%\", l2: \"55%\" },\n\t\t\t\t{ l1: \"88%\", l2: \"40%\" },\n\t\t\t],\n\t\t},\n\t];\n\n\treturn (\n\t\t<div className=\"hw-content-detail\">\n\t\t\t<div className=\"hw-content-detail-header\">\n\t\t\t\t<h1 className=\"hw-content-detail-title\">\n\t\t\t\t\t<span className=\"hw-skeleton hw-skeleton-title\" />\n\t\t\t\t</h1>\n\t\t\t\t<div className=\"hw-content-detail-meta\">\n\t\t\t\t\t<span className=\"hw-skeleton hw-skeleton-badge\" />\n\t\t\t\t\t<span className=\"hw-skeleton hw-skeleton-date\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"hw-content-detail-body\">\n\t\t\t\t<div className=\"hw-markdown\">\n\t\t\t\t\t{sections.map((s, i) => (\n\t\t\t\t\t\t<SkeletonSection\n\t\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\t\theaderWidth={s.headerWidth}\n\t\t\t\t\t\t\titems={s.items}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction SkeletonSection({\n\theaderWidth,\n\titems,\n}: {\n\theaderWidth: string;\n\titems: { l1: string; l2: string }[];\n}) {\n\treturn (\n\t\t<>\n\t\t\t<h2>\n\t\t\t\t<span\n\t\t\t\t\tclassName=\"hw-skeleton hw-skeleton-h2\"\n\t\t\t\t\tstyle={{ display: \"block\", width: headerWidth }}\n\t\t\t\t/>\n\t\t\t</h2>\n\t\t\t{items.map((item, j) => (\n\t\t\t\t<ul key={j}>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<div className=\"hw-skeleton-bullet-lines\">\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclassName=\"hw-skeleton hw-skeleton-bullet-line\"\n\t\t\t\t\t\t\t\tstyle={{ display: \"block\", width: item.l1 }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclassName=\"hw-skeleton hw-skeleton-bullet-line\"\n\t\t\t\t\t\t\t\tstyle={{ display: \"block\", width: item.l2, marginTop: 8 }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t))}\n\t\t</>\n\t);\n}\n","import { formatRelativeTime, t } from \"@helpway/widget-core\";\nimport type { ContentTabDisplay } from \"@helpway/types\";\nimport { useCallback, useRef, useState } from \"react\";\nimport type { ContentEntryItem } from \"../../hooks/use-content-tab\";\n\n/**\n * Content entry list — Intercom-style clean card layout.\n * Search bar at top, card entries with title + description + chevron.\n */\nexport function ContentListView({\n\tentries,\n\tisLoading,\n\thasMore,\n\tonSelect,\n\tonLoadMore,\n\tonSearch,\n\tsearchPlaceholder,\n\tdisplay,\n}: {\n\tentries: ContentEntryItem[];\n\tisLoading: boolean;\n\thasMore: boolean;\n\tonSelect: (slug: string) => void;\n\tonLoadMore: () => void;\n\tonSearch?: (query: string) => void;\n\tsearchPlaceholder?: string;\n\tdisplay?: ContentTabDisplay;\n}) {\n\tconst [searchText, setSearchText] = useState(\"\");\n\tconst debounceRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n\tconst handleSearch = useCallback(\n\t\t(value: string) => {\n\t\t\tsetSearchText(value);\n\t\t\tif (!onSearch) return;\n\t\t\tclearTimeout(debounceRef.current);\n\t\t\tdebounceRef.current = setTimeout(() => {\n\t\t\t\tonSearch(value.trim());\n\t\t\t}, 300);\n\t\t},\n\t\t[onSearch],\n\t);\n\n\treturn (\n\t\t<div className=\"hw-content-list\">\n\t\t\t{/* Search */}\n\t\t\t{onSearch && (\n\t\t\t\t<div className=\"hw-content-search\">\n\t\t\t\t\t<div className=\"hw-content-search-box\">\n\t\t\t\t\t\t<svg className=\"hw-content-search-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t\t\t\t\t<circle cx=\"11\" cy=\"11\" r=\"8\" />\n\t\t\t\t\t\t\t<line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tclassName=\"hw-content-search-input\"\n\t\t\t\t\t\t\tplaceholder={searchPlaceholder ?? t(\"widget.search\")}\n\t\t\t\t\t\t\tvalue={searchText}\n\t\t\t\t\t\t\tonChange={(e) => handleSearch(e.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Loading */}\n\t\t\t{isLoading && entries.length === 0 && (\n\t\t\t\t<div className=\"hw-skeleton-content\">\n\t\t\t\t\t{[1, 2, 3].map((i) => (\n\t\t\t\t\t\t<div key={i} className=\"hw-skeleton-content-item\">\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: \"70%\", height: 14 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: \"90%\", height: 12 }} />\n\t\t\t\t\t\t\t<div className=\"hw-skeleton hw-skeleton-line\" style={{ width: \"40%\", height: 10 }} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Empty */}\n\t\t\t{!isLoading && entries.length === 0 && (\n\t\t\t\t<div className=\"hw-content-empty\">\n\t\t\t\t\t<div className=\"hw-content-empty-title\">\n\t\t\t\t\t\t{searchText ? t(\"widget.no_results\") : t(\"widget.nothing_yet\")}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"hw-content-empty-desc\">\n\t\t\t\t\t\t{searchText ? t(\"widget.try_different\") : t(\"widget.check_back\")}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Entries */}\n\t\t\t{entries.length > 0 && (\n\t\t\t\t<div className=\"hw-content-entries\">\n\t\t\t\t\t{entries.map((entry) => (\n\t\t\t\t\t\t<ContentEntryCard key={entry.slug} entry={entry} onSelect={onSelect} display={display} />\n\t\t\t\t\t))}\n\t\t\t\t\t{hasMore && (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"hw-content-load-more\"\n\t\t\t\t\t\t\tonClick={onLoadMore}\n\t\t\t\t\t\t\tdisabled={isLoading}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{isLoading ? t(\"widget.loading\") : t(\"widget.load_more\")}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n// ── Entry Card — Intercom-style ──────────────────────────\n\nfunction truncateText(text: string | null, maxLen = 80): string {\n\tif (!text) return \"\";\n\tconst clean = text.replace(/[#*_`>\\[\\]!()-]/g, \"\").trim();\n\treturn clean.length > maxLen ? `${clean.slice(0, maxLen)}...` : clean;\n}\n\nfunction ContentEntryCard({\n\tentry,\n\tonSelect,\n\tdisplay,\n}: {\n\tentry: ContentEntryItem;\n\tonSelect: (slug: string) => void;\n\tdisplay?: ContentTabDisplay;\n}) {\n\tconst { customFields } = entry;\n\n\t// Use display mapping if configured, otherwise auto-detect from common field names\n\tconst badge = display?.badgeField\n\t\t? customFields[display.badgeField] ?? null\n\t\t: customFields.version ?? customFields.priority ?? customFields.type ?? null;\n\n\tconst subtitleValue = display?.subtitleField\n\t\t? (display.subtitleField === \"body\" ? entry.body : customFields[display.subtitleField]) ?? null\n\t\t: customFields.excerpt ?? customFields.summary ?? customFields.description ?? null;\n\n\tconst preview = subtitleValue ? truncateText(subtitleValue) : truncateText(entry.body);\n\n\treturn (\n\t\t<button type=\"button\" className=\"hw-content-entry\" onClick={() => onSelect(entry.slug)}>\n\t\t\t<div className=\"hw-content-entry-main\">\n\t\t\t\t<div className=\"hw-content-entry-text\">\n\t\t\t\t\t<span className=\"hw-content-entry-title\">{entry.title}</span>\n\t\t\t\t\t{preview && (\n\t\t\t\t\t\t<span className=\"hw-content-entry-desc\">{preview}</span>\n\t\t\t\t\t)}\n\t\t\t\t\t{(badge || entry.publishedAt) && (\n\t\t\t\t\t\t<div className=\"hw-content-entry-meta\">\n\t\t\t\t\t\t\t{badge && <span className=\"hw-content-entry-badge\">{badge}</span>}\n\t\t\t\t\t\t\t{entry.publishedAt && (\n\t\t\t\t\t\t\t\t<span className=\"hw-content-entry-date\">{formatRelativeTime(entry.publishedAt)}</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<svg className=\"hw-content-entry-chevron\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t\t\t<polyline points=\"9 18 15 12 9 6\" />\n\t\t\t\t</svg>\n\t\t\t</div>\n\t\t</button>\n\t);\n}\n","import type { WidgetContentTab } from \"@helpway/widget-core\";\nimport { t } from \"@helpway/widget-core\";\nimport { useEffect, useRef } from \"react\";\nimport { useGroupedContentTab } from \"../../hooks/use-grouped-content-tab\";\nimport type { ContentEntryItem } from \"../../hooks/use-content-tab\";\nimport { ContentDetailView } from \"./content-detail-view\";\nimport { ContentListView } from \"./content-list-view\";\n\n/**\n * Grouped content tab — category → items → detail drill-down.\n *\n * Three views managed by parent (DefaultWidget):\n * - subView = null → show categories\n * - subView = \"content-category\" → show items for activeCategory\n * - subView = \"content-detail\" → show item detail\n */\nexport function GroupedContentTabView({\n\ttab,\n\tsubView,\n\tdetailSlug,\n\tonSelectCategory,\n\tonSelectEntry,\n}: {\n\ttab: WidgetContentTab;\n\tsubView: string | null;\n\tdetailSlug: string | null;\n\tonSelectCategory: (category: ContentEntryItem) => void;\n\tonSelectEntry: (slug: string) => void;\n}) {\n\tconst {\n\t\tcategories,\n\t\tisCategoriesLoading,\n\t\titems,\n\t\tisItemsLoading,\n\t\titemsHasMore,\n\t\tactiveCategory,\n\t\tdetail,\n\t\tisLoadingDetail,\n\t\tinitFetch,\n\t\tselectCategory,\n\t\tsearchCategories,\n\t\tloadMoreItems,\n\t\tsearchItems,\n\t\tfetchDetail,\n\t\tclearCategory,\n\t} = useGroupedContentTab(tab.id);\n\n\t// Init fetch categories on mount\n\tuseEffect(() => {\n\t\tinitFetch();\n\t}, [initFetch]);\n\n\t// Fetch detail when slug changes\n\tuseEffect(() => {\n\t\tif (detailSlug && subView === \"content-detail\") {\n\t\t\tfetchDetail(detailSlug);\n\t\t}\n\t}, [detailSlug, subView, fetchDetail]);\n\n\t// Clean up hook state when navigating back to category list\n\tconst prevSubView = useRef(subView);\n\tuseEffect(() => {\n\t\tif (prevSubView.current === \"content-category\" && subView === null) {\n\t\t\tclearCategory();\n\t\t}\n\t\tprevSubView.current = subView;\n\t}, [subView, clearCategory]);\n\n\t// ── Detail view ──\n\tif (subView === \"content-detail\" && detailSlug) {\n\t\treturn <ContentDetailView entry={detail} isLoading={isLoadingDetail} />;\n\t}\n\n\t// ── Items list (within a category) ──\n\tif (subView === \"content-category\" && activeCategory) {\n\t\treturn (\n\t\t\t<ContentListView\n\t\t\t\tentries={items}\n\t\t\t\tisLoading={isItemsLoading}\n\t\t\t\thasMore={itemsHasMore}\n\t\t\t\tonSelect={onSelectEntry}\n\t\t\t\tonLoadMore={loadMoreItems}\n\t\t\t\tonSearch={searchItems}\n\t\t\t\tsearchPlaceholder={t(\"widget.search\")}\n\t\t\t\tdisplay={tab.display}\n\t\t\t/>\n\t\t);\n\t}\n\n\t// ── Categories list (with search) ──\n\treturn (\n\t\t<ContentListView\n\t\t\tentries={categories}\n\t\t\tisLoading={isCategoriesLoading}\n\t\t\thasMore={false}\n\t\t\tonSelect={(slug) => {\n\t\t\t\tconst cat = categories.find((c) => c.slug === slug);\n\t\t\t\tif (cat) {\n\t\t\t\t\tselectCategory(cat);\n\t\t\t\t\tonSelectCategory(cat);\n\t\t\t\t}\n\t\t\t}}\n\t\t\tonLoadMore={() => {}}\n\t\t\tonSearch={searchCategories}\n\t\t\tsearchPlaceholder={t(\"widget.search\")}\n\t\t/>\n\t);\n}\n","import type { WidgetContentTab } from \"@helpway/widget-core\";\nimport { CONTENT_CACHE_TTL, getLocale } from \"@helpway/widget-core\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { useWidgetContext, useWidgetStore } from \"../provider\";\nimport type { ContentEntryItem, ContentEntryDetail } from \"./use-content-tab\";\n\nconst EMPTY_TABS: WidgetContentTab[] = [];\n\n// ── Cache key helpers ──\n\nfunction categoriesKey(tabId: string, lang: string) {\n\treturn `grouped:${tabId}:${lang}:categories`;\n}\n\nfunction itemsKey(tabId: string, lang: string, groupSlug: string) {\n\treturn `grouped:${tabId}:${lang}:items:${groupSlug}`;\n}\n\nfunction detailKey(tabId: string, lang: string, slug: string) {\n\treturn `grouped:${tabId}:${lang}:detail:${slug}`;\n}\n\ninterface CachedItems {\n\titems: ContentEntryItem[];\n\thasMore: boolean;\n\tpage: number;\n}\n\nfunction readCache<T>(cache: Map<string, { data: unknown; ts: number }>, key: string): T | null {\n\tconst entry = cache.get(key);\n\tif (!entry) return null;\n\tif (Date.now() - entry.ts > CONTENT_CACHE_TTL) return null;\n\treturn entry.data as T;\n}\n\n/**\n * Hook for grouped content tabs (category → items drill-down).\n * Content is cached in the Zustand store so tab switches don't re-fetch.\n */\nexport function useGroupedContentTab(tabId: string) {\n\tconst { client, store } = useWidgetContext();\n\tconst contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_TABS;\n\tconst tab = contentTabs.find((t) => t.id === tabId) ?? null;\n\n\tconst lang = getLocale();\n\tconst cache = store.getState().contentCache;\n\n\t// ── Categories (top level) ──\n\tconst cachedCategories = readCache<ContentEntryItem[]>(cache, categoriesKey(tabId, lang));\n\tconst [categories, setCategories] = useState<ContentEntryItem[]>(cachedCategories ?? []);\n\tconst [isCategoriesLoading, setIsCategoriesLoading] = useState(false);\n\n\t// ── Items (within a category) ──\n\tconst [items, setItems] = useState<ContentEntryItem[]>([]);\n\tconst [isItemsLoading, setIsItemsLoading] = useState(false);\n\tconst [itemsHasMore, setItemsHasMore] = useState(false);\n\tconst itemsPageRef = useRef(1);\n\n\t// ── Detail (single item) ──\n\tconst [detail, setDetail] = useState<ContentEntryDetail | null>(null);\n\tconst [isLoadingDetail, setIsLoadingDetail] = useState(false);\n\n\t// ── Active category ──\n\tconst [activeCategory, setActiveCategory] = useState<ContentEntryItem | null>(null);\n\n\t// ── All categories (unfiltered, for client-side search) ──\n\tconst allCategoriesRef = useRef<ContentEntryItem[]>(cachedCategories ?? []);\n\n\t// ── Fetch categories ──\n\tconst fetchCategories = useCallback(async () => {\n\t\tif (!tab) return;\n\t\tsetIsCategoriesLoading(true);\n\t\ttry {\n\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\ttabId,\n\t\t\t\tpage: 1,\n\t\t\t\tlimit: 50,\n\t\t\t\tlanguage: getLocale(),\n\t\t\t});\n\t\t\tif (result.items) {\n\t\t\t\tallCategoriesRef.current = result.items;\n\t\t\t\tsetCategories(result.items);\n\t\t\t\tstore.getState().setContentCache(categoriesKey(tabId, getLocale()), result.items);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(\"[useGroupedContentTab] categories error:\", err);\n\t\t} finally {\n\t\t\tsetIsCategoriesLoading(false);\n\t\t}\n\t}, [client, tabId, tab, store]);\n\n\t// Init — only fetch if cache was empty\n\tconst initFetch = useCallback(() => {\n\t\tif (tab && categories.length === 0) {\n\t\t\tfetchCategories();\n\t\t}\n\t}, [fetchCategories, tab, categories.length]);\n\n\t// ── Fetch items for a category ──\n\tconst fetchItems = useCallback(\n\t\tasync (opts?: { page?: number; search?: string; reset?: boolean; groupSlug?: string }) => {\n\t\t\tif (!tab?.itemsModelSlug) return;\n\t\t\tconst p = opts?.page ?? 1;\n\t\t\tconst reset = opts?.reset ?? p === 1;\n\n\t\t\tsetIsItemsLoading(true);\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\t\ttabId,\n\t\t\t\t\tpage: p,\n\t\t\t\t\tlimit: 10,\n\t\t\t\t\tsearch: opts?.search,\n\t\t\t\t\tgroupSlug: opts?.groupSlug,\n\t\t\t\t\titemsModel: tab.itemsModelSlug,\n\t\t\t\t\tlanguage: getLocale(),\n\t\t\t\t});\n\t\t\t\tif (result.items) {\n\t\t\t\t\tsetItems((prev) => {\n\t\t\t\t\t\tconst nextItems = reset ? result.items! : [...prev, ...result.items!];\n\t\t\t\t\t\tif (!opts?.search && opts?.groupSlug) {\n\t\t\t\t\t\t\tstore.getState().setContentCache(\n\t\t\t\t\t\t\t\titemsKey(tabId, getLocale(), opts.groupSlug),\n\t\t\t\t\t\t\t\t{ items: nextItems, hasMore: result.hasMore, page: p } satisfies CachedItems,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nextItems;\n\t\t\t\t\t});\n\t\t\t\t\tsetItemsHasMore(result.hasMore);\n\t\t\t\t\titemsPageRef.current = p;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useGroupedContentTab] items error:\", err);\n\t\t\t} finally {\n\t\t\t\tsetIsItemsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client, tabId, tab, store],\n\t);\n\n\t// ── Select a category → load items from cache or fetch ──\n\tconst selectCategory = useCallback(\n\t\t(category: ContentEntryItem) => {\n\t\t\tsetActiveCategory(category);\n\t\t\tsetDetail(null);\n\n\t\t\tconst cached = readCache<CachedItems>(\n\t\t\t\tstore.getState().contentCache,\n\t\t\t\titemsKey(tabId, getLocale(), category.slug),\n\t\t\t);\n\t\t\tif (cached) {\n\t\t\t\tsetItems(cached.items);\n\t\t\t\tsetItemsHasMore(cached.hasMore);\n\t\t\t\titemsPageRef.current = cached.page;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetItems([]);\n\t\t\tfetchItems({ page: 1, reset: true, groupSlug: category.slug });\n\t\t},\n\t\t[fetchItems, store, tabId],\n\t);\n\n\t// ── Load more items ──\n\tconst loadMoreItems = useCallback(() => {\n\t\tif (!itemsHasMore || isItemsLoading || !activeCategory) return;\n\t\tfetchItems({\n\t\t\tpage: itemsPageRef.current + 1,\n\t\t\tgroupSlug: activeCategory.slug,\n\t\t});\n\t}, [fetchItems, itemsHasMore, isItemsLoading, activeCategory]);\n\n\t// ── Search items (cross-category) ──\n\tconst searchItems = useCallback(\n\t\t(query: string) => {\n\t\t\tsetItems([]);\n\t\t\tfetchItems({\n\t\t\t\tpage: 1,\n\t\t\t\treset: true,\n\t\t\t\tsearch: query || undefined,\n\t\t\t\tgroupSlug: query ? undefined : activeCategory?.slug,\n\t\t\t});\n\t\t},\n\t\t[fetchItems, activeCategory],\n\t);\n\n\t// ── Fetch item detail ──\n\tconst fetchDetail = useCallback(\n\t\tasync (slug: string) => {\n\t\t\tif (!tab?.itemsModelSlug) return;\n\n\t\t\tconst cached = readCache<ContentEntryDetail>(\n\t\t\t\tstore.getState().contentCache,\n\t\t\t\tdetailKey(tabId, getLocale(), slug),\n\t\t\t);\n\t\t\tif (cached) {\n\t\t\t\tsetDetail(cached);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetIsLoadingDetail(true);\n\t\t\ttry {\n\t\t\t\tconst result = await client.widget.getContent.query({\n\t\t\t\t\ttabId,\n\t\t\t\t\tslug,\n\t\t\t\t\titemsModel: tab.itemsModelSlug,\n\t\t\t\t\tlanguage: getLocale(),\n\t\t\t\t});\n\t\t\t\tif (result.entry) {\n\t\t\t\t\tconst entry = result.entry as ContentEntryDetail;\n\t\t\t\t\tsetDetail(entry);\n\t\t\t\t\tstore.getState().setContentCache(\n\t\t\t\t\t\tdetailKey(tabId, getLocale(), slug),\n\t\t\t\t\t\tentry,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"[useGroupedContentTab] detail error:\", err);\n\t\t\t} finally {\n\t\t\t\tsetIsLoadingDetail(false);\n\t\t\t}\n\t\t},\n\t\t[client, tabId, tab, store],\n\t);\n\n\t// ── Search categories (client-side, instant) ──\n\tconst searchCategories = useCallback(\n\t\t(query: string) => {\n\t\t\tif (!query.trim()) {\n\t\t\t\tsetCategories(allCategoriesRef.current);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst q = query.toLowerCase();\n\t\t\tsetCategories(\n\t\t\t\tallCategoriesRef.current.filter((cat) =>\n\t\t\t\t\tcat.title.toLowerCase().includes(q) ||\n\t\t\t\t\t(cat.customFields.description ?? \"\").toLowerCase().includes(q),\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\t[],\n\t);\n\n\tconst clearDetail = useCallback(() => {\n\t\tsetDetail(null);\n\t}, []);\n\n\tconst clearCategory = useCallback(() => {\n\t\tsetActiveCategory(null);\n\t\tsetItems([]);\n\t\tsetDetail(null);\n\t}, []);\n\n\treturn {\n\t\ttab,\n\t\tcategories,\n\t\tisCategoriesLoading,\n\t\titems,\n\t\tisItemsLoading,\n\t\titemsHasMore,\n\t\tactiveCategory,\n\t\tdetail,\n\t\tisLoadingDetail,\n\t\tinitFetch,\n\t\tselectCategory,\n\t\tsearchCategories,\n\t\tloadMoreItems,\n\t\tsearchItems,\n\t\tfetchDetail,\n\t\tclearDetail,\n\t\tclearCategory,\n\t};\n}\n","import {\n\tBookIcon,\n\tHelpCircleIcon,\n\tLightbulbIcon,\n\tMegaphoneIcon,\n\tNewspaperIcon,\n\tStarIcon,\n} from \"../icons\";\n\n/**\n * Maps icon string keys to Central Icons components.\n * Dashboard lets users pick from this set when configuring a content tab.\n * Falls back to BookIcon for unknown keys.\n */\nconst ICON_MAP: Record<string, React.FC> = {\n\tbook: BookIcon,\n\tmegaphone: MegaphoneIcon,\n\tlightbulb: LightbulbIcon,\n\t\"help-circle\": HelpCircleIcon,\n\tnewspaper: NewspaperIcon,\n\tstar: StarIcon,\n};\n\nexport function ContentTabIconComponent({ icon }: { icon: string }) {\n\tconst Icon = ICON_MAP[icon] ?? BookIcon;\n\treturn <Icon />;\n}\n","import type { TimelineItem, TimelineItemMetadata, TimelineItemPart } from \"@helpway/types\";\nimport { getInitials, getLocale, t } from \"@helpway/widget-core\";\nimport React, { useEffect, useRef } from \"react\";\nimport { useWidgetClient, useWidgetStore } from \"../provider\";\nimport { MessageBubble } from \"./message-bubble\";\n\nfunction parseParts(raw: TimelineItemPart[] | string | null): TimelineItemPart[] | null {\n\tif (!raw) return null;\n\tif (Array.isArray(raw)) return raw;\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\treturn Array.isArray(parsed) ? parsed : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Tolerate both shapes: when the API hydrates metadata it's already an\n * object; when it round-trips through CF tRPC over the wire it can land\n * as a JSON string. parseMetadata covers both.\n */\nfunction parseMetadata(\n\traw: TimelineItemMetadata | string | null | undefined,\n): TimelineItemMetadata | null {\n\tif (!raw) return null;\n\tif (typeof raw === \"object\") return raw;\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\treturn parsed && typeof parsed === \"object\" ? (parsed as TimelineItemMetadata) : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\ninterface MessageListProps {\n\titems: TimelineItem[];\n\tvisitorName?: string;\n\tisTyping?: boolean;\n\tisAiProcessing?: boolean;\n\thasMore?: boolean;\n\tisLoadingMore?: boolean;\n\tonLoadMore?: () => void;\n\t/** Slot rendered after all messages but before typing indicators (e.g. email prompt) */\n\trenderAfterMessages?: React.ReactNode;\n}\n\n/** Timeline with date separators, typing indicator, infinite scroll, and AI processing state */\nexport function MessageList({\n\titems,\n\tvisitorName,\n\tisTyping,\n\tisAiProcessing,\n\thasMore,\n\tisLoadingMore,\n\tonLoadMore,\n\trenderAfterMessages,\n}: MessageListProps) {\n\tconst bottomRef = useRef<HTMLDivElement>(null);\n\tconst topRef = useRef<HTMLDivElement>(null);\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\tconst prevItemCountRef = useRef(items.length);\n\tconst isInitialLoadRef = useRef(true);\n\t// Single source of truth — agent name comes from dashboard config.\n\tconst agentName = useWidgetStore((s) => s.agentConfig?.name) ?? t(\"widget.helpway_ai\");\n\tconst client = useWidgetClient();\n\tconst activeConversationId = useWidgetStore((s) => s.activeConversationId);\n\n\tconst handleQuickReplyTap = React.useCallback(\n\t\t(optionId: string, stepId: string) => {\n\t\t\tif (!activeConversationId) return;\n\t\t\t// Fire-and-forget — orchestrator runs the resume in the background\n\t\t\t// and emits new messages over WebSocket. Failure is swallowed so\n\t\t\t// the visitor never sees a tRPC error toast for this UX action.\n\t\t\tclient.widget.workflowReply\n\t\t\t\t.mutate({ conversationId: activeConversationId, stepId, optionId })\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tconsole.warn(\"[helpway] workflowReply failed:\", err);\n\t\t\t\t});\n\t\t},\n\t\t[client, activeConversationId],\n\t);\n\n\t// Auto-scroll to bottom on new messages (but NOT when loading older ones at top)\n\tuseEffect(() => {\n\t\tconst prevCount = prevItemCountRef.current;\n\t\tconst newCount = items.length;\n\t\tprevItemCountRef.current = newCount;\n\n\t\t// Initial load or new messages added at the end → scroll to bottom\n\t\tif (isInitialLoadRef.current || newCount > prevCount) {\n\t\t\t// Only scroll if the new items were appended (not prepended)\n\t\t\tconst lastItem = items[items.length - 1];\n\t\t\tconst prevLastItem = prevCount > 0 ? items[prevCount - 1] : null;\n\n\t\t\tif (isInitialLoadRef.current || !prevLastItem || lastItem?.id !== prevLastItem?.id) {\n\t\t\t\tbottomRef.current?.scrollIntoView({\n\t\t\t\t\tbehavior: isInitialLoadRef.current ? \"instant\" : \"smooth\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tisInitialLoadRef.current = false;\n\t\t}\n\t}, [items]);\n\n\t// Scroll to bottom when typing/AI indicators appear\n\tuseEffect(() => {\n\t\tif (isTyping || isAiProcessing) {\n\t\t\tbottomRef.current?.scrollIntoView({ behavior: \"smooth\" });\n\t\t}\n\t}, [isTyping, isAiProcessing]);\n\n\t// Infinite scroll — IntersectionObserver on the top sentinel\n\tuseEffect(() => {\n\t\tif (!hasMore || !onLoadMore || !topRef.current) return;\n\n\t\tconst observer = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tif (entries[0]?.isIntersecting && !isLoadingMore) {\n\t\t\t\t\t// Save scroll position before loading\n\t\t\t\t\tconst container = containerRef.current;\n\t\t\t\t\tconst prevScrollHeight = container?.scrollHeight ?? 0;\n\t\t\t\t\tconst prevScrollTop = container?.scrollTop ?? 0;\n\n\t\t\t\t\tonLoadMore();\n\n\t\t\t\t\t// Restore scroll position after DOM update (next frame)\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tif (container) {\n\t\t\t\t\t\t\tconst newScrollHeight = container.scrollHeight;\n\t\t\t\t\t\t\tcontainer.scrollTop = prevScrollTop + (newScrollHeight - prevScrollHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ root: containerRef.current, threshold: 0.1 },\n\t\t);\n\n\t\tobserver.observe(topRef.current);\n\t\treturn () => observer.disconnect();\n\t}, [hasMore, onLoadMore, isLoadingMore]);\n\n\tif (items.length === 0) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName=\"hw-messages\"\n\t\t\t\trole=\"log\"\n\t\t\t\taria-label={t(\"widget.aria_messages\")}\n\t\t\t\taria-live=\"polite\"\n\t\t\t>\n\t\t\t\t<div className=\"hw-empty\">\n\t\t\t\t\t<div className=\"hw-empty-icon\">\n\t\t\t\t\t\t<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n\t\t\t\t\t\t\t<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"hw-empty-text\">{t(\"widget.start_a_conversation\")}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tlet lastDateKey = \"\";\n\t// Stable \"today\" key (YYYY-MM-DD in local time) for separator gating.\n\t// We HIDE the separator for today entirely — matches Intercom/WhatsApp:\n\t// the date is implicit when \"now\", and showing it on every fresh\n\t// conversation creates a jarring vertical jump as the view fills in.\n\tconst todayKey = new Date().toLocaleDateString(\"en-CA\"); // en-CA is YYYY-MM-DD\n\tconst yesterday = new Date();\n\tyesterday.setDate(yesterday.getDate() - 1);\n\tconst yesterdayKey = yesterday.toLocaleDateString(\"en-CA\");\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tclassName=\"hw-messages\"\n\t\t\trole=\"log\"\n\t\t\taria-label={t(\"widget.aria_messages\")}\n\t\t\taria-live=\"polite\"\n\t\t>\n\t\t\t{/* Top sentinel for infinite scroll */}\n\t\t\t<div ref={topRef} className=\"hw-load-more-trigger\">\n\t\t\t\t{isLoadingMore && (\n\t\t\t\t\t<div className=\"hw-load-more-spinner\">\n\t\t\t\t\t\t<div />\n\t\t\t\t\t\t<div />\n\t\t\t\t\t\t<div />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{items.map((item) => {\n\t\t\t\tif (item.type === \"event\") {\n\t\t\t\t\treturn <EventCard key={(item as unknown as { _stableKey?: string })._stableKey ?? item.id} text={item.text ?? \"\"} />;\n\t\t\t\t}\n\n\t\t\t\t// Date separator — bucket by local YYYY-MM-DD; skip rendering\n\t\t\t\t// when the bucket is \"today\" so today's chats stay flush at the top.\n\t\t\t\tconst itemDate = new Date(item.createdAt);\n\t\t\t\tconst dateKey = itemDate.toLocaleDateString(\"en-CA\");\n\t\t\t\tconst isNewBucket = dateKey !== lastDateKey;\n\t\t\t\tif (isNewBucket) lastDateKey = dateKey;\n\t\t\t\tconst showDateSep = isNewBucket && dateKey !== todayKey;\n\t\t\t\tconst dateLabel =\n\t\t\t\t\tdateKey === yesterdayKey\n\t\t\t\t\t\t? t(\"widget.yesterday\")\n\t\t\t\t\t\t: itemDate.toLocaleDateString(getLocale(), {\n\t\t\t\t\t\t\t\tweekday: \"long\",\n\t\t\t\t\t\t\t\tmonth: \"short\",\n\t\t\t\t\t\t\t\tday: \"numeric\",\n\t\t\t\t\t\t\t});\n\n\t\t\t\t// Determine sender\n\t\t\t\tconst sender = item.visitorId ? \"visitor\" : item.aiAgentId ? \"ai\" : \"team\";\n\n\t\t\t\t// Show timestamp on the last message in a consecutive group from the same sender\n\t\t\t\tconst idx = items.indexOf(item);\n\t\t\t\tconst nextItem = items[idx + 1];\n\t\t\t\tconst nextSender = nextItem?.type === \"message\"\n\t\t\t\t\t? (nextItem.visitorId ? \"visitor\" : nextItem.aiAgentId ? \"ai\" : \"team\")\n\t\t\t\t\t: null;\n\t\t\t\tconst isLastInGroup = nextSender !== sender || nextItem?.type === \"event\";\n\t\t\t\tconst timeLabel = isLastInGroup\n\t\t\t\t\t? itemDate.toLocaleTimeString(getLocale(), { hour: \"2-digit\", minute: \"2-digit\" })\n\t\t\t\t\t: undefined;\n\n\t\t\t\treturn (\n\t\t\t\t\t<React.Fragment key={(item as unknown as { _stableKey?: string })._stableKey ?? item.id}>\n\t\t\t\t\t\t{showDateSep && (\n\t\t\t\t\t\t\t<div className=\"hw-date-sep\">\n\t\t\t\t\t\t\t\t<div className=\"hw-date-sep-line\" />\n\t\t\t\t\t\t\t\t<div className=\"hw-date-sep-text\">{dateLabel}</div>\n\t\t\t\t\t\t\t\t<div className=\"hw-date-sep-line\" />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<MessageBubble\n\t\t\t\t\t\t\ttext={item.text ?? \"\"}\n\t\t\t\t\t\t\tsender={sender}\n\t\t\t\t\t\t\tsenderName={sender === \"visitor\" ? visitorName : (item.userName ?? undefined)}\n\t\t\t\t\t\t\tparts={parseParts(item.parts)}\n\t\t\t\t\t\t\tmetadata={parseMetadata(\n\t\t\t\t\t\t\t\t(item as TimelineItem & { metadata?: TimelineItemMetadata | string | null })\n\t\t\t\t\t\t\t\t\t.metadata,\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tonQuickReplyTap={handleQuickReplyTap}\n\t\t\t\t\t\t\ttimestamp={timeLabel}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</React.Fragment>\n\t\t\t\t);\n\t\t\t})}\n\n\t\t\t{/* Slot for inline content after messages (e.g. email prompt) */}\n\t\t\t{renderAfterMessages}\n\n\t\t\t{/* AI processing indicator */}\n\t\t\t{isAiProcessing && (\n\t\t\t\t<div className=\"hw-typing\">\n\t\t\t\t\t<div className=\"hw-typing-label\">{agentName}</div>\n\t\t\t\t\t<div className=\"hw-typing-dots\">\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* Typing indicator (team, not AI) */}\n\t\t\t{isTyping && !isAiProcessing && (\n\t\t\t\t<div className=\"hw-typing\">\n\t\t\t\t\t<div className=\"hw-typing-dots\">\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t\t<div className=\"hw-typing-dot\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<div ref={bottomRef} />\n\t\t</div>\n\t);\n}\n\n// ── Event Card ────────────────────────────────────────\n\ninterface EventData {\n\taction: string;\n\tname: string;\n\timage?: string | null;\n}\n\nfunction parseEventData(text: string): EventData | null {\n\tif (!text.startsWith(\"{\")) return null;\n\ttry {\n\t\tconst data = JSON.parse(text);\n\t\tif (data.action && data.name) return data as EventData;\n\t} catch {\n\t\t/* plain text fallback */\n\t}\n\treturn null;\n}\n\nfunction EventCard({ text }: { text: string }) {\n\tconst data = parseEventData(text);\n\n\t// Structured event — rich card with avatar\n\tif (data) {\n\t\tconst message = data.action === \"joined\" ? t(\"widget.joined\") : t(\"widget.left\");\n\n\t\treturn (\n\t\t\t<div className=\"hw-event hw-event--card\">\n\t\t\t\t<div className=\"hw-event-avatar\">\n\t\t\t\t\t{data.image ? (\n\t\t\t\t\t\t<img src={data.image} alt=\"\" className=\"hw-event-avatar-img\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span>{getInitials(data.name)}</span>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hw-event-body\">\n\t\t\t\t\t<span className=\"hw-event-name\">{data.name}</span>{\" \"}\n\t\t\t\t\t<span className=\"hw-event-action\">{message}</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Plain text event (resolve, reopen, etc.)\n\treturn (\n\t\t<div className=\"hw-event\">\n\t\t\t<div className=\"hw-event-text\">{text}</div>\n\t\t</div>\n\t);\n}\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\":host {\\n all: initial;\\n font-family:\\n -apple-system,\\n BlinkMacSystemFont,\\n \\\"Segoe UI\\\",\\n Roboto,\\n \\\"Helvetica Neue\\\",\\n Arial,\\n sans-serif;\\n font-size: 14px;\\n line-height: 1.5;\\n color: #1a1a1a;\\n -webkit-font-smoothing: antialiased;\\n -moz-osx-font-smoothing: grayscale;\\n}\\n.hw-widget {\\n font-family:\\n -apple-system,\\n BlinkMacSystemFont,\\n \\\"Segoe UI\\\",\\n Roboto,\\n \\\"Helvetica Neue\\\",\\n Arial,\\n sans-serif;\\n font-size: 14px;\\n line-height: 1.5;\\n color: #1a1a1a;\\n -webkit-font-smoothing: antialiased;\\n -moz-osx-font-smoothing: grayscale;\\n}\\n.hw-widget *,\\n.hw-widget *::before,\\n.hw-widget *::after {\\n box-sizing: border-box;\\n margin: 0;\\n padding: 0;\\n}\\n:where(.hw-widget) {\\n --hw-primary: #171717;\\n --hw-primary-hover: #2a2a2a;\\n --hw-brand: #171717;\\n --hw-on-brand: #ffffff;\\n --hw-focus-border: #9ca3af;\\n --hw-focus-ring: rgba(0, 0, 0, 0.06);\\n --hw-accent: #6366f1;\\n --hw-bg: #ffffff;\\n --hw-bg-subtle: #fafafa;\\n --hw-bg-hover: #f5f5f5;\\n --hw-border: #f0f0f0;\\n --hw-border-md: #e5e5e5;\\n --hw-text: #111;\\n --hw-text-1: #111;\\n --hw-text-2: #666;\\n --hw-text-3: #999;\\n --hw-text-4: #bbb;\\n --hw-radius: 16px;\\n --hw-visitor-bubble-bg: #f0f0f0;\\n --hw-visitor-bubble-text: #1a1a1a;\\n --hw-font:\\n -apple-system,\\n BlinkMacSystemFont,\\n \\\"Segoe UI\\\",\\n Roboto,\\n \\\"Helvetica Neue\\\",\\n Arial,\\n sans-serif;\\n}\\n.hw-agent-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-agent-icon {\\n width: 100%;\\n height: 100%;\\n border-radius: inherit;\\n}\\n.hw-widget :focus-visible {\\n outline: 2px solid var(--hw-primary);\\n outline-offset: 2px;\\n}\\n.hw-widget :focus:not(:focus-visible) {\\n outline: none;\\n}\\n.hw-widget {\\n position: fixed;\\n bottom: 20px;\\n right: var(--hw-position-right, 20px);\\n left: var(--hw-position-left, auto);\\n z-index: 999999;\\n font-family: var(--hw-font);\\n}\\n.hw-bubble {\\n width: 48px;\\n height: 48px;\\n border-radius: 14px;\\n background: var(--hw-primary);\\n color: white;\\n border: none;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\\n transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s ease;\\n position: relative;\\n overflow: visible;\\n}\\n.hw-bubble--rounded {\\n border-radius: 14px;\\n}\\n.hw-bubble--square {\\n border-radius: 8px;\\n}\\n.hw-bubble--pill {\\n border-radius: 24px;\\n}\\n.hw-bubble--launcher-bubble,\\n.hw-bubble--launcher-help {\\n width: auto;\\n padding: 0 16px 0 12px;\\n gap: 8px;\\n border-radius: 24px;\\n}\\n.hw-bubble--launcher-bubble.hw-bubble--square,\\n.hw-bubble--launcher-help.hw-bubble--square {\\n border-radius: 8px;\\n}\\n.hw-bubble--launcher-bubble.hw-bubble--rounded,\\n.hw-bubble--launcher-help.hw-bubble--rounded {\\n border-radius: 14px;\\n}\\n.hw-bubble-label {\\n font-size: 14px;\\n font-weight: 600;\\n white-space: nowrap;\\n line-height: 1;\\n position: static;\\n opacity: 1;\\n transform: none;\\n}\\n.hw-bubble--launcher-bubble .hw-bubble-icon,\\n.hw-bubble--launcher-help .hw-bubble-icon {\\n position: static;\\n}\\n.hw-bubble:hover {\\n transform: scale(1.05);\\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);\\n}\\n.hw-bubble:active {\\n transform: scale(0.95);\\n}\\n.hw-bubble--open {\\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\\n}\\n.hw-bubble:focus-visible {\\n outline: 2px solid white;\\n outline-offset: 2px;\\n}\\n.hw-bubble-icon {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n position: absolute;\\n transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease;\\n}\\n.hw-bubble-icon svg {\\n width: 22px;\\n height: 22px;\\n}\\n.hw-bubble-icon--hidden {\\n transform: scale(0.3) rotate(90deg);\\n opacity: 0;\\n}\\n.hw-bubble-icon--bot {\\n}\\n.hw-bubble--avatar .hw-bubble-icon--bot {\\n width: 100%;\\n height: 100%;\\n}\\n.hw-bubble--avatar .hw-bubble-icon--bot .hw-agent-img {\\n width: 100%;\\n height: 100%;\\n border-radius: 0;\\n}\\n.hw-agent-img.hw-agent-img--logo {\\n object-fit: contain;\\n padding: 10px;\\n box-sizing: border-box;\\n}\\n.hw-bubble--avatar .hw-bubble-icon--bot .hw-agent-img.hw-agent-img--logo {\\n padding: 10px;\\n box-sizing: border-box;\\n object-fit: contain;\\n}\\n.hw-bubble-icon--close svg {\\n width: 22px;\\n height: 22px;\\n}\\n.hw-bubble-badge {\\n position: absolute;\\n top: -4px;\\n right: -4px;\\n min-width: 20px;\\n height: 20px;\\n border-radius: 10px;\\n background: var(--hw-primary);\\n color: white;\\n font-size: 11px;\\n font-weight: 700;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 0 5px;\\n border: 2px solid white;\\n animation: hw-badge-pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\\n}\\n@keyframes hw-badge-pop {\\n from {\\n transform: scale(0);\\n }\\n to {\\n transform: scale(1);\\n }\\n}\\n.hw-bubble-badge::after {\\n content: \\\"\\\";\\n position: absolute;\\n inset: -2px;\\n border-radius: inherit;\\n background: var(--hw-primary);\\n opacity: 0;\\n animation: hw-badge-pulse 2s ease-out infinite;\\n}\\n@keyframes hw-badge-pulse {\\n 0% {\\n opacity: 0.5;\\n transform: scale(1);\\n }\\n 100% {\\n opacity: 0;\\n transform: scale(1.8);\\n }\\n}\\n.hw-window {\\n position: absolute;\\n bottom: 72px;\\n right: var(--hw-window-right, 0);\\n left: var(--hw-window-left, auto);\\n width: 440px;\\n height: 640px;\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text);\\n border-radius: var(--hw-radius);\\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.04);\\n display: flex;\\n flex-direction: column;\\n overflow: hidden;\\n animation: hw-window-open 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);\\n transition: width 280ms cubic-bezier(0.4, 0, 0.2, 1), height 280ms cubic-bezier(0.4, 0, 0.2, 1);\\n}\\n.hw-window--reading {\\n width: min(720px, calc(100vw - 40px));\\n height: min(800px, calc(100vh - 100px));\\n}\\n@keyframes hw-window-open {\\n from {\\n opacity: 0;\\n transform: translateY(12px) scale(0.96);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n}\\n.hw-window--closing {\\n animation: hw-window-close 0.2s ease forwards;\\n}\\n@keyframes hw-window-close {\\n from {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n to {\\n opacity: 0;\\n transform: translateY(8px) scale(0.98);\\n }\\n}\\n.hw-content {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n overflow: hidden;\\n min-height: 0;\\n}\\n@media (prefers-reduced-motion: reduce) {\\n .hw-window,\\n .hw-window--closing,\\n .hw-content,\\n .hw-msg,\\n .hw-bubble-icon,\\n .hw-bubble-badge,\\n .hw-bubble-badge::after,\\n .hw-typing-dot,\\n .hw-loading-dot {\\n animation-duration: 0.01ms !important;\\n transition-duration: 0.01ms !important;\\n }\\n}\\n.hw-hero {\\n flex-shrink: 0;\\n background:\\n linear-gradient(\\n 160deg,\\n color-mix(in srgb, var(--hw-primary) 60%, black) 0%,\\n var(--hw-primary) 50%,\\n color-mix(in srgb, var(--hw-primary) 40%, black) 100%);\\n color: white;\\n padding: 20px 22px 40px;\\n}\\n.hw-hero-top {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n margin-bottom: 16px;\\n}\\n.hw-hero-close {\\n width: 30px;\\n height: 30px;\\n border-radius: 50%;\\n border: none;\\n background: rgba(255, 255, 255, 0.1);\\n color: rgba(255, 255, 255, 0.6);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n transition: background 0.15s, color 0.15s;\\n}\\n.hw-hero-close:hover {\\n background: rgba(255, 255, 255, 0.2);\\n color: white;\\n}\\n.hw-hero-close:active {\\n transform: scale(0.92);\\n transition:\\n transform 0.14s cubic-bezier(0.23, 1, 0.32, 1),\\n background 0.15s,\\n color 0.15s;\\n}\\n.hw-hero-close svg {\\n width: 20px;\\n height: 20px;\\n}\\n.hw-hero-bot-icon {\\n width: 36px;\\n height: 36px;\\n flex-shrink: 0;\\n color: white;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 10px;\\n overflow: hidden;\\n}\\n.hw-hero-bot-icon svg {\\n width: 32px;\\n height: 32px;\\n}\\n.hw-hero-greeting {\\n font-size: 26px;\\n font-weight: 700;\\n line-height: 1.15;\\n margin-bottom: 6px;\\n}\\n.hw-hero-greeting-name {\\n font-weight: 300;\\n}\\n.hw-hero-greeting-question {\\n font-weight: 700;\\n}\\n.hw-hero-subtitle {\\n font-size: 15px;\\n color: rgba(255, 255, 255, 0.5);\\n line-height: 1.35;\\n}\\n.hw-sheet {\\n flex: 1;\\n overflow-y: auto;\\n min-height: 0;\\n background: #ffffff;\\n border-radius: 20px 20px 0 0;\\n margin-top: -24px;\\n box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);\\n position: relative;\\n z-index: 1;\\n}\\n.hw-sheet-inner {\\n padding: 20px 16px;\\n display: flex;\\n flex-direction: column;\\n gap: 12px;\\n}\\n.hw-header {\\n display: flex;\\n align-items: center;\\n padding: 12px 16px;\\n background: var(--hw-primary);\\n color: white;\\n flex-shrink: 0;\\n gap: 10px;\\n}\\n.hw-header--sub {\\n justify-content: space-between;\\n background: transparent;\\n color: var(--hw-text);\\n border-bottom: 1px solid var(--hw-border);\\n}\\n.hw-header-back {\\n width: 28px;\\n height: 28px;\\n border-radius: 8px;\\n border: none;\\n background: transparent;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n transition: color 0.15s, background 0.15s;\\n flex-shrink: 0;\\n}\\n.hw-header-back svg {\\n width: 18px;\\n height: 18px;\\n}\\n.hw-header-back:hover {\\n color: var(--hw-text);\\n background: var(--hw-bg-subtle);\\n}\\n.hw-header-identity {\\n display: flex;\\n align-items: center;\\n gap: 10px;\\n flex: 1;\\n min-width: 0;\\n}\\n.hw-header-bot-icon {\\n width: 28px;\\n height: 28px;\\n flex-shrink: 0;\\n color: var(--hw-text);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 8px;\\n overflow: hidden;\\n background: var(--hw-agent-bg, transparent);\\n}\\n.hw-header-bot-icon svg {\\n width: 24px;\\n height: 24px;\\n}\\n.hw-header-bot-icon--team {\\n background: var(--hw-brand, #0a0a0a);\\n color: var(--hw-on-brand, #fff);\\n}\\n.hw-header-agent-img {\\n width: 100%;\\n height: 100%;\\n object-fit: var(--hw-agent-fit, cover);\\n padding: var(--hw-agent-pad, 0);\\n box-sizing: border-box;\\n}\\n.hw-header-agent-initials {\\n font-size: 11px;\\n font-weight: 600;\\n line-height: 1;\\n}\\n.hw-header-info {\\n flex: 1;\\n min-width: 0;\\n}\\n.hw-header-name {\\n font-size: 14px;\\n font-weight: 600;\\n line-height: 1.3;\\n}\\n.hw-header-status {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n line-height: 1.3;\\n}\\n.hw-header-close {\\n width: 28px;\\n height: 28px;\\n border-radius: 8px;\\n border: none;\\n background: transparent;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n transition:\\n background-color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n transform 140ms cubic-bezier(0.23, 1, 0.32, 1);\\n flex-shrink: 0;\\n}\\n.hw-header-close svg {\\n width: 20px;\\n height: 20px;\\n}\\n.hw-header-close:hover {\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text);\\n}\\n.hw-header-close:active {\\n transform: scale(0.92);\\n}\\n.hw-header--centered {\\n justify-content: space-between;\\n background: transparent;\\n color: var(--hw-text);\\n border-bottom: 1px solid var(--hw-border);\\n}\\n.hw-header--centered .hw-header-title {\\n position: absolute;\\n left: 50%;\\n transform: translateX(-50%);\\n max-width: calc(100% - 88px);\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n text-align: center;\\n}\\n.hw-header-spacer {\\n width: 28px;\\n flex-shrink: 0;\\n}\\n.hw-header--messages {\\n justify-content: space-between;\\n background: transparent;\\n color: var(--hw-text);\\n border-bottom: 1px solid var(--hw-border);\\n}\\n.hw-header-title {\\n font-size: 16px;\\n font-weight: 600;\\n}\\n.hw-header-actions {\\n display: flex;\\n align-items: center;\\n gap: 6px;\\n}\\n.hw-header-action {\\n width: 28px;\\n height: 28px;\\n border-radius: 8px;\\n border: none;\\n background: transparent;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n transition:\\n background-color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n transform 140ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n.hw-header-action svg {\\n width: 16px;\\n height: 16px;\\n}\\n.hw-header-action:hover {\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text);\\n}\\n.hw-header-action:active {\\n transform: scale(0.94);\\n}\\n.hw-card {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n width: 100%;\\n padding: 14px 16px;\\n border-radius: 14px;\\n background: var(--hw-bg);\\n border: 1px solid rgba(0, 0, 0, 0.06);\\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.03);\\n cursor: pointer;\\n transition: box-shadow 180ms cubic-bezier(0.23, 1, 0.32, 1), transform 180ms cubic-bezier(0.23, 1, 0.32, 1);\\n text-align: left;\\n color: var(--hw-text);\\n font-family: inherit;\\n}\\n.hw-card:hover {\\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.05);\\n transform: translateY(-1px);\\n}\\n.hw-card:active {\\n transform: translateY(0) scale(0.99);\\n transition-duration: 120ms;\\n}\\n.hw-card-body {\\n flex: 1;\\n min-width: 0;\\n}\\n.hw-card-title {\\n font-size: 14px;\\n font-weight: 600;\\n line-height: 1.3;\\n color: var(--hw-text);\\n}\\n.hw-card-meta {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n line-height: 1.3;\\n margin-top: 1px;\\n}\\n.hw-card-arrow {\\n width: 32px;\\n height: 32px;\\n border-radius: 50%;\\n background: var(--hw-primary);\\n color: white;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n}\\n.hw-card-arrow svg {\\n width: 14px;\\n height: 14px;\\n}\\n.hw-msgs-tab {\\n flex: 1;\\n overflow-y: auto;\\n padding: 12px 16px;\\n display: flex;\\n flex-direction: column;\\n gap: 8px;\\n}\\n.hw-recent-card {\\n border-radius: 14px;\\n background: var(--hw-bg);\\n border: 1px solid rgba(0, 0, 0, 0.06);\\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.03);\\n overflow: hidden;\\n}\\n.hw-recent-header {\\n font-size: 12px;\\n font-weight: 600;\\n color: var(--hw-text-2);\\n padding: 12px 14px 0;\\n}\\n.hw-recent-row {\\n display: flex;\\n align-items: center;\\n gap: 10px;\\n width: 100%;\\n padding: 10px 14px;\\n border: none;\\n border-bottom: 1px solid var(--hw-border);\\n background: none;\\n cursor: pointer;\\n text-align: left;\\n font-family: inherit;\\n color: var(--hw-text);\\n transition: background-color 140ms cubic-bezier(0.23, 1, 0.32, 1), transform 140ms cubic-bezier(0.23, 1, 0.32, 1);\\n position: relative;\\n}\\n.hw-recent-row:hover {\\n background: rgba(0, 0, 0, 0.03);\\n}\\n.hw-recent-row:active {\\n transform: scale(0.995);\\n}\\n.hw-recent-row--last {\\n border-bottom: none;\\n}\\n.hw-recent-row .hw-conv-card-avatar {\\n width: 32px;\\n height: 32px;\\n border-radius: 8px;\\n}\\n.hw-recent-row .hw-conv-card-avatar svg {\\n width: 18px;\\n height: 18px;\\n}\\n.hw-recent-row .hw-conv-card-name {\\n font-size: 13px;\\n}\\n.hw-recent-row .hw-conv-card-preview {\\n font-size: 12px;\\n}\\n.hw-recent-row--unread .hw-conv-card-name {\\n color: var(--hw-text);\\n}\\n.hw-recent-row--unread .hw-conv-card-time {\\n color: var(--hw-primary);\\n font-weight: 500;\\n}\\n.hw-recent-row-badge {\\n min-width: 18px;\\n height: 18px;\\n border-radius: 9px;\\n background: var(--hw-primary);\\n color: white;\\n font-size: 11px;\\n font-weight: 600;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 0 5px;\\n flex-shrink: 0;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-recent-see-all {\\n display: block;\\n width: 100%;\\n padding: 10px 14px;\\n text-align: center;\\n font-size: 13px;\\n font-weight: 500;\\n color: var(--hw-text);\\n background: none;\\n border: none;\\n border-top: 1px solid var(--hw-border);\\n cursor: pointer;\\n font-family: inherit;\\n transition: background 0.1s;\\n}\\n.hw-recent-see-all:hover {\\n background: rgba(0, 0, 0, 0.02);\\n}\\n.hw-conv-card {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n gap: 4px;\\n width: 100%;\\n padding: 14px 16px;\\n border-radius: 14px;\\n background: var(--hw-bg);\\n border: 1px solid rgba(0, 0, 0, 0.06);\\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.03);\\n cursor: pointer;\\n transition: box-shadow 0.15s, transform 0.1s;\\n text-align: left;\\n font-family: inherit;\\n color: var(--hw-text);\\n}\\n.hw-conv-card:hover {\\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.04);\\n}\\n.hw-conv-card:active {\\n transform: scale(0.99);\\n}\\n.hw-conv-card-row {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n}\\n.hw-conv-card-avatar {\\n width: 36px;\\n height: 36px;\\n border-radius: 10px;\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text-3);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n overflow: hidden;\\n}\\n.hw-conv-card-avatar svg {\\n width: 20px;\\n height: 20px;\\n}\\n.hw-conv-card-avatar-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-conv-card-avatar--team {\\n background: var(--hw-brand, #0a0a0a);\\n color: var(--hw-on-brand, #fff);\\n}\\n.hw-conv-card-avatar-initials {\\n font-size: 12px;\\n font-weight: 600;\\n line-height: 1;\\n letter-spacing: 0.02em;\\n}\\n.hw-conv-card-content {\\n flex: 1;\\n min-width: 0;\\n}\\n.hw-conv-card-top {\\n display: flex;\\n align-items: baseline;\\n gap: 8px;\\n}\\n.hw-conv-card-name {\\n flex: 1;\\n font-size: 14px;\\n font-weight: 600;\\n color: var(--hw-text);\\n}\\n.hw-conv-card-time {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n flex-shrink: 0;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-conv-card-preview {\\n font-size: 13px;\\n color: var(--hw-text-2);\\n overflow: hidden;\\n text-overflow: ellipsis;\\n white-space: nowrap;\\n line-height: 1.4;\\n margin-top: 1px;\\n}\\n.hw-conv-card--unread .hw-conv-card-name {\\n color: var(--hw-text);\\n}\\n.hw-conv-card--unread .hw-conv-card-time {\\n color: var(--hw-primary);\\n font-weight: 500;\\n}\\n.hw-conv-card-badge {\\n position: absolute;\\n top: 12px;\\n right: 12px;\\n min-width: 18px;\\n height: 18px;\\n border-radius: 9px;\\n background: var(--hw-primary);\\n color: white;\\n font-size: 11px;\\n font-weight: 600;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 0 5px;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-empty-state {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 32px;\\n text-align: center;\\n}\\n.hw-empty-icon-wrap {\\n width: 48px;\\n height: 48px;\\n border-radius: 50%;\\n background: var(--hw-bg-subtle);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n margin-bottom: 16px;\\n color: var(--hw-text-3);\\n}\\n.hw-empty-icon-wrap svg {\\n width: 24px;\\n height: 24px;\\n}\\n.hw-empty-title {\\n font-size: 15px;\\n font-weight: 600;\\n color: var(--hw-text);\\n margin-bottom: 4px;\\n}\\n.hw-empty-desc {\\n font-size: 13px;\\n color: var(--hw-text-3);\\n margin-bottom: 20px;\\n}\\n.hw-empty-btn {\\n padding: 8px 20px;\\n border-radius: 10px;\\n background: var(--hw-primary);\\n color: white;\\n border: none;\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n font-family: inherit;\\n transition: background 0.15s;\\n}\\n.hw-empty-btn:hover {\\n background: var(--hw-primary-hover);\\n}\\n.hw-tabs {\\n display: flex;\\n border-top: 1px solid var(--hw-border);\\n flex-shrink: 0;\\n background: var(--hw-bg-subtle);\\n}\\n.hw-tabs-item {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n gap: 2px;\\n padding: 8px 0;\\n border: none;\\n background: none;\\n cursor: pointer;\\n font-family: inherit;\\n font-size: 11px;\\n font-weight: 500;\\n color: var(--hw-text-3);\\n transition: color 0.15s;\\n}\\n.hw-tabs-item svg {\\n width: 22px;\\n height: 22px;\\n}\\n.hw-tabs-item--active {\\n color: var(--hw-text);\\n}\\n.hw-tabs-item:hover {\\n color: var(--hw-text-2);\\n}\\n.hw-tabs-item:active {\\n transform: scale(0.94);\\n transition: transform 0.14s cubic-bezier(0.23, 1, 0.32, 1), color 0.15s;\\n}\\n.hw-tabs-icon-wrap {\\n position: relative;\\n display: inline-flex;\\n}\\n.hw-tabs-badge {\\n position: absolute;\\n top: -6px;\\n right: -10px;\\n min-width: 16px;\\n height: 16px;\\n border-radius: 8px;\\n background: var(--hw-primary);\\n color: white;\\n font-size: 10px;\\n font-weight: 700;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 0 4px;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-messages {\\n flex: 1;\\n overflow-y: auto;\\n overflow-x: hidden;\\n padding: 16px 20px;\\n background: var(--hw-bg-subtle);\\n display: flex;\\n flex-direction: column;\\n gap: 2px;\\n overscroll-behavior: contain;\\n min-width: 0;\\n scrollbar-color: rgba(0, 0, 0, 0.2) transparent;\\n scrollbar-width: thin;\\n}\\n.hw-messages::-webkit-scrollbar {\\n width: 10px;\\n height: 10px;\\n}\\n.hw-messages::-webkit-scrollbar-track {\\n background: transparent;\\n}\\n.hw-messages::-webkit-scrollbar-thumb {\\n background: rgba(0, 0, 0, 0.16);\\n background-clip: content-box;\\n border: 3px solid transparent;\\n border-radius: 999px;\\n}\\n.hw-messages::-webkit-scrollbar-thumb:hover {\\n background: rgba(0, 0, 0, 0.28);\\n background-clip: content-box;\\n}\\n.hw-widget[data-theme=dark] .hw-messages {\\n scrollbar-color: rgba(255, 255, 255, 0.26) transparent;\\n}\\n.hw-widget[data-theme=dark] .hw-messages::-webkit-scrollbar-thumb {\\n background: rgba(255, 255, 255, 0.2);\\n background-clip: content-box;\\n}\\n.hw-widget[data-theme=dark] .hw-messages::-webkit-scrollbar-thumb:hover {\\n background: rgba(255, 255, 255, 0.32);\\n background-clip: content-box;\\n}\\n.hw-empty {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 32px;\\n color: var(--hw-text-3);\\n text-align: center;\\n}\\n.hw-empty-icon {\\n width: 40px;\\n height: 40px;\\n margin-bottom: 12px;\\n opacity: 0.3;\\n}\\n.hw-empty-text {\\n font-size: 13px;\\n}\\n.hw-date-sep {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n padding: 12px 0;\\n}\\n.hw-date-sep-line {\\n flex: 1;\\n height: 1px;\\n background: var(--hw-border-md);\\n}\\n.hw-date-sep-text {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n font-weight: 500;\\n white-space: nowrap;\\n}\\n.hw-msg {\\n display: flex;\\n padding: 4px 0;\\n max-width: 75%;\\n min-width: 0;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n@keyframes hw-msg-appear {\\n from {\\n opacity: 0;\\n transform: translateY(6px);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n}\\n.hw-msg--visitor {\\n align-self: flex-end;\\n}\\n.hw-msg--team,\\n.hw-msg--ai {\\n align-self: flex-start;\\n}\\n.hw-msg--ai {\\n width: 100%;\\n max-width: 100%;\\n}\\n.hw-msg-body {\\n display: flex;\\n flex-direction: column;\\n min-width: 0;\\n max-width: 100%;\\n}\\n.hw-msg-bubble {\\n padding: 10px 14px;\\n border-radius: 18px;\\n font-size: 14px;\\n line-height: 1.45;\\n white-space: pre-wrap;\\n word-break: break-word;\\n overflow-wrap: anywhere;\\n max-width: 100%;\\n}\\n.hw-msg--visitor .hw-msg-bubble {\\n background: var(--hw-primary);\\n color: white;\\n border-bottom-right-radius: 4px;\\n}\\n.hw-msg--team .hw-msg-bubble {\\n background: var(--hw-visitor-bubble-bg);\\n color: var(--hw-visitor-bubble-text);\\n border-bottom-left-radius: 4px;\\n}\\n.hw-msg--ai .hw-msg-bubble {\\n background: var(--hw-visitor-bubble-bg);\\n color: var(--hw-text);\\n border-bottom-left-radius: 4px;\\n white-space: normal;\\n max-width: min(100%, 640px);\\n}\\n.hw-msg--ai .hw-msg-body {\\n width: 100%;\\n}\\n.hw-msg--ai .hw-msg-bubble:has(.hw-code),\\n.hw-msg--ai .hw-msg-bubble:has(pre) {\\n width: 100%;\\n}\\n.hw-quick-replies {\\n display: flex;\\n flex-wrap: wrap;\\n gap: 6px;\\n margin-top: 8px;\\n}\\n.hw-quick-reply-btn {\\n font: inherit;\\n font-size: 13px;\\n font-weight: 500;\\n padding: 6px 14px;\\n border-radius: 18px;\\n border: 1px solid rgba(0, 0, 0, 0.12);\\n background: var(--hw-bg, #fff);\\n color: var(--hw-text-1, #1a1a1a);\\n cursor: pointer;\\n transition:\\n background 120ms ease,\\n border-color 120ms ease,\\n box-shadow 120ms ease,\\n transform 80ms ease;\\n line-height: 1.3;\\n}\\n.hw-quick-reply-btn:hover:not(:disabled) {\\n border-color: var(--hw-primary);\\n background: color-mix(in srgb, var(--hw-primary) 8%, transparent);\\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\\n}\\n.hw-quick-reply-btn:active:not(:disabled) {\\n transform: scale(0.97);\\n}\\n.hw-quick-reply-btn:disabled {\\n cursor: default;\\n opacity: 0.4;\\n}\\n.hw-quick-reply-btn[data-tapped=true] {\\n background: var(--hw-primary);\\n color: white;\\n border-color: var(--hw-primary);\\n opacity: 1;\\n}\\n.hw-quick-replies[data-cancelled=true] .hw-quick-reply-btn {\\n border-color: rgba(0, 0, 0, 0.08);\\n color: var(--hw-text-muted, #9ca3af);\\n}\\n.hw-msg--ai .hw-code {\\n width: 100%;\\n box-sizing: border-box;\\n}\\n.hw-msg-meta {\\n display: inline-flex;\\n align-items: center;\\n gap: 4px;\\n font-size: 11px;\\n color: var(--hw-text-3);\\n margin-top: 2px;\\n padding: 0 4px;\\n font-variant-numeric: tabular-nums;\\n}\\n.hw-msg-time {\\n white-space: nowrap;\\n}\\n.hw-msg--visitor .hw-msg-meta {\\n text-align: right;\\n}\\n.hw-msg--team .hw-msg-body,\\n.hw-msg--ai .hw-msg-body {\\n align-items: flex-start;\\n}\\n.hw-msg--visitor .hw-msg-body {\\n align-items: flex-end;\\n}\\n.hw-msg-sender {\\n font-size: 11px;\\n font-weight: 500;\\n color: var(--hw-text-3);\\n margin-bottom: 3px;\\n padding: 0 4px;\\n}\\n.hw-typing {\\n display: flex;\\n flex-direction: column;\\n gap: 3px;\\n padding: 8px 0;\\n width: fit-content;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n.hw-typing-label {\\n font-size: 11px;\\n font-weight: 500;\\n color: var(--hw-text-3);\\n padding: 0 4px;\\n}\\n.hw-typing-dots {\\n display: flex;\\n gap: 3px;\\n padding: 10px 14px;\\n width: fit-content;\\n background: var(--hw-visitor-bubble-bg);\\n border-radius: var(--hw-radius);\\n border-bottom-left-radius: 4px;\\n}\\n.hw-typing-dot {\\n width: 6px;\\n height: 6px;\\n border-radius: 50%;\\n background: var(--hw-text-3);\\n animation: hw-typing-bounce 1.4s infinite;\\n}\\n.hw-typing-dot:nth-child(2) {\\n animation-delay: 0.2s;\\n}\\n.hw-typing-dot:nth-child(3) {\\n animation-delay: 0.4s;\\n}\\n@keyframes hw-typing-bounce {\\n 0%, 60%, 100% {\\n transform: translateY(0);\\n }\\n 30% {\\n transform: translateY(-4px);\\n }\\n}\\n.hw-loading {\\n flex: 1;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.hw-loading-dots {\\n display: flex;\\n gap: 4px;\\n}\\n.hw-loading-dot {\\n width: 8px;\\n height: 8px;\\n border-radius: 50%;\\n background: var(--hw-text-4);\\n animation: hw-loading-pulse 1.4s infinite;\\n}\\n.hw-loading-dot:nth-child(2) {\\n animation-delay: 0.2s;\\n}\\n.hw-loading-dot:nth-child(3) {\\n animation-delay: 0.4s;\\n}\\n@keyframes hw-loading-pulse {\\n 0%, 60%, 100% {\\n opacity: 0.3;\\n transform: scale(0.8);\\n }\\n 30% {\\n opacity: 1;\\n transform: scale(1);\\n }\\n}\\n@keyframes hw-skeleton-shimmer {\\n 0% {\\n background-position: -200px 0;\\n }\\n 100% {\\n background-position: calc(200px + 100%) 0;\\n }\\n}\\n.hw-skeleton {\\n background:\\n linear-gradient(\\n 90deg,\\n var(--hw-bg-subtle) 25%,\\n rgba(0, 0, 0, 0.04) 50%,\\n var(--hw-bg-subtle) 75%);\\n background-size: 200px 100%;\\n animation: hw-skeleton-shimmer 1.5s ease-in-out infinite;\\n border-radius: 6px;\\n}\\n.hw-skeleton-messages {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n padding: 16px;\\n gap: 16px;\\n}\\n.hw-skeleton-msg {\\n display: flex;\\n gap: 10px;\\n align-items: flex-start;\\n}\\n.hw-skeleton-msg--right {\\n flex-direction: row-reverse;\\n}\\n.hw-skeleton-avatar {\\n width: 28px;\\n height: 28px;\\n border-radius: 8px;\\n flex-shrink: 0;\\n}\\n.hw-skeleton-bubble {\\n display: flex;\\n flex-direction: column;\\n gap: 6px;\\n}\\n.hw-skeleton-line {\\n height: 12px;\\n border-radius: 6px;\\n}\\n.hw-skeleton-convs {\\n display: flex;\\n flex-direction: column;\\n padding: 8px 0;\\n}\\n.hw-skeleton-conv {\\n display: flex;\\n gap: 10px;\\n align-items: center;\\n padding: 10px 16px;\\n}\\n.hw-skeleton-conv-avatar {\\n width: 36px;\\n height: 36px;\\n border-radius: 8px;\\n flex-shrink: 0;\\n}\\n.hw-skeleton-conv-lines {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n gap: 6px;\\n}\\n.hw-skeleton-content {\\n display: flex;\\n flex-direction: column;\\n padding: 12px 16px;\\n gap: 12px;\\n}\\n.hw-skeleton-content-item {\\n display: flex;\\n flex-direction: column;\\n gap: 6px;\\n padding: 12px;\\n border-radius: 10px;\\n background: var(--hw-bg);\\n}\\n.hw-skeleton-title {\\n height: 22px;\\n width: 65%;\\n border-radius: 6px;\\n}\\n.hw-skeleton-badge {\\n width: 42px;\\n height: 18px;\\n border-radius: 9px;\\n}\\n.hw-skeleton-date {\\n width: 60px;\\n height: 12px;\\n border-radius: 6px;\\n}\\n.hw-skeleton-h2 {\\n height: 16px;\\n border-radius: 6px;\\n}\\n.hw-skeleton-bullet {\\n padding-left: 20px;\\n display: flex;\\n flex-direction: column;\\n gap: 8px;\\n}\\n.hw-skeleton-bullet-line {\\n height: 14px;\\n border-radius: 7px;\\n}\\n.hw-email-card {\\n margin: 0 12px;\\n padding: 14px 16px 10px;\\n border: 1px solid var(--hw-border, rgba(0,0,0,0.08));\\n border-radius: 14px;\\n background: var(--hw-bg, #fff);\\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06), 0 4px 12px rgba(0, 0, 0, 0.03);\\n animation: hw-email-slide-in 0.25s ease-out;\\n}\\n@keyframes hw-email-slide-in {\\n from {\\n opacity: 0;\\n transform: translateY(8px);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n}\\n.hw-email-card-header {\\n display: flex;\\n align-items: flex-start;\\n gap: 10px;\\n margin-bottom: 12px;\\n}\\n.hw-email-card-icon {\\n flex-shrink: 0;\\n width: 32px;\\n height: 32px;\\n border-radius: 8px;\\n background: var(--hw-bg-hover, #f5f5f5);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n color: var(--hw-text, #1a1a1a);\\n}\\n.hw-email-card-title {\\n font-size: 13px;\\n font-weight: 600;\\n color: var(--hw-text, #1a1a1a);\\n line-height: 1.3;\\n margin: 0 0 2px;\\n}\\n.hw-email-card-subtitle {\\n font-size: 12px;\\n color: var(--hw-text-2, #888);\\n line-height: 1.4;\\n margin: 0;\\n}\\n.hw-email-card-input {\\n width: 100%;\\n padding: 9px 12px;\\n border-radius: 10px;\\n border: 1px solid var(--hw-border, rgba(0,0,0,0.1));\\n background: var(--hw-bg-subtle, #fafafa);\\n color: var(--hw-text, #1a1a1a);\\n font-size: 13px;\\n outline: none;\\n margin-bottom: 8px;\\n box-sizing: border-box;\\n transition: border-color 0.15s, box-shadow 0.15s;\\n}\\n.hw-email-card-input::placeholder {\\n color: var(--hw-text-3, #999);\\n}\\n.hw-email-card-input:focus {\\n border-color: var(--hw-focus-border, rgba(0,0,0,0.2));\\n box-shadow: 0 0 0 2px var(--hw-focus-ring, rgba(0,0,0,0.06));\\n}\\n.hw-email-card-input--error {\\n border-color: #ef4444;\\n}\\n.hw-email-card-submit {\\n width: 100%;\\n padding: 9px;\\n border-radius: 10px;\\n border: none;\\n background: var(--hw-brand, #0a0a0a);\\n color: var(--hw-on-brand, #fff);\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n transition: opacity 0.15s;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n gap: 6px;\\n}\\n.hw-email-card-submit:hover:not(:disabled) {\\n opacity: 0.88;\\n}\\n.hw-email-card-submit:disabled {\\n opacity: 0.5;\\n cursor: not-allowed;\\n}\\n.hw-email-card--success {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n gap: 6px;\\n padding: 10px 16px;\\n font-size: 13px;\\n color: var(--hw-text-2, #888);\\n animation: hw-email-slide-in 0.2s ease-out;\\n}\\n.hw-email-card--success svg {\\n flex-shrink: 0;\\n}\\n.hw-composer {\\n display: flex;\\n flex-direction: column;\\n padding: 12px 16px;\\n background: transparent;\\n flex-shrink: 0;\\n}\\n.hw-composer--compact {\\n padding: 8px 12px;\\n}\\n.hw-composer-box {\\n display: flex;\\n flex-direction: column;\\n border: 2px solid var(--hw-border-md);\\n border-radius: 16px;\\n overflow: hidden;\\n transition: border-color 0.2s;\\n background: var(--hw-bg);\\n}\\n.hw-composer-box:focus-within {\\n border-color: var(--hw-focus-border);\\n box-shadow: 0 0 0 3px var(--hw-focus-ring);\\n}\\n.hw-composer-input {\\n flex: 1;\\n resize: none;\\n border: none;\\n padding: 12px 16px 4px;\\n font-size: 14px;\\n font-family: inherit;\\n line-height: 1.4;\\n outline: none;\\n min-height: 40px;\\n max-height: 220px;\\n background: transparent;\\n color: var(--hw-text);\\n field-sizing: content;\\n}\\n.hw-composer-input:focus {\\n outline: none;\\n}\\n.hw-composer-input:focus-visible {\\n outline: none;\\n}\\n.hw-composer-input::placeholder {\\n color: var(--hw-text-4);\\n}\\n.hw-composer-toolbar {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n padding: 4px 10px 10px;\\n}\\n.hw-composer-toolbar-left {\\n display: flex;\\n align-items: center;\\n gap: 4px;\\n}\\n.hw-composer-send {\\n width: 32px;\\n height: 32px;\\n border-radius: 50%;\\n border: none;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n transition:\\n background-color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n color 140ms cubic-bezier(0.23, 1, 0.32, 1),\\n transform 140ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n.hw-composer-send:active:not(:disabled) {\\n transform: scale(0.9);\\n}\\n.hw-composer-send--active {\\n background: var(--hw-primary);\\n color: white;\\n}\\n.hw-composer-send--inactive {\\n background: var(--hw-border);\\n color: var(--hw-text-4);\\n cursor: default;\\n}\\n.hw-composer-send svg {\\n width: 14px;\\n height: 14px;\\n}\\n.hw-composer-charcount {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n font-variant-numeric: tabular-nums;\\n opacity: 1;\\n transform: translateY(0);\\n transition:\\n color 180ms cubic-bezier(0.23, 1, 0.32, 1),\\n opacity 180ms cubic-bezier(0.23, 1, 0.32, 1),\\n transform 180ms cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n@starting-style {\\n .hw-composer-charcount {\\n opacity: 0;\\n transform: translateY(3px);\\n }\\n}\\n.hw-composer-charcount--over {\\n color: #ef4444;\\n font-weight: 600;\\n}\\n@media (prefers-reduced-motion: reduce) {\\n .hw-composer-charcount {\\n transform: none;\\n transition: color 160ms ease, opacity 160ms ease;\\n }\\n @starting-style {\\n .hw-composer-charcount {\\n transform: none;\\n }\\n }\\n}\\n.hw-composer-previews {\\n display: flex;\\n gap: 6px;\\n padding: 8px 10px 0;\\n overflow-x: auto;\\n scrollbar-width: none;\\n}\\n.hw-composer-previews::-webkit-scrollbar {\\n display: none;\\n}\\n.hw-composer-preview {\\n position: relative;\\n width: 48px;\\n height: 48px;\\n border-radius: 8px;\\n overflow: hidden;\\n flex-shrink: 0;\\n background: var(--hw-border);\\n cursor: pointer;\\n}\\n.hw-composer-preview--error {\\n outline: 2px solid #ef4444;\\n outline-offset: -2px;\\n}\\n.hw-composer-preview-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-composer-preview-file {\\n width: 100%;\\n height: 100%;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n background: var(--hw-bg-subtle);\\n}\\n.hw-composer-preview-ext {\\n font-size: 10px;\\n font-weight: 700;\\n color: var(--hw-text-3);\\n text-transform: uppercase;\\n}\\n.hw-composer-preview-loader {\\n position: absolute;\\n inset: 0;\\n background: rgba(0, 0, 0, 0.35);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.hw-composer-preview-loader::after {\\n content: \\\"\\\";\\n width: 16px;\\n height: 16px;\\n border: 2px solid rgba(255, 255, 255, 0.3);\\n border-top-color: white;\\n border-radius: 50%;\\n animation: hw-spin 0.6s linear infinite;\\n}\\n@keyframes hw-spin {\\n to {\\n transform: rotate(360deg);\\n }\\n}\\n.hw-composer-preview-badge {\\n position: absolute;\\n top: 2px;\\n right: 2px;\\n width: 16px;\\n height: 16px;\\n border-radius: 50%;\\n background: #ef4444;\\n color: white;\\n font-size: 10px;\\n font-weight: 700;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.hw-composer-preview-remove {\\n position: absolute;\\n top: 2px;\\n right: 2px;\\n width: 18px;\\n height: 18px;\\n border-radius: 50%;\\n border: none;\\n background: rgba(0, 0, 0, 0.55);\\n color: white;\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n opacity: 0;\\n transition: opacity 0.15s;\\n}\\n.hw-composer-preview-remove svg {\\n width: 10px;\\n height: 10px;\\n}\\n.hw-composer-preview:hover .hw-composer-preview-remove {\\n opacity: 1;\\n}\\n.hw-composer-attach {\\n width: 28px;\\n height: 28px;\\n border: none;\\n background: none;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 6px;\\n opacity: 0.7;\\n transition: opacity 0.15s;\\n}\\n.hw-composer-attach:hover {\\n opacity: 1;\\n}\\n.hw-composer-attach svg {\\n width: 16px;\\n height: 16px;\\n}\\n.hw-msg-images {\\n display: flex;\\n flex-direction: column;\\n gap: 4px;\\n margin-bottom: 4px;\\n}\\n.hw-msg-image-link {\\n display: block;\\n border-radius: 14px;\\n overflow: hidden;\\n line-height: 0;\\n}\\n.hw-msg-image {\\n max-width: 140px;\\n max-height: 80px;\\n object-fit: cover;\\n border-radius: 8px;\\n outline: 1px solid rgba(0, 0, 0, 0.08);\\n outline-offset: -1px;\\n}\\n.hw-msg-files {\\n display: flex;\\n flex-direction: column;\\n gap: 4px;\\n margin-top: 4px;\\n}\\n.hw-msg-file {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 8px 12px;\\n border-radius: 10px;\\n background: var(--hw-bg-subtle);\\n text-decoration: none;\\n color: var(--hw-text);\\n transition: background 0.15s;\\n}\\n.hw-msg-file:hover {\\n background: var(--hw-border);\\n}\\n.hw-msg-file-icon {\\n flex-shrink: 0;\\n width: 20px;\\n height: 20px;\\n color: var(--hw-text-3);\\n}\\n.hw-msg-file-icon svg {\\n width: 100%;\\n height: 100%;\\n}\\n.hw-msg-file-info {\\n display: flex;\\n flex-direction: column;\\n min-width: 0;\\n}\\n.hw-msg-file-name {\\n font-size: 13px;\\n font-weight: 500;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.hw-msg-file-size {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n}\\n.hw-msg-image-link {\\n cursor: pointer;\\n border: none;\\n padding: 0;\\n background: none;\\n display: block;\\n line-height: 0;\\n}\\n.hw-hover-preview {\\n position: fixed;\\n z-index: 99998;\\n padding: 6px;\\n border-radius: 14px;\\n background: white;\\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.06);\\n cursor: pointer;\\n animation: hw-hover-in 0.15s ease-out;\\n}\\n@media (prefers-color-scheme: dark) {\\n .hw-hover-preview {\\n background: #1c1c1e;\\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08);\\n }\\n}\\n@keyframes hw-hover-in {\\n from {\\n opacity: 0;\\n transform: scale(0.96) translateY(4px);\\n }\\n to {\\n opacity: 1;\\n transform: scale(1) translateY(0);\\n }\\n}\\n.hw-hover-preview-img {\\n width: 100%;\\n max-height: 200px;\\n object-fit: contain;\\n border-radius: 10px;\\n display: block;\\n outline: 1px solid rgba(0, 0, 0, 0.08);\\n outline-offset: -1px;\\n}\\n.hw-hover-preview--doc {\\n display: flex;\\n align-items: center;\\n gap: 10px;\\n padding: 10px 14px;\\n}\\n.hw-hover-preview-doc-icon {\\n width: 28px;\\n height: 28px;\\n flex-shrink: 0;\\n}\\n.hw-hover-preview-doc-icon svg {\\n width: 100%;\\n height: 100%;\\n}\\n.hw-hover-preview-doc-info {\\n display: flex;\\n flex-direction: column;\\n min-width: 0;\\n}\\n.hw-hover-preview-doc-name {\\n font-size: 13px;\\n font-weight: 500;\\n color: var(--hw-text);\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.hw-hover-preview-doc-hint {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n}\\n.hw-event {\\n display: flex;\\n justify-content: center;\\n padding: 8px 16px;\\n}\\n.hw-event-text {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n text-align: center;\\n}\\n.hw-event--card {\\n justify-content: flex-start;\\n align-items: center;\\n gap: 10px;\\n background: var(--hw-bg-subtle);\\n padding: 10px 14px;\\n border-radius: 12px;\\n margin: 4px 16px;\\n}\\n.hw-event-avatar {\\n width: 32px;\\n height: 32px;\\n border-radius: 50%;\\n background: var(--hw-bg-hover, #e0e0e0);\\n color: var(--hw-text-2, #555);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n font-size: 11px;\\n font-weight: 600;\\n flex-shrink: 0;\\n overflow: hidden;\\n}\\n.hw-event-avatar-img {\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.hw-event-body {\\n font-size: 13px;\\n line-height: 1.3;\\n}\\n.hw-event-name {\\n font-weight: 600;\\n color: var(--hw-text);\\n}\\n.hw-event-action {\\n color: var(--hw-text-2);\\n}\\n.hw-resolved-banner {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 12px 16px;\\n border-top: 1px solid var(--hw-border);\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text-2);\\n font-size: 13px;\\n flex-shrink: 0;\\n}\\n.hw-new {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n background: var(--hw-bg-subtle);\\n}\\n.hw-new-body {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 32px 24px;\\n text-align: center;\\n}\\n.hw-new-welcome {\\n flex: 1;\\n padding: 16px 20px;\\n overflow-y: auto;\\n}\\n.hw-new-heading {\\n font-size: 17px;\\n font-weight: 600;\\n color: var(--hw-text);\\n margin-bottom: 6px;\\n}\\n.hw-new-desc {\\n font-size: 13px;\\n color: var(--hw-text-2);\\n margin-bottom: 24px;\\n}\\n.hw-powered {\\n text-align: center;\\n padding: 8px;\\n font-size: 11px;\\n color: var(--hw-text-4);\\n flex-shrink: 0;\\n}\\n.hw-powered a {\\n color: var(--hw-text-2);\\n text-decoration: none;\\n font-weight: 500;\\n}\\n.hw-powered a:hover {\\n color: var(--hw-text);\\n}\\n@media (max-width: 479px) {\\n .hw-widget {\\n bottom: 16px;\\n right: 16px;\\n left: auto;\\n }\\n .hw-window {\\n position: fixed;\\n top: 0;\\n left: 0;\\n right: 0;\\n bottom: 0;\\n width: 100%;\\n height: var(--hw-visible-height, 100%);\\n border-radius: 0;\\n animation: hw-mob-up 0.3s cubic-bezier(0.22, 1, 0.36, 1);\\n }\\n .hw-window--closing {\\n animation: hw-mob-down 0.2s ease forwards;\\n }\\n @keyframes hw-mob-up {\\n from {\\n opacity: 0;\\n transform: translateY(100%);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n }\\n @keyframes hw-mob-down {\\n from {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n to {\\n opacity: 0;\\n transform: translateY(100%);\\n }\\n }\\n .hw-hero {\\n padding-top: calc(20px + env(safe-area-inset-top, 0px));\\n }\\n .hw-header {\\n padding-top: env(safe-area-inset-top, 0px);\\n }\\n .hw-tabs {\\n padding-bottom: env(safe-area-inset-bottom, 0px);\\n }\\n .hw-composer {\\n padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));\\n }\\n .hw-powered {\\n padding-bottom: calc(5px + env(safe-area-inset-bottom, 0px));\\n }\\n .hw-header-close,\\n .hw-header-back,\\n .hw-header-action {\\n width: 34px;\\n height: 34px;\\n }\\n .hw-composer-send {\\n width: 40px;\\n height: 40px;\\n }\\n .hw-window ~ .hw-bubble {\\n display: none;\\n }\\n .hw-messages {\\n padding: 12px 14px;\\n }\\n .hw-msg {\\n max-width: 82%;\\n }\\n .hw-msg--ai {\\n max-width: 100%;\\n }\\n}\\n.hw-preview {\\n position: absolute;\\n bottom: calc(100% + 12px);\\n right: 0;\\n width: 300px;\\n max-width: calc(100vw - 40px);\\n background: var(--hw-bg);\\n border: 1px solid var(--hw-border);\\n border-radius: 16px;\\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06);\\n animation: hw-preview-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\\n overflow: hidden;\\n cursor: pointer;\\n transition: transform 0.15s, box-shadow 0.15s;\\n}\\n.hw-preview:hover {\\n transform: translateY(-2px);\\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15), 0 4px 12px rgba(0, 0, 0, 0.08);\\n}\\n@keyframes hw-preview-in {\\n from {\\n opacity: 0;\\n transform: translateY(8px) scale(0.95);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n}\\n@keyframes hw-preview-out {\\n from {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n to {\\n opacity: 0;\\n transform: translateY(8px) scale(0.95);\\n }\\n}\\n.hw-preview-header {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 12px 14px 0;\\n}\\n.hw-preview-avatar {\\n width: 28px;\\n height: 28px;\\n border-radius: 50%;\\n background:\\n linear-gradient(\\n 135deg,\\n var(--hw-primary),\\n color-mix(in srgb, var(--hw-primary) 50%, black));\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n color: white;\\n flex-shrink: 0;\\n overflow: hidden;\\n}\\n.hw-preview-avatar svg {\\n width: 16px;\\n height: 16px;\\n}\\n.hw-preview-name {\\n font-size: 13px;\\n font-weight: 600;\\n color: var(--hw-text);\\n flex: 1;\\n}\\n.hw-preview-close {\\n width: 24px;\\n height: 24px;\\n border: none;\\n background: transparent;\\n color: var(--hw-text-3);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 50%;\\n transition: background 0.15s, color 0.15s;\\n flex-shrink: 0;\\n}\\n.hw-preview-close:hover {\\n background: var(--hw-bg-subtle);\\n color: var(--hw-text-2);\\n}\\n.hw-preview-close:active {\\n transform: scale(0.90);\\n transition:\\n transform 0.14s cubic-bezier(0.23, 1, 0.32, 1),\\n background 0.15s,\\n color 0.15s;\\n}\\n.hw-preview-close svg {\\n width: 12px;\\n height: 12px;\\n}\\n.hw-preview-body {\\n padding: 4px 14px;\\n font-size: 14px;\\n line-height: 1.45;\\n color: var(--hw-text-2);\\n}\\n.hw-preview-body:first-of-type {\\n padding-top: 8px;\\n}\\n.hw-preview-body:last-child {\\n padding-bottom: 14px;\\n}\\n.hw-preview-prompt {\\n padding: 2px 14px 6px;\\n font-size: 14px;\\n font-weight: 500;\\n color: var(--hw-text-1);\\n}\\n.hw-preview-quick-replies {\\n display: flex;\\n flex-wrap: wrap;\\n gap: 6px;\\n padding: 0 14px 14px;\\n}\\n.hw-preview-qr-btn {\\n display: inline-flex;\\n align-items: center;\\n padding: 6px 14px;\\n font-size: 13px;\\n font-weight: 500;\\n line-height: 1.3;\\n color: var(--hw-brand, #000);\\n background: transparent;\\n border: 1px solid var(--hw-border, rgba(0, 0, 0, 0.1));\\n border-radius: 18px;\\n cursor: pointer;\\n transition: background 0.15s, border-color 0.15s;\\n}\\n.hw-preview-qr-btn:hover {\\n background: var(--hw-hover, rgba(0, 0, 0, 0.04));\\n border-color: var(--hw-brand, #000);\\n}\\n.hw-content-search {\\n padding: 10px 16px;\\n}\\n.hw-content-search-box {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 8px 12px;\\n background: var(--hw-bg);\\n border: 1px solid var(--hw-border-md);\\n border-radius: 10px;\\n transition: border-color 0.15s, box-shadow 0.15s;\\n}\\n.hw-content-search-box:focus-within {\\n border-color: var(--hw-focus-border);\\n box-shadow: 0 0 0 3px var(--hw-focus-ring);\\n}\\n.hw-content-search-input {\\n flex: 1;\\n border: none !important;\\n outline: none !important;\\n box-shadow: none !important;\\n background: none;\\n font-size: 13px;\\n color: var(--hw-text-1);\\n font-family: inherit;\\n line-height: 1;\\n -webkit-appearance: none;\\n}\\n.hw-content-search-input:focus,\\n.hw-content-search-input:focus-visible {\\n outline: none !important;\\n box-shadow: none !important;\\n border: none !important;\\n}\\n.hw-content-search-input::placeholder {\\n color: var(--hw-text-3);\\n}\\n.hw-content-search-icon {\\n width: 15px;\\n height: 15px;\\n color: var(--hw-text-3);\\n flex-shrink: 0;\\n}\\n.hw-content-list {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n}\\n.hw-content-entries {\\n flex: 1;\\n overflow-y: auto;\\n overscroll-behavior: contain;\\n}\\n.hw-content-entry {\\n display: block;\\n width: 100%;\\n padding: 14px 16px;\\n border: none;\\n border-bottom: 1px solid var(--hw-border);\\n background: none;\\n cursor: pointer;\\n text-align: left;\\n transition: background-color 0.15s ease;\\n -webkit-tap-highlight-color: transparent;\\n}\\n.hw-content-entry:hover {\\n background: var(--hw-bg-hover);\\n}\\n.hw-content-entry:active {\\n background: var(--hw-border);\\n}\\n.hw-content-entry:last-child {\\n border-bottom: none;\\n}\\n.hw-content-entry-main {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n}\\n.hw-content-entry-text {\\n flex: 1;\\n min-width: 0;\\n display: flex;\\n flex-direction: column;\\n gap: 3px;\\n}\\n.hw-content-entry-title {\\n font-size: 14px;\\n font-weight: 600;\\n color: var(--hw-text-1);\\n line-height: 1.3;\\n}\\n.hw-content-entry-desc {\\n font-size: 13px;\\n color: var(--hw-text-2);\\n line-height: 1.4;\\n display: -webkit-box;\\n -webkit-line-clamp: 2;\\n -webkit-box-orient: vertical;\\n overflow: hidden;\\n}\\n.hw-content-entry-meta {\\n display: flex;\\n align-items: center;\\n gap: 6px;\\n margin-top: 2px;\\n}\\n.hw-content-entry-badge {\\n font-size: 11px;\\n font-weight: 500;\\n color: var(--hw-text-3);\\n background: var(--hw-bg-hover);\\n padding: 1px 6px;\\n border-radius: 4px;\\n}\\n.hw-content-entry-date {\\n font-size: 11px;\\n color: var(--hw-text-3);\\n}\\n.hw-content-entry-chevron {\\n width: 16px;\\n height: 16px;\\n color: var(--hw-text-3);\\n flex-shrink: 0;\\n opacity: 0.5;\\n}\\n.hw-content-detail {\\n padding: 16px;\\n overflow-y: auto;\\n overscroll-behavior: contain;\\n height: 100%;\\n}\\n.hw-content-detail-header {\\n margin-bottom: 16px;\\n}\\n.hw-content-detail-title {\\n font-size: 17px;\\n font-weight: 700;\\n color: var(--hw-text-1);\\n margin: 0 0 6px;\\n line-height: 1.3;\\n display: flex;\\n align-items: center;\\n gap: 6px;\\n}\\n.hw-content-detail-meta {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n flex-wrap: wrap;\\n}\\n.hw-content-detail-date {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n}\\n.hw-content-detail-body {\\n font-size: 14px;\\n line-height: 1.6;\\n color: var(--hw-text-1);\\n}\\n.hw-markdown h1 {\\n font-size: 17px;\\n font-weight: 700;\\n margin: 0;\\n}\\n.hw-markdown h2 {\\n font-size: 15px;\\n font-weight: 600;\\n margin: 0;\\n}\\n.hw-markdown h3 {\\n font-size: 14px;\\n font-weight: 600;\\n margin: 0;\\n}\\n.hw-markdown p {\\n margin: 0;\\n}\\n.hw-markdown p:empty,\\n.hw-markdown div:empty,\\n.hw-markdown p:has(> br:only-child),\\n.hw-markdown div:has(> br:only-child) {\\n display: none;\\n}\\n.hw-markdown > * + * {\\n margin-top: 12px;\\n}\\n.hw-markdown > * + h1,\\n.hw-markdown > * + h2 {\\n margin-top: 20px;\\n}\\n.hw-markdown > * + h3 {\\n margin-top: 16px;\\n}\\n.hw-markdown > h1 + *,\\n.hw-markdown > h2 + *,\\n.hw-markdown > h3 + * {\\n margin-top: 8px;\\n}\\n.hw-markdown > *:first-child {\\n margin-top: 0;\\n}\\n.hw-markdown > *:last-child {\\n margin-bottom: 0;\\n}\\n.hw-markdown > br {\\n display: none;\\n}\\n.hw-markdown ul {\\n margin: 0;\\n padding-left: 20px;\\n}\\n.hw-markdown li {\\n margin: 4px 0;\\n}\\n.hw-markdown code {\\n font-family:\\n ui-monospace,\\n \\\"SF Mono\\\",\\n monospace;\\n font-size: 12px;\\n background: var(--hw-bg-hover);\\n padding: 1px 5px;\\n border-radius: 4px;\\n}\\n.hw-code {\\n margin: 10px 0;\\n border-radius: 10px;\\n overflow: hidden;\\n border: 1px solid var(--hw-border, rgba(0, 0, 0, 0.08));\\n background: var(--hw-bg-hover, #f5f5f4);\\n font-family:\\n ui-monospace,\\n \\\"SF Mono\\\",\\n \\\"Menlo\\\",\\n monospace;\\n}\\n.hw-code-header {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n gap: 10px;\\n padding: 7px 8px 7px 12px;\\n font-size: 11px;\\n color: var(--hw-text-2, #6b7280);\\n background: rgba(0, 0, 0, 0.03);\\n border-bottom: 1px solid var(--hw-border, rgba(0, 0, 0, 0.06));\\n}\\n.hw-code-lang {\\n text-transform: lowercase;\\n letter-spacing: 0.02em;\\n font-weight: 500;\\n}\\n.hw-code-actions {\\n display: inline-flex;\\n align-items: center;\\n gap: 1px;\\n}\\n.hw-code-action {\\n position: relative;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 22px;\\n height: 22px;\\n padding: 0;\\n font-family: inherit;\\n color: var(--hw-text-2, #6b7280);\\n background: transparent;\\n border: 1px solid transparent;\\n border-radius: 6px;\\n cursor: pointer;\\n opacity: 0.62;\\n transition:\\n background 120ms ease,\\n color 120ms ease,\\n opacity 120ms ease,\\n scale 120ms ease;\\n}\\n.hw-code-action:hover {\\n color: var(--hw-text, #111);\\n background: rgba(0, 0, 0, 0.06);\\n opacity: 1;\\n}\\n.hw-code-action:active {\\n scale: 0.96;\\n}\\n.hw-code-action svg {\\n width: 13px;\\n height: 13px;\\n}\\n.hw-code-copy-icon,\\n.hw-code-check-icon {\\n position: absolute;\\n inset: 50% auto auto 50%;\\n transition:\\n opacity 180ms cubic-bezier(0.2, 0, 0, 1),\\n scale 180ms cubic-bezier(0.2, 0, 0, 1),\\n filter 180ms cubic-bezier(0.2, 0, 0, 1);\\n translate: -50% -50%;\\n}\\n.hw-code-check-icon {\\n filter: blur(4px);\\n opacity: 0;\\n scale: 0.25;\\n}\\n.hw-code-copy--copied .hw-code-copy-icon {\\n filter: blur(4px);\\n opacity: 0;\\n scale: 0.25;\\n}\\n.hw-code-copy--copied .hw-code-check-icon {\\n filter: blur(0);\\n opacity: 1;\\n scale: 1;\\n}\\n.hw-code-copy-label {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n}\\n.hw-code-copy--copied {\\n color: #16a34a;\\n}\\n.hw-code-copy--failed {\\n color: #dc2626;\\n}\\n.hw-code pre {\\n margin: 0;\\n padding: 10px 12px;\\n background: transparent;\\n border-radius: 0;\\n overflow-x: auto;\\n max-width: 100%;\\n max-height: 320px;\\n scrollbar-color: rgba(0, 0, 0, 0.22) transparent;\\n scrollbar-width: thin;\\n}\\n.hw-code pre::-webkit-scrollbar {\\n width: 10px;\\n height: 10px;\\n}\\n.hw-code pre::-webkit-scrollbar-track {\\n background: transparent;\\n}\\n.hw-code pre::-webkit-scrollbar-thumb {\\n background: rgba(0, 0, 0, 0.18);\\n background-clip: content-box;\\n border: 3px solid transparent;\\n border-radius: 999px;\\n}\\n.hw-code pre::-webkit-scrollbar-thumb:hover {\\n background: rgba(0, 0, 0, 0.28);\\n background-clip: content-box;\\n}\\n.hw-code pre code {\\n display: block;\\n background: transparent;\\n padding: 0;\\n font-size: 12px;\\n line-height: 1.55;\\n white-space: pre;\\n color: var(--hw-text, #111);\\n}\\n@media (prefers-color-scheme: dark) {\\n .hw-code {\\n background: rgba(255, 255, 255, 0.04);\\n border-color: rgba(255, 255, 255, 0.08);\\n }\\n .hw-code-header {\\n background: rgba(255, 255, 255, 0.03);\\n border-bottom-color: rgba(255, 255, 255, 0.06);\\n }\\n .hw-code-action:hover,\\n .hw-code-action:focus-visible {\\n background: rgba(255, 255, 255, 0.08);\\n }\\n .hw-code pre {\\n scrollbar-color: rgba(255, 255, 255, 0.26) transparent;\\n }\\n .hw-code pre::-webkit-scrollbar-thumb {\\n background: rgba(255, 255, 255, 0.22);\\n background-clip: content-box;\\n }\\n .hw-code pre::-webkit-scrollbar-thumb:hover {\\n background: rgba(255, 255, 255, 0.32);\\n background-clip: content-box;\\n }\\n}\\n.hw-markdown pre {\\n margin: 8px 0;\\n padding: 10px 12px;\\n background: var(--hw-bg-hover);\\n border-radius: 8px;\\n overflow-x: auto;\\n max-width: 100%;\\n}\\n.hw-markdown pre code {\\n display: block;\\n background: transparent;\\n padding: 0;\\n border-radius: 0;\\n font-size: 12px;\\n line-height: 1.5;\\n white-space: pre;\\n word-break: normal;\\n color: inherit;\\n}\\n.hw-msg-bubble pre {\\n margin: 6px 0;\\n padding: 8px 10px;\\n background: rgba(0, 0, 0, 0.06);\\n border-radius: 6px;\\n overflow-x: auto;\\n max-width: 100%;\\n}\\n.hw-msg-bubble pre code {\\n background: transparent;\\n padding: 0;\\n font-size: 12px;\\n line-height: 1.5;\\n white-space: pre;\\n}\\n.hw-msg-bubble .hw-code pre {\\n margin: 0;\\n padding: 10px 12px;\\n background: transparent;\\n border-radius: 0;\\n}\\n.hw-msg-bubble .hw-code pre code {\\n background: transparent;\\n padding: 0;\\n font-size: 12px;\\n line-height: 1.55;\\n}\\n.hw-msg--team .hw-msg-bubble pre,\\n.hw-msg--visitor .hw-msg-bubble pre {\\n background: rgba(255, 255, 255, 0.12);\\n}\\n.hw-markdown blockquote {\\n margin: 0 0 12px;\\n padding: 8px 12px;\\n border-left: 3px solid var(--hw-border);\\n color: var(--hw-text-2);\\n font-style: italic;\\n}\\n.hw-markdown a {\\n color: var(--hw-primary);\\n text-decoration: underline;\\n text-underline-offset: 2px;\\n}\\n.hw-markdown img {\\n max-width: 100%;\\n border-radius: 8px;\\n margin: 8px 0;\\n outline: 1px solid rgba(0, 0, 0, 0.08);\\n outline-offset: -1px;\\n}\\n.hw-markdown hr {\\n border: none;\\n border-top: 1px solid var(--hw-border);\\n margin: 16px 0;\\n}\\n.hw-content-empty {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 40px 20px;\\n text-align: center;\\n}\\n.hw-content-empty-title {\\n font-size: 14px;\\n font-weight: 600;\\n color: var(--hw-text-1);\\n margin-bottom: 4px;\\n}\\n.hw-content-empty-desc {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n}\\n.hw-content-loading {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 40px 20px;\\n}\\n.hw-content-load-more {\\n display: block;\\n width: 100%;\\n padding: 10px;\\n border: none;\\n background: none;\\n color: var(--hw-primary);\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n text-align: center;\\n}\\n.hw-content-load-more:hover {\\n background: var(--hw-bg-hover);\\n}\\n.hw-content-load-more:disabled {\\n opacity: 0.5;\\n cursor: default;\\n}\\n@media (hover: none) {\\n .hw-composer-preview-remove {\\n opacity: 0.7;\\n }\\n}\\n.hw-composer--dragging .hw-composer-box {\\n border-color: var(--hw-primary);\\n background: color-mix(in srgb, var(--hw-primary) 4%, transparent);\\n}\\n.hw-composer-drop-overlay {\\n position: absolute;\\n inset: 0;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n background: color-mix(in srgb, var(--hw-bg) 90%, transparent);\\n border: 2px dashed var(--hw-primary);\\n border-radius: 12px;\\n z-index: 10;\\n pointer-events: none;\\n animation: hw-drop-pulse 1.5s ease-in-out infinite;\\n}\\n.hw-composer-drop-text {\\n font-size: 13px;\\n font-weight: 500;\\n color: var(--hw-primary);\\n}\\n@keyframes hw-drop-pulse {\\n 0%, 100% {\\n opacity: 0.8;\\n }\\n 50% {\\n opacity: 1;\\n }\\n}\\n.hw-disconnect {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n gap: 6px;\\n padding: 6px 12px;\\n background: #fef3c7;\\n color: #92400e;\\n font-size: 12px;\\n font-weight: 500;\\n flex-shrink: 0;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n.hw-disconnect-dot {\\n width: 6px;\\n height: 6px;\\n border-radius: 50%;\\n background: #f59e0b;\\n animation: hw-loading-pulse 1.4s infinite;\\n}\\n.hw-error-state {\\n flex: 1;\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n padding: 32px 24px;\\n text-align: center;\\n gap: 12px;\\n}\\n.hw-error-icon {\\n width: 48px;\\n height: 48px;\\n border-radius: 50%;\\n background: #fef2f2;\\n color: #ef4444;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n}\\n.hw-error-icon svg {\\n width: 24px;\\n height: 24px;\\n}\\n.hw-error-title {\\n font-size: 15px;\\n font-weight: 600;\\n color: var(--hw-text);\\n}\\n.hw-error-desc {\\n font-size: 13px;\\n color: var(--hw-text-2);\\n}\\n.hw-error-btn {\\n padding: 8px 20px;\\n border: 1px solid var(--hw-border-md);\\n border-radius: 8px;\\n background: var(--hw-bg);\\n color: var(--hw-text);\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n transition: background 0.15s;\\n}\\n.hw-error-btn:hover {\\n background: var(--hw-bg-hover);\\n}\\n.hw-send-error {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 8px 12px;\\n background: #fef2f2;\\n color: #dc2626;\\n font-size: 12px;\\n font-weight: 500;\\n flex-shrink: 0;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n.hw-send-error-retry {\\n margin-left: auto;\\n padding: 2px 8px;\\n border: 1px solid #fca5a5;\\n border-radius: 4px;\\n background: none;\\n color: #dc2626;\\n font-size: 11px;\\n font-weight: 600;\\n cursor: pointer;\\n}\\n.hw-send-error-retry:hover {\\n background: #fee2e2;\\n}\\n.hw-resolved {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n gap: 12px;\\n padding: 16px 20px;\\n border-top: 1px solid var(--hw-border);\\n flex-shrink: 0;\\n}\\n.hw-resolved-text {\\n font-size: 13px;\\n color: var(--hw-text-3);\\n font-weight: 500;\\n}\\n.hw-resolved-actions {\\n display: flex;\\n gap: 8px;\\n}\\n.hw-resolved-reopen {\\n padding: 6px 16px;\\n border: 1px solid var(--hw-border-md);\\n border-radius: 8px;\\n background: var(--hw-bg);\\n color: var(--hw-text);\\n font-size: 13px;\\n font-weight: 500;\\n cursor: pointer;\\n transition: background 0.15s;\\n}\\n.hw-resolved-reopen:hover {\\n background: var(--hw-bg-hover);\\n}\\n.hw-csat {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n gap: 8px;\\n}\\n.hw-csat-label {\\n font-size: 12px;\\n color: var(--hw-text-3);\\n}\\n.hw-csat-buttons {\\n display: flex;\\n gap: 8px;\\n}\\n.hw-csat-btn {\\n width: 36px;\\n height: 36px;\\n border: 1px solid var(--hw-border-md);\\n border-radius: 8px;\\n background: var(--hw-bg);\\n cursor: pointer;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n font-size: 18px;\\n transition:\\n transform 0.15s,\\n border-color 0.15s,\\n background 0.15s;\\n}\\n.hw-csat-btn:hover {\\n transform: scale(1.1);\\n border-color: var(--hw-text-3);\\n}\\n.hw-csat-btn--selected {\\n border-color: var(--hw-primary);\\n background: var(--hw-bg-hover);\\n transform: scale(1.15);\\n}\\n.hw-csat-thanks {\\n font-size: 12px;\\n color: #22c55e;\\n font-weight: 500;\\n animation: hw-msg-appear 0.25s ease-out;\\n}\\n.hw-load-more-trigger {\\n display: flex;\\n justify-content: center;\\n min-height: 1px;\\n}\\n.hw-load-more-trigger:has(.hw-load-more-spinner) {\\n padding: 8px 0;\\n}\\n.hw-load-more-spinner {\\n display: flex;\\n gap: 3px;\\n}\\n.hw-load-more-spinner > div {\\n width: 5px;\\n height: 5px;\\n border-radius: 50%;\\n background: var(--hw-text-4);\\n animation: hw-loading-pulse 1.4s infinite;\\n}\\n.hw-load-more-spinner > div:nth-child(2) {\\n animation-delay: 0.2s;\\n}\\n.hw-load-more-spinner > div:nth-child(3) {\\n animation-delay: 0.4s;\\n}\\n.hw-drag-handle {\\n display: none;\\n}\\n@media (max-width: 479px) {\\n .hw-drag-handle {\\n display: flex;\\n justify-content: center;\\n padding: 8px 0 4px;\\n flex-shrink: 0;\\n }\\n .hw-drag-handle-pill {\\n width: 32px;\\n height: 4px;\\n border-radius: 2px;\\n background: var(--hw-text-4);\\n }\\n}\\n.hw-msg-bubble p {\\n margin: 0 0 8px;\\n}\\n.hw-msg-bubble p:last-child {\\n margin-bottom: 0;\\n}\\n.hw-msg-bubble strong {\\n font-weight: 600;\\n}\\n.hw-msg-bubble em {\\n font-style: italic;\\n}\\n.hw-msg-bubble a {\\n color: var(--hw-primary);\\n text-decoration: underline;\\n text-underline-offset: 2px;\\n word-break: break-all;\\n}\\n.hw-msg-bubble a:hover {\\n opacity: 0.8;\\n}\\n.hw-msg--visitor .hw-msg-bubble a {\\n color: rgba(255, 255, 255, 0.9);\\n}\\n.hw-msg--visitor .hw-msg-bubble a:hover {\\n color: white;\\n}\\n.hw-msg-bubble ul,\\n.hw-msg-bubble ol {\\n margin: 4px 0 8px;\\n padding-left: 20px;\\n}\\n.hw-msg-bubble li {\\n margin: 2px 0;\\n}\\n.hw-msg-bubble code {\\n padding: 1px 4px;\\n border-radius: 3px;\\n background: rgba(0, 0, 0, 0.06);\\n font-size: 0.9em;\\n font-family:\\n ui-monospace,\\n SFMono-Regular,\\n Menlo,\\n monospace;\\n}\\n.hw-msg-bubble pre {\\n margin: 4px 0 8px;\\n padding: 8px 10px;\\n border-radius: 6px;\\n background: rgba(0, 0, 0, 0.06);\\n overflow-x: auto;\\n font-size: 0.85em;\\n}\\n.hw-msg-bubble pre code {\\n padding: 0;\\n background: none;\\n}\\n.hw-msg-bubble blockquote {\\n margin: 4px 0 8px;\\n padding: 4px 0 4px 12px;\\n border-left: 3px solid var(--hw-border-md);\\n color: var(--hw-text-2);\\n}\\n.hw-widget[data-theme=dark] {\\n --hw-bg: #1c1c1e;\\n --hw-bg-subtle: #161618;\\n --hw-bg-hover: #2c2c2e;\\n --hw-border: rgba(255, 255, 255, 0.08);\\n --hw-border-md: rgba(255, 255, 255, 0.14);\\n --hw-text: #f5f5f5;\\n --hw-text-1: #f5f5f5;\\n --hw-text-2: #a1a1aa;\\n --hw-text-3: #71717a;\\n --hw-text-4: #52525b;\\n --hw-visitor-bubble-bg: #2c2c2e;\\n --hw-visitor-bubble-text: #f5f5f5;\\n --hw-focus-border: rgba(255, 255, 255, 0.28);\\n --hw-focus-ring: rgba(255, 255, 255, 0.08);\\n --hw-brand: #f5f5f5;\\n --hw-on-brand: #1c1c1e;\\n}\\n@media (prefers-color-scheme: dark) {\\n .hw-widget:not([data-theme=light]) .hw-messages {\\n scrollbar-color: rgba(255, 255, 255, 0.26) transparent;\\n }\\n .hw-widget:not([data-theme=light]) .hw-messages::-webkit-scrollbar-thumb {\\n background: rgba(255, 255, 255, 0.2);\\n background-clip: content-box;\\n }\\n .hw-widget:not([data-theme=light]) .hw-messages::-webkit-scrollbar-thumb:hover {\\n background: rgba(255, 255, 255, 0.32);\\n background-clip: content-box;\\n }\\n .hw-widget:not([data-theme=light]) {\\n --hw-bg: #1c1c1e;\\n --hw-bg-subtle: #161618;\\n --hw-bg-hover: #2c2c2e;\\n --hw-border: rgba(255, 255, 255, 0.08);\\n --hw-border-md: rgba(255, 255, 255, 0.14);\\n --hw-text: #f5f5f5;\\n --hw-text-1: #f5f5f5;\\n --hw-text-2: #a1a1aa;\\n --hw-text-3: #71717a;\\n --hw-text-4: #52525b;\\n --hw-visitor-bubble-bg: #2c2c2e;\\n --hw-visitor-bubble-text: #f5f5f5;\\n --hw-focus-border: rgba(255, 255, 255, 0.28);\\n --hw-focus-ring: rgba(255, 255, 255, 0.08);\\n --hw-brand: #f5f5f5;\\n --hw-on-brand: #1c1c1e;\\n }\\n}\\n@media (prefers-color-scheme: dark) {\\n .hw-widget:not([data-theme=light]) .hw-header {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n .hw-header-bot-icon {\\n background: var(--hw-bg-hover);\\n }\\n .hw-header-name,\\n .hw-header-title {\\n color: var(--hw-text);\\n }\\n .hw-header-status {\\n color: var(--hw-text-2);\\n }\\n .hw-header-close,\\n .hw-header-back {\\n color: var(--hw-text-2);\\n }\\n .hw-header-close:hover,\\n .hw-header-back:hover {\\n background: var(--hw-bg-hover);\\n color: var(--hw-text);\\n }\\n .hw-content-entry {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n .hw-content-entry:hover {\\n background: var(--hw-bg-hover);\\n border-color: var(--hw-border-md);\\n }\\n .hw-content-empty,\\n .hw-empty {\\n color: var(--hw-text-3);\\n }\\n .hw-conv-card {\\n border-color: var(--hw-border);\\n }\\n .hw-recent-row {\\n border-color: var(--hw-border);\\n }\\n .hw-composer-drop-overlay {\\n background: rgba(0, 0, 0, 0.6);\\n color: var(--hw-text);\\n }\\n .hw-composer--dragging .hw-composer-box {\\n border-color: var(--hw-focus-border);\\n box-shadow: 0 0 0 3px var(--hw-focus-ring);\\n }\\n .hw-hero {\\n background:\\n linear-gradient(\\n 160deg,\\n color-mix(in srgb, var(--hw-primary) 40%, black) 0%,\\n var(--hw-primary) 50%,\\n color-mix(in srgb, var(--hw-primary) 25%, black) 100%);\\n }\\n .hw-sheet {\\n background: var(--hw-bg);\\n }\\n .hw-card {\\n background: var(--hw-bg-hover);\\n border-color: var(--hw-border);\\n }\\n .hw-card:hover {\\n background: #333;\\n }\\n .hw-window {\\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.06);\\n }\\n .hw-bubble:focus-visible {\\n outline-color: var(--hw-text-3);\\n }\\n .hw-msg--visitor .hw-msg-bubble {\\n background: var(--hw-primary);\\n color: white;\\n }\\n .hw-msg-bubble code {\\n background: rgba(255, 255, 255, 0.08);\\n }\\n .hw-msg-bubble pre {\\n background: rgba(255, 255, 255, 0.08);\\n }\\n .hw-composer-box {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n .hw-composer-input {\\n color: var(--hw-text);\\n }\\n .hw-tabs {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n .hw-conv-card:hover,\\n .hw-recent-row:hover {\\n background: var(--hw-bg-hover);\\n }\\n .hw-disconnect {\\n background: #422006;\\n color: #fcd34d;\\n }\\n .hw-send-error {\\n background: #450a0a;\\n color: #fca5a5;\\n }\\n .hw-error-icon {\\n background: #450a0a;\\n color: #f87171;\\n }\\n .hw-resolved {\\n border-color: var(--hw-border);\\n }\\n .hw-resolved-reopen,\\n .hw-csat-btn {\\n background: var(--hw-bg-hover);\\n border-color: var(--hw-border-md);\\n color: var(--hw-text);\\n }\\n .hw-hover-preview {\\n background: #1c1c1e;\\n border-color: var(--hw-border);\\n }\\n .hw-content-search-box {\\n background: var(--hw-bg-hover);\\n border-color: var(--hw-border-md);\\n }\\n .hw-preview {\\n background: var(--hw-bg);\\n border-color: var(--hw-border);\\n }\\n}\\n\")","\"use client\";\n\n/**\n * `<HelpwayWidget />` — one-line drop-in React component that renders\n * the full Helpway widget natively in React.\n *\n * Since v0.2, this is a native React render (not a script tag injection).\n * The widget-core + widget-react code is bundled with your app, so widget\n * updates ship via `npm update @helpway/react` — no separate widget.js\n * deploy required. Bundle impact: ~120KB gzipped (shared with any other\n * helpway/react imports in your app, so subsequent uses are free).\n *\n * Power-user alternative: import `{ SupportProvider, DefaultWidget, useWidget, … }`\n * directly for programmatic control (render your own chat UI, expose\n * identify() via hook instead of global, etc.).\n *\n * @see https://helpway.ai/docs/quick-start for setup\n * @see https://helpway.ai/docs/react-sdk for the three integration layers\n * (drop-in, provider + hooks, fully headless)\n * @see https://helpway.ai/docs/customization for theming via `theme` prop\n * and the dashboard config\n * @see https://helpway.ai/docs/integration-notes for CSP, SSR, multi-tenant\n */\n\nimport type { WidgetTheme } from \"@helpway/widget-core\";\nimport { SupportProvider } from \"./provider\";\nimport { DefaultWidget } from \"./themed/default-widget\";\n// Auto-import CSS so consumers don't need a separate `import \"@helpway/react/styles.css\"` step.\n// Side-effect import — evaluated once per bundle, tree-shaker preserves it via `sideEffects: [\"*.css\"]`.\nimport \"./themed/styles.css\";\n\nexport interface HelpwayWidgetProps {\n\t/**\n\t * Public API key from the Helpway dashboard. Required.\n\t * Format: `pk_live_…` or `pk_test_…`.\n\t */\n\tapiKey: string;\n\t/**\n\t * Override the default API URL. Almost no one needs this —\n\t * exposed for staging / self-hosted setups.\n\t * @default \"https://api.helpway.ai\"\n\t */\n\tapiUrl?: string;\n\t/**\n\t * Widget locale (e.g. \"tr\", \"en\", \"de\"). Falls back to server-side\n\t * detection (Accept-Language + CF-IPCountry) then widget-core default.\n\t */\n\tlocale?: string;\n\t/**\n\t * Deep link: auto-open this conversation after bootstrap.\n\t * Usually sourced from `?hw_conv=` URL param for email CTAs.\n\t */\n\tinitialConversationId?: string;\n\t/**\n\t * Called once after the widget has bootstrapped and exposes\n\t * the full programmatic API object (also available as `window.Helpway`).\n\t */\n\tonReady?: (api: HelpwayPublicAPI) => void;\n\t/**\n\t * Hide the default floating launcher button. Use with\n\t * `customLauncherSelector` or `window.Helpway.open()` to trigger\n\t * the widget from your own UI.\n\t */\n\thideLauncher?: boolean;\n\t/**\n\t * CSS selector for a custom trigger element (e.g. `\"#support-btn\"`).\n\t * Clicking the matched element calls `Helpway.open()`. Combine with\n\t * `hideLauncher` to fully replace the default bubble.\n\t */\n\tcustomLauncherSelector?: string;\n\t/** Fires when the widget panel opens */\n\tonOpen?: () => void;\n\t/** Fires when the widget panel closes */\n\tonClose?: () => void;\n\t/** Fires when the unread count changes */\n\tonUnreadChange?: (count: number) => void;\n\t/**\n\t * Developer-side theme override. Most consumers should configure\n\t * appearance from the dashboard so changes apply without a redeploy\n\t * — see https://helpway.ai/docs/customization. Use this prop only\n\t * for runtime-resolved theming (multi-tenant brand colors, dark/\n\t * light sync with the host app, etc). Values map to CSS custom\n\t * properties on the widget host. See the `WidgetTheme` type for\n\t * the full set of supported keys.\n\t */\n\ttheme?: WidgetTheme;\n\t/**\n\t * @deprecated Legacy prop from the v0.1 script-loader era. If set,\n\t * the `/widget.js` suffix is stripped to derive `apiUrl`. New code\n\t * should use `apiUrl` instead.\n\t */\n\tsrc?: string;\n}\n\n// Re-export for consumers who use the onReady callback type.\n// `onReady` receives the programmatic methods object; the global\n// `window.Helpway` is the callable wrapper around it (HelpwayAPI).\nimport type { HelpwayMethods } from \"@helpway/widget-core\";\nexport type HelpwayPublicAPI = HelpwayMethods;\n\n/**\n * Render this once at the root of your app (e.g. in `_app.tsx`,\n * `layout.tsx`, or `main.tsx`). Unmounting cleanly tears down the\n * widget and its WebSocket connection — useful for route-scoped mounts.\n */\nexport function HelpwayWidget({\n\tapiKey,\n\tapiUrl,\n\tlocale,\n\tinitialConversationId,\n\tonReady,\n\thideLauncher,\n\tcustomLauncherSelector,\n\tonOpen,\n\tonClose,\n\tonUnreadChange,\n\ttheme,\n\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\tsrc,\n}: HelpwayWidgetProps) {\n\tconst resolvedApiUrl = apiUrl ?? (src ? src.replace(/\\/widget\\.js$/, \"\") : undefined);\n\n\treturn (\n\t\t<SupportProvider\n\t\t\tapiKey={apiKey}\n\t\t\tapiUrl={resolvedApiUrl}\n\t\t\tlocale={locale}\n\t\t\tinitialConversationId={initialConversationId}\n\t\t\tonReady={onReady}\n\t\t\tcustomLauncherSelector={customLauncherSelector}\n\t\t\tonOpen={onOpen}\n\t\t\tonClose={onClose}\n\t\t\tonUnreadChange={onUnreadChange}\n\t\t\ttheme={theme}\n\t\t>\n\t\t\t<DefaultWidget hideLauncher={hideLauncher} />\n\t\t</SupportProvider>\n\t);\n}\n","import { useEffect } from \"react\";\nimport type { RealtimeEvent } from \"@helpway/types\";\nimport { useWidgetContext } from \"../provider\";\n\n/**\n * Subscribe to raw WebSocket events.\n * For advanced usage — most apps should use useTimeline/usePresence instead.\n *\n * Usage:\n * ```tsx\n * useRealtime((event) => {\n * if (event.type === 'timelineItemCreated') { ... }\n * })\n * ```\n */\nexport function useRealtime(handler: (event: RealtimeEvent) => void) {\n\tconst { ws } = useWidgetContext();\n\n\tuseEffect(() => {\n\t\treturn ws.onEvent(handler);\n\t}, [ws, handler]);\n}\n"],"mappings":"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","names":["client","store","emitter","ws","identify","api","el","useCallback","useEffect","useRef","useState","useCallback","useState","useState","useCallback","useCallback","useRef","useState","useState","useRef","useCallback","store","useEffect","useState","useState","useEffect","useCallback","useRef","useRef","useCallback","useCallback","useEffect","useRef","useState","useState","useRef","useEffect","useCallback","useCallback","useRef","useState","jsx","jsx","jsx","jsx","jsx","useEffect","useRef","useState","useEffect","useRef","jsx","jsx","jsxs","useRef","useEffect","useState","jsx","jsxs","useRef","useCallback","useState","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useCallback","useEffect","useCallback","useEffect","useState","t","useState","useCallback","useEffect","Fragment","jsx","jsxs","useCallback","useRef","useState","jsx","jsxs","useEffect","useRef","useCallback","useRef","useState","EMPTY_TABS","detailKey","readCache","t","useState","useRef","useCallback","jsx","useEffect","useRef","jsx","useEffect","useCallback","jsx","useEffect","useRef","jsx","jsxs","useRef","useEffect","Fragment","jsx","jsxs","resolveLabel","c","useState","useRef","useEffect","useCallback","t","focusable","jsx","useEffect","useEffect"]}