@helpway/react 0.1.0 → 0.2.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 CHANGED
@@ -1,32 +1,3 @@
1
- // src/helpway-widget.tsx
2
- import { useEffect } from "react";
3
- function HelpwayWidget({
4
- apiKey,
5
- src = "https://api.helpway.ai/widget.js"
6
- }) {
7
- useEffect(() => {
8
- if (typeof document === "undefined") return;
9
- const existing = document.querySelector(
10
- `script[data-helpway-loader="${apiKey}"]`
11
- );
12
- if (existing) return;
13
- const s = document.createElement("script");
14
- s.src = src;
15
- s.dataset.key = apiKey;
16
- s.dataset.helpwayLoader = apiKey;
17
- s.defer = true;
18
- document.body.appendChild(s);
19
- return () => {
20
- s.remove();
21
- try {
22
- window.dispatchEvent(new CustomEvent("helpway:cleanup"));
23
- } catch {
24
- }
25
- };
26
- }, [apiKey, src]);
27
- return null;
28
- }
29
-
30
1
  // ../widget-core/src/client.ts
31
2
  import { createTRPCClient, httpBatchLink } from "@trpc/client";
32
3
 
@@ -740,7 +711,7 @@ import {
740
711
  createContext,
741
712
  useCallback,
742
713
  useContext,
743
- useEffect as useEffect2,
714
+ useEffect,
744
715
  useRef,
745
716
  useState
746
717
  } from "react";
@@ -811,7 +782,7 @@ function SupportProvider({
811
782
  setHasBootstrapError(false);
812
783
  setBootstrapAttempt((n) => n + 1);
813
784
  }, []);
814
- useEffect2(() => {
785
+ useEffect(() => {
815
786
  let cancelled = false;
816
787
  async function bootstrap() {
817
788
  try {
@@ -903,7 +874,7 @@ function SupportProvider({
903
874
  ws.disconnect();
904
875
  };
905
876
  }, [client, store, ws, bootstrapAttempt]);
906
- useEffect2(() => {
877
+ useEffect(() => {
907
878
  if (locale != null) {
908
879
  setLocale(locale);
909
880
  }
@@ -936,176 +907,20 @@ function inferApiUrl() {
936
907
  return typeof window !== "undefined" ? window.location.origin : "http://localhost:52500";
937
908
  }
938
909
 
939
- // src/hooks/use-widget.ts
940
- function useWidget() {
941
- const { client } = useWidgetContext();
942
- const isReady = useWidgetStore((s) => s.isReady);
943
- const isConnecting = useWidgetStore((s) => s.isConnecting);
944
- const visitor = useWidgetStore((s) => s.visitor);
945
- const website = useWidgetStore((s) => s.website);
946
- const agentConfig = useWidgetStore((s) => s.agentConfig);
947
- async function identify(data) {
948
- return client.widget.identify.mutate(data);
949
- }
950
- return { isReady, isConnecting, visitor, website, agentConfig, identify };
951
- }
952
-
953
- // src/hooks/use-conversations.ts
954
- import { useCallback as useCallback2, useRef as useRef2, useState as useState2 } from "react";
955
- function useConversations() {
956
- const { client, store } = useWidgetContext();
957
- const conversations = useWidgetStore((s) => s.conversations);
958
- const setActiveConversation = useWidgetStore((s) => s.setActiveConversation);
959
- const [isCreating, setIsCreating] = useState2(false);
960
- const clientRef = useRef2(client);
961
- const storeRef = useRef2(store);
962
- clientRef.current = client;
963
- storeRef.current = store;
964
- const create = useCallback2(async (text) => {
965
- setIsCreating(true);
966
- const tempConversationId = `temp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
967
- const now = (/* @__PURE__ */ new Date()).toISOString();
968
- const optimisticMessageId = `optimistic-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
969
- const currentVisitorId = storeRef.current.getState().visitor?.id ?? null;
970
- const optimisticMsg = {
971
- id: optimisticMessageId,
972
- conversationId: tempConversationId,
973
- organizationId: "",
974
- type: "message",
975
- visibility: "public",
976
- text,
977
- parts: null,
978
- userId: null,
979
- visitorId: currentVisitorId,
980
- aiAgentId: null,
981
- createdAt: now,
982
- editedAt: null,
983
- deletedAt: null
984
- };
985
- const store2 = storeRef.current.getState();
986
- store2.addConversation({
987
- id: tempConversationId,
988
- title: null,
989
- status: "open",
990
- lastMessageText: text,
991
- lastMessageAt: now,
992
- unreadCount: 0
993
- });
994
- store2.setMessages(tempConversationId, [optimisticMsg]);
995
- store2.setActiveConversation(tempConversationId);
996
- try {
997
- const result = await clientRef.current.widget.createConversation.mutate({ text });
998
- const conv = result.conversation;
999
- storeRef.current.getState().remapConversationId(tempConversationId, conv.id);
1000
- if (result.item) {
1001
- storeRef.current.getState().replaceMessage(conv.id, optimisticMessageId, result.item);
1002
- }
1003
- if (result.welcomeItem) {
1004
- const welcome = result.welcomeItem;
1005
- const existing = storeRef.current.getState().messages.get(conv.id) ?? [];
1006
- const withoutWelcome = existing.filter((m) => m.id !== welcome.id);
1007
- storeRef.current.getState().setMessages(conv.id, [welcome, ...withoutWelcome]);
1008
- }
1009
- return conv;
1010
- } catch (err) {
1011
- storeRef.current.getState().removeMessage(tempConversationId, optimisticMessageId);
1012
- const convs = storeRef.current.getState().conversations.filter((c) => c.id !== tempConversationId);
1013
- storeRef.current.setState({ conversations: convs, activeConversationId: null });
1014
- throw err;
1015
- } finally {
1016
- setIsCreating(false);
1017
- }
1018
- }, []);
1019
- return { conversations, create, isCreating, setActiveConversation };
1020
- }
1021
-
1022
- // src/hooks/use-timeline.ts
1023
- import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
1024
- var EMPTY_ITEMS = [];
1025
- function useTimeline(conversationId) {
1026
- const { client, store } = useWidgetContext();
1027
- const messages = useWidgetStore(
1028
- (s) => conversationId ? s.messages.get(conversationId) ?? EMPTY_ITEMS : EMPTY_ITEMS
1029
- );
1030
- const [isLoading, setIsLoading] = useState3(false);
1031
- const [hasMore, setHasMore] = useState3(false);
1032
- const cursorRef = useRef3(void 0);
1033
- const clientRef = useRef3(client);
1034
- const storeRef = useRef3(store);
1035
- clientRef.current = client;
1036
- storeRef.current = store;
1037
- useEffect3(() => {
1038
- if (!conversationId) return;
1039
- if (conversationId.startsWith("temp-")) return;
1040
- let cancelled = false;
1041
- const existingMessages = storeRef.current.getState().messages.get(conversationId);
1042
- const hasSeed = !!existingMessages && existingMessages.length > 0;
1043
- if (hasSeed) {
1044
- storeRef.current.getState().clearUnread(conversationId);
1045
- clientRef.current.widget.markSeen.mutate({ conversationId }).catch(() => {
1046
- });
1047
- return () => {
1048
- cancelled = true;
1049
- };
1050
- }
1051
- setIsLoading(true);
1052
- async function load() {
1053
- try {
1054
- const data = await clientRef.current.widget.getTimeline.query({
1055
- conversationId,
1056
- limit: 50
1057
- });
1058
- if (cancelled) return;
1059
- if (data.items.length > 0) {
1060
- storeRef.current.getState().setMessages(conversationId, data.items);
1061
- }
1062
- setHasMore(data.hasMore);
1063
- cursorRef.current = data.nextCursor ?? void 0;
1064
- storeRef.current.getState().clearUnread(conversationId);
1065
- clientRef.current.widget.markSeen.mutate({ conversationId }).catch(() => {
1066
- });
1067
- } catch (err) {
1068
- console.error("[useTimeline] Failed to load:", err);
1069
- } finally {
1070
- if (!cancelled) setIsLoading(false);
1071
- }
1072
- }
1073
- load();
1074
- return () => {
1075
- cancelled = true;
1076
- };
1077
- }, [conversationId]);
1078
- const loadMore = useCallback3(async () => {
1079
- if (!conversationId || !hasMore || isLoading) return;
1080
- setIsLoading(true);
1081
- try {
1082
- const data = await clientRef.current.widget.getTimeline.query({
1083
- conversationId,
1084
- cursor: cursorRef.current,
1085
- limit: 50
1086
- });
1087
- const existing = storeRef.current.getState().messages.get(conversationId) ?? [];
1088
- storeRef.current.getState().setMessages(conversationId, [...data.items, ...existing]);
1089
- setHasMore(data.hasMore);
1090
- cursorRef.current = data.nextCursor ?? void 0;
1091
- } finally {
1092
- setIsLoading(false);
1093
- }
1094
- }, [conversationId, hasMore, isLoading]);
1095
- return { items: messages, isLoading, hasMore, loadMore };
1096
- }
910
+ // src/themed/default-widget.tsx
911
+ import { useCallback as useCallback12, useEffect as useEffect10, useRef as useRef13, useState as useState12 } from "react";
1097
912
 
1098
913
  // src/hooks/use-composer.ts
1099
- import { useCallback as useCallback4, useState as useState4 } from "react";
914
+ import { useCallback as useCallback2, useState as useState2 } from "react";
1100
915
  var MAX_ATTACHMENTS = 10;
1101
916
  var MAX_FILE_SIZE = 10 * 1024 * 1024;
1102
917
  function useComposer(conversationId) {
1103
918
  const { client, ws, store } = useWidgetContext();
1104
- const [text, setText] = useState4("");
1105
- const [isSubmitting, setIsSubmitting] = useState4(false);
1106
- const [attachments, setAttachments] = useState4([]);
1107
- const [sendError, setSendError] = useState4(null);
1108
- const addFiles = useCallback4(
919
+ const [text, setText] = useState2("");
920
+ const [isSubmitting, setIsSubmitting] = useState2(false);
921
+ const [attachments, setAttachments] = useState2([]);
922
+ const [sendError, setSendError] = useState2(null);
923
+ const addFiles = useCallback2(
1109
924
  async (files) => {
1110
925
  if (!conversationId) return;
1111
926
  const remaining = MAX_ATTACHMENTS - attachments.length;
@@ -1148,14 +963,14 @@ function useComposer(conversationId) {
1148
963
  },
1149
964
  [conversationId, attachments.length, client]
1150
965
  );
1151
- const removeAttachment = useCallback4((id) => {
966
+ const removeAttachment = useCallback2((id) => {
1152
967
  setAttachments((prev) => {
1153
968
  const item = prev.find((a) => a.id === id);
1154
969
  if (item?.previewUrl) URL.revokeObjectURL(item.previewUrl);
1155
970
  return prev.filter((a) => a.id !== id);
1156
971
  });
1157
972
  }, []);
1158
- const submit = useCallback4(async () => {
973
+ const submit = useCallback2(async () => {
1159
974
  const trimmed = text.trim();
1160
975
  const readyParts = attachments.filter((a) => a.part !== null).map((a) => a.part);
1161
976
  const hasText = trimmed.length > 0;
@@ -1232,7 +1047,7 @@ function useComposer(conversationId) {
1232
1047
  setIsSubmitting(false);
1233
1048
  }
1234
1049
  }, [text, attachments, conversationId, isSubmitting, client, ws, store]);
1235
- const clearSendError = useCallback4(() => setSendError(null), []);
1050
+ const clearSendError = useCallback2(() => setSendError(null), []);
1236
1051
  return {
1237
1052
  text,
1238
1053
  setText,
@@ -1259,8 +1074,89 @@ function fileToBase64(file) {
1259
1074
  });
1260
1075
  }
1261
1076
 
1077
+ // src/hooks/use-conversations.ts
1078
+ import { useCallback as useCallback3, useRef as useRef2, useState as useState3 } from "react";
1079
+ function useConversations() {
1080
+ const { client, store } = useWidgetContext();
1081
+ const conversations = useWidgetStore((s) => s.conversations);
1082
+ const setActiveConversation = useWidgetStore((s) => s.setActiveConversation);
1083
+ const [isCreating, setIsCreating] = useState3(false);
1084
+ const clientRef = useRef2(client);
1085
+ const storeRef = useRef2(store);
1086
+ clientRef.current = client;
1087
+ storeRef.current = store;
1088
+ const create = useCallback3(async (text) => {
1089
+ setIsCreating(true);
1090
+ const tempConversationId = `temp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
1091
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1092
+ const optimisticMessageId = `optimistic-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
1093
+ const currentVisitorId = storeRef.current.getState().visitor?.id ?? null;
1094
+ const optimisticMsg = {
1095
+ id: optimisticMessageId,
1096
+ conversationId: tempConversationId,
1097
+ organizationId: "",
1098
+ type: "message",
1099
+ visibility: "public",
1100
+ text,
1101
+ parts: null,
1102
+ userId: null,
1103
+ visitorId: currentVisitorId,
1104
+ aiAgentId: null,
1105
+ createdAt: now,
1106
+ editedAt: null,
1107
+ deletedAt: null
1108
+ };
1109
+ const store2 = storeRef.current.getState();
1110
+ store2.addConversation({
1111
+ id: tempConversationId,
1112
+ title: null,
1113
+ status: "open",
1114
+ lastMessageText: text,
1115
+ lastMessageAt: now,
1116
+ unreadCount: 0
1117
+ });
1118
+ store2.setMessages(tempConversationId, [optimisticMsg]);
1119
+ store2.setActiveConversation(tempConversationId);
1120
+ try {
1121
+ const result = await clientRef.current.widget.createConversation.mutate({ text });
1122
+ const conv = result.conversation;
1123
+ storeRef.current.getState().remapConversationId(tempConversationId, conv.id);
1124
+ if (result.item) {
1125
+ storeRef.current.getState().replaceMessage(conv.id, optimisticMessageId, result.item);
1126
+ }
1127
+ if (result.welcomeItem) {
1128
+ const welcome = result.welcomeItem;
1129
+ const existing = storeRef.current.getState().messages.get(conv.id) ?? [];
1130
+ const withoutWelcome = existing.filter((m) => m.id !== welcome.id);
1131
+ storeRef.current.getState().setMessages(conv.id, [welcome, ...withoutWelcome]);
1132
+ }
1133
+ return conv;
1134
+ } catch (err) {
1135
+ storeRef.current.getState().removeMessage(tempConversationId, optimisticMessageId);
1136
+ const convs = storeRef.current.getState().conversations.filter((c) => c.id !== tempConversationId);
1137
+ storeRef.current.setState({ conversations: convs, activeConversationId: null });
1138
+ throw err;
1139
+ } finally {
1140
+ setIsCreating(false);
1141
+ }
1142
+ }, []);
1143
+ return { conversations, create, isCreating, setActiveConversation };
1144
+ }
1145
+
1146
+ // src/hooks/use-i18n.ts
1147
+ import { useEffect as useEffect2, useState as useState4 } from "react";
1148
+ function useI18n() {
1149
+ const [rev, setRev] = useState4(() => getI18nRevision());
1150
+ useEffect2(() => {
1151
+ return onLocaleChange(() => {
1152
+ setRev(getI18nRevision());
1153
+ });
1154
+ }, []);
1155
+ return rev;
1156
+ }
1157
+
1262
1158
  // src/hooks/use-presence.ts
1263
- import { useCallback as useCallback5, useRef as useRef4 } from "react";
1159
+ import { useCallback as useCallback4, useRef as useRef3 } from "react";
1264
1160
  function usePresence(conversationId) {
1265
1161
  const { ws } = useWidgetContext();
1266
1162
  const isTyping = useWidgetStore(
@@ -1269,9 +1165,9 @@ function usePresence(conversationId) {
1269
1165
  const isAiProcessing = useWidgetStore(
1270
1166
  (s) => conversationId ? s.aiProcessing.get(conversationId) ?? false : false
1271
1167
  );
1272
- const typingTimer = useRef4(null);
1273
- const isSendingTyping = useRef4(false);
1274
- const setTyping = useCallback5(
1168
+ const typingTimer = useRef3(null);
1169
+ const isSendingTyping = useRef3(false);
1170
+ const setTyping = useCallback4(
1275
1171
  (typing) => {
1276
1172
  if (!conversationId) return;
1277
1173
  if (typingTimer.current) clearTimeout(typingTimer.current);
@@ -1296,6 +1192,82 @@ function usePresence(conversationId) {
1296
1192
  return { isTyping, isAiProcessing, setTyping };
1297
1193
  }
1298
1194
 
1195
+ // src/hooks/use-timeline.ts
1196
+ import { useCallback as useCallback5, useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
1197
+ var EMPTY_ITEMS = [];
1198
+ function useTimeline(conversationId) {
1199
+ const { client, store } = useWidgetContext();
1200
+ const messages = useWidgetStore(
1201
+ (s) => conversationId ? s.messages.get(conversationId) ?? EMPTY_ITEMS : EMPTY_ITEMS
1202
+ );
1203
+ const [isLoading, setIsLoading] = useState5(false);
1204
+ const [hasMore, setHasMore] = useState5(false);
1205
+ const cursorRef = useRef4(void 0);
1206
+ const clientRef = useRef4(client);
1207
+ const storeRef = useRef4(store);
1208
+ clientRef.current = client;
1209
+ storeRef.current = store;
1210
+ useEffect3(() => {
1211
+ if (!conversationId) return;
1212
+ if (conversationId.startsWith("temp-")) return;
1213
+ let cancelled = false;
1214
+ const existingMessages = storeRef.current.getState().messages.get(conversationId);
1215
+ const hasSeed = !!existingMessages && existingMessages.length > 0;
1216
+ if (hasSeed) {
1217
+ storeRef.current.getState().clearUnread(conversationId);
1218
+ clientRef.current.widget.markSeen.mutate({ conversationId }).catch(() => {
1219
+ });
1220
+ return () => {
1221
+ cancelled = true;
1222
+ };
1223
+ }
1224
+ setIsLoading(true);
1225
+ async function load() {
1226
+ try {
1227
+ const data = await clientRef.current.widget.getTimeline.query({
1228
+ conversationId,
1229
+ limit: 50
1230
+ });
1231
+ if (cancelled) return;
1232
+ if (data.items.length > 0) {
1233
+ storeRef.current.getState().setMessages(conversationId, data.items);
1234
+ }
1235
+ setHasMore(data.hasMore);
1236
+ cursorRef.current = data.nextCursor ?? void 0;
1237
+ storeRef.current.getState().clearUnread(conversationId);
1238
+ clientRef.current.widget.markSeen.mutate({ conversationId }).catch(() => {
1239
+ });
1240
+ } catch (err) {
1241
+ console.error("[useTimeline] Failed to load:", err);
1242
+ } finally {
1243
+ if (!cancelled) setIsLoading(false);
1244
+ }
1245
+ }
1246
+ load();
1247
+ return () => {
1248
+ cancelled = true;
1249
+ };
1250
+ }, [conversationId]);
1251
+ const loadMore = useCallback5(async () => {
1252
+ if (!conversationId || !hasMore || isLoading) return;
1253
+ setIsLoading(true);
1254
+ try {
1255
+ const data = await clientRef.current.widget.getTimeline.query({
1256
+ conversationId,
1257
+ cursor: cursorRef.current,
1258
+ limit: 50
1259
+ });
1260
+ const existing = storeRef.current.getState().messages.get(conversationId) ?? [];
1261
+ storeRef.current.getState().setMessages(conversationId, [...data.items, ...existing]);
1262
+ setHasMore(data.hasMore);
1263
+ cursorRef.current = data.nextCursor ?? void 0;
1264
+ } finally {
1265
+ setIsLoading(false);
1266
+ }
1267
+ }, [conversationId, hasMore, isLoading]);
1268
+ return { items: messages, isLoading, hasMore, loadMore };
1269
+ }
1270
+
1299
1271
  // src/hooks/use-unread.ts
1300
1272
  function useUnread() {
1301
1273
  const totalUnread = useWidgetStore(
@@ -1304,28 +1276,18 @@ function useUnread() {
1304
1276
  return { totalUnread };
1305
1277
  }
1306
1278
 
1307
- // src/hooks/use-realtime.ts
1308
- import { useEffect as useEffect4 } from "react";
1309
- function useRealtime(handler) {
1310
- const { ws } = useWidgetContext();
1311
- useEffect4(() => {
1312
- return ws.onEvent(handler);
1313
- }, [ws, handler]);
1314
- }
1315
-
1316
- // src/themed/default-widget.tsx
1317
- import { useCallback as useCallback12, useEffect as useEffect12, useRef as useRef13, useState as useState12 } from "react";
1318
-
1319
- // src/hooks/use-i18n.ts
1320
- import { useEffect as useEffect5, useState as useState5 } from "react";
1321
- function useI18n() {
1322
- const [rev, setRev] = useState5(() => getI18nRevision());
1323
- useEffect5(() => {
1324
- return onLocaleChange(() => {
1325
- setRev(getI18nRevision());
1326
- });
1327
- }, []);
1328
- return rev;
1279
+ // src/hooks/use-widget.ts
1280
+ function useWidget() {
1281
+ const { client } = useWidgetContext();
1282
+ const isReady = useWidgetStore((s) => s.isReady);
1283
+ const isConnecting = useWidgetStore((s) => s.isConnecting);
1284
+ const visitor = useWidgetStore((s) => s.visitor);
1285
+ const website = useWidgetStore((s) => s.website);
1286
+ const agentConfig = useWidgetStore((s) => s.agentConfig);
1287
+ async function identify(data) {
1288
+ return client.widget.identify.mutate(data);
1289
+ }
1290
+ return { isReady, isConnecting, visitor, website, agentConfig, identify };
1329
1291
  }
1330
1292
 
1331
1293
  // src/themed/composer.tsx
@@ -1359,7 +1321,7 @@ import { useCallback as useCallback6, useLayoutEffect, useRef as useRef6, useSta
1359
1321
  import { createPortal } from "react-dom";
1360
1322
 
1361
1323
  // src/themed/content/simple-markdown.tsx
1362
- import { useEffect as useEffect6, useRef as useRef5 } from "react";
1324
+ import { useEffect as useEffect4, useRef as useRef5 } from "react";
1363
1325
  import { jsx as jsx2 } from "react/jsx-runtime";
1364
1326
  function renderMarkdown(md) {
1365
1327
  const codeBlocks = [];
@@ -1421,7 +1383,7 @@ function MarkdownContent({
1421
1383
  }) {
1422
1384
  const rootRef = useRef5(null);
1423
1385
  const html = bodyHtml ?? (bodyMarkdown ? renderMarkdown(bodyMarkdown) : "");
1424
- useEffect6(() => {
1386
+ useEffect4(() => {
1425
1387
  const root = rootRef.current;
1426
1388
  if (!root) return;
1427
1389
  const handler = (e) => {
@@ -1929,7 +1891,7 @@ function extractFiles(data) {
1929
1891
  }
1930
1892
 
1931
1893
  // src/themed/debug-overlay.tsx
1932
- import { useEffect as useEffect7, useMemo, useRef as useRef8, useState as useState8 } from "react";
1894
+ import { useEffect as useEffect5, useMemo, useRef as useRef8, useState as useState8 } from "react";
1933
1895
  import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1934
1896
  var MAX_EVENTS = 60;
1935
1897
  function isDebugEnabled() {
@@ -1956,7 +1918,7 @@ function WidgetDebugOverlay() {
1956
1918
  const typingUsers = useWidgetStore((s) => s.typingUsers);
1957
1919
  const aiProcessingMap = useWidgetStore((s) => s.aiProcessing);
1958
1920
  const { store } = useWidgetContext();
1959
- useEffect7(() => {
1921
+ useEffect5(() => {
1960
1922
  setEnabled(isDebugEnabled());
1961
1923
  }, []);
1962
1924
  const pushEvent = useMemo(
@@ -1971,7 +1933,7 @@ function WidgetDebugOverlay() {
1971
1933
  },
1972
1934
  []
1973
1935
  );
1974
- useEffect7(() => {
1936
+ useEffect5(() => {
1975
1937
  if (!enabled) return;
1976
1938
  if (typeof window === "undefined" || typeof window.fetch !== "function") return;
1977
1939
  const originalFetch = window.fetch.bind(window);
@@ -2003,7 +1965,7 @@ function WidgetDebugOverlay() {
2003
1965
  window.fetch = originalFetch;
2004
1966
  };
2005
1967
  }, [enabled, pushEvent]);
2006
- useEffect7(() => {
1968
+ useEffect5(() => {
2007
1969
  if (!enabled) return;
2008
1970
  const original = store.getState().handleRealtimeEvent;
2009
1971
  store.setState({
@@ -2022,7 +1984,7 @@ function WidgetDebugOverlay() {
2022
1984
  [activeMessages]
2023
1985
  );
2024
1986
  const prevSigRef = useRef8(lastMsgSignature);
2025
- useEffect7(() => {
1987
+ useEffect5(() => {
2026
1988
  if (!enabled) return;
2027
1989
  if (prevSigRef.current !== lastMsgSignature) {
2028
1990
  prevSigRef.current = lastMsgSignature;
@@ -2175,10 +2137,10 @@ var styles = {
2175
2137
  };
2176
2138
 
2177
2139
  // src/themed/content/content-tab-view.tsx
2178
- import { useCallback as useCallback11, useEffect as useEffect10 } from "react";
2140
+ import { useCallback as useCallback11, useEffect as useEffect8 } from "react";
2179
2141
 
2180
2142
  // src/hooks/use-content-tab.ts
2181
- import { useCallback as useCallback8, useEffect as useEffect8, useState as useState9 } from "react";
2143
+ import { useCallback as useCallback8, useEffect as useEffect6, useState as useState9 } from "react";
2182
2144
  var EMPTY_TABS = [];
2183
2145
  function listKey(tabId, lang) {
2184
2146
  return `flat:${tabId}:${lang}:list`;
@@ -2293,7 +2255,7 @@ function useContentTab(tabId) {
2293
2255
  const clearDetail = useCallback8(() => {
2294
2256
  setDetail(null);
2295
2257
  }, []);
2296
- useEffect8(() => {
2258
+ useEffect6(() => {
2297
2259
  if (tab && entries.length === 0) {
2298
2260
  fetchEntries({ page: 1, reset: true });
2299
2261
  }
@@ -2439,7 +2401,7 @@ function ContentEntryCard({
2439
2401
  }
2440
2402
 
2441
2403
  // src/themed/content/grouped-content-tab-view.tsx
2442
- import { useEffect as useEffect9, useRef as useRef11 } from "react";
2404
+ import { useEffect as useEffect7, useRef as useRef11 } from "react";
2443
2405
 
2444
2406
  // src/hooks/use-grouped-content-tab.ts
2445
2407
  import { useCallback as useCallback10, useRef as useRef10, useState as useState11 } from "react";
@@ -2683,16 +2645,16 @@ function GroupedContentTabView({
2683
2645
  fetchDetail,
2684
2646
  clearCategory
2685
2647
  } = useGroupedContentTab(tab.id);
2686
- useEffect9(() => {
2648
+ useEffect7(() => {
2687
2649
  initFetch();
2688
2650
  }, [initFetch]);
2689
- useEffect9(() => {
2651
+ useEffect7(() => {
2690
2652
  if (detailSlug && subView === "content-detail") {
2691
2653
  fetchDetail(detailSlug);
2692
2654
  }
2693
2655
  }, [detailSlug, subView, fetchDetail]);
2694
2656
  const prevSubView = useRef11(subView);
2695
- useEffect9(() => {
2657
+ useEffect7(() => {
2696
2658
  if (prevSubView.current === "content-category" && subView === null) {
2697
2659
  clearCategory();
2698
2660
  }
@@ -2786,7 +2748,7 @@ function FlatContentTabView({
2786
2748
  loadMore,
2787
2749
  fetchDetail
2788
2750
  } = useContentTab(tab.id);
2789
- useEffect10(() => {
2751
+ useEffect8(() => {
2790
2752
  if (detailSlug) fetchDetail(detailSlug);
2791
2753
  }, [detailSlug, fetchDetail]);
2792
2754
  const handleSearch = useCallback11(
@@ -2829,7 +2791,7 @@ function ContentTabIconComponent({ icon }) {
2829
2791
  }
2830
2792
 
2831
2793
  // src/themed/message-list.tsx
2832
- import React, { useEffect as useEffect11, useRef as useRef12 } from "react";
2794
+ import React, { useEffect as useEffect9, useRef as useRef12 } from "react";
2833
2795
  import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
2834
2796
  function parseParts(raw) {
2835
2797
  if (!raw) return null;
@@ -2857,7 +2819,7 @@ function MessageList({
2857
2819
  const prevItemCountRef = useRef12(items.length);
2858
2820
  const isInitialLoadRef = useRef12(true);
2859
2821
  const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? t("widget.better_ai");
2860
- useEffect11(() => {
2822
+ useEffect9(() => {
2861
2823
  const prevCount = prevItemCountRef.current;
2862
2824
  const newCount = items.length;
2863
2825
  prevItemCountRef.current = newCount;
@@ -2872,12 +2834,12 @@ function MessageList({
2872
2834
  isInitialLoadRef.current = false;
2873
2835
  }
2874
2836
  }, [items]);
2875
- useEffect11(() => {
2837
+ useEffect9(() => {
2876
2838
  if (isTyping || isAiProcessing) {
2877
2839
  bottomRef.current?.scrollIntoView({ behavior: "smooth" });
2878
2840
  }
2879
2841
  }, [isTyping, isAiProcessing]);
2880
- useEffect11(() => {
2842
+ useEffect9(() => {
2881
2843
  if (!hasMore || !onLoadMore || !topRef.current) return;
2882
2844
  const observer = new IntersectionObserver(
2883
2845
  (entries) => {
@@ -3313,7 +3275,7 @@ function DefaultWidget({ initialOpen = false } = {}) {
3313
3275
  handleClose();
3314
3276
  }
3315
3277
  }, [handleClose]);
3316
- useEffect12(() => {
3278
+ useEffect10(() => {
3317
3279
  if (!isOpen || !windowRef.current) return;
3318
3280
  const vv = window.visualViewport;
3319
3281
  if (!vv) return;
@@ -3330,7 +3292,7 @@ function DefaultWidget({ initialOpen = false } = {}) {
3330
3292
  win.style.removeProperty("--hw-visible-height");
3331
3293
  };
3332
3294
  }, [isOpen]);
3333
- useEffect12(() => {
3295
+ useEffect10(() => {
3334
3296
  if (!isOpen || !windowRef.current) return;
3335
3297
  const win = windowRef.current;
3336
3298
  const handleKeyDown = (e) => {
@@ -3346,7 +3308,7 @@ function DefaultWidget({ initialOpen = false } = {}) {
3346
3308
  win.addEventListener("keydown", handleKeyDown);
3347
3309
  return () => win.removeEventListener("keydown", handleKeyDown);
3348
3310
  }, [isOpen, subView, handleClose, goBack]);
3349
- useEffect12(() => {
3311
+ useEffect10(() => {
3350
3312
  if (!isOpen || !windowRef.current) return;
3351
3313
  const win = windowRef.current;
3352
3314
  const getFocusable = () => win.querySelectorAll(
@@ -4091,7 +4053,7 @@ function MessagePreview({ onOpen }) {
4091
4053
  const dismissPreview = useWidgetStore((s) => s.dismissPreview);
4092
4054
  const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
4093
4055
  const [closing, setClosing] = useState12(false);
4094
- useEffect12(() => {
4056
+ useEffect10(() => {
4095
4057
  if (!preview) return;
4096
4058
  const timer = setTimeout(() => {
4097
4059
  setClosing(true);
@@ -4139,6 +4101,65 @@ function MessagePreview({ onOpen }) {
4139
4101
  }
4140
4102
  );
4141
4103
  }
4104
+
4105
+ // #style-inject:#style-inject
4106
+ function styleInject(css, { insertAt } = {}) {
4107
+ if (!css || typeof document === "undefined") return;
4108
+ const head = document.head || document.getElementsByTagName("head")[0];
4109
+ const style = document.createElement("style");
4110
+ style.type = "text/css";
4111
+ if (insertAt === "top") {
4112
+ if (head.firstChild) {
4113
+ head.insertBefore(style, head.firstChild);
4114
+ } else {
4115
+ head.appendChild(style);
4116
+ }
4117
+ } else {
4118
+ head.appendChild(style);
4119
+ }
4120
+ if (style.styleSheet) {
4121
+ style.styleSheet.cssText = css;
4122
+ } else {
4123
+ style.appendChild(document.createTextNode(css));
4124
+ }
4125
+ }
4126
+
4127
+ // src/themed/styles.css
4128
+ 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.hw-widget {\n --hw-primary: #171717;\n --hw-primary-hover: #2a2a2a;\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}\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-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-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}\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-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-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}\n.hw-msg-meta {\n font-size: 11px;\n color: var(--hw-text-3);\n margin-top: 3px;\n padding: 0 4px;\n opacity: 0;\n transition: opacity 0.15s;\n font-variant-numeric: tabular-nums;\n}\n.hw-msg:hover .hw-msg-meta,\n.hw-msg:focus-within .hw-msg-meta {\n opacity: 1;\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-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-surface, #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-brand, #0a0a0a);\n display: flex;\n align-items: center;\n justify-content: center;\n color: #fff;\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-muted, #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, #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;\n}\n.hw-email-card-input:focus {\n border-color: var(--hw-brand, #0a0a0a);\n box-shadow: 0 0 0 2px 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: #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-muted, #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: 120px;\n background: transparent;\n color: var(--hw-text);\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: #e0e0e0;\n color: #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.34, 1.56, 0.64, 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}\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: 20px 0 8px;\n}\n.hw-markdown h2 {\n font-size: 15px;\n font-weight: 600;\n margin: 16px 0 6px;\n}\n.hw-markdown h3 {\n font-size: 14px;\n font-weight: 600;\n margin: 12px 0 4px;\n}\n.hw-markdown p {\n margin: 0 0 12px;\n}\n.hw-markdown ul {\n margin: 0 0 12px;\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 padding: 6px 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-copy {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n font-size: 11px;\n font-family: inherit;\n color: var(--hw-text-2, #6b7280);\n background: transparent;\n border: 1px solid transparent;\n border-radius: 5px;\n cursor: pointer;\n transition: background 120ms ease, color 120ms ease;\n}\n.hw-code-copy:hover {\n color: var(--hw-text, #111);\n background: rgba(0, 0, 0, 0.06);\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}\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-copy:hover {\n background: rgba(255, 255, 255, 0.08);\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--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 .hw-msg-meta {\n opacity: 1;\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-msg-copy {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n margin-left: 4px;\n border: none;\n border-radius: 4px;\n background: none;\n color: var(--hw-text-4);\n cursor: pointer;\n vertical-align: middle;\n transition: color 0.15s, background 0.15s;\n padding: 0;\n flex-shrink: 0;\n}\n.hw-msg-copy:hover {\n background: var(--hw-bg-hover);\n color: var(--hw-text-2);\n}\n.hw-msg-copy svg {\n width: 12px;\n height: 12px;\n}\n.hw-msg-copy--done {\n color: #22c55e;\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}\n@media (prefers-color-scheme: dark) {\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 }\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-msg-copy:hover {\n background: var(--hw-bg-hover);\n color: var(--hw-text-2);\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');
4129
+
4130
+ // src/helpway-widget.tsx
4131
+ import { jsx as jsx13 } from "react/jsx-runtime";
4132
+ function HelpwayWidget({
4133
+ apiKey,
4134
+ apiUrl,
4135
+ locale,
4136
+ initialConversationId,
4137
+ onReady,
4138
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
4139
+ src
4140
+ }) {
4141
+ const resolvedApiUrl = apiUrl ?? (src ? src.replace(/\/widget\.js$/, "") : void 0);
4142
+ return /* @__PURE__ */ jsx13(
4143
+ SupportProvider,
4144
+ {
4145
+ apiKey,
4146
+ apiUrl: resolvedApiUrl,
4147
+ locale,
4148
+ initialConversationId,
4149
+ onReady,
4150
+ children: /* @__PURE__ */ jsx13(DefaultWidget, {})
4151
+ }
4152
+ );
4153
+ }
4154
+
4155
+ // src/hooks/use-realtime.ts
4156
+ import { useEffect as useEffect11 } from "react";
4157
+ function useRealtime(handler) {
4158
+ const { ws } = useWidgetContext();
4159
+ useEffect11(() => {
4160
+ return ws.onEvent(handler);
4161
+ }, [ws, handler]);
4162
+ }
4142
4163
  export {
4143
4164
  Composer,
4144
4165
  DefaultWidget,