@helpway/react 0.9.0 → 0.11.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.d.ts +125 -1
- package/dist/index.js +860 -458
- package/dist/index.js.map +1 -1
- package/package.json +1 -3
- package/src/themed/styles.css +246 -3
package/dist/index.js
CHANGED
|
@@ -17,17 +17,17 @@ function generateId() {
|
|
|
17
17
|
}
|
|
18
18
|
function getOrCreateVisitorId(publicKey) {
|
|
19
19
|
try {
|
|
20
|
-
const
|
|
21
|
-
const existing = localStorage.getItem(
|
|
20
|
+
const storageKey2 = keyFor(publicKey);
|
|
21
|
+
const existing = localStorage.getItem(storageKey2);
|
|
22
22
|
if (existing) return existing;
|
|
23
23
|
const legacy = localStorage.getItem(LEGACY_KEY);
|
|
24
24
|
if (legacy) {
|
|
25
|
-
localStorage.setItem(
|
|
25
|
+
localStorage.setItem(storageKey2, legacy);
|
|
26
26
|
localStorage.removeItem(LEGACY_KEY);
|
|
27
27
|
return legacy;
|
|
28
28
|
}
|
|
29
29
|
const id = generateId();
|
|
30
|
-
localStorage.setItem(
|
|
30
|
+
localStorage.setItem(storageKey2, id);
|
|
31
31
|
return id;
|
|
32
32
|
} catch {
|
|
33
33
|
return generateId();
|
|
@@ -223,8 +223,29 @@ var WebSocketManager = class {
|
|
|
223
223
|
// ../widget-core/src/store.ts
|
|
224
224
|
import { createStore } from "zustand/vanilla";
|
|
225
225
|
var CONTENT_CACHE_TTL = 5 * 60 * 1e3;
|
|
226
|
+
var PREVIEW_STORAGE_KEY = "helpway:incoming-preview";
|
|
227
|
+
function loadPersistedPreview() {
|
|
228
|
+
if (typeof window === "undefined") return null;
|
|
229
|
+
try {
|
|
230
|
+
const raw = window.localStorage.getItem(PREVIEW_STORAGE_KEY);
|
|
231
|
+
return raw ? JSON.parse(raw) : null;
|
|
232
|
+
} catch {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function persistPreview(preview) {
|
|
237
|
+
if (typeof window === "undefined") return;
|
|
238
|
+
try {
|
|
239
|
+
if (preview) {
|
|
240
|
+
window.localStorage.setItem(PREVIEW_STORAGE_KEY, JSON.stringify(preview));
|
|
241
|
+
} else {
|
|
242
|
+
window.localStorage.removeItem(PREVIEW_STORAGE_KEY);
|
|
243
|
+
}
|
|
244
|
+
} catch {
|
|
245
|
+
}
|
|
246
|
+
}
|
|
226
247
|
function createWidgetStore() {
|
|
227
|
-
|
|
248
|
+
const store = createStore((set, get) => ({
|
|
228
249
|
// Initial state
|
|
229
250
|
isReady: false,
|
|
230
251
|
isConnecting: true,
|
|
@@ -240,7 +261,9 @@ function createWidgetStore() {
|
|
|
240
261
|
isOpen: false,
|
|
241
262
|
isDismissed: false,
|
|
242
263
|
view: "home",
|
|
243
|
-
incomingPreview:
|
|
264
|
+
incomingPreview: loadPersistedPreview(),
|
|
265
|
+
announcementPreviews: [],
|
|
266
|
+
unseenAnnouncementCount: 0,
|
|
244
267
|
newConversationPrefill: null,
|
|
245
268
|
contentCache: /* @__PURE__ */ new Map(),
|
|
246
269
|
// ── Lifecycle ────────────────────────────────────
|
|
@@ -407,7 +430,8 @@ function createWidgetStore() {
|
|
|
407
430
|
setOpen(open) {
|
|
408
431
|
set((s) => ({
|
|
409
432
|
isOpen: open,
|
|
410
|
-
incomingPreview: open ? null : s.incomingPreview
|
|
433
|
+
incomingPreview: open ? null : s.incomingPreview,
|
|
434
|
+
announcementPreviews: open ? [] : s.announcementPreviews
|
|
411
435
|
}));
|
|
412
436
|
},
|
|
413
437
|
setDismissed(dismissed) {
|
|
@@ -422,6 +446,27 @@ function createWidgetStore() {
|
|
|
422
446
|
dismissPreview() {
|
|
423
447
|
set({ incomingPreview: null });
|
|
424
448
|
},
|
|
449
|
+
// ── Announcements ────────────────────────────────
|
|
450
|
+
setAnnouncementPreview(preview) {
|
|
451
|
+
set((s) => ({
|
|
452
|
+
announcementPreviews: [
|
|
453
|
+
...s.announcementPreviews.filter((p) => p.tabId !== preview.tabId),
|
|
454
|
+
preview
|
|
455
|
+
]
|
|
456
|
+
}));
|
|
457
|
+
},
|
|
458
|
+
dismissAnnouncementPreview(slug) {
|
|
459
|
+
if (slug) {
|
|
460
|
+
set((s) => ({
|
|
461
|
+
announcementPreviews: s.announcementPreviews.filter((p) => p.slug !== slug)
|
|
462
|
+
}));
|
|
463
|
+
} else {
|
|
464
|
+
set({ announcementPreviews: [] });
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
setUnseenAnnouncementCount(count) {
|
|
468
|
+
set({ unseenAnnouncementCount: count });
|
|
469
|
+
},
|
|
425
470
|
// ── Content Cache ────────────────────────────────
|
|
426
471
|
setContentCache(key, data) {
|
|
427
472
|
get().contentCache.set(key, { data, ts: Date.now() });
|
|
@@ -530,6 +575,16 @@ function createWidgetStore() {
|
|
|
530
575
|
}
|
|
531
576
|
}
|
|
532
577
|
}));
|
|
578
|
+
if (typeof window !== "undefined") {
|
|
579
|
+
let last = store.getState().incomingPreview;
|
|
580
|
+
store.subscribe((s) => {
|
|
581
|
+
if (s.incomingPreview !== last) {
|
|
582
|
+
last = s.incomingPreview;
|
|
583
|
+
persistPreview(s.incomingPreview);
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
return store;
|
|
533
588
|
}
|
|
534
589
|
|
|
535
590
|
// ../widget-core/src/api.ts
|
|
@@ -707,6 +762,8 @@ var en = {
|
|
|
707
762
|
"widget.reply_time": "We typically reply in a few minutes",
|
|
708
763
|
"widget.recent_conversations": "Recent conversations",
|
|
709
764
|
"widget.see_all": "See all conversations",
|
|
765
|
+
"widget.whats_new": "What's New",
|
|
766
|
+
"widget.view_all": "View all",
|
|
710
767
|
// Messages tab
|
|
711
768
|
"widget.no_messages": "No messages yet",
|
|
712
769
|
"widget.no_messages_desc": "Start a conversation to get help",
|
|
@@ -1353,10 +1410,171 @@ function inferApiUrl() {
|
|
|
1353
1410
|
}
|
|
1354
1411
|
|
|
1355
1412
|
// src/themed/default-widget.tsx
|
|
1356
|
-
import { useCallback as
|
|
1413
|
+
import { useCallback as useCallback12, useEffect as useEffect13, useRef as useRef14, useState as useState14 } from "react";
|
|
1414
|
+
|
|
1415
|
+
// src/hooks/use-announcements.ts
|
|
1416
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useRef as useRef2 } from "react";
|
|
1417
|
+
function storageKey(websiteId, visitorId) {
|
|
1418
|
+
return `helpway:${websiteId}:${visitorId}:announcements:seen`;
|
|
1419
|
+
}
|
|
1420
|
+
function hasSeenKey(websiteId, visitorId) {
|
|
1421
|
+
try {
|
|
1422
|
+
return localStorage.getItem(storageKey(websiteId, visitorId)) !== null;
|
|
1423
|
+
} catch {
|
|
1424
|
+
return false;
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
function getSeenSlugs(websiteId, visitorId) {
|
|
1428
|
+
try {
|
|
1429
|
+
const raw = localStorage.getItem(storageKey(websiteId, visitorId));
|
|
1430
|
+
if (!raw) return /* @__PURE__ */ new Set();
|
|
1431
|
+
return new Set(JSON.parse(raw));
|
|
1432
|
+
} catch {
|
|
1433
|
+
return /* @__PURE__ */ new Set();
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
function addSeenSlug(websiteId, visitorId, slug) {
|
|
1437
|
+
try {
|
|
1438
|
+
const seen = getSeenSlugs(websiteId, visitorId);
|
|
1439
|
+
seen.add(slug);
|
|
1440
|
+
localStorage.setItem(storageKey(websiteId, visitorId), JSON.stringify([...seen]));
|
|
1441
|
+
} catch {
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
function addSeenSlugs(websiteId, visitorId, slugs) {
|
|
1445
|
+
try {
|
|
1446
|
+
const seen = getSeenSlugs(websiteId, visitorId);
|
|
1447
|
+
for (const s of slugs) seen.add(s);
|
|
1448
|
+
localStorage.setItem(storageKey(websiteId, visitorId), JSON.stringify([...seen]));
|
|
1449
|
+
} catch {
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
function filterUnseen(entries, seen) {
|
|
1453
|
+
return entries.filter((e) => !seen.has(e.slug));
|
|
1454
|
+
}
|
|
1455
|
+
var EMPTY_TABS = [];
|
|
1456
|
+
function useAnnouncements() {
|
|
1457
|
+
const { client, store } = useWidgetContext();
|
|
1458
|
+
const isReady = useWidgetStore((s) => s.isReady);
|
|
1459
|
+
const websiteId = useWidgetStore((s) => s.website?.id) ?? null;
|
|
1460
|
+
const visitorId = useWidgetStore((s) => s.visitor?.id) ?? null;
|
|
1461
|
+
const isAnonymous = useWidgetStore((s) => !s.visitor?.contact);
|
|
1462
|
+
const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_TABS;
|
|
1463
|
+
const announcementTabs = useMemo(
|
|
1464
|
+
() => contentTabs.filter((t2) => t2.isAnnouncements),
|
|
1465
|
+
[contentTabs]
|
|
1466
|
+
);
|
|
1467
|
+
const checkedRef = useRef2(false);
|
|
1468
|
+
useEffect2(() => {
|
|
1469
|
+
if (!isReady || !websiteId || !visitorId || announcementTabs.length === 0) return;
|
|
1470
|
+
if (checkedRef.current) return;
|
|
1471
|
+
checkedRef.current = true;
|
|
1472
|
+
const isFirstVisit = !hasSeenKey(websiteId, visitorId);
|
|
1473
|
+
let pending = announcementTabs.length;
|
|
1474
|
+
let totalUnseen = 0;
|
|
1475
|
+
const allSlugs = [];
|
|
1476
|
+
function onTabDone(entries, tab) {
|
|
1477
|
+
allSlugs.push(...entries.map((e) => e.slug));
|
|
1478
|
+
if (!(isFirstVisit && !isAnonymous) && entries.length > 0) {
|
|
1479
|
+
const seen = getSeenSlugs(websiteId, visitorId);
|
|
1480
|
+
const unseen = filterUnseen(entries, seen);
|
|
1481
|
+
totalUnseen += unseen.length;
|
|
1482
|
+
const newest = unseen[0];
|
|
1483
|
+
if (newest && !store.getState().isOpen) {
|
|
1484
|
+
const badgeField = tab.display?.badgeField;
|
|
1485
|
+
store.getState().setAnnouncementPreview({
|
|
1486
|
+
title: newest.title,
|
|
1487
|
+
body: newest.body,
|
|
1488
|
+
slug: newest.slug,
|
|
1489
|
+
tabId: tab.id,
|
|
1490
|
+
badge: badgeField ? newest.customFields[badgeField] ?? null : null
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
pending--;
|
|
1495
|
+
if (pending === 0) {
|
|
1496
|
+
if (isFirstVisit && !isAnonymous) {
|
|
1497
|
+
if (allSlugs.length > 0) {
|
|
1498
|
+
addSeenSlugs(websiteId, visitorId, allSlugs);
|
|
1499
|
+
}
|
|
1500
|
+
store.getState().setUnseenAnnouncementCount(0);
|
|
1501
|
+
} else {
|
|
1502
|
+
store.getState().setUnseenAnnouncementCount(totalUnseen);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
for (const tab of announcementTabs) {
|
|
1507
|
+
const cacheKey = `announcements:${tab.id}:${getLocale()}`;
|
|
1508
|
+
const cached = store.getState().contentCache.get(cacheKey);
|
|
1509
|
+
if (cached && Date.now() - cached.ts < CONTENT_CACHE_TTL) {
|
|
1510
|
+
onTabDone(cached.data, tab);
|
|
1511
|
+
} else {
|
|
1512
|
+
client.widget.getContent.query({ tabId: tab.id, page: 1, limit: 5, language: getLocale() }).then((result) => {
|
|
1513
|
+
const entries = result.items ?? [];
|
|
1514
|
+
store.getState().setContentCache(cacheKey, entries);
|
|
1515
|
+
onTabDone(entries, tab);
|
|
1516
|
+
}).catch(() => {
|
|
1517
|
+
onTabDone([], tab);
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
}, [isReady, websiteId, visitorId, isAnonymous, announcementTabs, client, store]);
|
|
1522
|
+
const markEntrySeen = useCallback2(
|
|
1523
|
+
(slug) => {
|
|
1524
|
+
if (!websiteId || !visitorId || announcementTabs.length === 0) return;
|
|
1525
|
+
addSeenSlug(websiteId, visitorId, slug);
|
|
1526
|
+
const seen = getSeenSlugs(websiteId, visitorId);
|
|
1527
|
+
let total = 0;
|
|
1528
|
+
for (const tab of announcementTabs) {
|
|
1529
|
+
const cacheKey = `announcements:${tab.id}:${getLocale()}`;
|
|
1530
|
+
const cached = store.getState().contentCache.get(cacheKey);
|
|
1531
|
+
if (cached) {
|
|
1532
|
+
total += filterUnseen(cached.data, seen).length;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
store.getState().setUnseenAnnouncementCount(total);
|
|
1536
|
+
store.getState().dismissAnnouncementPreview(slug);
|
|
1537
|
+
},
|
|
1538
|
+
[websiteId, visitorId, announcementTabs, store]
|
|
1539
|
+
);
|
|
1540
|
+
const markAllSeen = useCallback2(() => {
|
|
1541
|
+
if (!websiteId || !visitorId || announcementTabs.length === 0) return;
|
|
1542
|
+
for (const tab of announcementTabs) {
|
|
1543
|
+
const cacheKey = `announcements:${tab.id}:${getLocale()}`;
|
|
1544
|
+
const cached = store.getState().contentCache.get(cacheKey);
|
|
1545
|
+
if (cached) {
|
|
1546
|
+
const entries = cached.data;
|
|
1547
|
+
addSeenSlugs(websiteId, visitorId, entries.map((e) => e.slug));
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
store.getState().setUnseenAnnouncementCount(0);
|
|
1551
|
+
store.getState().dismissAnnouncementPreview();
|
|
1552
|
+
}, [websiteId, visitorId, announcementTabs, store]);
|
|
1553
|
+
const getUnseenEntries = useCallback2(() => {
|
|
1554
|
+
if (announcementTabs.length === 0 || !websiteId || !visitorId) return [];
|
|
1555
|
+
const seen = getSeenSlugs(websiteId, visitorId);
|
|
1556
|
+
const result = [];
|
|
1557
|
+
for (const tab of announcementTabs) {
|
|
1558
|
+
const cacheKey = `announcements:${tab.id}:${getLocale()}`;
|
|
1559
|
+
const cached = store.getState().contentCache.get(cacheKey);
|
|
1560
|
+
if (cached) {
|
|
1561
|
+
for (const entry of filterUnseen(cached.data, seen)) {
|
|
1562
|
+
result.push({ ...entry, tabId: tab.id });
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
return result;
|
|
1567
|
+
}, [announcementTabs, websiteId, visitorId, store]);
|
|
1568
|
+
return {
|
|
1569
|
+
announcementTabs,
|
|
1570
|
+
markEntrySeen,
|
|
1571
|
+
markAllSeen,
|
|
1572
|
+
getUnseenEntries
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1357
1575
|
|
|
1358
1576
|
// src/hooks/use-composer.ts
|
|
1359
|
-
import { useCallback as
|
|
1577
|
+
import { useCallback as useCallback3, useState as useState2 } from "react";
|
|
1360
1578
|
var MAX_ATTACHMENTS = 10;
|
|
1361
1579
|
var MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
1362
1580
|
function useComposer(conversationId) {
|
|
@@ -1366,7 +1584,7 @@ function useComposer(conversationId) {
|
|
|
1366
1584
|
const [attachments, setAttachments] = useState2([]);
|
|
1367
1585
|
const [sendError, setSendError] = useState2(null);
|
|
1368
1586
|
const [emailGateConvId, setEmailGateConvId] = useState2(null);
|
|
1369
|
-
const addFiles =
|
|
1587
|
+
const addFiles = useCallback3(
|
|
1370
1588
|
async (files) => {
|
|
1371
1589
|
if (!conversationId) return;
|
|
1372
1590
|
const remaining = MAX_ATTACHMENTS - attachments.length;
|
|
@@ -1409,14 +1627,14 @@ function useComposer(conversationId) {
|
|
|
1409
1627
|
},
|
|
1410
1628
|
[conversationId, attachments.length, client]
|
|
1411
1629
|
);
|
|
1412
|
-
const removeAttachment =
|
|
1630
|
+
const removeAttachment = useCallback3((id) => {
|
|
1413
1631
|
setAttachments((prev) => {
|
|
1414
1632
|
const item = prev.find((a) => a.id === id);
|
|
1415
1633
|
if (item?.previewUrl) URL.revokeObjectURL(item.previewUrl);
|
|
1416
1634
|
return prev.filter((a) => a.id !== id);
|
|
1417
1635
|
});
|
|
1418
1636
|
}, []);
|
|
1419
|
-
const submit =
|
|
1637
|
+
const submit = useCallback3(async () => {
|
|
1420
1638
|
const trimmed = text.trim();
|
|
1421
1639
|
const readyParts = attachments.filter((a) => a.part !== null).map((a) => a.part);
|
|
1422
1640
|
const hasText = trimmed.length > 0;
|
|
@@ -1514,7 +1732,7 @@ function useComposer(conversationId) {
|
|
|
1514
1732
|
setIsSubmitting(false);
|
|
1515
1733
|
}
|
|
1516
1734
|
}, [text, attachments, conversationId, isSubmitting, client, ws, store]);
|
|
1517
|
-
const clearSendError =
|
|
1735
|
+
const clearSendError = useCallback3(() => setSendError(null), []);
|
|
1518
1736
|
return {
|
|
1519
1737
|
text,
|
|
1520
1738
|
setText,
|
|
@@ -1543,17 +1761,17 @@ function fileToBase64(file) {
|
|
|
1543
1761
|
}
|
|
1544
1762
|
|
|
1545
1763
|
// src/hooks/use-conversations.ts
|
|
1546
|
-
import { useCallback as
|
|
1764
|
+
import { useCallback as useCallback4, useRef as useRef3, useState as useState3 } from "react";
|
|
1547
1765
|
function useConversations() {
|
|
1548
1766
|
const { client, store } = useWidgetContext();
|
|
1549
1767
|
const conversations = useWidgetStore((s) => s.conversations);
|
|
1550
1768
|
const setActiveConversation = useWidgetStore((s) => s.setActiveConversation);
|
|
1551
1769
|
const [isCreating, setIsCreating] = useState3(false);
|
|
1552
|
-
const clientRef =
|
|
1553
|
-
const storeRef =
|
|
1770
|
+
const clientRef = useRef3(client);
|
|
1771
|
+
const storeRef = useRef3(store);
|
|
1554
1772
|
clientRef.current = client;
|
|
1555
1773
|
storeRef.current = store;
|
|
1556
|
-
const create =
|
|
1774
|
+
const create = useCallback4(async (text) => {
|
|
1557
1775
|
setIsCreating(true);
|
|
1558
1776
|
const tempConversationId = `temp-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
1559
1777
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1617,10 +1835,10 @@ function useConversations() {
|
|
|
1617
1835
|
}
|
|
1618
1836
|
|
|
1619
1837
|
// src/hooks/use-i18n.ts
|
|
1620
|
-
import { useEffect as
|
|
1838
|
+
import { useEffect as useEffect3, useState as useState4 } from "react";
|
|
1621
1839
|
function useI18n() {
|
|
1622
1840
|
const [rev, setRev] = useState4(() => getI18nRevision());
|
|
1623
|
-
|
|
1841
|
+
useEffect3(() => {
|
|
1624
1842
|
return onLocaleChange(() => {
|
|
1625
1843
|
setRev(getI18nRevision());
|
|
1626
1844
|
});
|
|
@@ -1629,7 +1847,7 @@ function useI18n() {
|
|
|
1629
1847
|
}
|
|
1630
1848
|
|
|
1631
1849
|
// src/hooks/use-presence.ts
|
|
1632
|
-
import { useCallback as
|
|
1850
|
+
import { useCallback as useCallback5, useRef as useRef4 } from "react";
|
|
1633
1851
|
function usePresence(conversationId) {
|
|
1634
1852
|
const { ws } = useWidgetContext();
|
|
1635
1853
|
const isTyping = useWidgetStore(
|
|
@@ -1638,9 +1856,9 @@ function usePresence(conversationId) {
|
|
|
1638
1856
|
const isAiProcessing = useWidgetStore(
|
|
1639
1857
|
(s) => conversationId ? s.aiProcessing.get(conversationId) ?? false : false
|
|
1640
1858
|
);
|
|
1641
|
-
const typingTimer =
|
|
1642
|
-
const isSendingTyping =
|
|
1643
|
-
const setTyping =
|
|
1859
|
+
const typingTimer = useRef4(null);
|
|
1860
|
+
const isSendingTyping = useRef4(false);
|
|
1861
|
+
const setTyping = useCallback5(
|
|
1644
1862
|
(typing) => {
|
|
1645
1863
|
if (!conversationId) return;
|
|
1646
1864
|
if (typingTimer.current) clearTimeout(typingTimer.current);
|
|
@@ -1666,7 +1884,7 @@ function usePresence(conversationId) {
|
|
|
1666
1884
|
}
|
|
1667
1885
|
|
|
1668
1886
|
// src/hooks/use-timeline.ts
|
|
1669
|
-
import { useCallback as
|
|
1887
|
+
import { useCallback as useCallback6, useEffect as useEffect4, useRef as useRef5, useState as useState5 } from "react";
|
|
1670
1888
|
var EMPTY_ITEMS = [];
|
|
1671
1889
|
function useTimeline(conversationId) {
|
|
1672
1890
|
const { client, store } = useWidgetContext();
|
|
@@ -1675,12 +1893,12 @@ function useTimeline(conversationId) {
|
|
|
1675
1893
|
);
|
|
1676
1894
|
const [isLoading, setIsLoading] = useState5(false);
|
|
1677
1895
|
const [hasMore, setHasMore] = useState5(false);
|
|
1678
|
-
const cursorRef =
|
|
1679
|
-
const clientRef =
|
|
1680
|
-
const storeRef =
|
|
1896
|
+
const cursorRef = useRef5(void 0);
|
|
1897
|
+
const clientRef = useRef5(client);
|
|
1898
|
+
const storeRef = useRef5(store);
|
|
1681
1899
|
clientRef.current = client;
|
|
1682
1900
|
storeRef.current = store;
|
|
1683
|
-
|
|
1901
|
+
useEffect4(() => {
|
|
1684
1902
|
if (!conversationId) return;
|
|
1685
1903
|
if (conversationId.startsWith("temp-")) return;
|
|
1686
1904
|
let cancelled = false;
|
|
@@ -1721,7 +1939,7 @@ function useTimeline(conversationId) {
|
|
|
1721
1939
|
cancelled = true;
|
|
1722
1940
|
};
|
|
1723
1941
|
}, [conversationId]);
|
|
1724
|
-
const loadMore =
|
|
1942
|
+
const loadMore = useCallback6(async () => {
|
|
1725
1943
|
if (!conversationId || !hasMore || isLoading) return;
|
|
1726
1944
|
setIsLoading(true);
|
|
1727
1945
|
try {
|
|
@@ -1764,7 +1982,7 @@ function useWidget() {
|
|
|
1764
1982
|
}
|
|
1765
1983
|
|
|
1766
1984
|
// src/themed/composer.tsx
|
|
1767
|
-
import { useCallback as
|
|
1985
|
+
import { useCallback as useCallback7, useRef as useRef8, useState as useState7 } from "react";
|
|
1768
1986
|
|
|
1769
1987
|
// src/themed/icons.tsx
|
|
1770
1988
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
@@ -1942,11 +2160,11 @@ function StarIcon({ size = 24, ...props }) {
|
|
|
1942
2160
|
}
|
|
1943
2161
|
|
|
1944
2162
|
// src/themed/message-bubble.tsx
|
|
1945
|
-
import { useEffect as
|
|
2163
|
+
import { useEffect as useEffect6, useLayoutEffect, useRef as useRef7, useState as useState6 } from "react";
|
|
1946
2164
|
import { createPortal } from "react-dom";
|
|
1947
2165
|
|
|
1948
2166
|
// src/themed/content/simple-markdown.tsx
|
|
1949
|
-
import { useEffect as
|
|
2167
|
+
import { useEffect as useEffect5, useRef as useRef6 } from "react";
|
|
1950
2168
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1951
2169
|
var 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>`;
|
|
1952
2170
|
var 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>`;
|
|
@@ -2027,9 +2245,9 @@ function MarkdownContent({
|
|
|
2027
2245
|
bodyMarkdown,
|
|
2028
2246
|
className
|
|
2029
2247
|
}) {
|
|
2030
|
-
const rootRef =
|
|
2248
|
+
const rootRef = useRef6(null);
|
|
2031
2249
|
const html = bodyHtml ?? (bodyMarkdown ? renderMarkdown(bodyMarkdown) : "");
|
|
2032
|
-
|
|
2250
|
+
useEffect5(() => {
|
|
2033
2251
|
const root = rootRef.current;
|
|
2034
2252
|
if (!root) return;
|
|
2035
2253
|
const isWhitespaceOnly = (el) => {
|
|
@@ -2048,7 +2266,7 @@ function MarkdownContent({
|
|
|
2048
2266
|
};
|
|
2049
2267
|
removeEmpties();
|
|
2050
2268
|
}, [html]);
|
|
2051
|
-
|
|
2269
|
+
useEffect5(() => {
|
|
2052
2270
|
const root = rootRef.current;
|
|
2053
2271
|
if (!root) return;
|
|
2054
2272
|
const handler = (e) => {
|
|
@@ -2093,14 +2311,14 @@ function MessageBubble({
|
|
|
2093
2311
|
onQuickReplyTap
|
|
2094
2312
|
}) {
|
|
2095
2313
|
const senderClass = `hw-msg--${sender}`;
|
|
2096
|
-
const bubbleRef =
|
|
2314
|
+
const bubbleRef = useRef7(null);
|
|
2097
2315
|
const imageParts = parts?.filter((p) => p.type === "image") ?? [];
|
|
2098
2316
|
const fileParts = parts?.filter((p) => p.type === "file") ?? [];
|
|
2099
2317
|
const linkPreviews = parts?.filter(
|
|
2100
2318
|
(p) => p.type === "link-preview"
|
|
2101
2319
|
) ?? [];
|
|
2102
2320
|
const hasText = text.length > 0;
|
|
2103
|
-
|
|
2321
|
+
useEffect6(() => {
|
|
2104
2322
|
const bubble = bubbleRef.current;
|
|
2105
2323
|
if (!bubble || sender !== "ai" && sender !== "team") return;
|
|
2106
2324
|
const handleClick = (event) => {
|
|
@@ -2157,7 +2375,7 @@ function QuickReplyButtons({
|
|
|
2157
2375
|
}
|
|
2158
2376
|
function PreviewableThumbnail({ src }) {
|
|
2159
2377
|
const [hover, setHover] = useState6(false);
|
|
2160
|
-
const ref =
|
|
2378
|
+
const ref = useRef7(null);
|
|
2161
2379
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
2162
2380
|
/* @__PURE__ */ jsx4(
|
|
2163
2381
|
"a",
|
|
@@ -2178,7 +2396,7 @@ function PreviewableThumbnail({ src }) {
|
|
|
2178
2396
|
var PREVIEWABLE_EXTS = /* @__PURE__ */ new Set(["pdf", "csv", "png", "jpg", "jpeg", "gif", "webp", "svg"]);
|
|
2179
2397
|
function FileCard({ file }) {
|
|
2180
2398
|
const [hover, setHover] = useState6(false);
|
|
2181
|
-
const ref =
|
|
2399
|
+
const ref = useRef7(null);
|
|
2182
2400
|
const ext = file.fileName.split(".").pop()?.toLowerCase() ?? "";
|
|
2183
2401
|
const isPreviewable = PREVIEWABLE_EXTS.has(ext);
|
|
2184
2402
|
const isImage = file.mimeType.startsWith("image/");
|
|
@@ -2404,12 +2622,12 @@ function Composer({
|
|
|
2404
2622
|
onRemoveAttachment,
|
|
2405
2623
|
disabled
|
|
2406
2624
|
}) {
|
|
2407
|
-
const ref =
|
|
2408
|
-
const fileInputRef =
|
|
2409
|
-
const supportsFieldSizing =
|
|
2625
|
+
const ref = useRef8(null);
|
|
2626
|
+
const fileInputRef = useRef8(null);
|
|
2627
|
+
const supportsFieldSizing = useRef8(
|
|
2410
2628
|
typeof CSS !== "undefined" && CSS.supports?.("field-sizing", "content")
|
|
2411
2629
|
);
|
|
2412
|
-
const handleKeyDown =
|
|
2630
|
+
const handleKeyDown = useCallback7(
|
|
2413
2631
|
(e) => {
|
|
2414
2632
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
2415
2633
|
e.preventDefault();
|
|
@@ -2418,7 +2636,7 @@ function Composer({
|
|
|
2418
2636
|
},
|
|
2419
2637
|
[onSubmit]
|
|
2420
2638
|
);
|
|
2421
|
-
const handleChange =
|
|
2639
|
+
const handleChange = useCallback7(
|
|
2422
2640
|
(e) => {
|
|
2423
2641
|
const value = e.target.value;
|
|
2424
2642
|
if (value.length > MAX_CHARS) return;
|
|
@@ -2434,7 +2652,7 @@ function Composer({
|
|
|
2434
2652
|
},
|
|
2435
2653
|
[onTextChange, onTyping]
|
|
2436
2654
|
);
|
|
2437
|
-
const handlePaste =
|
|
2655
|
+
const handlePaste = useCallback7(
|
|
2438
2656
|
(e) => {
|
|
2439
2657
|
if (!onAddFiles) return;
|
|
2440
2658
|
const files = extractFiles(e.clipboardData);
|
|
@@ -2446,22 +2664,22 @@ function Composer({
|
|
|
2446
2664
|
[onAddFiles]
|
|
2447
2665
|
);
|
|
2448
2666
|
const [isDragging, setIsDragging] = useState7(false);
|
|
2449
|
-
const dragCountRef =
|
|
2450
|
-
const handleDragEnter =
|
|
2667
|
+
const dragCountRef = useRef8(0);
|
|
2668
|
+
const handleDragEnter = useCallback7((e) => {
|
|
2451
2669
|
e.preventDefault();
|
|
2452
2670
|
dragCountRef.current++;
|
|
2453
2671
|
if (dragCountRef.current === 1) setIsDragging(true);
|
|
2454
2672
|
}, []);
|
|
2455
|
-
const handleDragLeave =
|
|
2673
|
+
const handleDragLeave = useCallback7((e) => {
|
|
2456
2674
|
e.preventDefault();
|
|
2457
2675
|
dragCountRef.current--;
|
|
2458
2676
|
if (dragCountRef.current === 0) setIsDragging(false);
|
|
2459
2677
|
}, []);
|
|
2460
|
-
const handleDragOver =
|
|
2678
|
+
const handleDragOver = useCallback7((e) => {
|
|
2461
2679
|
e.preventDefault();
|
|
2462
2680
|
e.dataTransfer.dropEffect = "copy";
|
|
2463
2681
|
}, []);
|
|
2464
|
-
const handleDrop =
|
|
2682
|
+
const handleDrop = useCallback7(
|
|
2465
2683
|
(e) => {
|
|
2466
2684
|
e.preventDefault();
|
|
2467
2685
|
dragCountRef.current = 0;
|
|
@@ -2472,10 +2690,10 @@ function Composer({
|
|
|
2472
2690
|
},
|
|
2473
2691
|
[onAddFiles]
|
|
2474
2692
|
);
|
|
2475
|
-
const handleFileClick =
|
|
2693
|
+
const handleFileClick = useCallback7(() => {
|
|
2476
2694
|
fileInputRef.current?.click();
|
|
2477
2695
|
}, []);
|
|
2478
|
-
const handleFileChange =
|
|
2696
|
+
const handleFileChange = useCallback7(
|
|
2479
2697
|
(e) => {
|
|
2480
2698
|
if (!onAddFiles || !e.target.files) return;
|
|
2481
2699
|
onAddFiles(Array.from(e.target.files));
|
|
@@ -2566,7 +2784,7 @@ function Composer({
|
|
|
2566
2784
|
}
|
|
2567
2785
|
function PreviewThumb({ attachment: a, onRemove }) {
|
|
2568
2786
|
const [hover, setHover] = useState7(false);
|
|
2569
|
-
const ref =
|
|
2787
|
+
const ref = useRef8(null);
|
|
2570
2788
|
return /* @__PURE__ */ jsxs3(
|
|
2571
2789
|
"div",
|
|
2572
2790
|
{
|
|
@@ -2605,7 +2823,7 @@ function extractFiles(data) {
|
|
|
2605
2823
|
}
|
|
2606
2824
|
|
|
2607
2825
|
// src/themed/debug-overlay.tsx
|
|
2608
|
-
import { useEffect as
|
|
2826
|
+
import { useEffect as useEffect7, useMemo as useMemo2, useRef as useRef9, useState as useState8 } from "react";
|
|
2609
2827
|
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2610
2828
|
var MAX_EVENTS = 60;
|
|
2611
2829
|
function isDebugEnabled() {
|
|
@@ -2626,16 +2844,16 @@ function WidgetDebugOverlay() {
|
|
|
2626
2844
|
const [enabled, setEnabled] = useState8(false);
|
|
2627
2845
|
const [open, setOpen] = useState8(true);
|
|
2628
2846
|
const [events, setEvents] = useState8([]);
|
|
2629
|
-
const eventsRef =
|
|
2847
|
+
const eventsRef = useRef9([]);
|
|
2630
2848
|
const activeId = useWidgetStore((s) => s.activeConversationId);
|
|
2631
2849
|
const messagesMap = useWidgetStore((s) => s.messages);
|
|
2632
2850
|
const typingUsers = useWidgetStore((s) => s.typingUsers);
|
|
2633
2851
|
const aiProcessingMap = useWidgetStore((s) => s.aiProcessing);
|
|
2634
2852
|
const { store } = useWidgetContext();
|
|
2635
|
-
|
|
2853
|
+
useEffect7(() => {
|
|
2636
2854
|
setEnabled(isDebugEnabled());
|
|
2637
2855
|
}, []);
|
|
2638
|
-
const pushEvent =
|
|
2856
|
+
const pushEvent = useMemo2(
|
|
2639
2857
|
() => (ev) => {
|
|
2640
2858
|
const e = {
|
|
2641
2859
|
...ev,
|
|
@@ -2647,7 +2865,7 @@ function WidgetDebugOverlay() {
|
|
|
2647
2865
|
},
|
|
2648
2866
|
[]
|
|
2649
2867
|
);
|
|
2650
|
-
|
|
2868
|
+
useEffect7(() => {
|
|
2651
2869
|
if (!enabled) return;
|
|
2652
2870
|
if (typeof window === "undefined" || typeof window.fetch !== "function") return;
|
|
2653
2871
|
const originalFetch = window.fetch.bind(window);
|
|
@@ -2679,7 +2897,7 @@ function WidgetDebugOverlay() {
|
|
|
2679
2897
|
window.fetch = originalFetch;
|
|
2680
2898
|
};
|
|
2681
2899
|
}, [enabled, pushEvent]);
|
|
2682
|
-
|
|
2900
|
+
useEffect7(() => {
|
|
2683
2901
|
if (!enabled) return;
|
|
2684
2902
|
const original = store.getState().handleRealtimeEvent;
|
|
2685
2903
|
store.setState({
|
|
@@ -2693,12 +2911,12 @@ function WidgetDebugOverlay() {
|
|
|
2693
2911
|
};
|
|
2694
2912
|
}, [enabled, store, pushEvent]);
|
|
2695
2913
|
const activeMessages = activeId ? messagesMap.get(activeId) ?? [] : [];
|
|
2696
|
-
const lastMsgSignature =
|
|
2914
|
+
const lastMsgSignature = useMemo2(
|
|
2697
2915
|
() => activeMessages.map((m) => `${m.id}:${senderOf(m)}:${m.createdAt}`).join("|"),
|
|
2698
2916
|
[activeMessages]
|
|
2699
2917
|
);
|
|
2700
|
-
const prevSigRef =
|
|
2701
|
-
|
|
2918
|
+
const prevSigRef = useRef9(lastMsgSignature);
|
|
2919
|
+
useEffect7(() => {
|
|
2702
2920
|
if (!enabled) return;
|
|
2703
2921
|
if (prevSigRef.current !== lastMsgSignature) {
|
|
2704
2922
|
prevSigRef.current = lastMsgSignature;
|
|
@@ -2851,11 +3069,11 @@ var styles = {
|
|
|
2851
3069
|
};
|
|
2852
3070
|
|
|
2853
3071
|
// src/themed/content/content-tab-view.tsx
|
|
2854
|
-
import { useCallback as
|
|
3072
|
+
import { useCallback as useCallback11, useEffect as useEffect10 } from "react";
|
|
2855
3073
|
|
|
2856
3074
|
// src/hooks/use-content-tab.ts
|
|
2857
|
-
import { useCallback as
|
|
2858
|
-
var
|
|
3075
|
+
import { useCallback as useCallback8, useEffect as useEffect8, useState as useState9 } from "react";
|
|
3076
|
+
var EMPTY_TABS2 = [];
|
|
2859
3077
|
function listKey(tabId, lang) {
|
|
2860
3078
|
return `flat:${tabId}:${lang}:list`;
|
|
2861
3079
|
}
|
|
@@ -2870,7 +3088,7 @@ function readCache(cache, key) {
|
|
|
2870
3088
|
}
|
|
2871
3089
|
function useContentTab(tabId) {
|
|
2872
3090
|
const { client, store } = useWidgetContext();
|
|
2873
|
-
const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ??
|
|
3091
|
+
const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_TABS2;
|
|
2874
3092
|
const tab = contentTabs.find((t2) => t2.id === tabId) ?? null;
|
|
2875
3093
|
const lang = getLocale();
|
|
2876
3094
|
const cache = store.getState().contentCache;
|
|
@@ -2889,7 +3107,7 @@ function useContentTab(tabId) {
|
|
|
2889
3107
|
const [page, setPage] = useState9(
|
|
2890
3108
|
() => readCache(cache, listKey(tabId, lang))?.page ?? 1
|
|
2891
3109
|
);
|
|
2892
|
-
const fetchEntries =
|
|
3110
|
+
const fetchEntries = useCallback8(
|
|
2893
3111
|
async (opts) => {
|
|
2894
3112
|
if (!tab) return;
|
|
2895
3113
|
const p = opts?.page ?? 1;
|
|
@@ -2928,11 +3146,11 @@ function useContentTab(tabId) {
|
|
|
2928
3146
|
},
|
|
2929
3147
|
[client, tabId, tab, store]
|
|
2930
3148
|
);
|
|
2931
|
-
const loadMore =
|
|
3149
|
+
const loadMore = useCallback8(() => {
|
|
2932
3150
|
if (!hasMore || isLoading) return;
|
|
2933
3151
|
fetchEntries({ page: page + 1 });
|
|
2934
3152
|
}, [fetchEntries, hasMore, isLoading, page]);
|
|
2935
|
-
const fetchDetail =
|
|
3153
|
+
const fetchDetail = useCallback8(
|
|
2936
3154
|
async (slug) => {
|
|
2937
3155
|
if (!tab) return;
|
|
2938
3156
|
const cached = readCache(
|
|
@@ -2966,10 +3184,10 @@ function useContentTab(tabId) {
|
|
|
2966
3184
|
},
|
|
2967
3185
|
[client, tabId, tab, store]
|
|
2968
3186
|
);
|
|
2969
|
-
const clearDetail =
|
|
3187
|
+
const clearDetail = useCallback8(() => {
|
|
2970
3188
|
setDetail(null);
|
|
2971
3189
|
}, []);
|
|
2972
|
-
|
|
3190
|
+
useEffect8(() => {
|
|
2973
3191
|
if (tab && entries.length === 0) {
|
|
2974
3192
|
fetchEntries({ page: 1, reset: true });
|
|
2975
3193
|
}
|
|
@@ -3078,7 +3296,7 @@ function SkeletonSection({
|
|
|
3078
3296
|
}
|
|
3079
3297
|
|
|
3080
3298
|
// src/themed/content/content-list-view.tsx
|
|
3081
|
-
import { useCallback as
|
|
3299
|
+
import { useCallback as useCallback9, useRef as useRef10, useState as useState10 } from "react";
|
|
3082
3300
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3083
3301
|
function ContentListView({
|
|
3084
3302
|
entries,
|
|
@@ -3091,8 +3309,8 @@ function ContentListView({
|
|
|
3091
3309
|
display
|
|
3092
3310
|
}) {
|
|
3093
3311
|
const [searchText, setSearchText] = useState10("");
|
|
3094
|
-
const debounceRef =
|
|
3095
|
-
const handleSearch =
|
|
3312
|
+
const debounceRef = useRef10(void 0);
|
|
3313
|
+
const handleSearch = useCallback9(
|
|
3096
3314
|
(value) => {
|
|
3097
3315
|
setSearchText(value);
|
|
3098
3316
|
if (!onSearch) return;
|
|
@@ -3172,11 +3390,11 @@ function ContentEntryCard({
|
|
|
3172
3390
|
}
|
|
3173
3391
|
|
|
3174
3392
|
// src/themed/content/grouped-content-tab-view.tsx
|
|
3175
|
-
import { useEffect as
|
|
3393
|
+
import { useEffect as useEffect9, useRef as useRef12 } from "react";
|
|
3176
3394
|
|
|
3177
3395
|
// src/hooks/use-grouped-content-tab.ts
|
|
3178
|
-
import { useCallback as
|
|
3179
|
-
var
|
|
3396
|
+
import { useCallback as useCallback10, useRef as useRef11, useState as useState11 } from "react";
|
|
3397
|
+
var EMPTY_TABS3 = [];
|
|
3180
3398
|
function categoriesKey(tabId, lang) {
|
|
3181
3399
|
return `grouped:${tabId}:${lang}:categories`;
|
|
3182
3400
|
}
|
|
@@ -3194,7 +3412,7 @@ function readCache2(cache, key) {
|
|
|
3194
3412
|
}
|
|
3195
3413
|
function useGroupedContentTab(tabId) {
|
|
3196
3414
|
const { client, store } = useWidgetContext();
|
|
3197
|
-
const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ??
|
|
3415
|
+
const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_TABS3;
|
|
3198
3416
|
const tab = contentTabs.find((t2) => t2.id === tabId) ?? null;
|
|
3199
3417
|
const lang = getLocale();
|
|
3200
3418
|
const cache = store.getState().contentCache;
|
|
@@ -3204,12 +3422,12 @@ function useGroupedContentTab(tabId) {
|
|
|
3204
3422
|
const [items, setItems] = useState11([]);
|
|
3205
3423
|
const [isItemsLoading, setIsItemsLoading] = useState11(false);
|
|
3206
3424
|
const [itemsHasMore, setItemsHasMore] = useState11(false);
|
|
3207
|
-
const itemsPageRef =
|
|
3425
|
+
const itemsPageRef = useRef11(1);
|
|
3208
3426
|
const [detail, setDetail] = useState11(null);
|
|
3209
3427
|
const [isLoadingDetail, setIsLoadingDetail] = useState11(false);
|
|
3210
3428
|
const [activeCategory, setActiveCategory] = useState11(null);
|
|
3211
|
-
const allCategoriesRef =
|
|
3212
|
-
const fetchCategories =
|
|
3429
|
+
const allCategoriesRef = useRef11(cachedCategories ?? []);
|
|
3430
|
+
const fetchCategories = useCallback10(async () => {
|
|
3213
3431
|
if (!tab) return;
|
|
3214
3432
|
setIsCategoriesLoading(true);
|
|
3215
3433
|
try {
|
|
@@ -3230,12 +3448,12 @@ function useGroupedContentTab(tabId) {
|
|
|
3230
3448
|
setIsCategoriesLoading(false);
|
|
3231
3449
|
}
|
|
3232
3450
|
}, [client, tabId, tab, store]);
|
|
3233
|
-
const initFetch =
|
|
3451
|
+
const initFetch = useCallback10(() => {
|
|
3234
3452
|
if (tab && categories.length === 0) {
|
|
3235
3453
|
fetchCategories();
|
|
3236
3454
|
}
|
|
3237
3455
|
}, [fetchCategories, tab, categories.length]);
|
|
3238
|
-
const fetchItems =
|
|
3456
|
+
const fetchItems = useCallback10(
|
|
3239
3457
|
async (opts) => {
|
|
3240
3458
|
if (!tab?.itemsModelSlug) return;
|
|
3241
3459
|
const p = opts?.page ?? 1;
|
|
@@ -3273,7 +3491,7 @@ function useGroupedContentTab(tabId) {
|
|
|
3273
3491
|
},
|
|
3274
3492
|
[client, tabId, tab, store]
|
|
3275
3493
|
);
|
|
3276
|
-
const selectCategory =
|
|
3494
|
+
const selectCategory = useCallback10(
|
|
3277
3495
|
(category) => {
|
|
3278
3496
|
setActiveCategory(category);
|
|
3279
3497
|
setDetail(null);
|
|
@@ -3292,14 +3510,14 @@ function useGroupedContentTab(tabId) {
|
|
|
3292
3510
|
},
|
|
3293
3511
|
[fetchItems, store, tabId]
|
|
3294
3512
|
);
|
|
3295
|
-
const loadMoreItems =
|
|
3513
|
+
const loadMoreItems = useCallback10(() => {
|
|
3296
3514
|
if (!itemsHasMore || isItemsLoading || !activeCategory) return;
|
|
3297
3515
|
fetchItems({
|
|
3298
3516
|
page: itemsPageRef.current + 1,
|
|
3299
3517
|
groupSlug: activeCategory.slug
|
|
3300
3518
|
});
|
|
3301
3519
|
}, [fetchItems, itemsHasMore, isItemsLoading, activeCategory]);
|
|
3302
|
-
const searchItems =
|
|
3520
|
+
const searchItems = useCallback10(
|
|
3303
3521
|
(query) => {
|
|
3304
3522
|
setItems([]);
|
|
3305
3523
|
fetchItems({
|
|
@@ -3311,7 +3529,7 @@ function useGroupedContentTab(tabId) {
|
|
|
3311
3529
|
},
|
|
3312
3530
|
[fetchItems, activeCategory]
|
|
3313
3531
|
);
|
|
3314
|
-
const fetchDetail =
|
|
3532
|
+
const fetchDetail = useCallback10(
|
|
3315
3533
|
async (slug) => {
|
|
3316
3534
|
if (!tab?.itemsModelSlug) return;
|
|
3317
3535
|
const cached = readCache2(
|
|
@@ -3346,7 +3564,7 @@ function useGroupedContentTab(tabId) {
|
|
|
3346
3564
|
},
|
|
3347
3565
|
[client, tabId, tab, store]
|
|
3348
3566
|
);
|
|
3349
|
-
const searchCategories =
|
|
3567
|
+
const searchCategories = useCallback10(
|
|
3350
3568
|
(query) => {
|
|
3351
3569
|
if (!query.trim()) {
|
|
3352
3570
|
setCategories(allCategoriesRef.current);
|
|
@@ -3361,10 +3579,10 @@ function useGroupedContentTab(tabId) {
|
|
|
3361
3579
|
},
|
|
3362
3580
|
[]
|
|
3363
3581
|
);
|
|
3364
|
-
const clearDetail =
|
|
3582
|
+
const clearDetail = useCallback10(() => {
|
|
3365
3583
|
setDetail(null);
|
|
3366
3584
|
}, []);
|
|
3367
|
-
const clearCategory =
|
|
3585
|
+
const clearCategory = useCallback10(() => {
|
|
3368
3586
|
setActiveCategory(null);
|
|
3369
3587
|
setItems([]);
|
|
3370
3588
|
setDetail(null);
|
|
@@ -3416,16 +3634,16 @@ function GroupedContentTabView({
|
|
|
3416
3634
|
fetchDetail,
|
|
3417
3635
|
clearCategory
|
|
3418
3636
|
} = useGroupedContentTab(tab.id);
|
|
3419
|
-
|
|
3637
|
+
useEffect9(() => {
|
|
3420
3638
|
initFetch();
|
|
3421
3639
|
}, [initFetch]);
|
|
3422
|
-
|
|
3640
|
+
useEffect9(() => {
|
|
3423
3641
|
if (detailSlug && subView === "content-detail") {
|
|
3424
3642
|
fetchDetail(detailSlug);
|
|
3425
3643
|
}
|
|
3426
3644
|
}, [detailSlug, subView, fetchDetail]);
|
|
3427
|
-
const prevSubView =
|
|
3428
|
-
|
|
3645
|
+
const prevSubView = useRef12(subView);
|
|
3646
|
+
useEffect9(() => {
|
|
3429
3647
|
if (prevSubView.current === "content-category" && subView === null) {
|
|
3430
3648
|
clearCategory();
|
|
3431
3649
|
}
|
|
@@ -3519,10 +3737,10 @@ function FlatContentTabView({
|
|
|
3519
3737
|
loadMore,
|
|
3520
3738
|
fetchDetail
|
|
3521
3739
|
} = useContentTab(tab.id);
|
|
3522
|
-
|
|
3740
|
+
useEffect10(() => {
|
|
3523
3741
|
if (detailSlug) fetchDetail(detailSlug);
|
|
3524
3742
|
}, [detailSlug, fetchDetail]);
|
|
3525
|
-
const handleSearch =
|
|
3743
|
+
const handleSearch = useCallback11(
|
|
3526
3744
|
(query) => {
|
|
3527
3745
|
fetchEntries({ page: 1, search: query || void 0, reset: true });
|
|
3528
3746
|
},
|
|
@@ -3561,9 +3779,97 @@ function ContentTabIconComponent({ icon }) {
|
|
|
3561
3779
|
return /* @__PURE__ */ jsx11(Icon, {});
|
|
3562
3780
|
}
|
|
3563
3781
|
|
|
3564
|
-
// src/themed/
|
|
3565
|
-
import
|
|
3782
|
+
// src/themed/announcement-previews.tsx
|
|
3783
|
+
import { useState as useState12 } from "react";
|
|
3784
|
+
|
|
3785
|
+
// src/themed/strip-markdown.ts
|
|
3786
|
+
function stripMarkdown(text) {
|
|
3787
|
+
return text.replace(/^#{1,6}\s+/gm, "").replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/^[-*+]\s+/gm, "").replace(/\[(.+?)\]\(.+?\)/g, "$1").replace(/`(.+?)`/g, "$1").replace(/\n{2,}/g, " ").replace(/\n/g, " ").trim();
|
|
3788
|
+
}
|
|
3789
|
+
|
|
3790
|
+
// src/themed/announcement-previews.tsx
|
|
3566
3791
|
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3792
|
+
function AnnouncementPreviews({
|
|
3793
|
+
onOpen,
|
|
3794
|
+
avatar,
|
|
3795
|
+
placement = "launcher",
|
|
3796
|
+
footer
|
|
3797
|
+
}) {
|
|
3798
|
+
const previews = useWidgetStore((s) => s.announcementPreviews);
|
|
3799
|
+
const dismissPreview = useWidgetStore((s) => s.dismissAnnouncementPreview);
|
|
3800
|
+
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
3801
|
+
if (previews.length === 0) return null;
|
|
3802
|
+
const stackPlacementClass = placement === "anchored" ? "hw-preview-stack--anchored " : "";
|
|
3803
|
+
return /* @__PURE__ */ jsx12("div", { className: `hw-preview-stack ${stackPlacementClass}`.trim(), children: previews.map((preview) => /* @__PURE__ */ jsx12(
|
|
3804
|
+
AnnouncementPreviewItem,
|
|
3805
|
+
{
|
|
3806
|
+
preview,
|
|
3807
|
+
agentName,
|
|
3808
|
+
avatar,
|
|
3809
|
+
placement,
|
|
3810
|
+
footer,
|
|
3811
|
+
onOpen,
|
|
3812
|
+
onDismiss: (slug) => dismissPreview(slug)
|
|
3813
|
+
},
|
|
3814
|
+
preview.slug
|
|
3815
|
+
)) });
|
|
3816
|
+
}
|
|
3817
|
+
function AnnouncementPreviewItem({
|
|
3818
|
+
preview,
|
|
3819
|
+
agentName,
|
|
3820
|
+
avatar,
|
|
3821
|
+
placement,
|
|
3822
|
+
footer,
|
|
3823
|
+
onOpen,
|
|
3824
|
+
onDismiss
|
|
3825
|
+
}) {
|
|
3826
|
+
const [closing, setClosing] = useState12(false);
|
|
3827
|
+
const handleClose = (e) => {
|
|
3828
|
+
e.stopPropagation();
|
|
3829
|
+
setClosing(true);
|
|
3830
|
+
setTimeout(() => {
|
|
3831
|
+
onDismiss(preview.slug);
|
|
3832
|
+
setClosing(false);
|
|
3833
|
+
}, 200);
|
|
3834
|
+
};
|
|
3835
|
+
const placementClass = placement === "anchored" ? "hw-preview--anchored " : "";
|
|
3836
|
+
return /* @__PURE__ */ jsxs7(
|
|
3837
|
+
"div",
|
|
3838
|
+
{
|
|
3839
|
+
className: `hw-preview hw-preview--announcement ${placementClass}${closing ? "hw-preview--closing" : ""}`.trim(),
|
|
3840
|
+
onClick: () => onOpen(preview.slug, preview.tabId),
|
|
3841
|
+
role: "button",
|
|
3842
|
+
tabIndex: 0,
|
|
3843
|
+
children: [
|
|
3844
|
+
/* @__PURE__ */ jsxs7("div", { className: "hw-preview-header", children: [
|
|
3845
|
+
/* @__PURE__ */ jsx12("div", { className: "hw-preview-avatar", children: avatar }),
|
|
3846
|
+
/* @__PURE__ */ jsx12("div", { className: "hw-preview-name", children: agentName }),
|
|
3847
|
+
/* @__PURE__ */ jsx12(
|
|
3848
|
+
"button",
|
|
3849
|
+
{
|
|
3850
|
+
type: "button",
|
|
3851
|
+
className: "hw-preview-close",
|
|
3852
|
+
onClick: handleClose,
|
|
3853
|
+
"aria-label": t("widget.aria_dismiss"),
|
|
3854
|
+
children: /* @__PURE__ */ jsx12(XIcon, { size: 20 })
|
|
3855
|
+
}
|
|
3856
|
+
)
|
|
3857
|
+
] }),
|
|
3858
|
+
preview.badge && /* @__PURE__ */ jsx12("div", { className: "hw-announcement-badge", children: preview.badge }),
|
|
3859
|
+
/* @__PURE__ */ jsx12("div", { className: "hw-preview-body hw-preview-body--title", children: preview.title }),
|
|
3860
|
+
preview.body && (() => {
|
|
3861
|
+
const clean = stripMarkdown(preview.body);
|
|
3862
|
+
return /* @__PURE__ */ jsx12("div", { className: "hw-preview-body hw-preview-body--desc", children: clean.length > 120 ? `${clean.slice(0, 120)}\u2026` : clean });
|
|
3863
|
+
})(),
|
|
3864
|
+
footer != null && footer !== false && /* @__PURE__ */ jsx12("div", { className: "hw-preview-footer", children: footer })
|
|
3865
|
+
]
|
|
3866
|
+
}
|
|
3867
|
+
);
|
|
3868
|
+
}
|
|
3869
|
+
|
|
3870
|
+
// src/themed/message-list.tsx
|
|
3871
|
+
import React, { useEffect as useEffect11, useRef as useRef13 } from "react";
|
|
3872
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3567
3873
|
function parseParts(raw) {
|
|
3568
3874
|
if (!raw) return null;
|
|
3569
3875
|
if (Array.isArray(raw)) return raw;
|
|
@@ -3595,11 +3901,11 @@ function MessageList({
|
|
|
3595
3901
|
onLoadMore,
|
|
3596
3902
|
renderAfterMessages
|
|
3597
3903
|
}) {
|
|
3598
|
-
const bottomRef =
|
|
3599
|
-
const topRef =
|
|
3600
|
-
const containerRef =
|
|
3601
|
-
const prevItemCountRef =
|
|
3602
|
-
const isInitialLoadRef =
|
|
3904
|
+
const bottomRef = useRef13(null);
|
|
3905
|
+
const topRef = useRef13(null);
|
|
3906
|
+
const containerRef = useRef13(null);
|
|
3907
|
+
const prevItemCountRef = useRef13(items.length);
|
|
3908
|
+
const isInitialLoadRef = useRef13(true);
|
|
3603
3909
|
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? t("widget.helpway_ai");
|
|
3604
3910
|
const client = useWidgetClient();
|
|
3605
3911
|
const activeConversationId = useWidgetStore((s) => s.activeConversationId);
|
|
@@ -3612,7 +3918,7 @@ function MessageList({
|
|
|
3612
3918
|
},
|
|
3613
3919
|
[client, activeConversationId]
|
|
3614
3920
|
);
|
|
3615
|
-
|
|
3921
|
+
useEffect11(() => {
|
|
3616
3922
|
const prevCount = prevItemCountRef.current;
|
|
3617
3923
|
const newCount = items.length;
|
|
3618
3924
|
prevItemCountRef.current = newCount;
|
|
@@ -3627,12 +3933,12 @@ function MessageList({
|
|
|
3627
3933
|
isInitialLoadRef.current = false;
|
|
3628
3934
|
}
|
|
3629
3935
|
}, [items]);
|
|
3630
|
-
|
|
3936
|
+
useEffect11(() => {
|
|
3631
3937
|
if (isTyping || isAiProcessing) {
|
|
3632
3938
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
3633
3939
|
}
|
|
3634
3940
|
}, [isTyping, isAiProcessing]);
|
|
3635
|
-
|
|
3941
|
+
useEffect11(() => {
|
|
3636
3942
|
if (!hasMore || !onLoadMore || !topRef.current) return;
|
|
3637
3943
|
const observer = new IntersectionObserver(
|
|
3638
3944
|
(entries) => {
|
|
@@ -3655,16 +3961,16 @@ function MessageList({
|
|
|
3655
3961
|
return () => observer.disconnect();
|
|
3656
3962
|
}, [hasMore, onLoadMore, isLoadingMore]);
|
|
3657
3963
|
if (items.length === 0) {
|
|
3658
|
-
return /* @__PURE__ */
|
|
3964
|
+
return /* @__PURE__ */ jsx13(
|
|
3659
3965
|
"div",
|
|
3660
3966
|
{
|
|
3661
3967
|
className: "hw-messages",
|
|
3662
3968
|
role: "log",
|
|
3663
3969
|
"aria-label": t("widget.aria_messages"),
|
|
3664
3970
|
"aria-live": "polite",
|
|
3665
|
-
children: /* @__PURE__ */
|
|
3666
|
-
/* @__PURE__ */
|
|
3667
|
-
/* @__PURE__ */
|
|
3971
|
+
children: /* @__PURE__ */ jsxs8("div", { className: "hw-empty", children: [
|
|
3972
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-empty-icon", children: /* @__PURE__ */ jsx13("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx13("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }) }) }),
|
|
3973
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-empty-text", children: t("widget.start_a_conversation") })
|
|
3668
3974
|
] })
|
|
3669
3975
|
}
|
|
3670
3976
|
);
|
|
@@ -3674,7 +3980,7 @@ function MessageList({
|
|
|
3674
3980
|
const yesterday = /* @__PURE__ */ new Date();
|
|
3675
3981
|
yesterday.setDate(yesterday.getDate() - 1);
|
|
3676
3982
|
const yesterdayKey = yesterday.toLocaleDateString("en-CA");
|
|
3677
|
-
return /* @__PURE__ */
|
|
3983
|
+
return /* @__PURE__ */ jsxs8(
|
|
3678
3984
|
"div",
|
|
3679
3985
|
{
|
|
3680
3986
|
ref: containerRef,
|
|
@@ -3683,14 +3989,14 @@ function MessageList({
|
|
|
3683
3989
|
"aria-label": t("widget.aria_messages"),
|
|
3684
3990
|
"aria-live": "polite",
|
|
3685
3991
|
children: [
|
|
3686
|
-
/* @__PURE__ */
|
|
3687
|
-
/* @__PURE__ */
|
|
3688
|
-
/* @__PURE__ */
|
|
3689
|
-
/* @__PURE__ */
|
|
3992
|
+
/* @__PURE__ */ jsx13("div", { ref: topRef, className: "hw-load-more-trigger", children: isLoadingMore && /* @__PURE__ */ jsxs8("div", { className: "hw-load-more-spinner", children: [
|
|
3993
|
+
/* @__PURE__ */ jsx13("div", {}),
|
|
3994
|
+
/* @__PURE__ */ jsx13("div", {}),
|
|
3995
|
+
/* @__PURE__ */ jsx13("div", {})
|
|
3690
3996
|
] }) }),
|
|
3691
3997
|
items.map((item) => {
|
|
3692
3998
|
if (item.type === "event") {
|
|
3693
|
-
return /* @__PURE__ */
|
|
3999
|
+
return /* @__PURE__ */ jsx13(EventCard, { text: item.text ?? "" }, item._stableKey ?? item.id);
|
|
3694
4000
|
}
|
|
3695
4001
|
const itemDate = new Date(item.createdAt);
|
|
3696
4002
|
const dateKey = itemDate.toLocaleDateString("en-CA");
|
|
@@ -3708,13 +4014,13 @@ function MessageList({
|
|
|
3708
4014
|
const nextSender = nextItem?.type === "message" ? nextItem.visitorId ? "visitor" : nextItem.aiAgentId ? "ai" : "team" : null;
|
|
3709
4015
|
const isLastInGroup = nextSender !== sender || nextItem?.type === "event";
|
|
3710
4016
|
const timeLabel = isLastInGroup ? itemDate.toLocaleTimeString(getLocale(), { hour: "2-digit", minute: "2-digit" }) : void 0;
|
|
3711
|
-
return /* @__PURE__ */
|
|
3712
|
-
showDateSep && /* @__PURE__ */
|
|
3713
|
-
/* @__PURE__ */
|
|
3714
|
-
/* @__PURE__ */
|
|
3715
|
-
/* @__PURE__ */
|
|
4017
|
+
return /* @__PURE__ */ jsxs8(React.Fragment, { children: [
|
|
4018
|
+
showDateSep && /* @__PURE__ */ jsxs8("div", { className: "hw-date-sep", children: [
|
|
4019
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-date-sep-line" }),
|
|
4020
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-date-sep-text", children: dateLabel }),
|
|
4021
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-date-sep-line" })
|
|
3716
4022
|
] }),
|
|
3717
|
-
/* @__PURE__ */
|
|
4023
|
+
/* @__PURE__ */ jsx13(
|
|
3718
4024
|
MessageBubble,
|
|
3719
4025
|
{
|
|
3720
4026
|
text: item.text ?? "",
|
|
@@ -3731,24 +4037,24 @@ function MessageList({
|
|
|
3731
4037
|
] }, item._stableKey ?? item.id);
|
|
3732
4038
|
}),
|
|
3733
4039
|
renderAfterMessages,
|
|
3734
|
-
streamingText && /* @__PURE__ */
|
|
3735
|
-
/* @__PURE__ */
|
|
3736
|
-
/* @__PURE__ */
|
|
4040
|
+
streamingText && /* @__PURE__ */ jsx13("div", { className: "hw-message hw-message-ai", children: /* @__PURE__ */ jsxs8("div", { className: "hw-bubble hw-bubble-ai", children: [
|
|
4041
|
+
/* @__PURE__ */ jsx13("span", { children: streamingText }),
|
|
4042
|
+
/* @__PURE__ */ jsx13("span", { className: "hw-streaming-cursor" })
|
|
3737
4043
|
] }) }),
|
|
3738
|
-
isAiProcessing && !streamingText && /* @__PURE__ */
|
|
3739
|
-
/* @__PURE__ */
|
|
3740
|
-
/* @__PURE__ */
|
|
3741
|
-
/* @__PURE__ */
|
|
3742
|
-
/* @__PURE__ */
|
|
3743
|
-
/* @__PURE__ */
|
|
4044
|
+
isAiProcessing && !streamingText && /* @__PURE__ */ jsxs8("div", { className: "hw-typing", children: [
|
|
4045
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-typing-label", children: agentName }),
|
|
4046
|
+
/* @__PURE__ */ jsxs8("div", { className: "hw-typing-dots", children: [
|
|
4047
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-typing-dot" }),
|
|
4048
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-typing-dot" }),
|
|
4049
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-typing-dot" })
|
|
3744
4050
|
] })
|
|
3745
4051
|
] }),
|
|
3746
|
-
isTyping && !isAiProcessing && /* @__PURE__ */
|
|
3747
|
-
/* @__PURE__ */
|
|
3748
|
-
/* @__PURE__ */
|
|
3749
|
-
/* @__PURE__ */
|
|
4052
|
+
isTyping && !isAiProcessing && /* @__PURE__ */ jsx13("div", { className: "hw-typing", children: /* @__PURE__ */ jsxs8("div", { className: "hw-typing-dots", children: [
|
|
4053
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-typing-dot" }),
|
|
4054
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-typing-dot" }),
|
|
4055
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-typing-dot" })
|
|
3750
4056
|
] }) }),
|
|
3751
|
-
/* @__PURE__ */
|
|
4057
|
+
/* @__PURE__ */ jsx13("div", { ref: bottomRef })
|
|
3752
4058
|
]
|
|
3753
4059
|
}
|
|
3754
4060
|
);
|
|
@@ -3766,20 +4072,109 @@ function EventCard({ text }) {
|
|
|
3766
4072
|
const data = parseEventData(text);
|
|
3767
4073
|
if (data) {
|
|
3768
4074
|
const message = data.action === "joined" ? t("widget.joined") : t("widget.left");
|
|
3769
|
-
return /* @__PURE__ */
|
|
3770
|
-
/* @__PURE__ */
|
|
3771
|
-
/* @__PURE__ */
|
|
3772
|
-
/* @__PURE__ */
|
|
4075
|
+
return /* @__PURE__ */ jsxs8("div", { className: "hw-event hw-event--card", children: [
|
|
4076
|
+
/* @__PURE__ */ jsx13("div", { className: "hw-event-avatar", children: data.image ? /* @__PURE__ */ jsx13("img", { src: data.image, alt: "", className: "hw-event-avatar-img" }) : /* @__PURE__ */ jsx13("span", { children: getInitials(data.name) }) }),
|
|
4077
|
+
/* @__PURE__ */ jsxs8("div", { className: "hw-event-body", children: [
|
|
4078
|
+
/* @__PURE__ */ jsx13("span", { className: "hw-event-name", children: data.name }),
|
|
3773
4079
|
" ",
|
|
3774
|
-
/* @__PURE__ */
|
|
4080
|
+
/* @__PURE__ */ jsx13("span", { className: "hw-event-action", children: message })
|
|
3775
4081
|
] })
|
|
3776
4082
|
] });
|
|
3777
4083
|
}
|
|
3778
|
-
return /* @__PURE__ */
|
|
4084
|
+
return /* @__PURE__ */ jsx13("div", { className: "hw-event", children: /* @__PURE__ */ jsx13("div", { className: "hw-event-text", children: text }) });
|
|
4085
|
+
}
|
|
4086
|
+
|
|
4087
|
+
// src/themed/message-preview.tsx
|
|
4088
|
+
import { useEffect as useEffect12, useState as useState13 } from "react";
|
|
4089
|
+
import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4090
|
+
function MessagePreview({
|
|
4091
|
+
onOpen,
|
|
4092
|
+
avatar,
|
|
4093
|
+
placement = "launcher",
|
|
4094
|
+
autoDismissMs = 8e3,
|
|
4095
|
+
footer
|
|
4096
|
+
}) {
|
|
4097
|
+
const preview = useWidgetStore((s) => s.incomingPreview);
|
|
4098
|
+
const dismissPreview = useWidgetStore((s) => s.dismissPreview);
|
|
4099
|
+
const setActiveConversation = useWidgetStore((s) => s.setActiveConversation);
|
|
4100
|
+
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
4101
|
+
const [closing, setClosing] = useState13(false);
|
|
4102
|
+
useEffect12(() => {
|
|
4103
|
+
if (!preview || preview.quickReplies) return;
|
|
4104
|
+
if (autoDismissMs == null || autoDismissMs <= 0) return;
|
|
4105
|
+
const timer = setTimeout(() => {
|
|
4106
|
+
setClosing(true);
|
|
4107
|
+
setTimeout(() => dismissPreview(), 200);
|
|
4108
|
+
}, autoDismissMs);
|
|
4109
|
+
return () => clearTimeout(timer);
|
|
4110
|
+
}, [preview, dismissPreview, autoDismissMs]);
|
|
4111
|
+
if (!preview) return null;
|
|
4112
|
+
const handleClose = (e) => {
|
|
4113
|
+
e.stopPropagation();
|
|
4114
|
+
setClosing(true);
|
|
4115
|
+
setTimeout(() => {
|
|
4116
|
+
dismissPreview();
|
|
4117
|
+
setClosing(false);
|
|
4118
|
+
}, 200);
|
|
4119
|
+
};
|
|
4120
|
+
const handleClick = () => {
|
|
4121
|
+
const targetConvId = preview.conversationId;
|
|
4122
|
+
dismissPreview();
|
|
4123
|
+
setActiveConversation(targetConvId);
|
|
4124
|
+
onOpen();
|
|
4125
|
+
};
|
|
4126
|
+
const messages = preview.messages?.length ? preview.messages : [{ text: preview.text }];
|
|
4127
|
+
const hasQr = preview.quickReplies && preview.quickReplies.options.length > 0;
|
|
4128
|
+
const placementClass = placement === "anchored" ? "hw-preview--anchored " : "";
|
|
4129
|
+
return /* @__PURE__ */ jsxs9(
|
|
4130
|
+
"div",
|
|
4131
|
+
{
|
|
4132
|
+
className: `hw-preview ${placementClass}${closing ? "hw-preview--closing" : ""}`,
|
|
4133
|
+
onClick: handleClick,
|
|
4134
|
+
role: "button",
|
|
4135
|
+
tabIndex: 0,
|
|
4136
|
+
children: [
|
|
4137
|
+
/* @__PURE__ */ jsxs9("div", { className: "hw-preview-header", children: [
|
|
4138
|
+
/* @__PURE__ */ jsx14("div", { className: "hw-preview-avatar", children: avatar }),
|
|
4139
|
+
/* @__PURE__ */ jsx14("div", { className: "hw-preview-name", children: agentName }),
|
|
4140
|
+
/* @__PURE__ */ jsx14(
|
|
4141
|
+
"button",
|
|
4142
|
+
{
|
|
4143
|
+
type: "button",
|
|
4144
|
+
className: "hw-preview-close",
|
|
4145
|
+
onClick: handleClose,
|
|
4146
|
+
"aria-label": t("widget.aria_dismiss"),
|
|
4147
|
+
children: /* @__PURE__ */ jsx14(XIcon, { size: 20 })
|
|
4148
|
+
}
|
|
4149
|
+
)
|
|
4150
|
+
] }),
|
|
4151
|
+
messages.map((m, i) => /* @__PURE__ */ jsx14("div", { className: "hw-preview-body", children: m.text }, i)),
|
|
4152
|
+
hasQr && /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
4153
|
+
preview.quickReplies.prompt && /* @__PURE__ */ jsx14("div", { className: "hw-preview-body", children: preview.quickReplies.prompt }),
|
|
4154
|
+
/* @__PURE__ */ jsx14("div", { className: "hw-preview-quick-replies", children: preview.quickReplies.options.map((opt) => /* @__PURE__ */ jsx14(
|
|
4155
|
+
"button",
|
|
4156
|
+
{
|
|
4157
|
+
type: "button",
|
|
4158
|
+
className: "hw-preview-qr-btn",
|
|
4159
|
+
onClick: (e) => {
|
|
4160
|
+
e.stopPropagation();
|
|
4161
|
+
dismissPreview();
|
|
4162
|
+
setActiveConversation(preview.conversationId);
|
|
4163
|
+
onOpen();
|
|
4164
|
+
},
|
|
4165
|
+
children: opt.label
|
|
4166
|
+
},
|
|
4167
|
+
opt.id
|
|
4168
|
+
)) })
|
|
4169
|
+
] }),
|
|
4170
|
+
footer != null && footer !== false && /* @__PURE__ */ jsx14("div", { className: "hw-preview-footer", children: footer })
|
|
4171
|
+
]
|
|
4172
|
+
}
|
|
4173
|
+
);
|
|
3779
4174
|
}
|
|
3780
4175
|
|
|
3781
4176
|
// src/themed/default-widget.tsx
|
|
3782
|
-
import { Fragment as
|
|
4177
|
+
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3783
4178
|
function resolveLabel2(label) {
|
|
3784
4179
|
if (!label.startsWith("widget.")) return label;
|
|
3785
4180
|
const resolved = t(label);
|
|
@@ -3791,7 +4186,7 @@ var EMPTY_CONTENT_TABS = [];
|
|
|
3791
4186
|
var DEFAULT_EN_WELCOME = "Hi there \u{1F44B}\nHow can we help?";
|
|
3792
4187
|
var DEFAULT_EN_SUBTITLE = "Usually replies in minutes";
|
|
3793
4188
|
function HelpwayMark({ className }) {
|
|
3794
|
-
return /* @__PURE__ */
|
|
4189
|
+
return /* @__PURE__ */ jsx15(
|
|
3795
4190
|
"svg",
|
|
3796
4191
|
{
|
|
3797
4192
|
className,
|
|
@@ -3801,7 +4196,7 @@ function HelpwayMark({ className }) {
|
|
|
3801
4196
|
fill: "none",
|
|
3802
4197
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3803
4198
|
"aria-hidden": "true",
|
|
3804
|
-
children: /* @__PURE__ */
|
|
4199
|
+
children: /* @__PURE__ */ jsx15(
|
|
3805
4200
|
"path",
|
|
3806
4201
|
{
|
|
3807
4202
|
d: "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",
|
|
@@ -3825,7 +4220,7 @@ function WidgetLogo({
|
|
|
3825
4220
|
});
|
|
3826
4221
|
const logoClass = forceAgent ? "hw-agent-img--logo" : "";
|
|
3827
4222
|
if (!forceAgent && activeId && assignee?.assigneeImage) {
|
|
3828
|
-
return /* @__PURE__ */
|
|
4223
|
+
return /* @__PURE__ */ jsx15(
|
|
3829
4224
|
"img",
|
|
3830
4225
|
{
|
|
3831
4226
|
src: assignee.assigneeImage,
|
|
@@ -3835,10 +4230,10 @@ function WidgetLogo({
|
|
|
3835
4230
|
);
|
|
3836
4231
|
}
|
|
3837
4232
|
if (agentConfig?.avatarUrl) {
|
|
3838
|
-
return /* @__PURE__ */
|
|
4233
|
+
return /* @__PURE__ */ jsx15("img", { src: agentConfig.avatarUrl, alt: "", className: `hw-agent-img ${logoClass} ${className ?? ""}` });
|
|
3839
4234
|
}
|
|
3840
4235
|
if (agentConfig?.avatarPreset) {
|
|
3841
|
-
return /* @__PURE__ */
|
|
4236
|
+
return /* @__PURE__ */ jsx15(
|
|
3842
4237
|
"div",
|
|
3843
4238
|
{
|
|
3844
4239
|
className: `hw-agent-icon ${className ?? ""}`,
|
|
@@ -3849,20 +4244,20 @@ function WidgetLogo({
|
|
|
3849
4244
|
justifyContent: "center",
|
|
3850
4245
|
borderRadius: 8
|
|
3851
4246
|
},
|
|
3852
|
-
children: /* @__PURE__ */
|
|
4247
|
+
children: /* @__PURE__ */ jsx15(AgentPresetIcon, { presetId: agentConfig.avatarPreset })
|
|
3853
4248
|
}
|
|
3854
4249
|
);
|
|
3855
4250
|
}
|
|
3856
4251
|
if (logoUrl) {
|
|
3857
|
-
return /* @__PURE__ */
|
|
4252
|
+
return /* @__PURE__ */ jsx15("img", { src: logoUrl, alt: "", className: `hw-agent-img hw-agent-img--logo ${className ?? ""}` });
|
|
3858
4253
|
}
|
|
3859
|
-
return /* @__PURE__ */
|
|
4254
|
+
return /* @__PURE__ */ jsx15(HelpwayMark, { className });
|
|
3860
4255
|
}
|
|
3861
4256
|
function LauncherIcon({ className }) {
|
|
3862
4257
|
const agentConfig = useWidgetStore((s) => s.agentConfig);
|
|
3863
|
-
const [imgLoaded, setImgLoaded] =
|
|
4258
|
+
const [imgLoaded, setImgLoaded] = useState14(false);
|
|
3864
4259
|
const imgSrc = agentConfig?.launcherIconUrl ?? null;
|
|
3865
|
-
|
|
4260
|
+
useEffect13(() => {
|
|
3866
4261
|
if (!imgSrc) return;
|
|
3867
4262
|
setImgLoaded(false);
|
|
3868
4263
|
const img = new Image();
|
|
@@ -3875,7 +4270,7 @@ function LauncherIcon({ className }) {
|
|
|
3875
4270
|
img.onerror = () => setImgLoaded(true);
|
|
3876
4271
|
}, [imgSrc]);
|
|
3877
4272
|
if (imgSrc) {
|
|
3878
|
-
return /* @__PURE__ */
|
|
4273
|
+
return /* @__PURE__ */ jsx15(
|
|
3879
4274
|
"img",
|
|
3880
4275
|
{
|
|
3881
4276
|
src: imgSrc,
|
|
@@ -3885,7 +4280,7 @@ function LauncherIcon({ className }) {
|
|
|
3885
4280
|
}
|
|
3886
4281
|
);
|
|
3887
4282
|
}
|
|
3888
|
-
return /* @__PURE__ */
|
|
4283
|
+
return /* @__PURE__ */ jsx15(WidgetLogo, { className, forceAgent: true });
|
|
3889
4284
|
}
|
|
3890
4285
|
var PRESET_SVG = {
|
|
3891
4286
|
// Helpway brand mark — octagonal chamfer with stylized "W" inside.
|
|
@@ -3944,7 +4339,7 @@ function AgentPresetIcon({ presetId }) {
|
|
|
3944
4339
|
const svgContent = PRESET_SVG[presetId] ?? PRESET_SVG.sparkle;
|
|
3945
4340
|
return (
|
|
3946
4341
|
// biome-ignore lint: trusted static SVG content from our icon library
|
|
3947
|
-
/* @__PURE__ */
|
|
4342
|
+
/* @__PURE__ */ jsx15(
|
|
3948
4343
|
"svg",
|
|
3949
4344
|
{
|
|
3950
4345
|
viewBox: "0 0 24 24",
|
|
@@ -3965,6 +4360,8 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
3965
4360
|
const isDismissed = useWidgetStore((s) => s.isDismissed);
|
|
3966
4361
|
const { totalUnread } = useUnread();
|
|
3967
4362
|
const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_CONTENT_TABS;
|
|
4363
|
+
const { announcementTabs, markEntrySeen, markAllSeen, getUnseenEntries } = useAnnouncements();
|
|
4364
|
+
const unseenAnnouncementCount = useWidgetStore((s) => s.unseenAnnouncementCount);
|
|
3968
4365
|
const visitorContact = useWidgetStore((s) => s.visitor?.contact);
|
|
3969
4366
|
if (process.env.NODE_ENV !== "production") {
|
|
3970
4367
|
console.debug("[Widget]", {
|
|
@@ -3974,22 +4371,22 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
3974
4371
|
});
|
|
3975
4372
|
}
|
|
3976
4373
|
const storeIsOpen = useWidgetStore((s) => s.isOpen);
|
|
3977
|
-
const [isClosing, setIsClosing] =
|
|
4374
|
+
const [isClosing, setIsClosing] = useState14(false);
|
|
3978
4375
|
const isOpen = storeIsOpen || isClosing;
|
|
3979
|
-
const [activeTab, setActiveTab] =
|
|
3980
|
-
const [subView, setSubView] =
|
|
3981
|
-
const [newText, setNewText] =
|
|
3982
|
-
const [contentDetailSlug, setContentDetailSlug] =
|
|
3983
|
-
const [contentCategoryName, setContentCategoryName] =
|
|
3984
|
-
const prevActiveIdRef =
|
|
3985
|
-
|
|
4376
|
+
const [activeTab, setActiveTab] = useState14("home");
|
|
4377
|
+
const [subView, setSubView] = useState14(null);
|
|
4378
|
+
const [newText, setNewText] = useState14("");
|
|
4379
|
+
const [contentDetailSlug, setContentDetailSlug] = useState14(null);
|
|
4380
|
+
const [contentCategoryName, setContentCategoryName] = useState14(null);
|
|
4381
|
+
const prevActiveIdRef = useRef14(activeId);
|
|
4382
|
+
useEffect13(() => {
|
|
3986
4383
|
if (activeId && activeId !== prevActiveIdRef.current && subView !== "conversation") {
|
|
3987
4384
|
setSubView("conversation");
|
|
3988
4385
|
}
|
|
3989
4386
|
prevActiveIdRef.current = activeId;
|
|
3990
4387
|
}, [activeId, subView]);
|
|
3991
4388
|
const prefill = useWidgetStore((s) => s.newConversationPrefill);
|
|
3992
|
-
|
|
4389
|
+
useEffect13(() => {
|
|
3993
4390
|
if (prefill !== null) {
|
|
3994
4391
|
if (prefill.length > 0) setNewText(prefill);
|
|
3995
4392
|
setSubView("new");
|
|
@@ -3997,18 +4394,18 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
3997
4394
|
store.getState().setNewConversationPrefill(null);
|
|
3998
4395
|
}
|
|
3999
4396
|
}, [prefill, store]);
|
|
4000
|
-
const closeTimerRef =
|
|
4397
|
+
const closeTimerRef = useRef14(void 0);
|
|
4001
4398
|
const welcomeMsgRaw = agentConfig?.welcomeMessage;
|
|
4002
4399
|
const welcomeIsFactoryDefault = !welcomeMsgRaw || welcomeMsgRaw === DEFAULT_EN_WELCOME;
|
|
4003
4400
|
const welcomeMessage = welcomeMsgRaw?.startsWith("widget.") ? t(welcomeMsgRaw) : welcomeIsFactoryDefault ? t("widget.welcome_message") : welcomeMsgRaw;
|
|
4004
|
-
const openConversation =
|
|
4401
|
+
const openConversation = useCallback12(
|
|
4005
4402
|
(id) => {
|
|
4006
4403
|
setActiveConversation(id);
|
|
4007
4404
|
setSubView("conversation");
|
|
4008
4405
|
},
|
|
4009
4406
|
[setActiveConversation]
|
|
4010
4407
|
);
|
|
4011
|
-
const openNewConversation =
|
|
4408
|
+
const openNewConversation = useCallback12(() => {
|
|
4012
4409
|
const agentId = agentConfig?.id;
|
|
4013
4410
|
if (!agentId) {
|
|
4014
4411
|
setSubView("new");
|
|
@@ -4034,7 +4431,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4034
4431
|
setActiveConversation(tempId);
|
|
4035
4432
|
setSubView("conversation");
|
|
4036
4433
|
}, [agentConfig?.id, store, setActiveConversation, welcomeMessage]);
|
|
4037
|
-
const goBack =
|
|
4434
|
+
const goBack = useCallback12(() => {
|
|
4038
4435
|
if (subView === "content-detail") {
|
|
4039
4436
|
const tabId = activeTab.startsWith("content:") ? activeTab.slice(8) : null;
|
|
4040
4437
|
const activeContentTab = tabId ? contentTabs.find((t2) => t2.id === tabId) : null;
|
|
@@ -4061,7 +4458,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4061
4458
|
setActiveConversation(null);
|
|
4062
4459
|
setSubView(null);
|
|
4063
4460
|
}, [setActiveConversation, subView, activeTab, contentTabs, contentCategoryName, client, store]);
|
|
4064
|
-
const switchTab =
|
|
4461
|
+
const switchTab = useCallback12(
|
|
4065
4462
|
(tab) => {
|
|
4066
4463
|
tabStateRef.current[activeTab] = { subView, activeId };
|
|
4067
4464
|
const saved = tabStateRef.current[tab];
|
|
@@ -4076,7 +4473,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4076
4473
|
[activeTab, subView, activeId, setActiveConversation]
|
|
4077
4474
|
);
|
|
4078
4475
|
const setStoreOpen = useWidgetStore((s) => s.setOpen);
|
|
4079
|
-
const handleBubbleClick =
|
|
4476
|
+
const handleBubbleClick = useCallback12(() => {
|
|
4080
4477
|
if (storeIsOpen) {
|
|
4081
4478
|
const leavingId = store.getState().activeConversationId;
|
|
4082
4479
|
if (leavingId && !leavingId.startsWith("temp-")) {
|
|
@@ -4096,7 +4493,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4096
4493
|
setStoreOpen(true);
|
|
4097
4494
|
}
|
|
4098
4495
|
}, [storeIsOpen, setStoreOpen, client, store]);
|
|
4099
|
-
const handleClose =
|
|
4496
|
+
const handleClose = useCallback12(() => {
|
|
4100
4497
|
const leavingId = store.getState().activeConversationId;
|
|
4101
4498
|
if (leavingId && !leavingId.startsWith("temp-")) {
|
|
4102
4499
|
store.getState().clearUnread(leavingId);
|
|
@@ -4109,7 +4506,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4109
4506
|
setStoreOpen(false);
|
|
4110
4507
|
}, 200);
|
|
4111
4508
|
}, [setStoreOpen, client, store]);
|
|
4112
|
-
const handleNewConversation =
|
|
4509
|
+
const handleNewConversation = useCallback12(async () => {
|
|
4113
4510
|
const trimmed = newText.trim();
|
|
4114
4511
|
if (!trimmed || isCreating) return;
|
|
4115
4512
|
const conv = await create(trimmed);
|
|
@@ -4118,16 +4515,16 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4118
4515
|
setSubView("conversation");
|
|
4119
4516
|
}
|
|
4120
4517
|
}, [newText, isCreating, create]);
|
|
4121
|
-
const windowRef =
|
|
4122
|
-
const bubbleRef =
|
|
4123
|
-
const tabStateRef =
|
|
4124
|
-
const touchStartY =
|
|
4125
|
-
const touchDeltaY =
|
|
4126
|
-
const handleTouchStart =
|
|
4518
|
+
const windowRef = useRef14(null);
|
|
4519
|
+
const bubbleRef = useRef14(null);
|
|
4520
|
+
const tabStateRef = useRef14({});
|
|
4521
|
+
const touchStartY = useRef14(0);
|
|
4522
|
+
const touchDeltaY = useRef14(0);
|
|
4523
|
+
const handleTouchStart = useCallback12((e) => {
|
|
4127
4524
|
touchStartY.current = e.touches[0]?.clientY ?? 0;
|
|
4128
4525
|
touchDeltaY.current = 0;
|
|
4129
4526
|
}, []);
|
|
4130
|
-
const handleTouchMove =
|
|
4527
|
+
const handleTouchMove = useCallback12((e) => {
|
|
4131
4528
|
const delta = (e.touches[0]?.clientY ?? 0) - touchStartY.current;
|
|
4132
4529
|
touchDeltaY.current = delta;
|
|
4133
4530
|
if (delta > 0 && windowRef.current) {
|
|
@@ -4135,7 +4532,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4135
4532
|
windowRef.current.style.opacity = `${Math.max(1 - delta / 400, 0.5)}`;
|
|
4136
4533
|
}
|
|
4137
4534
|
}, []);
|
|
4138
|
-
const handleTouchEnd =
|
|
4535
|
+
const handleTouchEnd = useCallback12(() => {
|
|
4139
4536
|
if (windowRef.current) {
|
|
4140
4537
|
windowRef.current.style.transform = "";
|
|
4141
4538
|
windowRef.current.style.opacity = "";
|
|
@@ -4144,7 +4541,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4144
4541
|
handleClose();
|
|
4145
4542
|
}
|
|
4146
4543
|
}, [handleClose]);
|
|
4147
|
-
|
|
4544
|
+
useEffect13(() => {
|
|
4148
4545
|
if (!isOpen || !windowRef.current) return;
|
|
4149
4546
|
const vv = window.visualViewport;
|
|
4150
4547
|
if (!vv) return;
|
|
@@ -4161,7 +4558,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4161
4558
|
win.style.removeProperty("--hw-visible-height");
|
|
4162
4559
|
};
|
|
4163
4560
|
}, [isOpen]);
|
|
4164
|
-
|
|
4561
|
+
useEffect13(() => {
|
|
4165
4562
|
if (!isOpen || !windowRef.current) return;
|
|
4166
4563
|
const win = windowRef.current;
|
|
4167
4564
|
const handleKeyDown = (e) => {
|
|
@@ -4177,8 +4574,8 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4177
4574
|
win.addEventListener("keydown", handleKeyDown);
|
|
4178
4575
|
return () => win.removeEventListener("keydown", handleKeyDown);
|
|
4179
4576
|
}, [isOpen, subView, handleClose, goBack]);
|
|
4180
|
-
|
|
4181
|
-
if (!isOpen || !windowRef.current) return;
|
|
4577
|
+
useEffect13(() => {
|
|
4578
|
+
if (!isOpen || !windowRef.current || hideLauncher) return;
|
|
4182
4579
|
const win = windowRef.current;
|
|
4183
4580
|
const getFocusable = () => win.querySelectorAll(
|
|
4184
4581
|
'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
@@ -4207,7 +4604,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4207
4604
|
const focusable = getFocusable();
|
|
4208
4605
|
if (focusable.length > 0) focusable[0]?.focus();
|
|
4209
4606
|
return () => win.removeEventListener("keydown", handleTab);
|
|
4210
|
-
}, [isOpen]);
|
|
4607
|
+
}, [isOpen, hideLauncher]);
|
|
4211
4608
|
const showTabBar = subView === null;
|
|
4212
4609
|
const activeConvSummary = useWidgetStore((s) => {
|
|
4213
4610
|
const id = s.activeConversationId;
|
|
@@ -4225,7 +4622,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4225
4622
|
const launcherStyle = agentConfig?.launcherStyle ?? "icon";
|
|
4226
4623
|
const bubbleStyle = agentConfig?.bubbleStyle ?? "rounded";
|
|
4227
4624
|
const hasUploadedAvatar = !!agentConfig?.avatarUrl;
|
|
4228
|
-
return /* @__PURE__ */
|
|
4625
|
+
return /* @__PURE__ */ jsxs10(
|
|
4229
4626
|
"div",
|
|
4230
4627
|
{
|
|
4231
4628
|
className: "hw-widget",
|
|
@@ -4238,16 +4635,16 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4238
4635
|
"--hw-window-left": widgetPosition === "bottom-left" ? "0" : "auto"
|
|
4239
4636
|
},
|
|
4240
4637
|
children: [
|
|
4241
|
-
isOpen && !isReady && !hasBootstrapError && /* @__PURE__ */
|
|
4242
|
-
/* @__PURE__ */
|
|
4243
|
-
/* @__PURE__ */
|
|
4244
|
-
/* @__PURE__ */
|
|
4638
|
+
isOpen && !isReady && !hasBootstrapError && /* @__PURE__ */ jsx15("div", { className: `hw-window ${isClosing ? "hw-window--closing" : ""}`, children: /* @__PURE__ */ jsxs10("div", { className: "hw-skeleton-loading", children: [
|
|
4639
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 120 } }),
|
|
4640
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 200 } }),
|
|
4641
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 160 } })
|
|
4245
4642
|
] }) }),
|
|
4246
|
-
isOpen && hasBootstrapError && /* @__PURE__ */
|
|
4247
|
-
/* @__PURE__ */
|
|
4248
|
-
/* @__PURE__ */
|
|
4643
|
+
isOpen && hasBootstrapError && /* @__PURE__ */ jsx15("div", { className: `hw-window ${isClosing ? "hw-window--closing" : ""}`, children: /* @__PURE__ */ jsxs10("div", { className: "hw-bootstrap-error", children: [
|
|
4644
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-bootstrap-error-text", children: t("widget.error_desc") }),
|
|
4645
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "hw-bootstrap-error-retry", onClick: retryBootstrap, children: t("widget.retry") })
|
|
4249
4646
|
] }) }),
|
|
4250
|
-
isOpen && isReady && /* @__PURE__ */
|
|
4647
|
+
isOpen && isReady && /* @__PURE__ */ jsxs10(
|
|
4251
4648
|
"div",
|
|
4252
4649
|
{
|
|
4253
4650
|
ref: windowRef,
|
|
@@ -4259,24 +4656,24 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4259
4656
|
onTouchMove: handleTouchMove,
|
|
4260
4657
|
onTouchEnd: handleTouchEnd,
|
|
4261
4658
|
children: [
|
|
4262
|
-
/* @__PURE__ */
|
|
4263
|
-
wsDisconnected && /* @__PURE__ */
|
|
4264
|
-
/* @__PURE__ */
|
|
4659
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-drag-handle", children: /* @__PURE__ */ jsx15("div", { className: "hw-drag-handle-pill" }) }),
|
|
4660
|
+
wsDisconnected && /* @__PURE__ */ jsxs10("div", { className: "hw-disconnect", children: [
|
|
4661
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-disconnect-dot" }),
|
|
4265
4662
|
t("widget.reconnecting")
|
|
4266
4663
|
] }),
|
|
4267
4664
|
(subView === "content-detail" || subView === "content-category") && (() => {
|
|
4268
4665
|
const tabId = activeTab.replace("content:", "");
|
|
4269
4666
|
const contentTab = contentTabs.find((t2) => t2.id === tabId);
|
|
4270
4667
|
const headerTitle = subView === "content-category" && contentCategoryName ? contentCategoryName : contentTab?.label ? resolveLabel2(contentTab.label) : t("widget.content");
|
|
4271
|
-
return /* @__PURE__ */
|
|
4272
|
-
/* @__PURE__ */
|
|
4668
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-header hw-header--centered", children: [
|
|
4669
|
+
/* @__PURE__ */ jsx15(
|
|
4273
4670
|
"button",
|
|
4274
4671
|
{
|
|
4275
4672
|
type: "button",
|
|
4276
4673
|
className: "hw-header-back",
|
|
4277
4674
|
onClick: goBack,
|
|
4278
4675
|
"aria-label": t("widget.aria_back"),
|
|
4279
|
-
children: /* @__PURE__ */
|
|
4676
|
+
children: /* @__PURE__ */ jsx15(
|
|
4280
4677
|
"svg",
|
|
4281
4678
|
{
|
|
4282
4679
|
viewBox: "0 0 24 24",
|
|
@@ -4285,33 +4682,33 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4285
4682
|
strokeWidth: 2,
|
|
4286
4683
|
strokeLinecap: "round",
|
|
4287
4684
|
strokeLinejoin: "round",
|
|
4288
|
-
children: /* @__PURE__ */
|
|
4685
|
+
children: /* @__PURE__ */ jsx15("path", { d: "M15 18l-6-6 6-6" })
|
|
4289
4686
|
}
|
|
4290
4687
|
)
|
|
4291
4688
|
}
|
|
4292
4689
|
),
|
|
4293
|
-
/* @__PURE__ */
|
|
4294
|
-
/* @__PURE__ */
|
|
4690
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-header-title", children: headerTitle }),
|
|
4691
|
+
/* @__PURE__ */ jsx15(
|
|
4295
4692
|
"button",
|
|
4296
4693
|
{
|
|
4297
4694
|
type: "button",
|
|
4298
4695
|
className: "hw-header-close",
|
|
4299
4696
|
onClick: handleClose,
|
|
4300
4697
|
"aria-label": t("widget.aria_close"),
|
|
4301
|
-
children: /* @__PURE__ */
|
|
4698
|
+
children: /* @__PURE__ */ jsx15(XIcon, { size: 20 })
|
|
4302
4699
|
}
|
|
4303
4700
|
)
|
|
4304
4701
|
] });
|
|
4305
4702
|
})(),
|
|
4306
|
-
subView !== null && subView !== "content-detail" && subView !== "content-category" && /* @__PURE__ */
|
|
4307
|
-
/* @__PURE__ */
|
|
4703
|
+
subView !== null && subView !== "content-detail" && subView !== "content-category" && /* @__PURE__ */ jsxs10("div", { className: "hw-header hw-header--sub", children: [
|
|
4704
|
+
/* @__PURE__ */ jsx15(
|
|
4308
4705
|
"button",
|
|
4309
4706
|
{
|
|
4310
4707
|
type: "button",
|
|
4311
4708
|
className: "hw-header-back",
|
|
4312
4709
|
onClick: goBack,
|
|
4313
4710
|
"aria-label": t("widget.aria_back"),
|
|
4314
|
-
children: /* @__PURE__ */
|
|
4711
|
+
children: /* @__PURE__ */ jsx15(
|
|
4315
4712
|
"svg",
|
|
4316
4713
|
{
|
|
4317
4714
|
viewBox: "0 0 24 24",
|
|
@@ -4320,66 +4717,82 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4320
4717
|
strokeWidth: 2,
|
|
4321
4718
|
strokeLinecap: "round",
|
|
4322
4719
|
strokeLinejoin: "round",
|
|
4323
|
-
children: /* @__PURE__ */
|
|
4720
|
+
children: /* @__PURE__ */ jsx15("path", { d: "M15 18l-6-6 6-6" })
|
|
4324
4721
|
}
|
|
4325
4722
|
)
|
|
4326
4723
|
}
|
|
4327
4724
|
),
|
|
4328
|
-
/* @__PURE__ */
|
|
4329
|
-
/* @__PURE__ */
|
|
4330
|
-
/* @__PURE__ */
|
|
4331
|
-
/* @__PURE__ */
|
|
4332
|
-
/* @__PURE__ */
|
|
4725
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-header-identity", children: [
|
|
4726
|
+
/* @__PURE__ */ jsx15("div", { className: `hw-header-bot-icon${hasTeamAgent ? " hw-header-bot-icon--team" : ""}`, children: hasTeamAgent && activeConvSummary?.lastMessageSenderImage ? /* @__PURE__ */ jsx15("img", { src: activeConvSummary.lastMessageSenderImage, alt: headerName, className: "hw-header-agent-img" }) : hasTeamAgent ? /* @__PURE__ */ jsx15("span", { className: "hw-header-agent-initials", children: headerName.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase() }) : /* @__PURE__ */ jsx15(WidgetLogo, {}) }),
|
|
4727
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-header-info", children: [
|
|
4728
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-header-name", children: headerName }),
|
|
4729
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-header-status", children: subtitleText })
|
|
4333
4730
|
] })
|
|
4334
4731
|
] }),
|
|
4335
|
-
/* @__PURE__ */
|
|
4732
|
+
/* @__PURE__ */ jsx15(
|
|
4336
4733
|
"button",
|
|
4337
4734
|
{
|
|
4338
4735
|
type: "button",
|
|
4339
4736
|
className: "hw-header-close",
|
|
4340
4737
|
onClick: handleClose,
|
|
4341
4738
|
"aria-label": t("widget.aria_close"),
|
|
4342
|
-
children: /* @__PURE__ */
|
|
4739
|
+
children: /* @__PURE__ */ jsx15(XIcon, { size: 20 })
|
|
4343
4740
|
}
|
|
4344
4741
|
)
|
|
4345
4742
|
] }),
|
|
4346
|
-
subView === null && activeTab === "home" && /* @__PURE__ */
|
|
4347
|
-
/* @__PURE__ */
|
|
4348
|
-
/* @__PURE__ */
|
|
4349
|
-
/* @__PURE__ */
|
|
4350
|
-
/* @__PURE__ */
|
|
4743
|
+
subView === null && activeTab === "home" && /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
4744
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-hero", children: [
|
|
4745
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-hero-top", children: [
|
|
4746
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-hero-bot-icon", children: /* @__PURE__ */ jsx15(WidgetLogo, {}) }),
|
|
4747
|
+
/* @__PURE__ */ jsx15(
|
|
4351
4748
|
"button",
|
|
4352
4749
|
{
|
|
4353
4750
|
type: "button",
|
|
4354
4751
|
className: "hw-hero-close",
|
|
4355
4752
|
onClick: handleClose,
|
|
4356
4753
|
"aria-label": t("widget.aria_close"),
|
|
4357
|
-
children: /* @__PURE__ */
|
|
4754
|
+
children: /* @__PURE__ */ jsx15(XIcon, { size: 20 })
|
|
4358
4755
|
}
|
|
4359
4756
|
)
|
|
4360
4757
|
] }),
|
|
4361
|
-
/* @__PURE__ */
|
|
4758
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-hero-greeting", children: welcomeMessage.split("\n").map((line, i) => /* @__PURE__ */ jsxs10(
|
|
4362
4759
|
"span",
|
|
4363
4760
|
{
|
|
4364
4761
|
className: i === 0 ? "hw-hero-greeting-name" : "hw-hero-greeting-question",
|
|
4365
4762
|
children: [
|
|
4366
|
-
i > 0 && /* @__PURE__ */
|
|
4763
|
+
i > 0 && /* @__PURE__ */ jsx15("br", {}),
|
|
4367
4764
|
line
|
|
4368
4765
|
]
|
|
4369
4766
|
},
|
|
4370
4767
|
i
|
|
4371
4768
|
)) }),
|
|
4372
|
-
/* @__PURE__ */
|
|
4769
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-hero-subtitle", children: subtitleText })
|
|
4373
4770
|
] }),
|
|
4374
|
-
/* @__PURE__ */
|
|
4375
|
-
/* @__PURE__ */
|
|
4376
|
-
/* @__PURE__ */
|
|
4377
|
-
/* @__PURE__ */
|
|
4378
|
-
/* @__PURE__ */
|
|
4771
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-sheet", children: /* @__PURE__ */ jsxs10("div", { className: "hw-sheet-inner", children: [
|
|
4772
|
+
/* @__PURE__ */ jsxs10("button", { type: "button", className: "hw-card", onClick: openNewConversation, children: [
|
|
4773
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-card-body", children: [
|
|
4774
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-card-title", children: t("widget.send_us_message") }),
|
|
4775
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-card-meta", children: t("widget.reply_time") })
|
|
4379
4776
|
] }),
|
|
4380
|
-
/* @__PURE__ */
|
|
4777
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-card-arrow", children: /* @__PURE__ */ jsx15(SendIcon, {}) })
|
|
4381
4778
|
] }),
|
|
4382
|
-
/* @__PURE__ */
|
|
4779
|
+
announcementTabs.length > 0 && /* @__PURE__ */ jsx15(
|
|
4780
|
+
WhatsNewCard,
|
|
4781
|
+
{
|
|
4782
|
+
getUnseenEntries,
|
|
4783
|
+
announcementTabs,
|
|
4784
|
+
onViewAll: () => {
|
|
4785
|
+
switchTab(`content:${announcementTabs[0].id}`);
|
|
4786
|
+
},
|
|
4787
|
+
onSelect: (slug, tabId) => {
|
|
4788
|
+
switchTab(`content:${tabId}`);
|
|
4789
|
+
setContentDetailSlug(slug);
|
|
4790
|
+
setSubView("content-detail");
|
|
4791
|
+
markEntrySeen(slug);
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4794
|
+
),
|
|
4795
|
+
/* @__PURE__ */ jsx15(
|
|
4383
4796
|
HomeView,
|
|
4384
4797
|
{
|
|
4385
4798
|
conversations,
|
|
@@ -4389,17 +4802,17 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4389
4802
|
)
|
|
4390
4803
|
] }) })
|
|
4391
4804
|
] }),
|
|
4392
|
-
subView === null && activeTab === "messages" && /* @__PURE__ */
|
|
4393
|
-
/* @__PURE__ */
|
|
4394
|
-
/* @__PURE__ */
|
|
4395
|
-
/* @__PURE__ */
|
|
4805
|
+
subView === null && activeTab === "messages" && /* @__PURE__ */ jsxs10("div", { className: "hw-header hw-header--centered", children: [
|
|
4806
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-header-spacer" }),
|
|
4807
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-header-title", children: t("widget.messages") }),
|
|
4808
|
+
/* @__PURE__ */ jsx15(
|
|
4396
4809
|
"button",
|
|
4397
4810
|
{
|
|
4398
4811
|
type: "button",
|
|
4399
4812
|
className: "hw-header-close",
|
|
4400
4813
|
onClick: handleClose,
|
|
4401
4814
|
"aria-label": t("widget.aria_close"),
|
|
4402
|
-
children: /* @__PURE__ */
|
|
4815
|
+
children: /* @__PURE__ */ jsx15(XIcon, { size: 20 })
|
|
4403
4816
|
}
|
|
4404
4817
|
)
|
|
4405
4818
|
] }),
|
|
@@ -4407,23 +4820,23 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4407
4820
|
const tabId = activeTab.replace("content:", "");
|
|
4408
4821
|
const contentTab = contentTabs.find((t2) => t2.id === tabId);
|
|
4409
4822
|
if (!contentTab) return null;
|
|
4410
|
-
return /* @__PURE__ */
|
|
4411
|
-
/* @__PURE__ */
|
|
4412
|
-
/* @__PURE__ */
|
|
4413
|
-
/* @__PURE__ */
|
|
4823
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-header hw-header--centered", children: [
|
|
4824
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-header-spacer" }),
|
|
4825
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-header-title", children: resolveLabel2(contentTab.label) }),
|
|
4826
|
+
/* @__PURE__ */ jsx15(
|
|
4414
4827
|
"button",
|
|
4415
4828
|
{
|
|
4416
4829
|
type: "button",
|
|
4417
4830
|
className: "hw-header-close",
|
|
4418
4831
|
onClick: handleClose,
|
|
4419
4832
|
"aria-label": t("widget.aria_close"),
|
|
4420
|
-
children: /* @__PURE__ */
|
|
4833
|
+
children: /* @__PURE__ */ jsx15(XIcon, { size: 20 })
|
|
4421
4834
|
}
|
|
4422
4835
|
)
|
|
4423
4836
|
] });
|
|
4424
4837
|
})(),
|
|
4425
|
-
(subView !== null || activeTab !== "home") && /* @__PURE__ */
|
|
4426
|
-
subView === null && activeTab === "messages" && /* @__PURE__ */
|
|
4838
|
+
(subView !== null || activeTab !== "home") && /* @__PURE__ */ jsxs10("div", { className: "hw-content", children: [
|
|
4839
|
+
subView === null && activeTab === "messages" && /* @__PURE__ */ jsx15(
|
|
4427
4840
|
MessagesView,
|
|
4428
4841
|
{
|
|
4429
4842
|
conversations,
|
|
@@ -4431,7 +4844,7 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4431
4844
|
onNewClick: openNewConversation
|
|
4432
4845
|
}
|
|
4433
4846
|
),
|
|
4434
|
-
subView === "new" && /* @__PURE__ */
|
|
4847
|
+
subView === "new" && /* @__PURE__ */ jsx15(
|
|
4435
4848
|
NewConversationView,
|
|
4436
4849
|
{
|
|
4437
4850
|
text: newText,
|
|
@@ -4441,12 +4854,12 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4441
4854
|
welcomeMessage
|
|
4442
4855
|
}
|
|
4443
4856
|
),
|
|
4444
|
-
subView === "conversation" && activeId && /* @__PURE__ */
|
|
4857
|
+
subView === "conversation" && activeId && /* @__PURE__ */ jsx15(ConversationView, { conversationId: activeId }),
|
|
4445
4858
|
activeTab.startsWith("content:") && (() => {
|
|
4446
4859
|
const tabId = activeTab.replace("content:", "");
|
|
4447
4860
|
const contentTab = contentTabs.find((t2) => t2.id === tabId);
|
|
4448
4861
|
if (!contentTab) return null;
|
|
4449
|
-
return /* @__PURE__ */
|
|
4862
|
+
return /* @__PURE__ */ jsx15(
|
|
4450
4863
|
ContentTabView,
|
|
4451
4864
|
{
|
|
4452
4865
|
tab: contentTab,
|
|
@@ -4465,27 +4878,43 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4465
4878
|
);
|
|
4466
4879
|
})()
|
|
4467
4880
|
] }),
|
|
4468
|
-
showTabBar && /* @__PURE__ */
|
|
4881
|
+
showTabBar && /* @__PURE__ */ jsx15(
|
|
4469
4882
|
TabBar,
|
|
4470
4883
|
{
|
|
4471
4884
|
activeTab,
|
|
4472
4885
|
onTabChange: switchTab,
|
|
4473
4886
|
unreadCount: totalUnread,
|
|
4474
4887
|
contentTabs,
|
|
4475
|
-
showMessagesTab: agentConfig?.showMessagesTab ?? true
|
|
4888
|
+
showMessagesTab: agentConfig?.showMessagesTab ?? true,
|
|
4889
|
+
unseenAnnouncementCount
|
|
4476
4890
|
}
|
|
4477
4891
|
),
|
|
4478
|
-
/* @__PURE__ */
|
|
4892
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-powered", children: [
|
|
4479
4893
|
t("widget.powered_by"),
|
|
4480
4894
|
" ",
|
|
4481
|
-
/* @__PURE__ */
|
|
4895
|
+
/* @__PURE__ */ jsx15("a", { href: "https://helpway.ai", target: "_blank", rel: "noopener noreferrer", children: "Helpway" })
|
|
4482
4896
|
] })
|
|
4483
4897
|
]
|
|
4484
4898
|
}
|
|
4485
4899
|
),
|
|
4486
|
-
isReady && !isOpen && !isDismissed && !hideLauncher && /* @__PURE__ */
|
|
4487
|
-
/* @__PURE__ */
|
|
4488
|
-
|
|
4900
|
+
isReady && !isOpen && !isDismissed && !hideLauncher && /* @__PURE__ */ jsx15(MessagePreview, { onOpen: handleBubbleClick, avatar: /* @__PURE__ */ jsx15(WidgetLogo, {}) }),
|
|
4901
|
+
isReady && !isOpen && !isDismissed && !hideLauncher && /* @__PURE__ */ jsx15(
|
|
4902
|
+
AnnouncementPreviews,
|
|
4903
|
+
{
|
|
4904
|
+
avatar: /* @__PURE__ */ jsx15(WidgetLogo, {}),
|
|
4905
|
+
onOpen: (slug, tabId) => {
|
|
4906
|
+
markEntrySeen(slug);
|
|
4907
|
+
handleBubbleClick();
|
|
4908
|
+
setTimeout(() => {
|
|
4909
|
+
switchTab(`content:${tabId}`);
|
|
4910
|
+
setContentDetailSlug(slug);
|
|
4911
|
+
setSubView("content-detail");
|
|
4912
|
+
}, 50);
|
|
4913
|
+
}
|
|
4914
|
+
}
|
|
4915
|
+
),
|
|
4916
|
+
/* @__PURE__ */ jsx15(WidgetDebugOverlay, {}),
|
|
4917
|
+
isReady && !isDismissed && (!hideLauncher || isOpen) && /* @__PURE__ */ jsxs10(
|
|
4489
4918
|
"button",
|
|
4490
4919
|
{
|
|
4491
4920
|
ref: bubbleRef,
|
|
@@ -4502,22 +4931,25 @@ function DefaultWidget({ hideLauncher = false } = {}) {
|
|
|
4502
4931
|
"aria-expanded": isOpen,
|
|
4503
4932
|
"aria-haspopup": "dialog",
|
|
4504
4933
|
children: [
|
|
4505
|
-
/* @__PURE__ */
|
|
4934
|
+
/* @__PURE__ */ jsx15(
|
|
4506
4935
|
"span",
|
|
4507
4936
|
{
|
|
4508
4937
|
className: `hw-bubble-icon hw-bubble-icon--bot ${isOpen ? "hw-bubble-icon--hidden" : ""}`,
|
|
4509
|
-
children: /* @__PURE__ */
|
|
4938
|
+
children: /* @__PURE__ */ jsx15(LauncherIcon, {})
|
|
4510
4939
|
}
|
|
4511
4940
|
),
|
|
4512
|
-
/* @__PURE__ */
|
|
4941
|
+
/* @__PURE__ */ jsx15(
|
|
4513
4942
|
"span",
|
|
4514
4943
|
{
|
|
4515
4944
|
className: `hw-bubble-icon hw-bubble-icon--close ${!isOpen ? "hw-bubble-icon--hidden" : ""}`,
|
|
4516
|
-
children: /* @__PURE__ */
|
|
4945
|
+
children: /* @__PURE__ */ jsx15(XIcon, { size: 24 })
|
|
4517
4946
|
}
|
|
4518
4947
|
),
|
|
4519
|
-
launcherStyle !== "icon" && !isOpen && /* @__PURE__ */
|
|
4520
|
-
!isOpen && totalUnread > 0 && /* @__PURE__ */
|
|
4948
|
+
launcherStyle !== "icon" && !isOpen && /* @__PURE__ */ jsx15("span", { className: "hw-bubble-label", children: launcherStyle === "help" ? t("widget.help") : companyName }),
|
|
4949
|
+
!isOpen && (totalUnread > 0 || unseenAnnouncementCount > 0) && /* @__PURE__ */ jsxs10("div", { className: "hw-bubble-badge", children: [
|
|
4950
|
+
totalUnread > 0 ? totalUnread : "",
|
|
4951
|
+
totalUnread === 0 && unseenAnnouncementCount > 0 && /* @__PURE__ */ jsx15("span", { className: "hw-bubble-badge-dot" })
|
|
4952
|
+
] })
|
|
4521
4953
|
]
|
|
4522
4954
|
}
|
|
4523
4955
|
)
|
|
@@ -4530,10 +4962,11 @@ function TabBar({
|
|
|
4530
4962
|
onTabChange,
|
|
4531
4963
|
unreadCount,
|
|
4532
4964
|
contentTabs,
|
|
4533
|
-
showMessagesTab = true
|
|
4965
|
+
showMessagesTab = true,
|
|
4966
|
+
unseenAnnouncementCount = 0
|
|
4534
4967
|
}) {
|
|
4535
|
-
return /* @__PURE__ */
|
|
4536
|
-
/* @__PURE__ */
|
|
4968
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-tabs", role: "tablist", children: [
|
|
4969
|
+
/* @__PURE__ */ jsxs10(
|
|
4537
4970
|
"button",
|
|
4538
4971
|
{
|
|
4539
4972
|
type: "button",
|
|
@@ -4542,12 +4975,12 @@ function TabBar({
|
|
|
4542
4975
|
role: "tab",
|
|
4543
4976
|
"aria-selected": activeTab === "home",
|
|
4544
4977
|
children: [
|
|
4545
|
-
/* @__PURE__ */
|
|
4546
|
-
/* @__PURE__ */
|
|
4978
|
+
/* @__PURE__ */ jsx15(HomeIcon, {}),
|
|
4979
|
+
/* @__PURE__ */ jsx15("span", { children: t("widget.home") })
|
|
4547
4980
|
]
|
|
4548
4981
|
}
|
|
4549
4982
|
),
|
|
4550
|
-
showMessagesTab && /* @__PURE__ */
|
|
4983
|
+
showMessagesTab && /* @__PURE__ */ jsxs10(
|
|
4551
4984
|
"button",
|
|
4552
4985
|
{
|
|
4553
4986
|
type: "button",
|
|
@@ -4556,15 +4989,15 @@ function TabBar({
|
|
|
4556
4989
|
role: "tab",
|
|
4557
4990
|
"aria-selected": activeTab === "messages",
|
|
4558
4991
|
children: [
|
|
4559
|
-
/* @__PURE__ */
|
|
4560
|
-
/* @__PURE__ */
|
|
4561
|
-
unreadCount > 0 && /* @__PURE__ */
|
|
4992
|
+
/* @__PURE__ */ jsxs10("span", { className: "hw-tabs-icon-wrap", children: [
|
|
4993
|
+
/* @__PURE__ */ jsx15(MessagesIcon, {}),
|
|
4994
|
+
unreadCount > 0 && /* @__PURE__ */ jsx15("span", { className: "hw-tabs-badge", children: unreadCount > 99 ? "99+" : unreadCount })
|
|
4562
4995
|
] }),
|
|
4563
|
-
/* @__PURE__ */
|
|
4996
|
+
/* @__PURE__ */ jsx15("span", { children: t("widget.messages") })
|
|
4564
4997
|
]
|
|
4565
4998
|
}
|
|
4566
4999
|
),
|
|
4567
|
-
contentTabs.map((tab) => /* @__PURE__ */
|
|
5000
|
+
contentTabs.map((tab) => /* @__PURE__ */ jsxs10(
|
|
4568
5001
|
"button",
|
|
4569
5002
|
{
|
|
4570
5003
|
type: "button",
|
|
@@ -4573,8 +5006,11 @@ function TabBar({
|
|
|
4573
5006
|
role: "tab",
|
|
4574
5007
|
"aria-selected": activeTab === `content:${tab.id}`,
|
|
4575
5008
|
children: [
|
|
4576
|
-
/* @__PURE__ */
|
|
4577
|
-
|
|
5009
|
+
/* @__PURE__ */ jsxs10("span", { className: "hw-tabs-icon-wrap", children: [
|
|
5010
|
+
/* @__PURE__ */ jsx15(ContentTabIconComponent, { icon: tab.icon }),
|
|
5011
|
+
tab.isAnnouncements && unseenAnnouncementCount > 0 && /* @__PURE__ */ jsx15("span", { className: "hw-tabs-dot" })
|
|
5012
|
+
] }),
|
|
5013
|
+
/* @__PURE__ */ jsx15("span", { children: resolveLabel2(tab.label) })
|
|
4578
5014
|
]
|
|
4579
5015
|
},
|
|
4580
5016
|
tab.id
|
|
@@ -4588,9 +5024,9 @@ function HomeView({
|
|
|
4588
5024
|
}) {
|
|
4589
5025
|
const recent = conversations.slice(0, 3);
|
|
4590
5026
|
if (recent.length === 0) return null;
|
|
4591
|
-
return /* @__PURE__ */
|
|
4592
|
-
/* @__PURE__ */
|
|
4593
|
-
recent.map((conv, i) => /* @__PURE__ */
|
|
5027
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-recent-card", children: [
|
|
5028
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-recent-header", children: t("widget.recent_conversations") }),
|
|
5029
|
+
recent.map((conv, i) => /* @__PURE__ */ jsx15(
|
|
4594
5030
|
ConversationRow,
|
|
4595
5031
|
{
|
|
4596
5032
|
conversation: conv,
|
|
@@ -4599,7 +5035,7 @@ function HomeView({
|
|
|
4599
5035
|
},
|
|
4600
5036
|
conv.id
|
|
4601
5037
|
)),
|
|
4602
|
-
conversations.length > 3 && /* @__PURE__ */
|
|
5038
|
+
conversations.length > 3 && /* @__PURE__ */ jsx15("button", { type: "button", className: "hw-recent-see-all", onClick: onMessagesClick, children: t("widget.see_all") })
|
|
4603
5039
|
] });
|
|
4604
5040
|
}
|
|
4605
5041
|
function MessagesView({
|
|
@@ -4608,28 +5044,28 @@ function MessagesView({
|
|
|
4608
5044
|
onNewClick
|
|
4609
5045
|
}) {
|
|
4610
5046
|
if (conversations.length === 0) {
|
|
4611
|
-
return /* @__PURE__ */
|
|
4612
|
-
/* @__PURE__ */
|
|
4613
|
-
/* @__PURE__ */
|
|
4614
|
-
/* @__PURE__ */
|
|
4615
|
-
/* @__PURE__ */
|
|
5047
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-empty-state", children: [
|
|
5048
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-empty-icon-wrap", children: /* @__PURE__ */ jsx15(MessagesIcon, {}) }),
|
|
5049
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-empty-title", children: t("widget.no_messages") }),
|
|
5050
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-empty-desc", children: t("widget.no_messages_desc") }),
|
|
5051
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "hw-empty-btn", onClick: onNewClick, children: t("widget.start_conversation") })
|
|
4616
5052
|
] });
|
|
4617
5053
|
}
|
|
4618
|
-
return /* @__PURE__ */
|
|
5054
|
+
return /* @__PURE__ */ jsx15("div", { className: "hw-msgs-tab", children: conversations.map((conv) => /* @__PURE__ */ jsx15(ConversationCard, { conversation: conv, onSelect }, conv.id)) });
|
|
4619
5055
|
}
|
|
4620
5056
|
function ConvCardBody({ conv }) {
|
|
4621
5057
|
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
4622
5058
|
const isTeam = conv.lastMessageSenderType === "team" && conv.lastMessageSenderName;
|
|
4623
5059
|
const displayName = isTeam ? conv.lastMessageSenderName : agentName;
|
|
4624
5060
|
const preview = conv.lastMessageText ?? t("widget.no_preview");
|
|
4625
|
-
return /* @__PURE__ */
|
|
4626
|
-
/* @__PURE__ */
|
|
4627
|
-
/* @__PURE__ */
|
|
4628
|
-
/* @__PURE__ */
|
|
4629
|
-
/* @__PURE__ */
|
|
4630
|
-
conv.lastMessageAt && /* @__PURE__ */
|
|
5061
|
+
return /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
5062
|
+
/* @__PURE__ */ jsx15("div", { className: `hw-conv-card-avatar${isTeam ? " hw-conv-card-avatar--team" : ""}`, children: isTeam ? conv.lastMessageSenderImage ? /* @__PURE__ */ jsx15("img", { src: conv.lastMessageSenderImage, alt: displayName, className: "hw-conv-card-avatar-img" }) : /* @__PURE__ */ jsx15("span", { className: "hw-conv-card-avatar-initials", children: displayName.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase() }) : /* @__PURE__ */ jsx15(WidgetLogo, {}) }),
|
|
5063
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-conv-card-content", children: [
|
|
5064
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-conv-card-top", children: [
|
|
5065
|
+
/* @__PURE__ */ jsx15("span", { className: "hw-conv-card-name", children: displayName }),
|
|
5066
|
+
conv.lastMessageAt && /* @__PURE__ */ jsx15("span", { className: "hw-conv-card-time", children: formatRelativeTime(conv.lastMessageAt) })
|
|
4631
5067
|
] }),
|
|
4632
|
-
/* @__PURE__ */
|
|
5068
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-conv-card-preview", children: preview })
|
|
4633
5069
|
] })
|
|
4634
5070
|
] });
|
|
4635
5071
|
}
|
|
@@ -4638,15 +5074,15 @@ function ConversationCard({
|
|
|
4638
5074
|
onSelect
|
|
4639
5075
|
}) {
|
|
4640
5076
|
const hasUnread = conv.unreadCount > 0;
|
|
4641
|
-
return /* @__PURE__ */
|
|
5077
|
+
return /* @__PURE__ */ jsxs10(
|
|
4642
5078
|
"button",
|
|
4643
5079
|
{
|
|
4644
5080
|
type: "button",
|
|
4645
5081
|
className: `hw-conv-card ${hasUnread ? "hw-conv-card--unread" : ""}`,
|
|
4646
5082
|
onClick: () => onSelect(conv.id),
|
|
4647
5083
|
children: [
|
|
4648
|
-
/* @__PURE__ */
|
|
4649
|
-
hasUnread && /* @__PURE__ */
|
|
5084
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-conv-card-row", children: /* @__PURE__ */ jsx15(ConvCardBody, { conv }) }),
|
|
5085
|
+
hasUnread && /* @__PURE__ */ jsx15("div", { className: "hw-conv-card-badge", children: conv.unreadCount })
|
|
4650
5086
|
]
|
|
4651
5087
|
}
|
|
4652
5088
|
);
|
|
@@ -4657,15 +5093,15 @@ function ConversationRow({
|
|
|
4657
5093
|
isLast
|
|
4658
5094
|
}) {
|
|
4659
5095
|
const hasUnread = conv.unreadCount > 0;
|
|
4660
|
-
return /* @__PURE__ */
|
|
5096
|
+
return /* @__PURE__ */ jsxs10(
|
|
4661
5097
|
"button",
|
|
4662
5098
|
{
|
|
4663
5099
|
type: "button",
|
|
4664
5100
|
className: `hw-recent-row ${hasUnread ? "hw-recent-row--unread" : ""} ${isLast ? "hw-recent-row--last" : ""}`,
|
|
4665
5101
|
onClick: () => onSelect(conv.id),
|
|
4666
5102
|
children: [
|
|
4667
|
-
/* @__PURE__ */
|
|
4668
|
-
hasUnread && /* @__PURE__ */
|
|
5103
|
+
/* @__PURE__ */ jsx15(ConvCardBody, { conv }),
|
|
5104
|
+
hasUnread && /* @__PURE__ */ jsx15("div", { className: "hw-recent-row-badge", children: conv.unreadCount })
|
|
4669
5105
|
]
|
|
4670
5106
|
}
|
|
4671
5107
|
);
|
|
@@ -4673,10 +5109,10 @@ function ConversationRow({
|
|
|
4673
5109
|
function InlineEmailPrompt({ conversationId }) {
|
|
4674
5110
|
const { client, store } = useWidgetContext();
|
|
4675
5111
|
const updateContact = useWidgetStore((s) => s.updateVisitorContact);
|
|
4676
|
-
const [email, setEmail] =
|
|
4677
|
-
const [isSubmitting, setIsSubmitting] =
|
|
4678
|
-
const [isSuccess, setIsSuccess] =
|
|
4679
|
-
const [hasError, setHasError] =
|
|
5112
|
+
const [email, setEmail] = useState14("");
|
|
5113
|
+
const [isSubmitting, setIsSubmitting] = useState14(false);
|
|
5114
|
+
const [isSuccess, setIsSuccess] = useState14(false);
|
|
5115
|
+
const [hasError, setHasError] = useState14(false);
|
|
4680
5116
|
const handleSubmit = async () => {
|
|
4681
5117
|
const trimmed = email.trim();
|
|
4682
5118
|
if (!trimmed || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmed)) {
|
|
@@ -4717,23 +5153,23 @@ function InlineEmailPrompt({ conversationId }) {
|
|
|
4717
5153
|
}
|
|
4718
5154
|
};
|
|
4719
5155
|
if (isSuccess) {
|
|
4720
|
-
return /* @__PURE__ */
|
|
4721
|
-
/* @__PURE__ */
|
|
5156
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-email-card hw-email-card--success", children: [
|
|
5157
|
+
/* @__PURE__ */ jsx15("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "#22c55e", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx15("polyline", { points: "20 6 9 17 4 12" }) }),
|
|
4722
5158
|
t("widget.email_saved")
|
|
4723
5159
|
] });
|
|
4724
5160
|
}
|
|
4725
|
-
return /* @__PURE__ */
|
|
4726
|
-
/* @__PURE__ */
|
|
4727
|
-
/* @__PURE__ */
|
|
4728
|
-
/* @__PURE__ */
|
|
4729
|
-
/* @__PURE__ */
|
|
5161
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-email-card", children: [
|
|
5162
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-email-card-header", children: [
|
|
5163
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-email-card-icon", children: /* @__PURE__ */ jsxs10("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
5164
|
+
/* @__PURE__ */ jsx15("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
|
|
5165
|
+
/* @__PURE__ */ jsx15("path", { d: "M22 7l-10 7L2 7" })
|
|
4730
5166
|
] }) }),
|
|
4731
|
-
/* @__PURE__ */
|
|
4732
|
-
/* @__PURE__ */
|
|
4733
|
-
/* @__PURE__ */
|
|
5167
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
5168
|
+
/* @__PURE__ */ jsx15("p", { className: "hw-email-card-title", children: t("widget.email_title") }),
|
|
5169
|
+
/* @__PURE__ */ jsx15("p", { className: "hw-email-card-subtitle", children: t("widget.email_subtitle") })
|
|
4734
5170
|
] })
|
|
4735
5171
|
] }),
|
|
4736
|
-
/* @__PURE__ */
|
|
5172
|
+
/* @__PURE__ */ jsx15(
|
|
4737
5173
|
"input",
|
|
4738
5174
|
{
|
|
4739
5175
|
type: "email",
|
|
@@ -4749,14 +5185,14 @@ function InlineEmailPrompt({ conversationId }) {
|
|
|
4749
5185
|
placeholder: t("widget.email_placeholder")
|
|
4750
5186
|
}
|
|
4751
5187
|
),
|
|
4752
|
-
/* @__PURE__ */
|
|
5188
|
+
/* @__PURE__ */ jsx15(
|
|
4753
5189
|
"button",
|
|
4754
5190
|
{
|
|
4755
5191
|
type: "button",
|
|
4756
5192
|
className: "hw-email-card-submit",
|
|
4757
5193
|
onClick: handleSubmit,
|
|
4758
5194
|
disabled: isSubmitting || !email.trim(),
|
|
4759
|
-
children: isSubmitting ? /* @__PURE__ */
|
|
5195
|
+
children: isSubmitting ? /* @__PURE__ */ jsx15("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "10", strokeDasharray: "32", strokeDashoffset: "32", children: /* @__PURE__ */ jsx15("animate", { attributeName: "stroke-dashoffset", values: "32;0", dur: "1s", repeatCount: "indefinite" }) }) }) : t("widget.email_continue")
|
|
4760
5196
|
}
|
|
4761
5197
|
)
|
|
4762
5198
|
] });
|
|
@@ -4768,8 +5204,8 @@ function NewConversationView({
|
|
|
4768
5204
|
isSubmitting,
|
|
4769
5205
|
welcomeMessage
|
|
4770
5206
|
}) {
|
|
4771
|
-
return /* @__PURE__ */
|
|
4772
|
-
/* @__PURE__ */
|
|
5207
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-new", children: [
|
|
5208
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-new-welcome", children: /* @__PURE__ */ jsx15(
|
|
4773
5209
|
MessageBubble,
|
|
4774
5210
|
{
|
|
4775
5211
|
text: welcomeMessage,
|
|
@@ -4777,7 +5213,7 @@ function NewConversationView({
|
|
|
4777
5213
|
parts: null
|
|
4778
5214
|
}
|
|
4779
5215
|
) }),
|
|
4780
|
-
/* @__PURE__ */
|
|
5216
|
+
/* @__PURE__ */ jsx15(
|
|
4781
5217
|
Composer,
|
|
4782
5218
|
{
|
|
4783
5219
|
text,
|
|
@@ -4822,27 +5258,27 @@ function ConversationView({ conversationId }) {
|
|
|
4822
5258
|
const needsEmailPostReply = !!agentConfig?.requireVisitorEmail && !hasEmail && visitorMessageCount >= 2 && hasAiReply;
|
|
4823
5259
|
const needsEmail = needsEmailPostReply || !!emailGateConvId;
|
|
4824
5260
|
if (isLoading && items.length === 0) {
|
|
4825
|
-
return /* @__PURE__ */
|
|
4826
|
-
/* @__PURE__ */
|
|
4827
|
-
/* @__PURE__ */
|
|
4828
|
-
/* @__PURE__ */
|
|
4829
|
-
/* @__PURE__ */
|
|
4830
|
-
/* @__PURE__ */
|
|
5261
|
+
return /* @__PURE__ */ jsx15("div", { className: "hw-messages", children: /* @__PURE__ */ jsxs10("div", { className: "hw-skeleton-messages", children: [
|
|
5262
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-skeleton-msg", children: [
|
|
5263
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-avatar" }),
|
|
5264
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-skeleton-bubble", children: [
|
|
5265
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 140 } }),
|
|
5266
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 200 } })
|
|
4831
5267
|
] })
|
|
4832
5268
|
] }),
|
|
4833
|
-
/* @__PURE__ */
|
|
4834
|
-
/* @__PURE__ */
|
|
4835
|
-
/* @__PURE__ */
|
|
4836
|
-
/* @__PURE__ */
|
|
4837
|
-
/* @__PURE__ */
|
|
4838
|
-
/* @__PURE__ */
|
|
4839
|
-
/* @__PURE__ */
|
|
5269
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton-msg hw-skeleton-msg--right", children: /* @__PURE__ */ jsx15("div", { className: "hw-skeleton-bubble", style: { alignItems: "flex-end" }, children: /* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 160 } }) }) }),
|
|
5270
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-skeleton-msg", children: [
|
|
5271
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-avatar" }),
|
|
5272
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-skeleton-bubble", children: [
|
|
5273
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 180 } }),
|
|
5274
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 120 } }),
|
|
5275
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-skeleton hw-skeleton-line", style: { width: 80 } })
|
|
4840
5276
|
] })
|
|
4841
5277
|
] })
|
|
4842
5278
|
] }) });
|
|
4843
5279
|
}
|
|
4844
|
-
return /* @__PURE__ */
|
|
4845
|
-
/* @__PURE__ */
|
|
5280
|
+
return /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
5281
|
+
/* @__PURE__ */ jsx15(
|
|
4846
5282
|
MessageList,
|
|
4847
5283
|
{
|
|
4848
5284
|
items,
|
|
@@ -4854,63 +5290,55 @@ function ConversationView({ conversationId }) {
|
|
|
4854
5290
|
onLoadMore: loadMore
|
|
4855
5291
|
}
|
|
4856
5292
|
),
|
|
4857
|
-
isResolved
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
{
|
|
4864
|
-
type: "button",
|
|
4865
|
-
className: "hw-send-error-retry",
|
|
4866
|
-
onClick: () => {
|
|
4867
|
-
clearSendError();
|
|
4868
|
-
submit();
|
|
4869
|
-
},
|
|
4870
|
-
children: t("widget.retry")
|
|
4871
|
-
}
|
|
4872
|
-
)
|
|
4873
|
-
] }),
|
|
4874
|
-
/* @__PURE__ */ jsx13(
|
|
4875
|
-
Composer,
|
|
5293
|
+
isResolved && /* @__PURE__ */ jsx15(ResolvedBanner, { conversationId }),
|
|
5294
|
+
needsEmail && /* @__PURE__ */ jsx15(InlineEmailPrompt, { conversationId: emailGateConvId ?? void 0 }),
|
|
5295
|
+
sendError && /* @__PURE__ */ jsxs10("div", { className: "hw-send-error", children: [
|
|
5296
|
+
sendError,
|
|
5297
|
+
/* @__PURE__ */ jsx15(
|
|
5298
|
+
"button",
|
|
4876
5299
|
{
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
onRemoveAttachment: removeAttachment,
|
|
4885
|
-
disabled: needsEmail
|
|
5300
|
+
type: "button",
|
|
5301
|
+
className: "hw-send-error-retry",
|
|
5302
|
+
onClick: () => {
|
|
5303
|
+
clearSendError();
|
|
5304
|
+
submit();
|
|
5305
|
+
},
|
|
5306
|
+
children: t("widget.retry")
|
|
4886
5307
|
}
|
|
4887
5308
|
)
|
|
4888
|
-
] })
|
|
5309
|
+
] }),
|
|
5310
|
+
/* @__PURE__ */ jsx15(
|
|
5311
|
+
Composer,
|
|
5312
|
+
{
|
|
5313
|
+
text,
|
|
5314
|
+
onTextChange: setText,
|
|
5315
|
+
onSubmit: submit,
|
|
5316
|
+
onTyping: setTyping,
|
|
5317
|
+
isSubmitting,
|
|
5318
|
+
attachments,
|
|
5319
|
+
onAddFiles: addFiles,
|
|
5320
|
+
onRemoveAttachment: removeAttachment,
|
|
5321
|
+
disabled: needsEmail
|
|
5322
|
+
}
|
|
5323
|
+
)
|
|
4889
5324
|
] });
|
|
4890
5325
|
}
|
|
4891
5326
|
function ResolvedBanner({ conversationId }) {
|
|
4892
5327
|
const { client } = useWidgetContext();
|
|
4893
|
-
const [csatRating, setCsatRating] =
|
|
4894
|
-
const [csatSubmitted, setCsatSubmitted] =
|
|
4895
|
-
const handleReopen = async () => {
|
|
4896
|
-
try {
|
|
4897
|
-
await client.widget.sendMessage.mutate({ conversationId, text: t("widget.send_followup") });
|
|
4898
|
-
} catch (err) {
|
|
4899
|
-
console.error("Failed to reopen:", err);
|
|
4900
|
-
}
|
|
4901
|
-
};
|
|
5328
|
+
const [csatRating, setCsatRating] = useState14(null);
|
|
5329
|
+
const [csatSubmitted, setCsatSubmitted] = useState14(false);
|
|
4902
5330
|
const handleCsat = (rating) => {
|
|
4903
5331
|
setCsatRating(rating);
|
|
4904
5332
|
setCsatSubmitted(true);
|
|
4905
5333
|
client.widget.sendCsat.mutate({ conversationId, rating }).catch(() => {
|
|
4906
5334
|
});
|
|
4907
5335
|
};
|
|
4908
|
-
return /* @__PURE__ */
|
|
4909
|
-
/* @__PURE__ */
|
|
4910
|
-
!csatSubmitted ? /* @__PURE__ */
|
|
4911
|
-
/* @__PURE__ */
|
|
4912
|
-
/* @__PURE__ */
|
|
4913
|
-
/* @__PURE__ */
|
|
5336
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-resolved", children: [
|
|
5337
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-resolved-text", children: t("widget.resolved_text") }),
|
|
5338
|
+
!csatSubmitted ? /* @__PURE__ */ jsxs10("div", { className: "hw-csat", children: [
|
|
5339
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-csat-label", children: t("widget.csat_label") }),
|
|
5340
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-csat-buttons", children: [
|
|
5341
|
+
/* @__PURE__ */ jsx15(
|
|
4914
5342
|
"button",
|
|
4915
5343
|
{
|
|
4916
5344
|
type: "button",
|
|
@@ -4920,7 +5348,7 @@ function ResolvedBanner({ conversationId }) {
|
|
|
4920
5348
|
children: "\u{1F44D}"
|
|
4921
5349
|
}
|
|
4922
5350
|
),
|
|
4923
|
-
/* @__PURE__ */
|
|
5351
|
+
/* @__PURE__ */ jsx15(
|
|
4924
5352
|
"button",
|
|
4925
5353
|
{
|
|
4926
5354
|
type: "button",
|
|
@@ -4931,85 +5359,56 @@ function ResolvedBanner({ conversationId }) {
|
|
|
4931
5359
|
}
|
|
4932
5360
|
)
|
|
4933
5361
|
] })
|
|
4934
|
-
] }) : /* @__PURE__ */
|
|
4935
|
-
/* @__PURE__ */ jsx13("div", { className: "hw-resolved-actions", children: /* @__PURE__ */ jsx13("button", { type: "button", className: "hw-resolved-reopen", onClick: handleReopen, children: t("widget.send_followup") }) })
|
|
5362
|
+
] }) : /* @__PURE__ */ jsx15("div", { className: "hw-csat-thanks", children: t("widget.csat_thanks") })
|
|
4936
5363
|
] });
|
|
4937
5364
|
}
|
|
4938
|
-
function
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
}, 8e3);
|
|
4950
|
-
return () => clearTimeout(timer);
|
|
4951
|
-
}, [preview, dismissPreview]);
|
|
4952
|
-
if (!preview) return null;
|
|
4953
|
-
const handleClose = (e) => {
|
|
4954
|
-
e.stopPropagation();
|
|
4955
|
-
setClosing(true);
|
|
4956
|
-
setTimeout(() => {
|
|
4957
|
-
dismissPreview();
|
|
4958
|
-
setClosing(false);
|
|
4959
|
-
}, 200);
|
|
4960
|
-
};
|
|
4961
|
-
const handleClick = () => {
|
|
4962
|
-
const targetConvId = preview.conversationId;
|
|
4963
|
-
dismissPreview();
|
|
4964
|
-
setActiveConversation(targetConvId);
|
|
4965
|
-
onOpen();
|
|
4966
|
-
};
|
|
4967
|
-
const messages = preview.messages?.length ? preview.messages : [{ text: preview.text }];
|
|
4968
|
-
const hasQr = preview.quickReplies && preview.quickReplies.options.length > 0;
|
|
4969
|
-
return /* @__PURE__ */ jsxs8(
|
|
4970
|
-
"div",
|
|
4971
|
-
{
|
|
4972
|
-
className: `hw-preview ${closing ? "hw-preview--closing" : ""}`,
|
|
4973
|
-
onClick: handleClick,
|
|
4974
|
-
role: "button",
|
|
4975
|
-
tabIndex: 0,
|
|
4976
|
-
children: [
|
|
4977
|
-
/* @__PURE__ */ jsxs8("div", { className: "hw-preview-header", children: [
|
|
4978
|
-
/* @__PURE__ */ jsx13("div", { className: "hw-preview-avatar", children: /* @__PURE__ */ jsx13(WidgetLogo, {}) }),
|
|
4979
|
-
/* @__PURE__ */ jsx13("div", { className: "hw-preview-name", children: agentName }),
|
|
4980
|
-
/* @__PURE__ */ jsx13(
|
|
4981
|
-
"button",
|
|
4982
|
-
{
|
|
4983
|
-
type: "button",
|
|
4984
|
-
className: "hw-preview-close",
|
|
4985
|
-
onClick: handleClose,
|
|
4986
|
-
"aria-label": t("widget.aria_dismiss"),
|
|
4987
|
-
children: /* @__PURE__ */ jsx13(XIcon, { size: 20 })
|
|
4988
|
-
}
|
|
4989
|
-
)
|
|
4990
|
-
] }),
|
|
4991
|
-
messages.map((m, i) => /* @__PURE__ */ jsx13("div", { className: "hw-preview-body", children: m.text }, i)),
|
|
4992
|
-
hasQr && /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
4993
|
-
preview.quickReplies.prompt && /* @__PURE__ */ jsx13("div", { className: "hw-preview-body", children: preview.quickReplies.prompt }),
|
|
4994
|
-
/* @__PURE__ */ jsx13("div", { className: "hw-preview-quick-replies", children: preview.quickReplies.options.map((opt) => /* @__PURE__ */ jsx13(
|
|
4995
|
-
"button",
|
|
4996
|
-
{
|
|
4997
|
-
type: "button",
|
|
4998
|
-
className: "hw-preview-qr-btn",
|
|
4999
|
-
onClick: (e) => {
|
|
5000
|
-
e.stopPropagation();
|
|
5001
|
-
dismissPreview();
|
|
5002
|
-
setActiveConversation(preview.conversationId);
|
|
5003
|
-
onOpen();
|
|
5004
|
-
},
|
|
5005
|
-
children: opt.label
|
|
5006
|
-
},
|
|
5007
|
-
opt.id
|
|
5008
|
-
)) })
|
|
5009
|
-
] })
|
|
5010
|
-
]
|
|
5011
|
-
}
|
|
5365
|
+
function WhatsNewCard({
|
|
5366
|
+
getUnseenEntries,
|
|
5367
|
+
announcementTabs,
|
|
5368
|
+
onViewAll,
|
|
5369
|
+
onSelect
|
|
5370
|
+
}) {
|
|
5371
|
+
const unseen = getUnseenEntries();
|
|
5372
|
+
if (unseen.length === 0) return null;
|
|
5373
|
+
const display = unseen.slice(0, 3);
|
|
5374
|
+
const badgeFieldMap = new Map(
|
|
5375
|
+
announcementTabs.map((t2) => [t2.id, t2.display?.badgeField])
|
|
5012
5376
|
);
|
|
5377
|
+
return /* @__PURE__ */ jsxs10("div", { className: "hw-whats-new", children: [
|
|
5378
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-whats-new-header", children: [
|
|
5379
|
+
/* @__PURE__ */ jsx15("span", { className: "hw-whats-new-title", children: resolveLabel2("widget.whats_new") }),
|
|
5380
|
+
/* @__PURE__ */ jsxs10("button", { type: "button", className: "hw-whats-new-view-all", onClick: onViewAll, children: [
|
|
5381
|
+
resolveLabel2("widget.view_all"),
|
|
5382
|
+
" \u2192"
|
|
5383
|
+
] })
|
|
5384
|
+
] }),
|
|
5385
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-whats-new-list", children: display.map((entry) => {
|
|
5386
|
+
const badgeField = badgeFieldMap.get(entry.tabId);
|
|
5387
|
+
return /* @__PURE__ */ jsxs10(
|
|
5388
|
+
"button",
|
|
5389
|
+
{
|
|
5390
|
+
type: "button",
|
|
5391
|
+
className: "hw-whats-new-item",
|
|
5392
|
+
onClick: () => onSelect(entry.slug, entry.tabId),
|
|
5393
|
+
children: [
|
|
5394
|
+
badgeField && entry.customFields[badgeField] && /* @__PURE__ */ jsxs10("div", { className: "hw-whats-new-item-top", children: [
|
|
5395
|
+
/* @__PURE__ */ jsx15("span", { className: "hw-whats-new-badge", children: entry.customFields[badgeField] }),
|
|
5396
|
+
entry.publishedAt && /* @__PURE__ */ jsx15("span", { className: "hw-whats-new-time", children: formatRelativeTime(entry.publishedAt) })
|
|
5397
|
+
] }),
|
|
5398
|
+
/* @__PURE__ */ jsxs10("div", { className: "hw-whats-new-item-title", children: [
|
|
5399
|
+
entry.title,
|
|
5400
|
+
!badgeField && entry.publishedAt && /* @__PURE__ */ jsx15("span", { className: "hw-whats-new-time-inline", children: formatRelativeTime(entry.publishedAt) })
|
|
5401
|
+
] }),
|
|
5402
|
+
entry.body && (() => {
|
|
5403
|
+
const clean = stripMarkdown(entry.body);
|
|
5404
|
+
return /* @__PURE__ */ jsx15("div", { className: "hw-whats-new-item-body", children: clean.length > 80 ? `${clean.slice(0, 80)}\u2026` : clean });
|
|
5405
|
+
})()
|
|
5406
|
+
]
|
|
5407
|
+
},
|
|
5408
|
+
entry.slug
|
|
5409
|
+
);
|
|
5410
|
+
}) })
|
|
5411
|
+
] });
|
|
5013
5412
|
}
|
|
5014
5413
|
|
|
5015
5414
|
// #style-inject:#style-inject
|
|
@@ -5035,10 +5434,10 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
5035
5434
|
}
|
|
5036
5435
|
|
|
5037
5436
|
// src/themed/styles.css
|
|
5038
|
-
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@keyframes hw-bubble-enter {\n from {\n opacity: 0;\n transform: scale(0.6);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\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 animation: hw-bubble-enter 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) both;\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,\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}\n.hw-hero-bot-icon svg {\n width: 32px;\n height: 32px;\n}\n.hw-hero-bot-icon .hw-agent-img,\n.hw-hero-bot-icon .hw-agent-icon {\n border-radius: inherit;\n overflow: hidden;\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 background: var(--hw-agent-bg, var(--hw-agent-bg-default, 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: cover;\n border-radius: inherit;\n}\n.hw-header-bot-icon .hw-agent-img,\n.hw-header-bot-icon .hw-agent-icon {\n border-radius: inherit;\n overflow: hidden;\n}\n.hw-header-bot-icon .hw-agent-img {\n object-fit: var(--hw-agent-fit, var(--hw-agent-fit-default, cover));\n padding: var(--hw-agent-pad, var(--hw-agent-pad-default, 0));\n box-sizing: border-box;\n}\n.hw-widget[data-has-avatar=true] {\n --hw-agent-bg-default: var(--hw-primary);\n --hw-agent-fit-default: contain;\n --hw-agent-pad-default: 6px;\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-agent-bg, var(--hw-agent-bg-default, 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 .hw-agent-img {\n object-fit: var(--hw-agent-fit, var(--hw-agent-fit-default, cover));\n padding: var(--hw-agent-pad, var(--hw-agent-pad-default, 0));\n box-sizing: border-box;\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-streaming-cursor {\n display: inline-block;\n width: 2px;\n height: 1em;\n background: currentColor;\n opacity: 0.6;\n margin-left: 1px;\n vertical-align: text-bottom;\n animation: hw-cursor-blink 0.8s step-end infinite;\n}\n@keyframes hw-cursor-blink {\n 50% {\n opacity: 0;\n }\n}\n.hw-link-preview {\n display: flex;\n flex-direction: column;\n border: 1px solid rgba(0, 0, 0, 0.08);\n border-radius: 10px;\n overflow: hidden;\n text-decoration: none;\n color: inherit;\n margin-top: 6px;\n transition: background 0.15s;\n}\n.hw-link-preview:hover {\n background: rgba(0, 0, 0, 0.02);\n}\n.hw-link-preview-img {\n width: 100%;\n max-height: 140px;\n object-fit: cover;\n}\n.hw-link-preview-body {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n.hw-link-preview-favicon {\n width: 16px;\n height: 16px;\n border-radius: 2px;\n}\n.hw-link-preview-title {\n font-size: 13px;\n font-weight: 600;\n line-height: 1.3;\n color: var(--hw-text, #1a1a1a);\n}\n.hw-link-preview-desc {\n font-size: 12px;\n line-height: 1.4;\n color: var(--hw-text-muted, #6b7280);\n}\n.hw-link-preview-url {\n font-size: 11px;\n color: var(--hw-text-muted, #9ca3af);\n}\n.hw-msg-links {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-width: 280px;\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 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-agent-bg, var(--hw-agent-bg-default, 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-avatar .hw-agent-img {\n object-fit: var(--hw-agent-fit, var(--hw-agent-fit-default, cover));\n padding: var(--hw-agent-pad, var(--hw-agent-pad-default, 0));\n box-sizing: border-box;\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');
|
|
5437
|
+
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@keyframes hw-bubble-enter {\n from {\n opacity: 0;\n transform: scale(0.6);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\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 animation: hw-bubble-enter 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) both;\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 - 112px));\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,\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}\n.hw-hero-bot-icon svg {\n width: 32px;\n height: 32px;\n}\n.hw-hero-bot-icon .hw-agent-img,\n.hw-hero-bot-icon .hw-agent-icon {\n border-radius: inherit;\n overflow: hidden;\n object-fit: contain;\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 background: var(--hw-agent-bg, var(--hw-agent-bg-default, 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: cover;\n border-radius: inherit;\n}\n.hw-header-bot-icon .hw-agent-img,\n.hw-header-bot-icon .hw-agent-icon {\n border-radius: inherit;\n overflow: hidden;\n}\n.hw-header-bot-icon .hw-agent-img {\n object-fit: var(--hw-agent-fit, var(--hw-agent-fit-default, cover));\n padding: var(--hw-agent-pad, var(--hw-agent-pad-default, 0));\n box-sizing: border-box;\n}\n.hw-widget[data-has-avatar=true] {\n --hw-agent-bg-default: var(--hw-primary);\n --hw-agent-fit-default: contain;\n --hw-agent-pad-default: 6px;\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-agent-bg, var(--hw-agent-bg-default, 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 .hw-agent-img {\n object-fit: var(--hw-agent-fit, var(--hw-agent-fit-default, cover));\n padding: var(--hw-agent-pad, var(--hw-agent-pad-default, 0));\n box-sizing: border-box;\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 overflow: visible;\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-streaming-cursor {\n display: inline-block;\n width: 2px;\n height: 1em;\n background: currentColor;\n opacity: 0.6;\n margin-left: 1px;\n vertical-align: text-bottom;\n animation: hw-cursor-blink 0.8s step-end infinite;\n}\n@keyframes hw-cursor-blink {\n 50% {\n opacity: 0;\n }\n}\n.hw-link-preview {\n display: flex;\n flex-direction: column;\n border: 1px solid rgba(0, 0, 0, 0.08);\n border-radius: 10px;\n overflow: hidden;\n text-decoration: none;\n color: inherit;\n margin-top: 6px;\n transition: background 0.15s;\n}\n.hw-link-preview:hover {\n background: rgba(0, 0, 0, 0.02);\n}\n.hw-link-preview-img {\n width: 100%;\n max-height: 140px;\n object-fit: cover;\n}\n.hw-link-preview-body {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n.hw-link-preview-favicon {\n width: 16px;\n height: 16px;\n border-radius: 2px;\n}\n.hw-link-preview-title {\n font-size: 13px;\n font-weight: 600;\n line-height: 1.3;\n color: var(--hw-text, #1a1a1a);\n}\n.hw-link-preview-desc {\n font-size: 12px;\n line-height: 1.4;\n color: var(--hw-text-muted, #6b7280);\n}\n.hw-link-preview-url {\n font-size: 11px;\n color: var(--hw-text-muted, #9ca3af);\n}\n.hw-msg-links {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-width: 280px;\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 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-agent-bg, var(--hw-agent-bg-default, 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-avatar .hw-agent-img {\n object-fit: var(--hw-agent-fit, var(--hw-agent-fit-default, cover));\n padding: var(--hw-agent-pad, var(--hw-agent-pad-default, 0));\n box-sizing: border-box;\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.hw-preview--anchored {\n position: static;\n bottom: auto;\n right: auto;\n width: 100%;\n max-width: 100%;\n}\n.hw-preview.hw-preview--anchored .hw-preview-avatar {\n background: none;\n}\n.hw-preview.hw-preview--anchored .hw-preview-avatar img,\n.hw-preview.hw-preview--anchored .hw-preview-avatar svg {\n width: 100%;\n height: 100%;\n object-fit: contain;\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-footer {\n margin-top: 2px;\n padding: 8px 14px 12px;\n border-top: 1px solid var(--hw-border);\n font-size: 11px;\n line-height: 1.3;\n color: var(--hw-text-2);\n opacity: 0.65;\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-preview--closing {\n animation: hw-preview-out 0.2s ease-in forwards;\n}\n.hw-preview-stack {\n position: absolute;\n bottom: calc(100% + 12px);\n right: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.hw-preview-stack .hw-preview {\n position: relative;\n bottom: auto;\n right: auto;\n}\n.hw-preview-stack.hw-preview-stack--anchored {\n position: static;\n bottom: auto;\n right: auto;\n width: 100%;\n}\n.hw-preview--announcement {\n width: 340px;\n}\n.hw-preview--announcement .hw-preview-body--title {\n font-weight: 600;\n color: var(--hw-text);\n font-size: 15px;\n line-height: 1.3;\n padding-top: 10px;\n}\n.hw-preview--announcement .hw-preview-body--desc {\n font-size: 13px;\n color: var(--hw-text-2);\n line-height: 1.5;\n padding-bottom: 16px;\n}\n.hw-announcement-badge {\n display: inline-block;\n margin: 8px 14px 0;\n padding: 2px 8px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--hw-primary);\n background: color-mix(in srgb, var(--hw-primary) 10%, transparent);\n border-radius: 4px;\n}\n.hw-whats-new {\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-whats-new-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px 0;\n}\n.hw-whats-new-title {\n font-size: 12px;\n font-weight: 600;\n color: var(--hw-text-2);\n}\n.hw-whats-new-view-all {\n font-size: 11px;\n font-weight: 500;\n color: var(--hw-primary);\n background: none;\n border: none;\n cursor: pointer;\n padding: 0;\n font-family: inherit;\n}\n.hw-whats-new-view-all:hover {\n opacity: 0.8;\n}\n.hw-whats-new-list {\n display: flex;\n flex-direction: column;\n}\n.hw-whats-new-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\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 ease;\n}\n.hw-whats-new-item:last-child {\n border-bottom: none;\n}\n.hw-whats-new-item:hover {\n background: rgba(0, 0, 0, 0.03);\n}\n.hw-whats-new-item-top {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.hw-whats-new-badge {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--hw-primary);\n}\n.hw-whats-new-time {\n font-size: 11px;\n color: var(--hw-text-3);\n margin-left: auto;\n}\n.hw-whats-new-item-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--hw-text);\n line-height: 1.3;\n display: flex;\n align-items: baseline;\n gap: 8px;\n}\n.hw-whats-new-time-inline {\n font-size: 11px;\n font-weight: 400;\n color: var(--hw-text-3);\n margin-left: auto;\n flex-shrink: 0;\n}\n.hw-whats-new-item-body {\n font-size: 12px;\n color: var(--hw-text-2);\n line-height: 1.4;\n}\n.hw-tabs-dot {\n position: absolute;\n top: -2px;\n right: -6px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--hw-primary);\n animation: hw-badge-pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n.hw-bubble-badge-dot {\n display: block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: white;\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 flex: 1;\n min-height: 0;\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');
|
|
5039
5438
|
|
|
5040
5439
|
// src/helpway-widget.tsx
|
|
5041
|
-
import { jsx as
|
|
5440
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
5042
5441
|
function HelpwayWidget({
|
|
5043
5442
|
apiKey,
|
|
5044
5443
|
apiUrl,
|
|
@@ -5055,7 +5454,7 @@ function HelpwayWidget({
|
|
|
5055
5454
|
src
|
|
5056
5455
|
}) {
|
|
5057
5456
|
const resolvedApiUrl = apiUrl ?? (src ? src.replace(/\/widget\.js$/, "") : void 0);
|
|
5058
|
-
return /* @__PURE__ */
|
|
5457
|
+
return /* @__PURE__ */ jsx16(
|
|
5059
5458
|
SupportProvider,
|
|
5060
5459
|
{
|
|
5061
5460
|
apiKey,
|
|
@@ -5068,27 +5467,30 @@ function HelpwayWidget({
|
|
|
5068
5467
|
onClose,
|
|
5069
5468
|
onUnreadChange,
|
|
5070
5469
|
theme,
|
|
5071
|
-
children: /* @__PURE__ */
|
|
5470
|
+
children: /* @__PURE__ */ jsx16(DefaultWidget, { hideLauncher })
|
|
5072
5471
|
}
|
|
5073
5472
|
);
|
|
5074
5473
|
}
|
|
5075
5474
|
|
|
5076
5475
|
// src/hooks/use-realtime.ts
|
|
5077
|
-
import { useEffect as
|
|
5476
|
+
import { useEffect as useEffect14 } from "react";
|
|
5078
5477
|
function useRealtime(handler) {
|
|
5079
5478
|
const { ws } = useWidgetContext();
|
|
5080
|
-
|
|
5479
|
+
useEffect14(() => {
|
|
5081
5480
|
return ws.onEvent(handler);
|
|
5082
5481
|
}, [ws, handler]);
|
|
5083
5482
|
}
|
|
5084
5483
|
export {
|
|
5484
|
+
AnnouncementPreviews,
|
|
5085
5485
|
Composer,
|
|
5086
5486
|
DefaultWidget,
|
|
5087
5487
|
HelpwayWidget,
|
|
5088
5488
|
MarkdownContent,
|
|
5089
5489
|
MessageBubble,
|
|
5090
5490
|
MessageList,
|
|
5491
|
+
MessagePreview,
|
|
5091
5492
|
SupportProvider,
|
|
5493
|
+
WidgetLogo,
|
|
5092
5494
|
clearVisitorId,
|
|
5093
5495
|
formatRelativeTime,
|
|
5094
5496
|
formatTime,
|