@helpway/react 0.15.2 → 0.16.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 +60 -2
- package/dist/index.js +1224 -896
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/themed/styles.css +80 -0
package/dist/index.js
CHANGED
|
@@ -66,6 +66,36 @@ function createWidgetClient(config) {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
// ../types/src/model-registry.ts
|
|
70
|
+
var AI_MODELS = {
|
|
71
|
+
"openai/gpt-5.5": {
|
|
72
|
+
label: "GPT-5.5",
|
|
73
|
+
provider: "OpenAI",
|
|
74
|
+
maxTokens: 32768
|
|
75
|
+
},
|
|
76
|
+
"openai/gpt-4.1": {
|
|
77
|
+
label: "GPT-4.1",
|
|
78
|
+
provider: "OpenAI",
|
|
79
|
+
maxTokens: 32768
|
|
80
|
+
},
|
|
81
|
+
"openai/gpt-4.1-mini": {
|
|
82
|
+
label: "GPT-4.1 Mini",
|
|
83
|
+
provider: "OpenAI",
|
|
84
|
+
maxTokens: 32768
|
|
85
|
+
},
|
|
86
|
+
"openai/gpt-4o": {
|
|
87
|
+
label: "GPT-4o",
|
|
88
|
+
provider: "OpenAI",
|
|
89
|
+
maxTokens: 4096
|
|
90
|
+
},
|
|
91
|
+
"openai/gpt-4o-mini": {
|
|
92
|
+
label: "GPT-4o Mini",
|
|
93
|
+
provider: "OpenAI",
|
|
94
|
+
maxTokens: 4096
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
var AI_MODEL_IDS = Object.keys(AI_MODELS);
|
|
98
|
+
|
|
69
99
|
// ../types/src/realtime-events.ts
|
|
70
100
|
var WsEventType = {
|
|
71
101
|
ConnectionEstablished: "connectionEstablished",
|
|
@@ -343,6 +373,9 @@ var DOC_NAV_ICON_MAP = Object.fromEntries(
|
|
|
343
373
|
DOC_NAV_ICONS.map((i) => [i.name, i])
|
|
344
374
|
);
|
|
345
375
|
|
|
376
|
+
// ../widget-core/src/version.ts
|
|
377
|
+
var SDK_VERSION = "0.16.0".length > 0 ? "0.16.0" : "dev";
|
|
378
|
+
|
|
346
379
|
// ../widget-core/src/ws.ts
|
|
347
380
|
var WebSocketManager = class {
|
|
348
381
|
ws = null;
|
|
@@ -384,7 +417,9 @@ var WebSocketManager = class {
|
|
|
384
417
|
type: "visitor",
|
|
385
418
|
id: this.config.visitorId,
|
|
386
419
|
websiteId: this.config.websiteId,
|
|
387
|
-
key: this.config.apiKey
|
|
420
|
+
key: this.config.apiKey,
|
|
421
|
+
// SDK version on the hello (#167): the server logs it per connect.
|
|
422
|
+
v: SDK_VERSION
|
|
388
423
|
});
|
|
389
424
|
const ws = new WebSocket(`${base}/ws?${params}`);
|
|
390
425
|
ws.onopen = () => {
|
|
@@ -479,88 +514,397 @@ var WebSocketManager = class {
|
|
|
479
514
|
|
|
480
515
|
// ../widget-core/src/store.ts
|
|
481
516
|
import { createStore } from "zustand/vanilla";
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
517
|
+
|
|
518
|
+
// ../widget-core/src/i18n.ts
|
|
519
|
+
var en = {
|
|
520
|
+
// Navigation & tabs
|
|
521
|
+
"widget.home": "Home",
|
|
522
|
+
"widget.messages": "Messages",
|
|
523
|
+
"widget.help": "Help",
|
|
524
|
+
// Home screen
|
|
525
|
+
"widget.send_us_message": "Send us a message",
|
|
526
|
+
"widget.reply_time": "We typically reply in a few minutes",
|
|
527
|
+
"widget.recent_conversations": "Recent conversations",
|
|
528
|
+
"widget.see_all": "See all conversations",
|
|
529
|
+
"widget.whats_new": "What's New",
|
|
530
|
+
"widget.view_all": "View all",
|
|
531
|
+
// Messages tab
|
|
532
|
+
"widget.no_messages": "No messages yet",
|
|
533
|
+
"widget.no_messages_desc": "Start a conversation to get help",
|
|
534
|
+
"widget.start_conversation": "Start a conversation",
|
|
535
|
+
"widget.no_preview": "No messages yet",
|
|
536
|
+
// Conversation
|
|
537
|
+
"widget.new_conversation": "New conversation",
|
|
538
|
+
"widget.talk_to_human": "Talk to a human",
|
|
539
|
+
"widget.talk_to_human_message": "I'd like to talk to a human, please.",
|
|
540
|
+
"widget.aria_options": "Conversation options",
|
|
541
|
+
"widget.resolved_text": "This conversation has been resolved",
|
|
542
|
+
"widget.send_followup": "Send a follow-up",
|
|
543
|
+
"widget.start_a_conversation": "Start a conversation",
|
|
544
|
+
// Composer
|
|
545
|
+
"widget.placeholder": "Send a message...",
|
|
546
|
+
"widget.placeholder_new": "How can we help?",
|
|
547
|
+
"widget.drop_files": "Drop files here",
|
|
548
|
+
// CSAT
|
|
549
|
+
"widget.csat_label": "How was your experience?",
|
|
550
|
+
"widget.csat_thanks": "Thanks for your feedback!",
|
|
551
|
+
// Inline email collection (after AI reply)
|
|
552
|
+
"widget.email_title": "Don't miss our reply",
|
|
553
|
+
"widget.email_subtitle": "We'll email you when we respond",
|
|
554
|
+
"widget.email_placeholder": "you@email.com",
|
|
555
|
+
"widget.email_continue": "Send",
|
|
556
|
+
"widget.email_saved": "You'll be notified by email",
|
|
557
|
+
"widget.email_dismiss": "No thanks",
|
|
558
|
+
// Errors
|
|
559
|
+
"widget.error_title": "Something went wrong",
|
|
560
|
+
"widget.error_desc": "Failed to load. Please try again.",
|
|
561
|
+
"widget.retry": "Retry",
|
|
562
|
+
"widget.reconnecting": "Reconnecting...",
|
|
563
|
+
"widget.send_error": "Message not sent",
|
|
564
|
+
// Date separators (today is implicit — never rendered)
|
|
565
|
+
"widget.yesterday": "Yesterday",
|
|
566
|
+
// Sender labels
|
|
567
|
+
"widget.helpway_ai": "Helpway AI",
|
|
568
|
+
"widget.support": "Support",
|
|
569
|
+
// Events
|
|
570
|
+
"widget.joined": "joined the conversation",
|
|
571
|
+
"widget.left": "left the conversation",
|
|
572
|
+
// Content/search
|
|
573
|
+
"widget.content": "Content",
|
|
574
|
+
"widget.search": "Search...",
|
|
575
|
+
"widget.no_results": "No results found",
|
|
576
|
+
"widget.try_different": "Try a different search term",
|
|
577
|
+
"widget.nothing_yet": "Nothing here yet",
|
|
578
|
+
"widget.check_back": "Check back later for updates",
|
|
579
|
+
"widget.load_more": "Load more",
|
|
580
|
+
"widget.loading": "Loading...",
|
|
581
|
+
// Copy
|
|
582
|
+
"widget.copy": "Copy message",
|
|
583
|
+
"widget.copied": "Copied",
|
|
584
|
+
// File upload
|
|
585
|
+
"widget.file_too_large": "File too large (max 10 MB)",
|
|
586
|
+
"widget.click_to_open": "Click to open",
|
|
587
|
+
"widget.caption_required": "Add a message to send with your attachment",
|
|
588
|
+
// Accessibility
|
|
589
|
+
"widget.aria_chat": "Support chat",
|
|
590
|
+
"widget.aria_close": "Close",
|
|
591
|
+
"widget.aria_back": "Back",
|
|
592
|
+
"widget.aria_send": "Send message",
|
|
593
|
+
"widget.aria_open_image": "Open image",
|
|
594
|
+
"widget.aria_attach": "Attach file",
|
|
595
|
+
"widget.aria_dictate": "Dictate message",
|
|
596
|
+
"widget.aria_input": "Message input",
|
|
597
|
+
"widget.aria_remove": "Remove",
|
|
598
|
+
"widget.aria_dismiss": "Dismiss",
|
|
599
|
+
"widget.aria_open": "Open support",
|
|
600
|
+
"widget.aria_close_support": "Close support",
|
|
601
|
+
"widget.aria_good": "Good",
|
|
602
|
+
"widget.aria_bad": "Bad",
|
|
603
|
+
"widget.aria_messages": "Messages",
|
|
604
|
+
// Time (relative)
|
|
605
|
+
"widget.time_now": "now",
|
|
606
|
+
"widget.time_yesterday": "Yesterday",
|
|
607
|
+
// Powered by
|
|
608
|
+
"widget.powered_by": "Powered by",
|
|
609
|
+
// Closed-state dock — overflow row when the announcement stack is clipped
|
|
610
|
+
/* Plural handled by two keys rather than a rule. The widget's `t()` does
|
|
611
|
+
`{{var}}` substitution and nothing else, and inventing a plural engine for
|
|
612
|
+
one string would be the larger mistake; the languages we ship differ on
|
|
613
|
+
where the count sits, not on how many forms it needs here. */
|
|
614
|
+
/* A state, not a count. "3" in a pill reads as unread; this row is telling the
|
|
615
|
+
visitor the thread is waiting on THEM, which is a different thing and the one
|
|
616
|
+
that decides whether an answered conversation gets abandoned. */
|
|
617
|
+
"widget.awaiting_your_reply": "Awaiting your reply",
|
|
618
|
+
"widget.more_announcements_one": "+1 more update",
|
|
619
|
+
"widget.more_announcements": "+{{count}} more updates",
|
|
620
|
+
// Hero / home screen
|
|
621
|
+
/* One line, not two. The second line was "How can we help?" — the exact string
|
|
622
|
+
the composer's own placeholder shows, two inches below it. The input is what
|
|
623
|
+
asks the question; the greeting only has to say hello. */
|
|
624
|
+
"widget.welcome_message": "Hi there \u{1F44B}",
|
|
625
|
+
"widget.subtitle_text": "Usually replies in minutes"
|
|
626
|
+
};
|
|
627
|
+
var currentLocale = "en";
|
|
628
|
+
var translations = {};
|
|
629
|
+
var isLoaded = false;
|
|
630
|
+
var revision = 0;
|
|
631
|
+
var listeners = [];
|
|
632
|
+
function t(key, params) {
|
|
633
|
+
const value = translations[key] ?? en[key] ?? key;
|
|
634
|
+
if (!params) return value;
|
|
635
|
+
return value.replace(/\{\{(\w+)\}\}/g, (_, k) => {
|
|
636
|
+
return params[k]?.toString() ?? `{{${k}}}`;
|
|
637
|
+
});
|
|
486
638
|
}
|
|
487
|
-
function
|
|
488
|
-
|
|
489
|
-
try {
|
|
490
|
-
const raw = window.localStorage.getItem(PREVIEW_STORAGE_KEY);
|
|
491
|
-
return raw ? JSON.parse(raw) : null;
|
|
492
|
-
} catch {
|
|
493
|
-
return null;
|
|
494
|
-
}
|
|
639
|
+
function getLocale() {
|
|
640
|
+
return currentLocale;
|
|
495
641
|
}
|
|
496
|
-
function
|
|
497
|
-
|
|
642
|
+
function getI18nRevision() {
|
|
643
|
+
return revision;
|
|
644
|
+
}
|
|
645
|
+
function onLocaleChange(fn) {
|
|
646
|
+
listeners.push(fn);
|
|
647
|
+
return () => {
|
|
648
|
+
const idx = listeners.indexOf(fn);
|
|
649
|
+
if (idx >= 0) listeners.splice(idx, 1);
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
async function initI18n(options) {
|
|
653
|
+
if (options?.cdnBase) {
|
|
654
|
+
cdnBase = options.cdnBase;
|
|
655
|
+
}
|
|
656
|
+
const detected = options?.locale ?? (typeof navigator !== "undefined" ? navigator.language : "en");
|
|
657
|
+
currentLocale = normalizeLocale(detected);
|
|
658
|
+
if (currentLocale === "en") {
|
|
659
|
+
isLoaded = true;
|
|
660
|
+
notify();
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
498
663
|
try {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
664
|
+
const data = await fetchTranslations(currentLocale);
|
|
665
|
+
if (data) {
|
|
666
|
+
for (const [key, value] of Object.entries(data)) {
|
|
667
|
+
if (typeof value === "string") {
|
|
668
|
+
translations[`widget.${key}`] = value;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
503
671
|
}
|
|
504
|
-
} catch {
|
|
672
|
+
} catch (err) {
|
|
673
|
+
console.warn(`[Helpway] Failed to fetch ${currentLocale} translations, using English`, err);
|
|
505
674
|
}
|
|
675
|
+
isLoaded = true;
|
|
676
|
+
notify();
|
|
506
677
|
}
|
|
507
|
-
function
|
|
508
|
-
|
|
678
|
+
async function setLocale(locale) {
|
|
679
|
+
const normalized = normalizeLocale(locale);
|
|
680
|
+
if (normalized === currentLocale) return;
|
|
681
|
+
currentLocale = normalized;
|
|
682
|
+
translations = {};
|
|
683
|
+
if (normalized === "en") {
|
|
684
|
+
notify();
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
509
687
|
try {
|
|
510
|
-
const
|
|
511
|
-
if (
|
|
512
|
-
|
|
688
|
+
const data = await fetchTranslations(normalized);
|
|
689
|
+
if (data) {
|
|
690
|
+
for (const [key, value] of Object.entries(data)) {
|
|
691
|
+
if (typeof value === "string") {
|
|
692
|
+
translations[`widget.${key}`] = value;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
513
696
|
} catch {
|
|
514
|
-
return null;
|
|
515
697
|
}
|
|
698
|
+
notify();
|
|
516
699
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
700
|
+
var cdnBase = "https://cdn.better-i18n.com/helpway/widget";
|
|
701
|
+
async function fetchTranslations(locale) {
|
|
702
|
+
const url = `${cdnBase}/${locale}/translations.json`;
|
|
703
|
+
let res = await fetch(url);
|
|
704
|
+
if (!res.ok && locale.includes("-")) {
|
|
705
|
+
const base = locale.split("-")[0];
|
|
706
|
+
res = await fetch(`${cdnBase}/${base}/translations.json`);
|
|
707
|
+
}
|
|
708
|
+
if (!res.ok) return null;
|
|
709
|
+
const data = await res.json();
|
|
710
|
+
const widgetNs = data.widget;
|
|
711
|
+
if (widgetNs && typeof widgetNs === "object" && !Array.isArray(widgetNs)) {
|
|
712
|
+
const result = {};
|
|
713
|
+
for (const [k, v] of Object.entries(widgetNs)) {
|
|
714
|
+
if (typeof v === "string") result[k] = v;
|
|
715
|
+
}
|
|
716
|
+
return result;
|
|
523
717
|
}
|
|
524
718
|
return null;
|
|
525
719
|
}
|
|
526
|
-
function
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
720
|
+
function normalizeLocale(input) {
|
|
721
|
+
const regional = ["pt-br", "zh-cn", "zh-tw", "zh-hk"];
|
|
722
|
+
const lower = input.toLowerCase().replace("_", "-");
|
|
723
|
+
for (const r of regional) {
|
|
724
|
+
if (lower.startsWith(r)) return r;
|
|
725
|
+
}
|
|
726
|
+
return lower.split("-")[0] ?? "en";
|
|
727
|
+
}
|
|
728
|
+
function notify() {
|
|
729
|
+
revision++;
|
|
730
|
+
for (const fn of listeners) {
|
|
731
|
+
try {
|
|
732
|
+
fn();
|
|
733
|
+
} catch {
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// ../widget-core/src/utils.ts
|
|
739
|
+
function formatRelativeTime(date) {
|
|
740
|
+
const now = Date.now();
|
|
741
|
+
const then = typeof date === "string" ? new Date(date).getTime() : date.getTime();
|
|
742
|
+
const diffMs = now - then;
|
|
743
|
+
const diffMin = Math.floor(diffMs / 6e4);
|
|
744
|
+
const diffHour = Math.floor(diffMs / 36e5);
|
|
745
|
+
const diffDay = Math.floor(diffMs / 864e5);
|
|
746
|
+
if (diffMin < 1) return t("widget.time_now");
|
|
747
|
+
if (diffMin < 60) return `${diffMin}m`;
|
|
748
|
+
if (diffHour < 24) return `${diffHour}h`;
|
|
749
|
+
if (diffDay === 1) return t("widget.time_yesterday");
|
|
750
|
+
if (diffDay < 7) return `${diffDay}d`;
|
|
751
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
752
|
+
return d.toLocaleDateString(getLocale(), { month: "short", day: "numeric" });
|
|
753
|
+
}
|
|
754
|
+
function formatTime(date) {
|
|
755
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
756
|
+
return d.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
|
|
757
|
+
}
|
|
758
|
+
function resolveLabel(label) {
|
|
759
|
+
if (!label.startsWith("widget.")) return label;
|
|
760
|
+
const resolved = t(label);
|
|
761
|
+
if (resolved === label) {
|
|
762
|
+
return label.replace("widget.", "").replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase());
|
|
763
|
+
}
|
|
764
|
+
return resolved;
|
|
765
|
+
}
|
|
766
|
+
function getInitials(value) {
|
|
767
|
+
if (!value) return "?";
|
|
768
|
+
if (value.includes("@")) return (value[0] ?? "?").toUpperCase();
|
|
769
|
+
const parts = value.trim().split(/\s+/);
|
|
770
|
+
if (parts.length >= 2) {
|
|
771
|
+
return ((parts[0]?.[0] ?? "") + (parts[1]?.[0] ?? "")).toUpperCase();
|
|
772
|
+
}
|
|
773
|
+
return (parts[0]?.[0] ?? "?").toUpperCase();
|
|
774
|
+
}
|
|
775
|
+
function parseTimelineItemMetadata(raw) {
|
|
776
|
+
if (!raw) return null;
|
|
777
|
+
if (typeof raw === "object") return raw;
|
|
778
|
+
try {
|
|
779
|
+
const parsed = JSON.parse(raw);
|
|
780
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
781
|
+
} catch {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
function previewQuickReplies(metadata) {
|
|
786
|
+
const parsed = parseTimelineItemMetadata(metadata);
|
|
787
|
+
if (parsed?.kind !== "quick_replies") return null;
|
|
788
|
+
if (!Array.isArray(parsed.options) || parsed.options.length === 0) return null;
|
|
789
|
+
if (parsed.cancelled) return null;
|
|
790
|
+
return {
|
|
791
|
+
stepId: parsed.stepId,
|
|
792
|
+
prompt: parsed.prompt ?? null,
|
|
793
|
+
options: parsed.options.map((o) => ({ id: o.id, label: o.label }))
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
function splitAnnouncementStack(previews, maxVisible) {
|
|
797
|
+
const room = Number.isFinite(maxVisible) ? Math.max(0, Math.trunc(maxVisible)) : previews.length;
|
|
798
|
+
return { visible: previews.slice(0, room), hidden: previews.slice(room) };
|
|
799
|
+
}
|
|
800
|
+
function isAwaitingVisitorReply(conversation) {
|
|
801
|
+
if (conversation.status !== "open") return false;
|
|
802
|
+
return conversation.lastMessageSenderType === "team" || conversation.unreadCount > 0;
|
|
803
|
+
}
|
|
804
|
+
function awaitingReplyCount(conversations) {
|
|
805
|
+
return conversations.filter(isAwaitingVisitorReply).length;
|
|
806
|
+
}
|
|
807
|
+
var PREVIEW_BODY_LIMIT = 120;
|
|
808
|
+
function truncatePreviewBody(text, limit = PREVIEW_BODY_LIMIT) {
|
|
809
|
+
if (text.length <= limit) return text;
|
|
810
|
+
const slice = text.slice(0, limit);
|
|
811
|
+
const lastSpace = slice.lastIndexOf(" ");
|
|
812
|
+
const cut = lastSpace > limit * 0.6 ? slice.slice(0, lastSpace) : slice;
|
|
813
|
+
return `${cut.trimEnd()}\u2026`;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// ../widget-core/src/store.ts
|
|
817
|
+
var CONTENT_CACHE_TTL = 5 * 60 * 1e3;
|
|
818
|
+
var PREVIEW_STORAGE_KEY = "helpway:incoming-preview";
|
|
819
|
+
function streamingKeyFor(conversationId) {
|
|
820
|
+
return `streaming-${conversationId}`;
|
|
821
|
+
}
|
|
822
|
+
function loadPersistedPreview() {
|
|
823
|
+
if (typeof window === "undefined") return null;
|
|
824
|
+
try {
|
|
825
|
+
const raw = window.localStorage.getItem(PREVIEW_STORAGE_KEY);
|
|
826
|
+
return raw ? JSON.parse(raw) : null;
|
|
827
|
+
} catch {
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
function persistPreview(preview) {
|
|
832
|
+
if (typeof window === "undefined") return;
|
|
833
|
+
try {
|
|
834
|
+
if (preview) {
|
|
835
|
+
window.localStorage.setItem(PREVIEW_STORAGE_KEY, JSON.stringify(preview));
|
|
836
|
+
} else {
|
|
837
|
+
window.localStorage.removeItem(PREVIEW_STORAGE_KEY);
|
|
838
|
+
}
|
|
839
|
+
} catch {
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
function parseJoinEvent(text) {
|
|
843
|
+
if (!text.startsWith("{")) return null;
|
|
844
|
+
try {
|
|
845
|
+
const parsed = JSON.parse(text);
|
|
846
|
+
if (parsed.action !== "joined") return null;
|
|
847
|
+
return { name: parsed.name ?? null, image: parsed.image ?? null };
|
|
848
|
+
} catch {
|
|
849
|
+
return null;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
function latestAssignee(items) {
|
|
853
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
854
|
+
const item = items[i];
|
|
855
|
+
if (item?.type !== "event" || !item.text) continue;
|
|
856
|
+
const joined = parseJoinEvent(item.text);
|
|
857
|
+
if (joined) return joined;
|
|
858
|
+
}
|
|
859
|
+
return null;
|
|
860
|
+
}
|
|
861
|
+
var AI_INDICATOR_MAX_MS = 45e3;
|
|
862
|
+
function createWidgetStore() {
|
|
863
|
+
const indicatorWatchdogs = /* @__PURE__ */ new Map();
|
|
864
|
+
const clearWatchdog = (conversationId) => {
|
|
865
|
+
const timer = indicatorWatchdogs.get(conversationId);
|
|
866
|
+
if (timer !== void 0) {
|
|
867
|
+
clearTimeout(timer);
|
|
868
|
+
indicatorWatchdogs.delete(conversationId);
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
const store = createStore((set, get) => ({
|
|
872
|
+
// Initial state
|
|
873
|
+
isReady: false,
|
|
874
|
+
isConnecting: true,
|
|
875
|
+
visitor: null,
|
|
876
|
+
website: null,
|
|
877
|
+
agentConfig: null,
|
|
878
|
+
conversations: [],
|
|
879
|
+
activeConversationId: null,
|
|
880
|
+
messages: /* @__PURE__ */ new Map(),
|
|
881
|
+
typingUsers: /* @__PURE__ */ new Map(),
|
|
882
|
+
aiProcessing: /* @__PURE__ */ new Map(),
|
|
883
|
+
streamingText: /* @__PURE__ */ new Map(),
|
|
884
|
+
isOpen: false,
|
|
885
|
+
isDismissed: false,
|
|
886
|
+
view: "home",
|
|
887
|
+
incomingPreview: loadPersistedPreview(),
|
|
888
|
+
announcementPreviews: [],
|
|
889
|
+
unseenAnnouncementCount: 0,
|
|
890
|
+
newConversationPrefill: null,
|
|
891
|
+
pendingContentDetail: null,
|
|
892
|
+
contentCache: /* @__PURE__ */ new Map(),
|
|
893
|
+
// ── Lifecycle ────────────────────────────────────
|
|
894
|
+
setReady(visitor, website, agentConfig) {
|
|
895
|
+
set({
|
|
896
|
+
isReady: true,
|
|
897
|
+
isConnecting: false,
|
|
898
|
+
visitor,
|
|
899
|
+
website,
|
|
900
|
+
agentConfig: agentConfig ?? null
|
|
901
|
+
});
|
|
902
|
+
},
|
|
903
|
+
setConnecting(connecting) {
|
|
904
|
+
set({ isConnecting: connecting });
|
|
905
|
+
},
|
|
906
|
+
// ── Conversations ────────────────────────────────
|
|
907
|
+
setConversations(conversations) {
|
|
564
908
|
set({ conversations });
|
|
565
909
|
},
|
|
566
910
|
addConversation(conversation) {
|
|
@@ -683,6 +1027,17 @@ function createWidgetStore() {
|
|
|
683
1027
|
});
|
|
684
1028
|
},
|
|
685
1029
|
remapConversationId(oldId, newId) {
|
|
1030
|
+
if (indicatorWatchdogs.has(oldId)) {
|
|
1031
|
+
clearWatchdog(oldId);
|
|
1032
|
+
indicatorWatchdogs.set(
|
|
1033
|
+
newId,
|
|
1034
|
+
setTimeout(() => {
|
|
1035
|
+
indicatorWatchdogs.delete(newId);
|
|
1036
|
+
get().setAiProcessing(newId, false);
|
|
1037
|
+
get().setTyping(newId, false);
|
|
1038
|
+
}, AI_INDICATOR_MAX_MS)
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
686
1041
|
set((state) => {
|
|
687
1042
|
const nextMessages = new Map(state.messages);
|
|
688
1043
|
const tempItems = nextMessages.get(oldId) ?? [];
|
|
@@ -765,6 +1120,17 @@ function createWidgetStore() {
|
|
|
765
1120
|
});
|
|
766
1121
|
},
|
|
767
1122
|
setAiProcessing(conversationId, processing) {
|
|
1123
|
+
clearWatchdog(conversationId);
|
|
1124
|
+
if (processing) {
|
|
1125
|
+
indicatorWatchdogs.set(
|
|
1126
|
+
conversationId,
|
|
1127
|
+
setTimeout(() => {
|
|
1128
|
+
indicatorWatchdogs.delete(conversationId);
|
|
1129
|
+
get().setAiProcessing(conversationId, false);
|
|
1130
|
+
get().setTyping(conversationId, false);
|
|
1131
|
+
}, AI_INDICATOR_MAX_MS)
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
768
1134
|
set((state) => {
|
|
769
1135
|
const next = new Map(state.aiProcessing);
|
|
770
1136
|
next.set(conversationId, processing);
|
|
@@ -789,6 +1155,9 @@ function createWidgetStore() {
|
|
|
789
1155
|
*/
|
|
790
1156
|
appendStreamChunk(conversationId, delta, done) {
|
|
791
1157
|
void done;
|
|
1158
|
+
if (get().aiProcessing.get(conversationId)) {
|
|
1159
|
+
get().setAiProcessing(conversationId, true);
|
|
1160
|
+
}
|
|
792
1161
|
set((state) => {
|
|
793
1162
|
const next = new Map(state.streamingText);
|
|
794
1163
|
const prev = next.get(conversationId) ?? "";
|
|
@@ -895,6 +1264,9 @@ function createWidgetStore() {
|
|
|
895
1264
|
const isIncoming = !event.item.visitorId;
|
|
896
1265
|
const currentState = get();
|
|
897
1266
|
const isViewingThis = currentState.isOpen && currentState.activeConversationId === event.conversationId;
|
|
1267
|
+
const qr = previewQuickReplies(
|
|
1268
|
+
event.item.metadata
|
|
1269
|
+
);
|
|
898
1270
|
set((s) => ({
|
|
899
1271
|
conversations: s.conversations.map(
|
|
900
1272
|
(c) => c.id === event.conversationId ? {
|
|
@@ -908,11 +1280,18 @@ function createWidgetStore() {
|
|
|
908
1280
|
// Show preview bubble if widget is closed and message is incoming
|
|
909
1281
|
...isIncoming && !currentState.isOpen ? {
|
|
910
1282
|
incomingPreview: {
|
|
911
|
-
|
|
1283
|
+
/* Empty for a quick-replies step, always. The prompt belongs to the
|
|
1284
|
+
card's quick-replies block, which prints it directly above the
|
|
1285
|
+
buttons — putting it here too rendered it twice, once as a message
|
|
1286
|
+
body and once as the prompt. And a prompt-less step persists the
|
|
1287
|
+
option labels as its bullet-list fallback, so carrying `text`
|
|
1288
|
+
through would enumerate in prose the buttons sitting underneath. */
|
|
1289
|
+
text: qr ? "" : event.item.text ?? "",
|
|
912
1290
|
conversationId: event.conversationId,
|
|
913
1291
|
timestamp: Date.now(),
|
|
914
1292
|
senderName: event.item.userName ?? null,
|
|
915
|
-
senderImage: event.item.userImage ?? null
|
|
1293
|
+
senderImage: event.item.userImage ?? null,
|
|
1294
|
+
...qr ? { quickReplies: qr } : {}
|
|
916
1295
|
}
|
|
917
1296
|
} : {}
|
|
918
1297
|
}));
|
|
@@ -1161,251 +1540,80 @@ var WidgetEventEmitter = class {
|
|
|
1161
1540
|
}
|
|
1162
1541
|
};
|
|
1163
1542
|
|
|
1164
|
-
// ../widget-core/src/
|
|
1165
|
-
var
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
"widget.new_conversation": "New conversation",
|
|
1184
|
-
"widget.talk_to_human": "Talk to a human",
|
|
1185
|
-
"widget.talk_to_human_message": "I'd like to talk to a human, please.",
|
|
1186
|
-
"widget.aria_options": "Conversation options",
|
|
1187
|
-
"widget.resolved_text": "This conversation has been resolved",
|
|
1188
|
-
"widget.send_followup": "Send a follow-up",
|
|
1189
|
-
"widget.start_a_conversation": "Start a conversation",
|
|
1190
|
-
// Composer
|
|
1191
|
-
"widget.placeholder": "Send a message...",
|
|
1192
|
-
"widget.placeholder_new": "How can we help?",
|
|
1193
|
-
"widget.drop_files": "Drop files here",
|
|
1194
|
-
// CSAT
|
|
1195
|
-
"widget.csat_label": "How was your experience?",
|
|
1196
|
-
"widget.csat_thanks": "Thanks for your feedback!",
|
|
1197
|
-
// Inline email collection (after AI reply)
|
|
1198
|
-
"widget.email_title": "Don't miss our reply",
|
|
1199
|
-
"widget.email_subtitle": "We'll email you when we respond",
|
|
1200
|
-
"widget.email_placeholder": "you@email.com",
|
|
1201
|
-
"widget.email_continue": "Send",
|
|
1202
|
-
"widget.email_saved": "You'll be notified by email",
|
|
1203
|
-
"widget.email_dismiss": "No thanks",
|
|
1204
|
-
// Errors
|
|
1205
|
-
"widget.error_title": "Something went wrong",
|
|
1206
|
-
"widget.error_desc": "Failed to load. Please try again.",
|
|
1207
|
-
"widget.retry": "Retry",
|
|
1208
|
-
"widget.reconnecting": "Reconnecting...",
|
|
1209
|
-
"widget.send_error": "Message not sent",
|
|
1210
|
-
// Date separators (today is implicit — never rendered)
|
|
1211
|
-
"widget.yesterday": "Yesterday",
|
|
1212
|
-
// Sender labels
|
|
1213
|
-
"widget.helpway_ai": "Helpway AI",
|
|
1214
|
-
"widget.support": "Support",
|
|
1215
|
-
// Events
|
|
1216
|
-
"widget.joined": "joined the conversation",
|
|
1217
|
-
"widget.left": "left the conversation",
|
|
1218
|
-
// Content/search
|
|
1219
|
-
"widget.content": "Content",
|
|
1220
|
-
"widget.search": "Search...",
|
|
1221
|
-
"widget.no_results": "No results found",
|
|
1222
|
-
"widget.try_different": "Try a different search term",
|
|
1223
|
-
"widget.nothing_yet": "Nothing here yet",
|
|
1224
|
-
"widget.check_back": "Check back later for updates",
|
|
1225
|
-
"widget.load_more": "Load more",
|
|
1226
|
-
"widget.loading": "Loading...",
|
|
1227
|
-
// Copy
|
|
1228
|
-
"widget.copy": "Copy message",
|
|
1229
|
-
"widget.copied": "Copied",
|
|
1230
|
-
// File upload
|
|
1231
|
-
"widget.file_too_large": "File too large (max 10 MB)",
|
|
1232
|
-
"widget.click_to_open": "Click to open",
|
|
1233
|
-
"widget.caption_required": "Add a message to send with your attachment",
|
|
1234
|
-
// Accessibility
|
|
1235
|
-
"widget.aria_chat": "Support chat",
|
|
1236
|
-
"widget.aria_close": "Close",
|
|
1237
|
-
"widget.aria_back": "Back",
|
|
1238
|
-
"widget.aria_send": "Send message",
|
|
1239
|
-
"widget.aria_open_image": "Open image",
|
|
1240
|
-
"widget.aria_attach": "Attach file",
|
|
1241
|
-
"widget.aria_dictate": "Dictate message",
|
|
1242
|
-
"widget.aria_input": "Message input",
|
|
1243
|
-
"widget.aria_remove": "Remove",
|
|
1244
|
-
"widget.aria_dismiss": "Dismiss",
|
|
1245
|
-
"widget.aria_open": "Open support",
|
|
1246
|
-
"widget.aria_close_support": "Close support",
|
|
1247
|
-
"widget.aria_good": "Good",
|
|
1248
|
-
"widget.aria_bad": "Bad",
|
|
1249
|
-
"widget.aria_messages": "Messages",
|
|
1250
|
-
// Time (relative)
|
|
1251
|
-
"widget.time_now": "now",
|
|
1252
|
-
"widget.time_yesterday": "Yesterday",
|
|
1253
|
-
// Powered by
|
|
1254
|
-
"widget.powered_by": "Powered by",
|
|
1255
|
-
// Hero / home screen
|
|
1256
|
-
/* One line, not two. The second line was "How can we help?" — the exact string
|
|
1257
|
-
the composer's own placeholder shows, two inches below it. The input is what
|
|
1258
|
-
asks the question; the greeting only has to say hello. */
|
|
1259
|
-
"widget.welcome_message": "Hi there \u{1F44B}",
|
|
1260
|
-
"widget.subtitle_text": "Usually replies in minutes"
|
|
1261
|
-
};
|
|
1262
|
-
var currentLocale = "en";
|
|
1263
|
-
var translations = {};
|
|
1264
|
-
var isLoaded = false;
|
|
1265
|
-
var revision = 0;
|
|
1266
|
-
var listeners = [];
|
|
1267
|
-
function t(key, params) {
|
|
1268
|
-
const value = translations[key] ?? en[key] ?? key;
|
|
1269
|
-
if (!params) return value;
|
|
1270
|
-
return value.replace(/\{\{(\w+)\}\}/g, (_, k) => {
|
|
1271
|
-
return params[k]?.toString() ?? `{{${k}}}`;
|
|
1272
|
-
});
|
|
1273
|
-
}
|
|
1274
|
-
function getLocale() {
|
|
1275
|
-
return currentLocale;
|
|
1276
|
-
}
|
|
1277
|
-
function getI18nRevision() {
|
|
1278
|
-
return revision;
|
|
1279
|
-
}
|
|
1280
|
-
function onLocaleChange(fn) {
|
|
1281
|
-
listeners.push(fn);
|
|
1282
|
-
return () => {
|
|
1283
|
-
const idx = listeners.indexOf(fn);
|
|
1284
|
-
if (idx >= 0) listeners.splice(idx, 1);
|
|
1543
|
+
// ../widget-core/src/page-tracker.ts
|
|
1544
|
+
var DEFAULT_TITLE_SETTLE_MS = 50;
|
|
1545
|
+
var DEFAULT_TITLE_MAX_WAIT_MS = 1e3;
|
|
1546
|
+
function createPageTracker(deps) {
|
|
1547
|
+
const settleMs = deps.settleMs ?? DEFAULT_TITLE_SETTLE_MS;
|
|
1548
|
+
const maxWaitMs = deps.maxWaitMs ?? DEFAULT_TITLE_MAX_WAIT_MS;
|
|
1549
|
+
const schedule = deps.setTimeout ?? ((fn, ms) => setTimeout(fn, ms));
|
|
1550
|
+
const cancel = deps.clearTimeout ?? ((h) => clearTimeout(h));
|
|
1551
|
+
let pending = null;
|
|
1552
|
+
let lastReported = null;
|
|
1553
|
+
let correctionArmedFor = null;
|
|
1554
|
+
let fallbackTimer = null;
|
|
1555
|
+
let settleTimer = null;
|
|
1556
|
+
let stopped = false;
|
|
1557
|
+
const clearTimers = () => {
|
|
1558
|
+
if (fallbackTimer !== null) cancel(fallbackTimer);
|
|
1559
|
+
if (settleTimer !== null) cancel(settleTimer);
|
|
1560
|
+
fallbackTimer = null;
|
|
1561
|
+
settleTimer = null;
|
|
1285
1562
|
};
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
}
|
|
1291
|
-
const
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1563
|
+
const send = (page) => {
|
|
1564
|
+
if (lastReported && lastReported.url === page.url && lastReported.title === page.title) return;
|
|
1565
|
+
lastReported = page;
|
|
1566
|
+
deps.report(page);
|
|
1567
|
+
};
|
|
1568
|
+
const settle = (source) => {
|
|
1569
|
+
if (stopped || !pending) return;
|
|
1570
|
+
const title = deps.getTitle();
|
|
1571
|
+
if (source === "title" && title === pending.titleAtNavigate) return;
|
|
1572
|
+
const { url, titleAtNavigate } = pending;
|
|
1573
|
+
pending = null;
|
|
1574
|
+
clearTimers();
|
|
1575
|
+
send({ url, title });
|
|
1576
|
+
correctionArmedFor = source === "fallback" && title === titleAtNavigate ? url : null;
|
|
1577
|
+
};
|
|
1578
|
+
const onTitleChange = () => {
|
|
1579
|
+
if (stopped) return;
|
|
1580
|
+
if (pending) {
|
|
1581
|
+
if (settleTimer !== null) cancel(settleTimer);
|
|
1582
|
+
settleTimer = schedule(() => {
|
|
1583
|
+
settleTimer = null;
|
|
1584
|
+
settle("title");
|
|
1585
|
+
}, settleMs);
|
|
1586
|
+
return;
|
|
1306
1587
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
}
|
|
1313
|
-
async function setLocale(locale) {
|
|
1314
|
-
const normalized = normalizeLocale(locale);
|
|
1315
|
-
if (normalized === currentLocale) return;
|
|
1316
|
-
currentLocale = normalized;
|
|
1317
|
-
translations = {};
|
|
1318
|
-
if (normalized === "en") {
|
|
1319
|
-
notify();
|
|
1320
|
-
return;
|
|
1321
|
-
}
|
|
1322
|
-
try {
|
|
1323
|
-
const data = await fetchTranslations(normalized);
|
|
1324
|
-
if (data) {
|
|
1325
|
-
for (const [key, value] of Object.entries(data)) {
|
|
1326
|
-
if (typeof value === "string") {
|
|
1327
|
-
translations[`widget.${key}`] = value;
|
|
1328
|
-
}
|
|
1588
|
+
if (correctionArmedFor !== null && deps.getUrl() === correctionArmedFor) {
|
|
1589
|
+
const title = deps.getTitle();
|
|
1590
|
+
if (lastReported && title !== lastReported.title) {
|
|
1591
|
+
correctionArmedFor = null;
|
|
1592
|
+
send({ url: lastReported.url, title });
|
|
1329
1593
|
}
|
|
1330
1594
|
}
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
return result;
|
|
1352
|
-
}
|
|
1353
|
-
return null;
|
|
1354
|
-
}
|
|
1355
|
-
function normalizeLocale(input) {
|
|
1356
|
-
const regional = ["pt-br", "zh-cn", "zh-tw", "zh-hk"];
|
|
1357
|
-
const lower = input.toLowerCase().replace("_", "-");
|
|
1358
|
-
for (const r of regional) {
|
|
1359
|
-
if (lower.startsWith(r)) return r;
|
|
1360
|
-
}
|
|
1361
|
-
return lower.split("-")[0] ?? "en";
|
|
1362
|
-
}
|
|
1363
|
-
function notify() {
|
|
1364
|
-
revision++;
|
|
1365
|
-
for (const fn of listeners) {
|
|
1366
|
-
try {
|
|
1367
|
-
fn();
|
|
1368
|
-
} catch {
|
|
1595
|
+
};
|
|
1596
|
+
const unobserve = deps.observeTitle(onTitleChange);
|
|
1597
|
+
return {
|
|
1598
|
+
navigate() {
|
|
1599
|
+
if (stopped) return;
|
|
1600
|
+
const url = deps.getUrl();
|
|
1601
|
+
if (pending?.url === url) return;
|
|
1602
|
+
clearTimers();
|
|
1603
|
+
correctionArmedFor = null;
|
|
1604
|
+
pending = { url, titleAtNavigate: deps.getTitle() };
|
|
1605
|
+
fallbackTimer = schedule(() => {
|
|
1606
|
+
fallbackTimer = null;
|
|
1607
|
+
settle("fallback");
|
|
1608
|
+
}, maxWaitMs);
|
|
1609
|
+
},
|
|
1610
|
+
stop() {
|
|
1611
|
+
stopped = true;
|
|
1612
|
+
clearTimers();
|
|
1613
|
+
pending = null;
|
|
1614
|
+
unobserve();
|
|
1369
1615
|
}
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
// ../widget-core/src/utils.ts
|
|
1374
|
-
function formatRelativeTime(date) {
|
|
1375
|
-
const now = Date.now();
|
|
1376
|
-
const then = typeof date === "string" ? new Date(date).getTime() : date.getTime();
|
|
1377
|
-
const diffMs = now - then;
|
|
1378
|
-
const diffMin = Math.floor(diffMs / 6e4);
|
|
1379
|
-
const diffHour = Math.floor(diffMs / 36e5);
|
|
1380
|
-
const diffDay = Math.floor(diffMs / 864e5);
|
|
1381
|
-
if (diffMin < 1) return t("widget.time_now");
|
|
1382
|
-
if (diffMin < 60) return `${diffMin}m`;
|
|
1383
|
-
if (diffHour < 24) return `${diffHour}h`;
|
|
1384
|
-
if (diffDay === 1) return t("widget.time_yesterday");
|
|
1385
|
-
if (diffDay < 7) return `${diffDay}d`;
|
|
1386
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
1387
|
-
return d.toLocaleDateString(getLocale(), { month: "short", day: "numeric" });
|
|
1388
|
-
}
|
|
1389
|
-
function formatTime(date) {
|
|
1390
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
1391
|
-
return d.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
|
|
1392
|
-
}
|
|
1393
|
-
function resolveLabel(label) {
|
|
1394
|
-
if (!label.startsWith("widget.")) return label;
|
|
1395
|
-
const resolved = t(label);
|
|
1396
|
-
if (resolved === label) {
|
|
1397
|
-
return label.replace("widget.", "").replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase());
|
|
1398
|
-
}
|
|
1399
|
-
return resolved;
|
|
1400
|
-
}
|
|
1401
|
-
function getInitials(value) {
|
|
1402
|
-
if (!value) return "?";
|
|
1403
|
-
if (value.includes("@")) return (value[0] ?? "?").toUpperCase();
|
|
1404
|
-
const parts = value.trim().split(/\s+/);
|
|
1405
|
-
if (parts.length >= 2) {
|
|
1406
|
-
return ((parts[0]?.[0] ?? "") + (parts[1]?.[0] ?? "")).toUpperCase();
|
|
1407
|
-
}
|
|
1408
|
-
return (parts[0]?.[0] ?? "?").toUpperCase();
|
|
1616
|
+
};
|
|
1409
1617
|
}
|
|
1410
1618
|
|
|
1411
1619
|
// src/provider.tsx
|
|
@@ -1457,6 +1665,8 @@ function SupportProvider({
|
|
|
1457
1665
|
const [hasBootstrapError, setHasBootstrapError] = useState(false);
|
|
1458
1666
|
const [wsDisconnected, setWsDisconnected] = useState(false);
|
|
1459
1667
|
const [bootstrapAttempt, setBootstrapAttempt] = useState(0);
|
|
1668
|
+
const sourceLocaleRef = useRef(locale);
|
|
1669
|
+
const getSourceLocale = useCallback(() => sourceLocaleRef.current, []);
|
|
1460
1670
|
if (!initRef.current) {
|
|
1461
1671
|
const resolvedApiUrl = apiUrl ?? inferApiUrl();
|
|
1462
1672
|
const client2 = createWidgetClient({
|
|
@@ -1484,6 +1694,7 @@ function SupportProvider({
|
|
|
1484
1694
|
const metaLocale = data.metadata?.locale;
|
|
1485
1695
|
if (typeof metaLocale === "string" && metaLocale.length > 0) {
|
|
1486
1696
|
setLocale(metaLocale);
|
|
1697
|
+
sourceLocaleRef.current = metaLocale;
|
|
1487
1698
|
}
|
|
1488
1699
|
} catch (err) {
|
|
1489
1700
|
console.error("[Helpway] identify failed:", err);
|
|
@@ -1511,7 +1722,7 @@ function SupportProvider({
|
|
|
1511
1722
|
store.getState().setReady(data.visitor, data.website, data.agentConfig);
|
|
1512
1723
|
setHasBootstrapError(false);
|
|
1513
1724
|
if (data.visitor?.id) {
|
|
1514
|
-
syncVisitorId(apiKey, data.visitor.id);
|
|
1725
|
+
syncVisitorId(apiKey, data.visitor.signedId ?? data.visitor.id);
|
|
1515
1726
|
}
|
|
1516
1727
|
const convData = await client.widget.listConversations.query();
|
|
1517
1728
|
if (cancelled) return;
|
|
@@ -1524,11 +1735,20 @@ function SupportProvider({
|
|
|
1524
1735
|
lastMessageSenderType: c.lastMessageSenderType,
|
|
1525
1736
|
lastMessageSenderName: c.lastMessageSenderName,
|
|
1526
1737
|
lastMessageSenderImage: c.lastMessageSenderImage,
|
|
1527
|
-
|
|
1738
|
+
/* The server's count, not a zero.
|
|
1739
|
+
|
|
1740
|
+
This was the literal `0`, which meant `useUnread()` answered 0 on
|
|
1741
|
+
every page load however many replies were waiting — the value
|
|
1742
|
+
described "messages that arrived while this tab has been open",
|
|
1743
|
+
not "unread". A badge shipped against the hook downstream never
|
|
1744
|
+
rendered once, with an unanswered agent message on screen.
|
|
1745
|
+
|
|
1746
|
+
Still defaulted, because a widget on an older API build gets a
|
|
1747
|
+
payload without the field, and 0 is the honest answer there — the
|
|
1748
|
+
socket path raises it from there as messages land. */
|
|
1749
|
+
unreadCount: c.unreadCount ?? 0
|
|
1528
1750
|
});
|
|
1529
|
-
store.getState().setConversations(
|
|
1530
|
-
convData.conversations.map(mapConversation)
|
|
1531
|
-
);
|
|
1751
|
+
store.getState().setConversations(convData.conversations.map(mapConversation));
|
|
1532
1752
|
if (data.website?.id && data.visitor?.id) {
|
|
1533
1753
|
ws.configure({ websiteId: data.website.id, visitorId: data.visitor.id });
|
|
1534
1754
|
ws.connect();
|
|
@@ -1567,27 +1787,19 @@ function SupportProvider({
|
|
|
1567
1787
|
} catch {
|
|
1568
1788
|
}
|
|
1569
1789
|
}
|
|
1570
|
-
|
|
1571
|
-
client.widget.updatePage.mutate({
|
|
1572
|
-
url: window.location.href,
|
|
1573
|
-
title: document.title || window.location.pathname
|
|
1574
|
-
}).catch(() => {
|
|
1575
|
-
});
|
|
1576
|
-
}
|
|
1790
|
+
pageTracker?.navigate();
|
|
1577
1791
|
if (initialConversationId && !cancelled) {
|
|
1578
1792
|
if (deepLinkToken) {
|
|
1579
1793
|
try {
|
|
1580
1794
|
const redeemed = await client.widget.redeemDeepLink.mutate({ token: deepLinkToken });
|
|
1581
1795
|
if (!cancelled && redeemed?.visitorId && redeemed.visitorId !== data.visitor?.id) {
|
|
1582
|
-
syncVisitorId(apiKey, redeemed.visitorId);
|
|
1796
|
+
syncVisitorId(apiKey, redeemed.signedVisitorId ?? redeemed.visitorId);
|
|
1583
1797
|
const freshData = await client.widget.bootstrap.query();
|
|
1584
1798
|
if (!cancelled) {
|
|
1585
1799
|
store.getState().setReady(freshData.visitor, freshData.website, freshData.agentConfig);
|
|
1586
1800
|
const freshConvs = await client.widget.listConversations.query();
|
|
1587
1801
|
if (!cancelled) {
|
|
1588
|
-
store.getState().setConversations(
|
|
1589
|
-
freshConvs.conversations.map(mapConversation)
|
|
1590
|
-
);
|
|
1802
|
+
store.getState().setConversations(freshConvs.conversations.map(mapConversation));
|
|
1591
1803
|
}
|
|
1592
1804
|
}
|
|
1593
1805
|
}
|
|
@@ -1609,19 +1821,29 @@ function SupportProvider({
|
|
|
1609
1821
|
}
|
|
1610
1822
|
}
|
|
1611
1823
|
}
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1824
|
+
const pageTracker = typeof window === "undefined" ? null : createPageTracker({
|
|
1825
|
+
getUrl: () => window.location.href,
|
|
1826
|
+
getTitle: () => document.title || window.location.pathname,
|
|
1827
|
+
observeTitle: (onChange) => {
|
|
1828
|
+
if (typeof MutationObserver === "undefined") return () => {
|
|
1829
|
+
};
|
|
1830
|
+
const observer = new MutationObserver(onChange);
|
|
1831
|
+
observer.observe(document.head ?? document.documentElement, {
|
|
1832
|
+
subtree: true,
|
|
1833
|
+
childList: true,
|
|
1834
|
+
characterData: true
|
|
1835
|
+
});
|
|
1836
|
+
return () => observer.disconnect();
|
|
1837
|
+
},
|
|
1838
|
+
report: (page) => {
|
|
1839
|
+
client.widget.updatePage.mutate(page).catch(() => {
|
|
1622
1840
|
});
|
|
1623
|
-
}
|
|
1841
|
+
}
|
|
1842
|
+
});
|
|
1843
|
+
const reportPage = () => {
|
|
1844
|
+
pageTracker?.navigate();
|
|
1624
1845
|
};
|
|
1846
|
+
bootstrap();
|
|
1625
1847
|
const origPush = window.history.pushState.bind(window.history);
|
|
1626
1848
|
const origReplace = window.history.replaceState.bind(window.history);
|
|
1627
1849
|
window.history.pushState = function patchedPush(...args) {
|
|
@@ -1676,7 +1898,7 @@ function SupportProvider({
|
|
|
1676
1898
|
unsub();
|
|
1677
1899
|
clearInterval(wsCheck);
|
|
1678
1900
|
if (markSeenTimer) clearTimeout(markSeenTimer);
|
|
1679
|
-
|
|
1901
|
+
pageTracker?.stop();
|
|
1680
1902
|
window.history.pushState = origPush;
|
|
1681
1903
|
window.history.replaceState = origReplace;
|
|
1682
1904
|
window.removeEventListener("popstate", reportPage);
|
|
@@ -1686,6 +1908,7 @@ function SupportProvider({
|
|
|
1686
1908
|
useEffect(() => {
|
|
1687
1909
|
if (locale != null) {
|
|
1688
1910
|
setLocale(locale);
|
|
1911
|
+
sourceLocaleRef.current = locale;
|
|
1689
1912
|
}
|
|
1690
1913
|
}, [locale]);
|
|
1691
1914
|
useEffect(() => {
|
|
@@ -1759,7 +1982,8 @@ function SupportProvider({
|
|
|
1759
1982
|
emitter,
|
|
1760
1983
|
hasBootstrapError,
|
|
1761
1984
|
wsDisconnected,
|
|
1762
|
-
retryBootstrap
|
|
1985
|
+
retryBootstrap,
|
|
1986
|
+
getSourceLocale
|
|
1763
1987
|
};
|
|
1764
1988
|
return /* @__PURE__ */ jsx(WidgetContext.Provider, { value: ctxValue, children });
|
|
1765
1989
|
}
|
|
@@ -2022,6 +2246,11 @@ function useAnnouncements() {
|
|
|
2022
2246
|
};
|
|
2023
2247
|
}
|
|
2024
2248
|
|
|
2249
|
+
// src/hooks/use-awaiting-reply.ts
|
|
2250
|
+
function useAwaitingReply() {
|
|
2251
|
+
return useWidgetStore((s) => awaitingReplyCount(s.conversations));
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2025
2254
|
// src/hooks/use-composer.ts
|
|
2026
2255
|
import { useCallback as useCallback3, useState as useState2 } from "react";
|
|
2027
2256
|
function currentPagePayload() {
|
|
@@ -2048,7 +2277,7 @@ var ACCEPTED_TYPES = [
|
|
|
2048
2277
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
2049
2278
|
].join(",");
|
|
2050
2279
|
function useComposer(boundConversationId) {
|
|
2051
|
-
const { client, ws, store } = useWidgetContext();
|
|
2280
|
+
const { client, ws, store, getSourceLocale } = useWidgetContext();
|
|
2052
2281
|
const conversationId = boundConversationId;
|
|
2053
2282
|
const [text, setText] = useState2("");
|
|
2054
2283
|
const [isSubmitting, setIsSubmitting] = useState2(false);
|
|
@@ -2173,12 +2402,14 @@ function useComposer(boundConversationId) {
|
|
|
2173
2402
|
} catch {
|
|
2174
2403
|
}
|
|
2175
2404
|
} else if (isTempConversation) {
|
|
2405
|
+
const sourceLocale = getSourceLocale();
|
|
2176
2406
|
const result = await client.widget.createConversation.mutate({
|
|
2177
2407
|
...hasText ? { text: trimmed } : {},
|
|
2178
2408
|
...hasAttachments ? { parts: readyParts } : {},
|
|
2179
2409
|
/* The first message is the one that most needs this — someone
|
|
2180
2410
|
lands on a page and immediately asks what it is. */
|
|
2181
|
-
...currentPagePayload()
|
|
2411
|
+
...currentPagePayload(),
|
|
2412
|
+
...sourceLocale ? { sourceLocale } : {}
|
|
2182
2413
|
});
|
|
2183
2414
|
const conv = result.conversation;
|
|
2184
2415
|
store.getState().remapConversationId(conversationId2, conv.id);
|
|
@@ -2216,7 +2447,7 @@ function useComposer(boundConversationId) {
|
|
|
2216
2447
|
setIsSubmitting(false);
|
|
2217
2448
|
}
|
|
2218
2449
|
},
|
|
2219
|
-
[text, attachments, boundConversationId, isSubmitting, client, ws, store]
|
|
2450
|
+
[text, attachments, boundConversationId, isSubmitting, client, ws, store, getSourceLocale]
|
|
2220
2451
|
);
|
|
2221
2452
|
const clearSendError = useCallback3(() => setSendError(null), []);
|
|
2222
2453
|
return {
|
|
@@ -2249,15 +2480,17 @@ function fileToBase64(file) {
|
|
|
2249
2480
|
// src/hooks/use-conversations.ts
|
|
2250
2481
|
import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
2251
2482
|
function useConversations() {
|
|
2252
|
-
const { client, store } = useWidgetContext();
|
|
2483
|
+
const { client, store, getSourceLocale } = useWidgetContext();
|
|
2253
2484
|
const conversations = useWidgetStore((s) => s.conversations);
|
|
2254
2485
|
const setActiveConversation = useWidgetStore((s) => s.setActiveConversation);
|
|
2255
2486
|
const [isCreating, setIsCreating] = useState3(false);
|
|
2256
2487
|
const clientRef = useRef3(client);
|
|
2257
2488
|
const storeRef = useRef3(store);
|
|
2489
|
+
const getSourceLocaleRef = useRef3(getSourceLocale);
|
|
2258
2490
|
useEffect3(() => {
|
|
2259
2491
|
clientRef.current = client;
|
|
2260
2492
|
storeRef.current = store;
|
|
2493
|
+
getSourceLocaleRef.current = getSourceLocale;
|
|
2261
2494
|
});
|
|
2262
2495
|
const create = useCallback4(async (text) => {
|
|
2263
2496
|
setIsCreating(true);
|
|
@@ -2297,7 +2530,11 @@ function useConversations() {
|
|
|
2297
2530
|
store2.setMessages(tempConversationId, [optimisticMsg]);
|
|
2298
2531
|
store2.setActiveConversation(tempConversationId);
|
|
2299
2532
|
try {
|
|
2300
|
-
const
|
|
2533
|
+
const sourceLocale = getSourceLocaleRef.current();
|
|
2534
|
+
const result = await clientRef.current.widget.createConversation.mutate({
|
|
2535
|
+
text,
|
|
2536
|
+
...sourceLocale ? { sourceLocale } : {}
|
|
2537
|
+
});
|
|
2301
2538
|
const conv = result.conversation;
|
|
2302
2539
|
storeRef.current.getState().remapConversationId(tempConversationId, conv.id);
|
|
2303
2540
|
if (result.item) {
|
|
@@ -2323,6 +2560,13 @@ function useConversations() {
|
|
|
2323
2560
|
}
|
|
2324
2561
|
|
|
2325
2562
|
// src/hooks/use-header-identity.ts
|
|
2563
|
+
function conversationIdentity(conv) {
|
|
2564
|
+
const teamSender = conv?.lastMessageSenderType === "team" && conv?.lastMessageSenderName ? conv : null;
|
|
2565
|
+
return {
|
|
2566
|
+
humanName: conv?.assigneeName ?? teamSender?.lastMessageSenderName ?? null,
|
|
2567
|
+
humanImage: conv?.assigneeImage ?? teamSender?.lastMessageSenderImage ?? null
|
|
2568
|
+
};
|
|
2569
|
+
}
|
|
2326
2570
|
function useHeaderIdentity() {
|
|
2327
2571
|
const activeConvSummary = useWidgetStore((s) => {
|
|
2328
2572
|
const id = s.activeConversationId;
|
|
@@ -2330,9 +2574,7 @@ function useHeaderIdentity() {
|
|
|
2330
2574
|
});
|
|
2331
2575
|
const agentConfigName = useWidgetStore((s) => s.agentConfig?.name);
|
|
2332
2576
|
const websiteName = useWidgetStore((s) => s.website?.name);
|
|
2333
|
-
const
|
|
2334
|
-
const humanName = activeConvSummary?.assigneeName ?? teamSender?.lastMessageSenderName ?? null;
|
|
2335
|
-
const humanImage = activeConvSummary?.assigneeImage ?? teamSender?.lastMessageSenderImage ?? null;
|
|
2577
|
+
const { humanName, humanImage } = conversationIdentity(activeConvSummary);
|
|
2336
2578
|
const companyName = agentConfigName ?? websiteName ?? "Support";
|
|
2337
2579
|
return {
|
|
2338
2580
|
humanName,
|
|
@@ -2494,6 +2736,9 @@ function useWidget() {
|
|
|
2494
2736
|
return { isReady, isConnecting, visitor, website, agentConfig, identify };
|
|
2495
2737
|
}
|
|
2496
2738
|
|
|
2739
|
+
// src/shell/docked-bar.tsx
|
|
2740
|
+
import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef7, useState as useState7 } from "react";
|
|
2741
|
+
|
|
2497
2742
|
// src/themed/composer.tsx
|
|
2498
2743
|
import { useCallback as useCallback7, useRef as useRef6, useState as useState6 } from "react";
|
|
2499
2744
|
|
|
@@ -2891,310 +3136,63 @@ function Composer({
|
|
|
2891
3136
|
"input",
|
|
2892
3137
|
{
|
|
2893
3138
|
ref: fileInputRef,
|
|
2894
|
-
type: "file",
|
|
2895
|
-
accept: ACCEPTED_TYPES,
|
|
2896
|
-
multiple: true,
|
|
2897
|
-
hidden: true,
|
|
2898
|
-
onChange: handleFileChange
|
|
2899
|
-
}
|
|
2900
|
-
),
|
|
2901
|
-
showCharCount && /* @__PURE__ */ jsx3("span", { className: `hw-composer-charcount ${isOverLimit ? "hw-composer-charcount--over" : ""}`, children: MAX_CHARS - text.length })
|
|
2902
|
-
] }),
|
|
2903
|
-
/* @__PURE__ */ jsx3(
|
|
2904
|
-
"button",
|
|
2905
|
-
{
|
|
2906
|
-
type: "button",
|
|
2907
|
-
className: `hw-composer-send ${canSend && !isOverLimit && !disabled ? "hw-composer-send--active" : "hw-composer-send--inactive"}`,
|
|
2908
|
-
onClick: () => onSubmit(),
|
|
2909
|
-
disabled: disabled || !canSend || isSubmitting || isOverLimit,
|
|
2910
|
-
"aria-label": t("widget.aria_send"),
|
|
2911
|
-
children: /* @__PURE__ */ jsx3(SendIcon, {})
|
|
2912
|
-
}
|
|
2913
|
-
)
|
|
2914
|
-
] })
|
|
2915
|
-
] })
|
|
2916
|
-
}
|
|
2917
|
-
);
|
|
2918
|
-
}
|
|
2919
|
-
function PreviewThumb({ attachment: a, onRemove }) {
|
|
2920
|
-
return /* @__PURE__ */ jsxs2("div", { className: `hw-composer-preview ${a.error ? "hw-composer-preview--error" : ""}`, children: [
|
|
2921
|
-
a.previewUrl ? /* @__PURE__ */ jsx3("img", { src: a.previewUrl, alt: a.file.name, className: "hw-composer-preview-img" }) : /* @__PURE__ */ jsx3("div", { className: "hw-composer-preview-file", children: /* @__PURE__ */ jsx3("span", { className: "hw-composer-preview-ext", children: a.file.name.split(".").pop()?.toUpperCase() ?? "FILE" }) }),
|
|
2922
|
-
a.isUploading && /* @__PURE__ */ jsx3("div", { className: "hw-composer-preview-loader" }),
|
|
2923
|
-
a.error && /* @__PURE__ */ jsx3("div", { className: "hw-composer-preview-badge", title: a.error, children: "!" }),
|
|
2924
|
-
onRemove && /* @__PURE__ */ jsx3(
|
|
2925
|
-
"button",
|
|
2926
|
-
{
|
|
2927
|
-
type: "button",
|
|
2928
|
-
className: "hw-composer-preview-remove",
|
|
2929
|
-
onClick: onRemove,
|
|
2930
|
-
"aria-label": t("widget.aria_remove"),
|
|
2931
|
-
children: /* @__PURE__ */ jsx3(XIcon, {})
|
|
2932
|
-
}
|
|
2933
|
-
)
|
|
2934
|
-
] });
|
|
2935
|
-
}
|
|
2936
|
-
function extractFiles(data) {
|
|
2937
|
-
const files = [];
|
|
2938
|
-
if (data.files) {
|
|
2939
|
-
for (let i = 0; i < data.files.length; i++) {
|
|
2940
|
-
const file = data.files[i];
|
|
2941
|
-
if (file) files.push(file);
|
|
2942
|
-
}
|
|
2943
|
-
}
|
|
2944
|
-
return files;
|
|
2945
|
-
}
|
|
2946
|
-
|
|
2947
|
-
// src/themed/debug-overlay.tsx
|
|
2948
|
-
import { useEffect as useEffect6, useMemo as useMemo2, useRef as useRef7, useState as useState7 } from "react";
|
|
2949
|
-
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2950
|
-
var MAX_EVENTS = 60;
|
|
2951
|
-
function isDebugEnabled() {
|
|
2952
|
-
if (typeof window === "undefined") return false;
|
|
2953
|
-
if (typeof window.localStorage !== "undefined" && window.localStorage.getItem("hw:debug") === "1") {
|
|
2954
|
-
return true;
|
|
2955
|
-
}
|
|
2956
|
-
const search = window.location?.search ?? "";
|
|
2957
|
-
return search.includes("hwdebug=1") || search.includes("debug=hw");
|
|
2958
|
-
}
|
|
2959
|
-
function senderOf(item) {
|
|
2960
|
-
if (item.visitorId) return "visitor";
|
|
2961
|
-
if (item.aiAgentId) return "ai";
|
|
2962
|
-
if (item.userId) return "team";
|
|
2963
|
-
return item.type;
|
|
2964
|
-
}
|
|
2965
|
-
function WidgetDebugOverlay() {
|
|
2966
|
-
const [enabled, setEnabled] = useState7(false);
|
|
2967
|
-
const [open, setOpen] = useState7(true);
|
|
2968
|
-
const [events, setEvents] = useState7([]);
|
|
2969
|
-
const eventsRef = useRef7([]);
|
|
2970
|
-
const activeId = useWidgetStore((s) => s.activeConversationId);
|
|
2971
|
-
const messagesMap = useWidgetStore((s) => s.messages);
|
|
2972
|
-
const typingUsers = useWidgetStore((s) => s.typingUsers);
|
|
2973
|
-
const aiProcessingMap = useWidgetStore((s) => s.aiProcessing);
|
|
2974
|
-
const { store } = useWidgetContext();
|
|
2975
|
-
useEffect6(() => {
|
|
2976
|
-
setEnabled(isDebugEnabled());
|
|
2977
|
-
}, []);
|
|
2978
|
-
const pushEvent = useMemo2(
|
|
2979
|
-
() => (ev) => {
|
|
2980
|
-
const e = {
|
|
2981
|
-
...ev,
|
|
2982
|
-
id: `${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
2983
|
-
t: Date.now()
|
|
2984
|
-
};
|
|
2985
|
-
eventsRef.current = [e, ...eventsRef.current].slice(0, MAX_EVENTS);
|
|
2986
|
-
setEvents(eventsRef.current);
|
|
2987
|
-
},
|
|
2988
|
-
[]
|
|
2989
|
-
);
|
|
2990
|
-
useEffect6(() => {
|
|
2991
|
-
if (!enabled) return;
|
|
2992
|
-
if (typeof window === "undefined" || typeof window.fetch !== "function") return;
|
|
2993
|
-
const originalFetch = window.fetch.bind(window);
|
|
2994
|
-
const patched = (async (input, init) => {
|
|
2995
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
2996
|
-
const isTrpc = url.includes("/trpc/");
|
|
2997
|
-
if (isTrpc) {
|
|
2998
|
-
const method = init?.method ?? (typeof input !== "string" && !(input instanceof URL) ? input.method : "GET");
|
|
2999
|
-
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
3000
|
-
pushEvent({ kind: "trpc", label: `\u2192 ${method} ${label}`, detail: shortJson(init?.body) });
|
|
3001
|
-
}
|
|
3002
|
-
try {
|
|
3003
|
-
const res = await originalFetch(input, init);
|
|
3004
|
-
if (isTrpc) {
|
|
3005
|
-
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
3006
|
-
pushEvent({ kind: "trpc", label: `\u2190 ${res.status} ${label}` });
|
|
3007
|
-
}
|
|
3008
|
-
return res;
|
|
3009
|
-
} catch (err) {
|
|
3010
|
-
if (isTrpc) {
|
|
3011
|
-
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
3012
|
-
pushEvent({ kind: "error", label: `\u2718 ${label}`, detail: err instanceof Error ? err.message : String(err) });
|
|
3013
|
-
}
|
|
3014
|
-
throw err;
|
|
3015
|
-
}
|
|
3016
|
-
});
|
|
3017
|
-
window.fetch = patched;
|
|
3018
|
-
return () => {
|
|
3019
|
-
window.fetch = originalFetch;
|
|
3020
|
-
};
|
|
3021
|
-
}, [enabled, pushEvent]);
|
|
3022
|
-
useEffect6(() => {
|
|
3023
|
-
if (!enabled) return;
|
|
3024
|
-
const original = store.getState().handleRealtimeEvent;
|
|
3025
|
-
store.setState({
|
|
3026
|
-
handleRealtimeEvent: (ev) => {
|
|
3027
|
-
pushEvent({ kind: "ws", label: ev.type, detail: shortJson(ev) });
|
|
3028
|
-
original(ev);
|
|
3029
|
-
}
|
|
3030
|
-
});
|
|
3031
|
-
return () => {
|
|
3032
|
-
store.setState({ handleRealtimeEvent: original });
|
|
3033
|
-
};
|
|
3034
|
-
}, [enabled, store, pushEvent]);
|
|
3035
|
-
const activeMessages = activeId ? messagesMap.get(activeId) ?? [] : [];
|
|
3036
|
-
const lastMsgSignature = useMemo2(
|
|
3037
|
-
() => activeMessages.map((m) => `${m.id}:${senderOf(m)}:${m.createdAt}`).join("|"),
|
|
3038
|
-
[activeMessages]
|
|
3039
|
-
);
|
|
3040
|
-
const prevSigRef = useRef7(lastMsgSignature);
|
|
3041
|
-
useEffect6(() => {
|
|
3042
|
-
if (!enabled) return;
|
|
3043
|
-
if (prevSigRef.current !== lastMsgSignature) {
|
|
3044
|
-
prevSigRef.current = lastMsgSignature;
|
|
3045
|
-
pushEvent({
|
|
3046
|
-
kind: "store",
|
|
3047
|
-
label: `messages[${activeMessages.length}]`,
|
|
3048
|
-
detail: activeMessages.map((m, i) => `${i}:${senderOf(m)}=${(m.text ?? "").slice(0, 24)}`).join(" | ")
|
|
3049
|
-
});
|
|
3050
|
-
}
|
|
3051
|
-
}, [lastMsgSignature, activeMessages, enabled, pushEvent]);
|
|
3052
|
-
if (!enabled) return null;
|
|
3053
|
-
const isTyping = activeId ? typingUsers.get(activeId) : false;
|
|
3054
|
-
const isAi = activeId ? aiProcessingMap.get(activeId) : false;
|
|
3055
|
-
return /* @__PURE__ */ jsxs3("div", { style: styles.wrap, children: [
|
|
3056
|
-
/* @__PURE__ */ jsxs3("div", { style: styles.header, children: [
|
|
3057
|
-
/* @__PURE__ */ jsx4("strong", { children: "hw debug" }),
|
|
3058
|
-
/* @__PURE__ */ jsxs3("span", { style: styles.meta, children: [
|
|
3059
|
-
" ",
|
|
3060
|
-
"\xB7 conv ",
|
|
3061
|
-
activeId ? activeId.slice(0, 10) : "\u2014",
|
|
3062
|
-
" \xB7 items ",
|
|
3063
|
-
activeMessages.length,
|
|
3064
|
-
" \xB7 typing ",
|
|
3065
|
-
isTyping ? "Y" : "n",
|
|
3066
|
-
" \xB7 ai ",
|
|
3067
|
-
isAi ? "Y" : "n"
|
|
3068
|
-
] }),
|
|
3069
|
-
/* @__PURE__ */ jsx4("button", { type: "button", style: styles.btn, onClick: () => setOpen((v) => !v), children: open ? "hide" : "show" }),
|
|
3070
|
-
/* @__PURE__ */ jsx4("button", { type: "button", style: styles.btn, onClick: () => {
|
|
3071
|
-
eventsRef.current = [];
|
|
3072
|
-
setEvents([]);
|
|
3073
|
-
}, children: "clear" })
|
|
3074
|
-
] }),
|
|
3075
|
-
open && /* @__PURE__ */ jsxs3("div", { style: styles.body, children: [
|
|
3076
|
-
/* @__PURE__ */ jsxs3("div", { style: styles.section, children: [
|
|
3077
|
-
/* @__PURE__ */ jsx4("div", { style: styles.sectionTitle, children: "messages (active)" }),
|
|
3078
|
-
activeMessages.length === 0 ? /* @__PURE__ */ jsx4("div", { style: styles.empty, children: "empty" }) : activeMessages.map((m, i) => /* @__PURE__ */ jsxs3("div", { style: styles.row, children: [
|
|
3079
|
-
/* @__PURE__ */ jsx4("span", { style: { ...styles.badge, background: colorFor(senderOf(m)) }, children: i }),
|
|
3080
|
-
/* @__PURE__ */ jsx4("span", { style: styles.sender, children: senderOf(m) }),
|
|
3081
|
-
/* @__PURE__ */ jsx4("span", { style: styles.ts, children: m.createdAt.slice(11, 23) }),
|
|
3082
|
-
/* @__PURE__ */ jsx4("span", { style: styles.text, children: (m.text ?? "").slice(0, 60) })
|
|
3083
|
-
] }, m.id))
|
|
3084
|
-
] }),
|
|
3085
|
-
/* @__PURE__ */ jsxs3("div", { style: styles.section, children: [
|
|
3086
|
-
/* @__PURE__ */ jsx4("div", { style: styles.sectionTitle, children: "events" }),
|
|
3087
|
-
events.length === 0 ? /* @__PURE__ */ jsx4("div", { style: styles.empty, children: "no events yet \u2014 send a message" }) : events.map((e) => /* @__PURE__ */ jsxs3("div", { style: styles.row, children: [
|
|
3088
|
-
/* @__PURE__ */ jsx4("span", { style: { ...styles.badge, background: kindColor(e.kind) }, children: e.kind }),
|
|
3089
|
-
/* @__PURE__ */ jsx4("span", { style: styles.ts, children: new Date(e.t).toISOString().slice(11, 23) }),
|
|
3090
|
-
/* @__PURE__ */ jsx4("span", { style: styles.evLabel, children: e.label }),
|
|
3091
|
-
e.detail && /* @__PURE__ */ jsx4("span", { style: styles.detail, children: e.detail })
|
|
3092
|
-
] }, e.id))
|
|
3093
|
-
] })
|
|
3094
|
-
] })
|
|
3095
|
-
] });
|
|
3096
|
-
}
|
|
3097
|
-
function shortJson(v) {
|
|
3098
|
-
if (v === void 0) return "";
|
|
3099
|
-
try {
|
|
3100
|
-
const s = JSON.stringify(v);
|
|
3101
|
-
if (!s) return "";
|
|
3102
|
-
return s.length > 180 ? `${s.slice(0, 177)}\u2026` : s;
|
|
3103
|
-
} catch {
|
|
3104
|
-
return String(v);
|
|
3105
|
-
}
|
|
3106
|
-
}
|
|
3107
|
-
function colorFor(sender) {
|
|
3108
|
-
switch (sender) {
|
|
3109
|
-
case "visitor":
|
|
3110
|
-
return "#1d4ed8";
|
|
3111
|
-
case "ai":
|
|
3112
|
-
return "#7c3aed";
|
|
3113
|
-
case "team":
|
|
3114
|
-
return "#16a34a";
|
|
3115
|
-
default:
|
|
3116
|
-
return "#6b7280";
|
|
3117
|
-
}
|
|
3118
|
-
}
|
|
3119
|
-
function kindColor(kind) {
|
|
3120
|
-
switch (kind) {
|
|
3121
|
-
case "trpc":
|
|
3122
|
-
return "#0ea5e9";
|
|
3123
|
-
case "ws":
|
|
3124
|
-
return "#f97316";
|
|
3125
|
-
case "store":
|
|
3126
|
-
return "#64748b";
|
|
3127
|
-
case "error":
|
|
3128
|
-
return "#dc2626";
|
|
3129
|
-
}
|
|
3130
|
-
}
|
|
3131
|
-
var styles = {
|
|
3132
|
-
wrap: {
|
|
3133
|
-
position: "fixed",
|
|
3134
|
-
right: 12,
|
|
3135
|
-
bottom: 12,
|
|
3136
|
-
zIndex: 2147483e3,
|
|
3137
|
-
width: 420,
|
|
3138
|
-
maxHeight: "70vh",
|
|
3139
|
-
background: "rgba(9,9,11,0.94)",
|
|
3140
|
-
color: "#e5e7eb",
|
|
3141
|
-
borderRadius: 10,
|
|
3142
|
-
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
3143
|
-
fontSize: 11,
|
|
3144
|
-
boxShadow: "0 12px 30px rgba(0,0,0,0.35)",
|
|
3145
|
-
overflow: "hidden",
|
|
3146
|
-
pointerEvents: "auto"
|
|
3147
|
-
},
|
|
3148
|
-
header: {
|
|
3149
|
-
display: "flex",
|
|
3150
|
-
alignItems: "center",
|
|
3151
|
-
gap: 6,
|
|
3152
|
-
padding: "6px 10px",
|
|
3153
|
-
background: "#18181b",
|
|
3154
|
-
borderBottom: "1px solid #27272a"
|
|
3155
|
-
},
|
|
3156
|
-
meta: { flex: 1, color: "#a1a1aa", fontSize: 10 },
|
|
3157
|
-
btn: {
|
|
3158
|
-
background: "#27272a",
|
|
3159
|
-
color: "#e4e4e7",
|
|
3160
|
-
border: "1px solid #3f3f46",
|
|
3161
|
-
borderRadius: 4,
|
|
3162
|
-
padding: "2px 8px",
|
|
3163
|
-
cursor: "pointer",
|
|
3164
|
-
fontSize: 10
|
|
3165
|
-
},
|
|
3166
|
-
body: { display: "flex", flexDirection: "column", maxHeight: "calc(70vh - 32px)", overflow: "auto" },
|
|
3167
|
-
section: { borderBottom: "1px solid #27272a", padding: "6px 10px" },
|
|
3168
|
-
sectionTitle: { color: "#a1a1aa", fontSize: 10, textTransform: "uppercase", letterSpacing: 0.6, marginBottom: 4 },
|
|
3169
|
-
row: {
|
|
3170
|
-
display: "grid",
|
|
3171
|
-
gridTemplateColumns: "32px 56px 72px 1fr",
|
|
3172
|
-
gap: 6,
|
|
3173
|
-
alignItems: "baseline",
|
|
3174
|
-
padding: "2px 0",
|
|
3175
|
-
borderTop: "1px dashed #27272a"
|
|
3176
|
-
},
|
|
3177
|
-
badge: {
|
|
3178
|
-
display: "inline-block",
|
|
3179
|
-
borderRadius: 3,
|
|
3180
|
-
padding: "1px 4px",
|
|
3181
|
-
color: "white",
|
|
3182
|
-
fontSize: 9,
|
|
3183
|
-
textAlign: "center"
|
|
3184
|
-
},
|
|
3185
|
-
sender: { color: "#d4d4d8" },
|
|
3186
|
-
ts: { color: "#71717a", fontSize: 10 },
|
|
3187
|
-
text: { color: "#e4e4e7", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" },
|
|
3188
|
-
evLabel: { color: "#e4e4e7" },
|
|
3189
|
-
detail: { gridColumn: "1 / -1", color: "#a1a1aa", fontSize: 10, whiteSpace: "pre-wrap", wordBreak: "break-all" },
|
|
3190
|
-
empty: { color: "#52525b", fontStyle: "italic", fontSize: 10 }
|
|
3191
|
-
};
|
|
3139
|
+
type: "file",
|
|
3140
|
+
accept: ACCEPTED_TYPES,
|
|
3141
|
+
multiple: true,
|
|
3142
|
+
hidden: true,
|
|
3143
|
+
onChange: handleFileChange
|
|
3144
|
+
}
|
|
3145
|
+
),
|
|
3146
|
+
showCharCount && /* @__PURE__ */ jsx3("span", { className: `hw-composer-charcount ${isOverLimit ? "hw-composer-charcount--over" : ""}`, children: MAX_CHARS - text.length })
|
|
3147
|
+
] }),
|
|
3148
|
+
/* @__PURE__ */ jsx3(
|
|
3149
|
+
"button",
|
|
3150
|
+
{
|
|
3151
|
+
type: "button",
|
|
3152
|
+
className: `hw-composer-send ${canSend && !isOverLimit && !disabled ? "hw-composer-send--active" : "hw-composer-send--inactive"}`,
|
|
3153
|
+
onClick: () => onSubmit(),
|
|
3154
|
+
disabled: disabled || !canSend || isSubmitting || isOverLimit,
|
|
3155
|
+
"aria-label": t("widget.aria_send"),
|
|
3156
|
+
children: /* @__PURE__ */ jsx3(SendIcon, {})
|
|
3157
|
+
}
|
|
3158
|
+
)
|
|
3159
|
+
] })
|
|
3160
|
+
] })
|
|
3161
|
+
}
|
|
3162
|
+
);
|
|
3163
|
+
}
|
|
3164
|
+
function PreviewThumb({ attachment: a, onRemove }) {
|
|
3165
|
+
return /* @__PURE__ */ jsxs2("div", { className: `hw-composer-preview ${a.error ? "hw-composer-preview--error" : ""}`, children: [
|
|
3166
|
+
a.previewUrl ? /* @__PURE__ */ jsx3("img", { src: a.previewUrl, alt: a.file.name, className: "hw-composer-preview-img" }) : /* @__PURE__ */ jsx3("div", { className: "hw-composer-preview-file", children: /* @__PURE__ */ jsx3("span", { className: "hw-composer-preview-ext", children: a.file.name.split(".").pop()?.toUpperCase() ?? "FILE" }) }),
|
|
3167
|
+
a.isUploading && /* @__PURE__ */ jsx3("div", { className: "hw-composer-preview-loader" }),
|
|
3168
|
+
a.error && /* @__PURE__ */ jsx3("div", { className: "hw-composer-preview-badge", title: a.error, children: "!" }),
|
|
3169
|
+
onRemove && /* @__PURE__ */ jsx3(
|
|
3170
|
+
"button",
|
|
3171
|
+
{
|
|
3172
|
+
type: "button",
|
|
3173
|
+
className: "hw-composer-preview-remove",
|
|
3174
|
+
onClick: onRemove,
|
|
3175
|
+
"aria-label": t("widget.aria_remove"),
|
|
3176
|
+
children: /* @__PURE__ */ jsx3(XIcon, {})
|
|
3177
|
+
}
|
|
3178
|
+
)
|
|
3179
|
+
] });
|
|
3180
|
+
}
|
|
3181
|
+
function extractFiles(data) {
|
|
3182
|
+
const files = [];
|
|
3183
|
+
if (data.files) {
|
|
3184
|
+
for (let i = 0; i < data.files.length; i++) {
|
|
3185
|
+
const file = data.files[i];
|
|
3186
|
+
if (file) files.push(file);
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
return files;
|
|
3190
|
+
}
|
|
3192
3191
|
|
|
3193
3192
|
// src/shell/docked-bar.tsx
|
|
3194
|
-
import {
|
|
3195
|
-
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3193
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3196
3194
|
function useDismissableOffer(suggestions) {
|
|
3197
|
-
const [dismissedKey, setDismissedKey] =
|
|
3195
|
+
const [dismissedKey, setDismissedKey] = useState7(null);
|
|
3198
3196
|
const questions = (suggestions ?? []).map(
|
|
3199
3197
|
(entry) => typeof entry === "string" ? entry : entry.question
|
|
3200
3198
|
);
|
|
@@ -3210,14 +3208,14 @@ function recognitionCtor() {
|
|
|
3210
3208
|
return scope.SpeechRecognition ?? scope.webkitSpeechRecognition ?? null;
|
|
3211
3209
|
}
|
|
3212
3210
|
function useDictation(onText) {
|
|
3213
|
-
const [listening, setListening] =
|
|
3214
|
-
const recRef =
|
|
3215
|
-
const onTextRef =
|
|
3216
|
-
|
|
3211
|
+
const [listening, setListening] = useState7(false);
|
|
3212
|
+
const recRef = useRef7(null);
|
|
3213
|
+
const onTextRef = useRef7(onText);
|
|
3214
|
+
useEffect6(() => {
|
|
3217
3215
|
onTextRef.current = onText;
|
|
3218
3216
|
}, [onText]);
|
|
3219
|
-
const [supported] =
|
|
3220
|
-
|
|
3217
|
+
const [supported] = useState7(() => recognitionCtor() !== null);
|
|
3218
|
+
useEffect6(
|
|
3221
3219
|
() => () => {
|
|
3222
3220
|
recRef.current?.stop();
|
|
3223
3221
|
recRef.current = null;
|
|
@@ -3284,10 +3282,10 @@ function DockedBar({
|
|
|
3284
3282
|
sendError,
|
|
3285
3283
|
onClearSendError
|
|
3286
3284
|
}) {
|
|
3287
|
-
const [focused, setFocused] =
|
|
3288
|
-
const inputRef =
|
|
3289
|
-
const boxRef =
|
|
3290
|
-
const fileInputRef =
|
|
3285
|
+
const [focused, setFocused] = useState7(false);
|
|
3286
|
+
const inputRef = useRef7(null);
|
|
3287
|
+
const boxRef = useRef7(null);
|
|
3288
|
+
const fileInputRef = useRef7(null);
|
|
3291
3289
|
const { questions: visibleQuestions, dismiss: dismissOffer } = useDismissableOffer(suggestions);
|
|
3292
3290
|
const dictation = useDictation((chunk) => {
|
|
3293
3291
|
const current = inputRef.current?.value ?? value;
|
|
@@ -3303,7 +3301,7 @@ function DockedBar({
|
|
|
3303
3301
|
el.style.height = `${next}px`;
|
|
3304
3302
|
box.dataset.grown = next > GROWN_AT ? "true" : "false";
|
|
3305
3303
|
}, []);
|
|
3306
|
-
|
|
3304
|
+
useEffect6(grow, [grow, value]);
|
|
3307
3305
|
const handleKeyDown = useCallback8(
|
|
3308
3306
|
(event) => {
|
|
3309
3307
|
if (event.key !== "Enter" || event.shiftKey) return;
|
|
@@ -3333,19 +3331,19 @@ function DockedBar({
|
|
|
3333
3331
|
const uploading = attachments?.some((a) => a.isUploading) ?? false;
|
|
3334
3332
|
const hasAttachment = attachments?.some((a) => a.part !== null) ?? false;
|
|
3335
3333
|
const canSend = (!!value.trim() || hasAttachment) && !uploading && !disabled;
|
|
3336
|
-
return /* @__PURE__ */
|
|
3337
|
-
showSuggestions && /* @__PURE__ */
|
|
3334
|
+
return /* @__PURE__ */ jsxs3("div", { className: "hw-dock", onFocus: () => setFocused(true), onBlur: onDockBlur, children: [
|
|
3335
|
+
showSuggestions && /* @__PURE__ */ jsx4("div", { className: "hw-dock-suggestions", children: visibleQuestions.map((question, index) => (
|
|
3338
3336
|
/* The pill stays a button and the dismiss is a sibling, not a nested
|
|
3339
3337
|
button — a button inside a button is invalid and the inner click
|
|
3340
3338
|
would still fire the outer one. Only the first row carries the ×,
|
|
3341
3339
|
since it closes the whole offer. */
|
|
3342
|
-
/* @__PURE__ */
|
|
3340
|
+
/* @__PURE__ */ jsxs3(
|
|
3343
3341
|
"span",
|
|
3344
3342
|
{
|
|
3345
3343
|
className: "hw-dock-pill-row",
|
|
3346
3344
|
style: { animationDelay: `${120 + index * 90}ms` },
|
|
3347
3345
|
children: [
|
|
3348
|
-
/* @__PURE__ */
|
|
3346
|
+
/* @__PURE__ */ jsx4(
|
|
3349
3347
|
"button",
|
|
3350
3348
|
{
|
|
3351
3349
|
type: "button",
|
|
@@ -3354,14 +3352,14 @@ function DockedBar({
|
|
|
3354
3352
|
children: question
|
|
3355
3353
|
}
|
|
3356
3354
|
),
|
|
3357
|
-
index === 0 && /* @__PURE__ */
|
|
3355
|
+
index === 0 && /* @__PURE__ */ jsx4(
|
|
3358
3356
|
"button",
|
|
3359
3357
|
{
|
|
3360
3358
|
type: "button",
|
|
3361
3359
|
className: "hw-dock-pill-dismiss",
|
|
3362
3360
|
"aria-label": t("widget.aria_dismiss"),
|
|
3363
3361
|
onClick: dismissOffer,
|
|
3364
|
-
children: /* @__PURE__ */
|
|
3362
|
+
children: /* @__PURE__ */ jsx4(
|
|
3365
3363
|
"svg",
|
|
3366
3364
|
{
|
|
3367
3365
|
viewBox: "0 0 24 24",
|
|
@@ -3370,7 +3368,7 @@ function DockedBar({
|
|
|
3370
3368
|
strokeWidth: "2.5",
|
|
3371
3369
|
strokeLinecap: "round",
|
|
3372
3370
|
"aria-hidden": "true",
|
|
3373
|
-
children: /* @__PURE__ */
|
|
3371
|
+
children: /* @__PURE__ */ jsx4("path", { d: "M18 6 6 18M6 6l12 12" })
|
|
3374
3372
|
}
|
|
3375
3373
|
)
|
|
3376
3374
|
}
|
|
@@ -3380,8 +3378,8 @@ function DockedBar({
|
|
|
3380
3378
|
question
|
|
3381
3379
|
)
|
|
3382
3380
|
)) }),
|
|
3383
|
-
sendError && /* @__PURE__ */
|
|
3384
|
-
/* @__PURE__ */
|
|
3381
|
+
sendError && /* @__PURE__ */ jsx4("div", { className: "hw-dock-error", role: "alert", children: sendError }),
|
|
3382
|
+
/* @__PURE__ */ jsxs3(
|
|
3385
3383
|
"div",
|
|
3386
3384
|
{
|
|
3387
3385
|
className: "hw-dock-bar",
|
|
@@ -3390,7 +3388,7 @@ function DockedBar({
|
|
|
3390
3388
|
onMouseDown: onReopen,
|
|
3391
3389
|
onTouchStart: onReopen,
|
|
3392
3390
|
children: [
|
|
3393
|
-
!!attachments?.length && /* @__PURE__ */
|
|
3391
|
+
!!attachments?.length && /* @__PURE__ */ jsx4("div", { className: "hw-dock-previews", children: attachments.map((a) => /* @__PURE__ */ jsx4(
|
|
3394
3392
|
PreviewThumb,
|
|
3395
3393
|
{
|
|
3396
3394
|
attachment: a,
|
|
@@ -3398,7 +3396,7 @@ function DockedBar({
|
|
|
3398
3396
|
},
|
|
3399
3397
|
a.id
|
|
3400
3398
|
)) }),
|
|
3401
|
-
/* @__PURE__ */
|
|
3399
|
+
/* @__PURE__ */ jsx4(
|
|
3402
3400
|
"textarea",
|
|
3403
3401
|
{
|
|
3404
3402
|
ref: inputRef,
|
|
@@ -3416,8 +3414,8 @@ function DockedBar({
|
|
|
3416
3414
|
onPaste: handlePaste
|
|
3417
3415
|
}
|
|
3418
3416
|
),
|
|
3419
|
-
/* @__PURE__ */
|
|
3420
|
-
dictation.supported && /* @__PURE__ */
|
|
3417
|
+
/* @__PURE__ */ jsxs3("div", { className: "hw-dock-actions", children: [
|
|
3418
|
+
dictation.supported && /* @__PURE__ */ jsx4(
|
|
3421
3419
|
"button",
|
|
3422
3420
|
{
|
|
3423
3421
|
type: "button",
|
|
@@ -3427,11 +3425,11 @@ function DockedBar({
|
|
|
3427
3425
|
"aria-pressed": dictation.listening,
|
|
3428
3426
|
disabled,
|
|
3429
3427
|
onClick: dictation.toggle,
|
|
3430
|
-
children: /* @__PURE__ */
|
|
3428
|
+
children: /* @__PURE__ */ jsx4(MicGlyph, {})
|
|
3431
3429
|
}
|
|
3432
3430
|
),
|
|
3433
|
-
onAddFiles && /* @__PURE__ */
|
|
3434
|
-
/* @__PURE__ */
|
|
3431
|
+
onAddFiles && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
3432
|
+
/* @__PURE__ */ jsx4(
|
|
3435
3433
|
"button",
|
|
3436
3434
|
{
|
|
3437
3435
|
type: "button",
|
|
@@ -3439,10 +3437,10 @@ function DockedBar({
|
|
|
3439
3437
|
"aria-label": t("widget.aria_attach"),
|
|
3440
3438
|
disabled,
|
|
3441
3439
|
onClick: () => fileInputRef.current?.click(),
|
|
3442
|
-
children: /* @__PURE__ */
|
|
3440
|
+
children: /* @__PURE__ */ jsx4(PaperclipIcon, { size: 17 })
|
|
3443
3441
|
}
|
|
3444
3442
|
),
|
|
3445
|
-
/* @__PURE__ */
|
|
3443
|
+
/* @__PURE__ */ jsx4(
|
|
3446
3444
|
"input",
|
|
3447
3445
|
{
|
|
3448
3446
|
ref: fileInputRef,
|
|
@@ -3458,7 +3456,7 @@ function DockedBar({
|
|
|
3458
3456
|
}
|
|
3459
3457
|
)
|
|
3460
3458
|
] }),
|
|
3461
|
-
/* @__PURE__ */
|
|
3459
|
+
/* @__PURE__ */ jsx4(
|
|
3462
3460
|
"button",
|
|
3463
3461
|
{
|
|
3464
3462
|
type: "button",
|
|
@@ -3466,7 +3464,7 @@ function DockedBar({
|
|
|
3466
3464
|
"aria-label": t("widget.aria_send"),
|
|
3467
3465
|
disabled: !canSend,
|
|
3468
3466
|
onClick: onSubmit,
|
|
3469
|
-
children: /* @__PURE__ */
|
|
3467
|
+
children: /* @__PURE__ */ jsx4(ArrowUpIcon, { size: 16 })
|
|
3470
3468
|
}
|
|
3471
3469
|
)
|
|
3472
3470
|
] })
|
|
@@ -3476,7 +3474,7 @@ function DockedBar({
|
|
|
3476
3474
|
] });
|
|
3477
3475
|
}
|
|
3478
3476
|
function MicGlyph() {
|
|
3479
|
-
return /* @__PURE__ */
|
|
3477
|
+
return /* @__PURE__ */ jsxs3(
|
|
3480
3478
|
"svg",
|
|
3481
3479
|
{
|
|
3482
3480
|
width: "17",
|
|
@@ -3489,19 +3487,121 @@ function MicGlyph() {
|
|
|
3489
3487
|
strokeLinejoin: "round",
|
|
3490
3488
|
"aria-hidden": "true",
|
|
3491
3489
|
children: [
|
|
3492
|
-
/* @__PURE__ */
|
|
3493
|
-
/* @__PURE__ */
|
|
3494
|
-
/* @__PURE__ */
|
|
3490
|
+
/* @__PURE__ */ jsx4("path", { d: "M12 3.5a3 3 0 0 1 3 3v4.5a3 3 0 0 1-6 0V6.5a3 3 0 0 1 3-3Z" }),
|
|
3491
|
+
/* @__PURE__ */ jsx4("path", { d: "M5.5 11v.5a6.5 6.5 0 0 0 13 0V11" }),
|
|
3492
|
+
/* @__PURE__ */ jsx4("path", { d: "M12 18v3" })
|
|
3493
|
+
]
|
|
3494
|
+
}
|
|
3495
|
+
);
|
|
3496
|
+
}
|
|
3497
|
+
|
|
3498
|
+
// src/themed/announcement-previews.tsx
|
|
3499
|
+
import { useState as useState8 } from "react";
|
|
3500
|
+
|
|
3501
|
+
// src/themed/strip-markdown.ts
|
|
3502
|
+
function stripMarkdown(text) {
|
|
3503
|
+
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();
|
|
3504
|
+
}
|
|
3505
|
+
|
|
3506
|
+
// src/themed/announcement-previews.tsx
|
|
3507
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3508
|
+
function AnnouncementPreviews({
|
|
3509
|
+
onOpen,
|
|
3510
|
+
avatar,
|
|
3511
|
+
placement = "launcher",
|
|
3512
|
+
footer,
|
|
3513
|
+
maxVisible = Number.POSITIVE_INFINITY
|
|
3514
|
+
}) {
|
|
3515
|
+
const previews = useWidgetStore((s) => s.announcementPreviews);
|
|
3516
|
+
const dismissPreview = useWidgetStore((s) => s.dismissAnnouncementPreview);
|
|
3517
|
+
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
3518
|
+
if (previews.length === 0) return null;
|
|
3519
|
+
const stackPlacementClass = placement === "anchored" ? "hw-preview-stack--anchored " : "";
|
|
3520
|
+
const { visible, hidden } = splitAnnouncementStack(previews, maxVisible);
|
|
3521
|
+
const next = hidden[0];
|
|
3522
|
+
return /* @__PURE__ */ jsxs4("div", { className: `hw-preview-stack ${stackPlacementClass}`.trim(), children: [
|
|
3523
|
+
visible.map((preview) => /* @__PURE__ */ jsx5(
|
|
3524
|
+
AnnouncementPreviewItem,
|
|
3525
|
+
{
|
|
3526
|
+
preview,
|
|
3527
|
+
agentName,
|
|
3528
|
+
avatar,
|
|
3529
|
+
placement,
|
|
3530
|
+
footer,
|
|
3531
|
+
onOpen,
|
|
3532
|
+
onDismiss: (slug) => dismissPreview(slug)
|
|
3533
|
+
},
|
|
3534
|
+
preview.slug
|
|
3535
|
+
)),
|
|
3536
|
+
next && /* @__PURE__ */ jsx5(
|
|
3537
|
+
"button",
|
|
3538
|
+
{
|
|
3539
|
+
type: "button",
|
|
3540
|
+
className: "hw-preview-more",
|
|
3541
|
+
onClick: () => onOpen(next.slug, next.tabId),
|
|
3542
|
+
children: hidden.length === 1 ? t("widget.more_announcements_one") : t("widget.more_announcements", { count: hidden.length })
|
|
3543
|
+
}
|
|
3544
|
+
)
|
|
3545
|
+
] });
|
|
3546
|
+
}
|
|
3547
|
+
function AnnouncementPreviewItem({
|
|
3548
|
+
preview,
|
|
3549
|
+
agentName,
|
|
3550
|
+
avatar,
|
|
3551
|
+
placement,
|
|
3552
|
+
footer,
|
|
3553
|
+
onOpen,
|
|
3554
|
+
onDismiss
|
|
3555
|
+
}) {
|
|
3556
|
+
const [closing, setClosing] = useState8(false);
|
|
3557
|
+
const handleClose = (e) => {
|
|
3558
|
+
e.stopPropagation();
|
|
3559
|
+
setClosing(true);
|
|
3560
|
+
setTimeout(() => {
|
|
3561
|
+
onDismiss(preview.slug);
|
|
3562
|
+
setClosing(false);
|
|
3563
|
+
}, 200);
|
|
3564
|
+
};
|
|
3565
|
+
const placementClass = placement === "anchored" ? "hw-preview--anchored " : "";
|
|
3566
|
+
return /* @__PURE__ */ jsxs4(
|
|
3567
|
+
"div",
|
|
3568
|
+
{
|
|
3569
|
+
className: `hw-preview hw-preview--announcement ${placementClass}${closing ? "hw-preview--closing" : ""}`.trim(),
|
|
3570
|
+
onClick: () => onOpen(preview.slug, preview.tabId),
|
|
3571
|
+
role: "button",
|
|
3572
|
+
tabIndex: 0,
|
|
3573
|
+
children: [
|
|
3574
|
+
/* @__PURE__ */ jsxs4("div", { className: "hw-preview-header", children: [
|
|
3575
|
+
/* @__PURE__ */ jsx5("div", { className: "hw-preview-avatar", children: avatar }),
|
|
3576
|
+
/* @__PURE__ */ jsx5("div", { className: "hw-preview-name", children: agentName }),
|
|
3577
|
+
/* @__PURE__ */ jsx5(
|
|
3578
|
+
"button",
|
|
3579
|
+
{
|
|
3580
|
+
type: "button",
|
|
3581
|
+
className: "hw-preview-close",
|
|
3582
|
+
onClick: handleClose,
|
|
3583
|
+
"aria-label": t("widget.aria_dismiss"),
|
|
3584
|
+
children: /* @__PURE__ */ jsx5(XIcon, { size: 20 })
|
|
3585
|
+
}
|
|
3586
|
+
)
|
|
3587
|
+
] }),
|
|
3588
|
+
/* @__PURE__ */ jsx5("div", { className: "hw-preview-body hw-preview-body--title", children: preview.title }),
|
|
3589
|
+
preview.body && (() => {
|
|
3590
|
+
const clean = stripMarkdown(preview.body);
|
|
3591
|
+
return /* @__PURE__ */ jsx5("div", { className: "hw-preview-body hw-preview-body--desc", children: truncatePreviewBody(clean) });
|
|
3592
|
+
})(),
|
|
3593
|
+
preview.badge && /* @__PURE__ */ jsx5("div", { className: "hw-announcement-badge", children: preview.badge }),
|
|
3594
|
+
footer != null && footer !== false && /* @__PURE__ */ jsx5("div", { className: "hw-preview-footer", children: footer })
|
|
3495
3595
|
]
|
|
3496
3596
|
}
|
|
3497
3597
|
);
|
|
3498
3598
|
}
|
|
3499
3599
|
|
|
3500
3600
|
// src/themed/content/content-tab-view.tsx
|
|
3501
|
-
import { useCallback as useCallback12, useEffect as
|
|
3601
|
+
import { useCallback as useCallback12, useEffect as useEffect10 } from "react";
|
|
3502
3602
|
|
|
3503
3603
|
// src/hooks/use-content-tab.ts
|
|
3504
|
-
import { useCallback as useCallback9, useEffect as
|
|
3604
|
+
import { useCallback as useCallback9, useEffect as useEffect7, useState as useState9 } from "react";
|
|
3505
3605
|
var EMPTY_TABS2 = [];
|
|
3506
3606
|
function listKey(tabId, lang) {
|
|
3507
3607
|
return `flat:${tabId}:${lang}:list`;
|
|
@@ -3616,7 +3716,7 @@ function useContentTab(tabId) {
|
|
|
3616
3716
|
const clearDetail = useCallback9(() => {
|
|
3617
3717
|
setDetail(null);
|
|
3618
3718
|
}, []);
|
|
3619
|
-
|
|
3719
|
+
useEffect7(() => {
|
|
3620
3720
|
if (tab && entries.length === 0) {
|
|
3621
3721
|
fetchEntries({ page: 1, reset: true });
|
|
3622
3722
|
}
|
|
@@ -3637,7 +3737,7 @@ function useContentTab(tabId) {
|
|
|
3637
3737
|
}
|
|
3638
3738
|
|
|
3639
3739
|
// src/themed/content/simple-markdown.tsx
|
|
3640
|
-
import { useEffect as
|
|
3740
|
+
import { useEffect as useEffect8, useRef as useRef8 } from "react";
|
|
3641
3741
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
3642
3742
|
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>`;
|
|
3643
3743
|
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>`;
|
|
@@ -3752,9 +3852,9 @@ function MarkdownContent({
|
|
|
3752
3852
|
bodyMarkdown,
|
|
3753
3853
|
className
|
|
3754
3854
|
}) {
|
|
3755
|
-
const rootRef =
|
|
3855
|
+
const rootRef = useRef8(null);
|
|
3756
3856
|
const html = bodyHtml ?? (bodyMarkdown ? renderMarkdown(bodyMarkdown) : "");
|
|
3757
|
-
|
|
3857
|
+
useEffect8(() => {
|
|
3758
3858
|
const root = rootRef.current;
|
|
3759
3859
|
if (!root) return;
|
|
3760
3860
|
const isWhitespaceOnly = (el) => {
|
|
@@ -3773,7 +3873,7 @@ function MarkdownContent({
|
|
|
3773
3873
|
};
|
|
3774
3874
|
removeEmpties();
|
|
3775
3875
|
}, [html]);
|
|
3776
|
-
|
|
3876
|
+
useEffect8(() => {
|
|
3777
3877
|
const root = rootRef.current;
|
|
3778
3878
|
if (!root) return;
|
|
3779
3879
|
const handler = (e) => {
|
|
@@ -3903,7 +4003,7 @@ function SkeletonSection({
|
|
|
3903
4003
|
}
|
|
3904
4004
|
|
|
3905
4005
|
// src/themed/content/content-list-view.tsx
|
|
3906
|
-
import { useCallback as useCallback10, useRef as
|
|
4006
|
+
import { useCallback as useCallback10, useRef as useRef9, useState as useState10 } from "react";
|
|
3907
4007
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3908
4008
|
function ContentListView({
|
|
3909
4009
|
entries,
|
|
@@ -3916,7 +4016,7 @@ function ContentListView({
|
|
|
3916
4016
|
display
|
|
3917
4017
|
}) {
|
|
3918
4018
|
const [searchText, setSearchText] = useState10("");
|
|
3919
|
-
const debounceRef =
|
|
4019
|
+
const debounceRef = useRef9(void 0);
|
|
3920
4020
|
const handleSearch = useCallback10(
|
|
3921
4021
|
(value) => {
|
|
3922
4022
|
setSearchText(value);
|
|
@@ -3997,10 +4097,10 @@ function ContentEntryCard({
|
|
|
3997
4097
|
}
|
|
3998
4098
|
|
|
3999
4099
|
// src/themed/content/grouped-content-tab-view.tsx
|
|
4000
|
-
import { useEffect as
|
|
4100
|
+
import { useEffect as useEffect9, useRef as useRef11 } from "react";
|
|
4001
4101
|
|
|
4002
4102
|
// src/hooks/use-grouped-content-tab.ts
|
|
4003
|
-
import { useCallback as useCallback11, useRef as
|
|
4103
|
+
import { useCallback as useCallback11, useRef as useRef10, useState as useState11 } from "react";
|
|
4004
4104
|
var EMPTY_TABS3 = [];
|
|
4005
4105
|
function categoriesKey(tabId, lang) {
|
|
4006
4106
|
return `grouped:${tabId}:${lang}:categories`;
|
|
@@ -4029,11 +4129,11 @@ function useGroupedContentTab(tabId) {
|
|
|
4029
4129
|
const [items, setItems] = useState11([]);
|
|
4030
4130
|
const [isItemsLoading, setIsItemsLoading] = useState11(false);
|
|
4031
4131
|
const [itemsHasMore, setItemsHasMore] = useState11(false);
|
|
4032
|
-
const itemsPageRef =
|
|
4132
|
+
const itemsPageRef = useRef10(1);
|
|
4033
4133
|
const [detail, setDetail] = useState11(null);
|
|
4034
4134
|
const [isLoadingDetail, setIsLoadingDetail] = useState11(false);
|
|
4035
4135
|
const [activeCategory, setActiveCategory] = useState11(null);
|
|
4036
|
-
const allCategoriesRef =
|
|
4136
|
+
const allCategoriesRef = useRef10(cachedCategories ?? []);
|
|
4037
4137
|
const fetchCategories = useCallback11(async () => {
|
|
4038
4138
|
if (!tab) return;
|
|
4039
4139
|
setIsCategoriesLoading(true);
|
|
@@ -4241,16 +4341,16 @@ function GroupedContentTabView({
|
|
|
4241
4341
|
fetchDetail,
|
|
4242
4342
|
clearCategory
|
|
4243
4343
|
} = useGroupedContentTab(tab.id);
|
|
4244
|
-
|
|
4344
|
+
useEffect9(() => {
|
|
4245
4345
|
initFetch();
|
|
4246
4346
|
}, [initFetch]);
|
|
4247
|
-
|
|
4347
|
+
useEffect9(() => {
|
|
4248
4348
|
if (detailSlug && subView === "content-detail") {
|
|
4249
4349
|
fetchDetail(detailSlug);
|
|
4250
4350
|
}
|
|
4251
4351
|
}, [detailSlug, subView, fetchDetail]);
|
|
4252
|
-
const prevSubView =
|
|
4253
|
-
|
|
4352
|
+
const prevSubView = useRef11(subView);
|
|
4353
|
+
useEffect9(() => {
|
|
4254
4354
|
if (prevSubView.current === "content-category" && subView === null) {
|
|
4255
4355
|
clearCategory();
|
|
4256
4356
|
}
|
|
@@ -4344,7 +4444,7 @@ function FlatContentTabView({
|
|
|
4344
4444
|
loadMore,
|
|
4345
4445
|
fetchDetail
|
|
4346
4446
|
} = useContentTab(tab.id);
|
|
4347
|
-
|
|
4447
|
+
useEffect10(() => {
|
|
4348
4448
|
if (detailSlug) fetchDetail(detailSlug);
|
|
4349
4449
|
}, [detailSlug, fetchDetail]);
|
|
4350
4450
|
const handleSearch = useCallback12(
|
|
@@ -4368,111 +4468,269 @@ function FlatContentTabView({
|
|
|
4368
4468
|
searchPlaceholder: `${t("widget.search")} ${resolveLabel(tab.label).toLowerCase()}...`,
|
|
4369
4469
|
display: tab.display
|
|
4370
4470
|
}
|
|
4371
|
-
);
|
|
4372
|
-
}
|
|
4373
|
-
|
|
4374
|
-
// src/themed/content/tab-icon.tsx
|
|
4375
|
-
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
4376
|
-
var ICON_MAP = {
|
|
4377
|
-
book: BookIcon,
|
|
4378
|
-
megaphone: MegaphoneIcon,
|
|
4379
|
-
lightbulb: LightbulbIcon,
|
|
4380
|
-
"help-circle": HelpCircleIcon,
|
|
4381
|
-
newspaper: NewspaperIcon,
|
|
4382
|
-
star: StarIcon
|
|
4383
|
-
};
|
|
4384
|
-
function ContentTabIconComponent({ icon }) {
|
|
4385
|
-
const Icon = ICON_MAP[icon] ?? BookIcon;
|
|
4386
|
-
return /* @__PURE__ */ jsx11(Icon, {});
|
|
4471
|
+
);
|
|
4472
|
+
}
|
|
4473
|
+
|
|
4474
|
+
// src/themed/content/tab-icon.tsx
|
|
4475
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
4476
|
+
var ICON_MAP = {
|
|
4477
|
+
book: BookIcon,
|
|
4478
|
+
megaphone: MegaphoneIcon,
|
|
4479
|
+
lightbulb: LightbulbIcon,
|
|
4480
|
+
"help-circle": HelpCircleIcon,
|
|
4481
|
+
newspaper: NewspaperIcon,
|
|
4482
|
+
star: StarIcon
|
|
4483
|
+
};
|
|
4484
|
+
function ContentTabIconComponent({ icon }) {
|
|
4485
|
+
const Icon = ICON_MAP[icon] ?? BookIcon;
|
|
4486
|
+
return /* @__PURE__ */ jsx11(Icon, {});
|
|
4487
|
+
}
|
|
4488
|
+
|
|
4489
|
+
// src/themed/debug-overlay.tsx
|
|
4490
|
+
import { useEffect as useEffect11, useMemo as useMemo2, useRef as useRef12, useState as useState12 } from "react";
|
|
4491
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4492
|
+
var MAX_EVENTS = 60;
|
|
4493
|
+
function isDebugEnabled() {
|
|
4494
|
+
if (typeof window === "undefined") return false;
|
|
4495
|
+
if (typeof window.localStorage !== "undefined" && window.localStorage.getItem("hw:debug") === "1") {
|
|
4496
|
+
return true;
|
|
4497
|
+
}
|
|
4498
|
+
const search = window.location?.search ?? "";
|
|
4499
|
+
return search.includes("hwdebug=1") || search.includes("debug=hw");
|
|
4500
|
+
}
|
|
4501
|
+
function senderOf(item) {
|
|
4502
|
+
if (item.visitorId) return "visitor";
|
|
4503
|
+
if (item.aiAgentId) return "ai";
|
|
4504
|
+
if (item.userId) return "team";
|
|
4505
|
+
return item.type;
|
|
4506
|
+
}
|
|
4507
|
+
function WidgetDebugOverlay() {
|
|
4508
|
+
const [enabled, setEnabled] = useState12(false);
|
|
4509
|
+
const [open, setOpen] = useState12(true);
|
|
4510
|
+
const [events, setEvents] = useState12([]);
|
|
4511
|
+
const eventsRef = useRef12([]);
|
|
4512
|
+
const activeId = useWidgetStore((s) => s.activeConversationId);
|
|
4513
|
+
const messagesMap = useWidgetStore((s) => s.messages);
|
|
4514
|
+
const typingUsers = useWidgetStore((s) => s.typingUsers);
|
|
4515
|
+
const aiProcessingMap = useWidgetStore((s) => s.aiProcessing);
|
|
4516
|
+
const { store } = useWidgetContext();
|
|
4517
|
+
useEffect11(() => {
|
|
4518
|
+
setEnabled(isDebugEnabled());
|
|
4519
|
+
}, []);
|
|
4520
|
+
const pushEvent = useMemo2(
|
|
4521
|
+
() => (ev) => {
|
|
4522
|
+
const e = {
|
|
4523
|
+
...ev,
|
|
4524
|
+
id: `${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
4525
|
+
t: Date.now()
|
|
4526
|
+
};
|
|
4527
|
+
eventsRef.current = [e, ...eventsRef.current].slice(0, MAX_EVENTS);
|
|
4528
|
+
setEvents(eventsRef.current);
|
|
4529
|
+
},
|
|
4530
|
+
[]
|
|
4531
|
+
);
|
|
4532
|
+
useEffect11(() => {
|
|
4533
|
+
if (!enabled) return;
|
|
4534
|
+
if (typeof window === "undefined" || typeof window.fetch !== "function") return;
|
|
4535
|
+
const originalFetch = window.fetch.bind(window);
|
|
4536
|
+
const patched = (async (input, init) => {
|
|
4537
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
4538
|
+
const isTrpc = url.includes("/trpc/");
|
|
4539
|
+
if (isTrpc) {
|
|
4540
|
+
const method = init?.method ?? (typeof input !== "string" && !(input instanceof URL) ? input.method : "GET");
|
|
4541
|
+
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
4542
|
+
pushEvent({ kind: "trpc", label: `\u2192 ${method} ${label}`, detail: shortJson(init?.body) });
|
|
4543
|
+
}
|
|
4544
|
+
try {
|
|
4545
|
+
const res = await originalFetch(input, init);
|
|
4546
|
+
if (isTrpc) {
|
|
4547
|
+
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
4548
|
+
pushEvent({ kind: "trpc", label: `\u2190 ${res.status} ${label}` });
|
|
4549
|
+
}
|
|
4550
|
+
return res;
|
|
4551
|
+
} catch (err) {
|
|
4552
|
+
if (isTrpc) {
|
|
4553
|
+
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
4554
|
+
pushEvent({ kind: "error", label: `\u2718 ${label}`, detail: err instanceof Error ? err.message : String(err) });
|
|
4555
|
+
}
|
|
4556
|
+
throw err;
|
|
4557
|
+
}
|
|
4558
|
+
});
|
|
4559
|
+
window.fetch = patched;
|
|
4560
|
+
return () => {
|
|
4561
|
+
window.fetch = originalFetch;
|
|
4562
|
+
};
|
|
4563
|
+
}, [enabled, pushEvent]);
|
|
4564
|
+
useEffect11(() => {
|
|
4565
|
+
if (!enabled) return;
|
|
4566
|
+
const original = store.getState().handleRealtimeEvent;
|
|
4567
|
+
store.setState({
|
|
4568
|
+
handleRealtimeEvent: (ev) => {
|
|
4569
|
+
pushEvent({ kind: "ws", label: ev.type, detail: shortJson(ev) });
|
|
4570
|
+
original(ev);
|
|
4571
|
+
}
|
|
4572
|
+
});
|
|
4573
|
+
return () => {
|
|
4574
|
+
store.setState({ handleRealtimeEvent: original });
|
|
4575
|
+
};
|
|
4576
|
+
}, [enabled, store, pushEvent]);
|
|
4577
|
+
const activeMessages = activeId ? messagesMap.get(activeId) ?? [] : [];
|
|
4578
|
+
const lastMsgSignature = useMemo2(
|
|
4579
|
+
() => activeMessages.map((m) => `${m.id}:${senderOf(m)}:${m.createdAt}`).join("|"),
|
|
4580
|
+
[activeMessages]
|
|
4581
|
+
);
|
|
4582
|
+
const prevSigRef = useRef12(lastMsgSignature);
|
|
4583
|
+
useEffect11(() => {
|
|
4584
|
+
if (!enabled) return;
|
|
4585
|
+
if (prevSigRef.current !== lastMsgSignature) {
|
|
4586
|
+
prevSigRef.current = lastMsgSignature;
|
|
4587
|
+
pushEvent({
|
|
4588
|
+
kind: "store",
|
|
4589
|
+
label: `messages[${activeMessages.length}]`,
|
|
4590
|
+
detail: activeMessages.map((m, i) => `${i}:${senderOf(m)}=${(m.text ?? "").slice(0, 24)}`).join(" | ")
|
|
4591
|
+
});
|
|
4592
|
+
}
|
|
4593
|
+
}, [lastMsgSignature, activeMessages, enabled, pushEvent]);
|
|
4594
|
+
if (!enabled) return null;
|
|
4595
|
+
const isTyping = activeId ? typingUsers.get(activeId) : false;
|
|
4596
|
+
const isAi = activeId ? aiProcessingMap.get(activeId) : false;
|
|
4597
|
+
return /* @__PURE__ */ jsxs7("div", { style: styles.wrap, children: [
|
|
4598
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.header, children: [
|
|
4599
|
+
/* @__PURE__ */ jsx12("strong", { children: "hw debug" }),
|
|
4600
|
+
/* @__PURE__ */ jsxs7("span", { style: styles.meta, children: [
|
|
4601
|
+
" ",
|
|
4602
|
+
"\xB7 conv ",
|
|
4603
|
+
activeId ? activeId.slice(0, 10) : "\u2014",
|
|
4604
|
+
" \xB7 items ",
|
|
4605
|
+
activeMessages.length,
|
|
4606
|
+
" \xB7 typing ",
|
|
4607
|
+
isTyping ? "Y" : "n",
|
|
4608
|
+
" \xB7 ai ",
|
|
4609
|
+
isAi ? "Y" : "n"
|
|
4610
|
+
] }),
|
|
4611
|
+
/* @__PURE__ */ jsx12("button", { type: "button", style: styles.btn, onClick: () => setOpen((v) => !v), children: open ? "hide" : "show" }),
|
|
4612
|
+
/* @__PURE__ */ jsx12("button", { type: "button", style: styles.btn, onClick: () => {
|
|
4613
|
+
eventsRef.current = [];
|
|
4614
|
+
setEvents([]);
|
|
4615
|
+
}, children: "clear" })
|
|
4616
|
+
] }),
|
|
4617
|
+
open && /* @__PURE__ */ jsxs7("div", { style: styles.body, children: [
|
|
4618
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.section, children: [
|
|
4619
|
+
/* @__PURE__ */ jsx12("div", { style: styles.sectionTitle, children: "messages (active)" }),
|
|
4620
|
+
activeMessages.length === 0 ? /* @__PURE__ */ jsx12("div", { style: styles.empty, children: "empty" }) : activeMessages.map((m, i) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
4621
|
+
/* @__PURE__ */ jsx12("span", { style: { ...styles.badge, background: colorFor(senderOf(m)) }, children: i }),
|
|
4622
|
+
/* @__PURE__ */ jsx12("span", { style: styles.sender, children: senderOf(m) }),
|
|
4623
|
+
/* @__PURE__ */ jsx12("span", { style: styles.ts, children: m.createdAt.slice(11, 23) }),
|
|
4624
|
+
/* @__PURE__ */ jsx12("span", { style: styles.text, children: (m.text ?? "").slice(0, 60) })
|
|
4625
|
+
] }, m.id))
|
|
4626
|
+
] }),
|
|
4627
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.section, children: [
|
|
4628
|
+
/* @__PURE__ */ jsx12("div", { style: styles.sectionTitle, children: "events" }),
|
|
4629
|
+
events.length === 0 ? /* @__PURE__ */ jsx12("div", { style: styles.empty, children: "no events yet \u2014 send a message" }) : events.map((e) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
4630
|
+
/* @__PURE__ */ jsx12("span", { style: { ...styles.badge, background: kindColor(e.kind) }, children: e.kind }),
|
|
4631
|
+
/* @__PURE__ */ jsx12("span", { style: styles.ts, children: new Date(e.t).toISOString().slice(11, 23) }),
|
|
4632
|
+
/* @__PURE__ */ jsx12("span", { style: styles.evLabel, children: e.label }),
|
|
4633
|
+
e.detail && /* @__PURE__ */ jsx12("span", { style: styles.detail, children: e.detail })
|
|
4634
|
+
] }, e.id))
|
|
4635
|
+
] })
|
|
4636
|
+
] })
|
|
4637
|
+
] });
|
|
4387
4638
|
}
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4639
|
+
function shortJson(v) {
|
|
4640
|
+
if (v === void 0) return "";
|
|
4641
|
+
try {
|
|
4642
|
+
const s = JSON.stringify(v);
|
|
4643
|
+
if (!s) return "";
|
|
4644
|
+
return s.length > 180 ? `${s.slice(0, 177)}\u2026` : s;
|
|
4645
|
+
} catch {
|
|
4646
|
+
return String(v);
|
|
4647
|
+
}
|
|
4395
4648
|
}
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
4408
|
-
if (previews.length === 0) return null;
|
|
4409
|
-
const stackPlacementClass = placement === "anchored" ? "hw-preview-stack--anchored " : "";
|
|
4410
|
-
return /* @__PURE__ */ jsx12("div", { className: `hw-preview-stack ${stackPlacementClass}`.trim(), children: previews.map((preview) => /* @__PURE__ */ jsx12(
|
|
4411
|
-
AnnouncementPreviewItem,
|
|
4412
|
-
{
|
|
4413
|
-
preview,
|
|
4414
|
-
agentName,
|
|
4415
|
-
avatar,
|
|
4416
|
-
placement,
|
|
4417
|
-
footer,
|
|
4418
|
-
onOpen,
|
|
4419
|
-
onDismiss: (slug) => dismissPreview(slug)
|
|
4420
|
-
},
|
|
4421
|
-
preview.slug
|
|
4422
|
-
)) });
|
|
4649
|
+
function colorFor(sender) {
|
|
4650
|
+
switch (sender) {
|
|
4651
|
+
case "visitor":
|
|
4652
|
+
return "#1d4ed8";
|
|
4653
|
+
case "ai":
|
|
4654
|
+
return "#7c3aed";
|
|
4655
|
+
case "team":
|
|
4656
|
+
return "#16a34a";
|
|
4657
|
+
default:
|
|
4658
|
+
return "#6b7280";
|
|
4659
|
+
}
|
|
4423
4660
|
}
|
|
4424
|
-
function
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
e.stopPropagation();
|
|
4436
|
-
setClosing(true);
|
|
4437
|
-
setTimeout(() => {
|
|
4438
|
-
onDismiss(preview.slug);
|
|
4439
|
-
setClosing(false);
|
|
4440
|
-
}, 200);
|
|
4441
|
-
};
|
|
4442
|
-
const placementClass = placement === "anchored" ? "hw-preview--anchored " : "";
|
|
4443
|
-
return /* @__PURE__ */ jsxs7(
|
|
4444
|
-
"div",
|
|
4445
|
-
{
|
|
4446
|
-
className: `hw-preview hw-preview--announcement ${placementClass}${closing ? "hw-preview--closing" : ""}`.trim(),
|
|
4447
|
-
onClick: () => onOpen(preview.slug, preview.tabId),
|
|
4448
|
-
role: "button",
|
|
4449
|
-
tabIndex: 0,
|
|
4450
|
-
children: [
|
|
4451
|
-
/* @__PURE__ */ jsxs7("div", { className: "hw-preview-header", children: [
|
|
4452
|
-
/* @__PURE__ */ jsx12("div", { className: "hw-preview-avatar", children: avatar }),
|
|
4453
|
-
/* @__PURE__ */ jsx12("div", { className: "hw-preview-name", children: agentName }),
|
|
4454
|
-
/* @__PURE__ */ jsx12(
|
|
4455
|
-
"button",
|
|
4456
|
-
{
|
|
4457
|
-
type: "button",
|
|
4458
|
-
className: "hw-preview-close",
|
|
4459
|
-
onClick: handleClose,
|
|
4460
|
-
"aria-label": t("widget.aria_dismiss"),
|
|
4461
|
-
children: /* @__PURE__ */ jsx12(XIcon, { size: 20 })
|
|
4462
|
-
}
|
|
4463
|
-
)
|
|
4464
|
-
] }),
|
|
4465
|
-
/* @__PURE__ */ jsx12("div", { className: "hw-preview-body hw-preview-body--title", children: preview.title }),
|
|
4466
|
-
preview.body && (() => {
|
|
4467
|
-
const clean = stripMarkdown(preview.body);
|
|
4468
|
-
return /* @__PURE__ */ jsx12("div", { className: "hw-preview-body hw-preview-body--desc", children: clean.length > 120 ? `${clean.slice(0, 120)}\u2026` : clean });
|
|
4469
|
-
})(),
|
|
4470
|
-
preview.badge && /* @__PURE__ */ jsx12("div", { className: "hw-announcement-badge", children: preview.badge }),
|
|
4471
|
-
footer != null && footer !== false && /* @__PURE__ */ jsx12("div", { className: "hw-preview-footer", children: footer })
|
|
4472
|
-
]
|
|
4473
|
-
}
|
|
4474
|
-
);
|
|
4661
|
+
function kindColor(kind) {
|
|
4662
|
+
switch (kind) {
|
|
4663
|
+
case "trpc":
|
|
4664
|
+
return "#0ea5e9";
|
|
4665
|
+
case "ws":
|
|
4666
|
+
return "#f97316";
|
|
4667
|
+
case "store":
|
|
4668
|
+
return "#64748b";
|
|
4669
|
+
case "error":
|
|
4670
|
+
return "#dc2626";
|
|
4671
|
+
}
|
|
4475
4672
|
}
|
|
4673
|
+
var styles = {
|
|
4674
|
+
wrap: {
|
|
4675
|
+
position: "fixed",
|
|
4676
|
+
right: 12,
|
|
4677
|
+
bottom: 12,
|
|
4678
|
+
zIndex: 2147483e3,
|
|
4679
|
+
width: 420,
|
|
4680
|
+
maxHeight: "70vh",
|
|
4681
|
+
background: "rgba(9,9,11,0.94)",
|
|
4682
|
+
color: "#e5e7eb",
|
|
4683
|
+
borderRadius: 10,
|
|
4684
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
4685
|
+
fontSize: 11,
|
|
4686
|
+
boxShadow: "0 12px 30px rgba(0,0,0,0.35)",
|
|
4687
|
+
overflow: "hidden",
|
|
4688
|
+
pointerEvents: "auto"
|
|
4689
|
+
},
|
|
4690
|
+
header: {
|
|
4691
|
+
display: "flex",
|
|
4692
|
+
alignItems: "center",
|
|
4693
|
+
gap: 6,
|
|
4694
|
+
padding: "6px 10px",
|
|
4695
|
+
background: "#18181b",
|
|
4696
|
+
borderBottom: "1px solid #27272a"
|
|
4697
|
+
},
|
|
4698
|
+
meta: { flex: 1, color: "#a1a1aa", fontSize: 10 },
|
|
4699
|
+
btn: {
|
|
4700
|
+
background: "#27272a",
|
|
4701
|
+
color: "#e4e4e7",
|
|
4702
|
+
border: "1px solid #3f3f46",
|
|
4703
|
+
borderRadius: 4,
|
|
4704
|
+
padding: "2px 8px",
|
|
4705
|
+
cursor: "pointer",
|
|
4706
|
+
fontSize: 10
|
|
4707
|
+
},
|
|
4708
|
+
body: { display: "flex", flexDirection: "column", maxHeight: "calc(70vh - 32px)", overflow: "auto" },
|
|
4709
|
+
section: { borderBottom: "1px solid #27272a", padding: "6px 10px" },
|
|
4710
|
+
sectionTitle: { color: "#a1a1aa", fontSize: 10, textTransform: "uppercase", letterSpacing: 0.6, marginBottom: 4 },
|
|
4711
|
+
row: {
|
|
4712
|
+
display: "grid",
|
|
4713
|
+
gridTemplateColumns: "32px 56px 72px 1fr",
|
|
4714
|
+
gap: 6,
|
|
4715
|
+
alignItems: "baseline",
|
|
4716
|
+
padding: "2px 0",
|
|
4717
|
+
borderTop: "1px dashed #27272a"
|
|
4718
|
+
},
|
|
4719
|
+
badge: {
|
|
4720
|
+
display: "inline-block",
|
|
4721
|
+
borderRadius: 3,
|
|
4722
|
+
padding: "1px 4px",
|
|
4723
|
+
color: "white",
|
|
4724
|
+
fontSize: 9,
|
|
4725
|
+
textAlign: "center"
|
|
4726
|
+
},
|
|
4727
|
+
sender: { color: "#d4d4d8" },
|
|
4728
|
+
ts: { color: "#71717a", fontSize: 10 },
|
|
4729
|
+
text: { color: "#e4e4e7", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" },
|
|
4730
|
+
evLabel: { color: "#e4e4e7" },
|
|
4731
|
+
detail: { gridColumn: "1 / -1", color: "#a1a1aa", fontSize: 10, whiteSpace: "pre-wrap", wordBreak: "break-all" },
|
|
4732
|
+
empty: { color: "#52525b", fontStyle: "italic", fontSize: 10 }
|
|
4733
|
+
};
|
|
4476
4734
|
|
|
4477
4735
|
// src/themed/message-bubble.tsx
|
|
4478
4736
|
import { useEffect as useEffect12, useLayoutEffect, useRef as useRef13, useState as useState13 } from "react";
|
|
@@ -4825,15 +5083,18 @@ function parseParts(raw) {
|
|
|
4825
5083
|
return null;
|
|
4826
5084
|
}
|
|
4827
5085
|
}
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
5086
|
+
var DATE_KEY_FMT = new Intl.DateTimeFormat("en-CA");
|
|
5087
|
+
var displayFmtCache = /* @__PURE__ */ new Map();
|
|
5088
|
+
function displayDateFormatter(locale) {
|
|
5089
|
+
const hit = displayFmtCache.get(locale);
|
|
5090
|
+
if (hit) return hit;
|
|
5091
|
+
const fmt = new Intl.DateTimeFormat(locale, {
|
|
5092
|
+
weekday: "long",
|
|
5093
|
+
month: "short",
|
|
5094
|
+
day: "numeric"
|
|
5095
|
+
});
|
|
5096
|
+
displayFmtCache.set(locale, fmt);
|
|
5097
|
+
return fmt;
|
|
4837
5098
|
}
|
|
4838
5099
|
function MessageList({
|
|
4839
5100
|
items,
|
|
@@ -4927,10 +5188,10 @@ function MessageList({
|
|
|
4927
5188
|
);
|
|
4928
5189
|
}
|
|
4929
5190
|
let lastDateKey = "";
|
|
4930
|
-
const todayKey = (/* @__PURE__ */ new Date())
|
|
5191
|
+
const todayKey = DATE_KEY_FMT.format(/* @__PURE__ */ new Date());
|
|
4931
5192
|
const yesterday = /* @__PURE__ */ new Date();
|
|
4932
5193
|
yesterday.setDate(yesterday.getDate() - 1);
|
|
4933
|
-
const yesterdayKey =
|
|
5194
|
+
const yesterdayKey = DATE_KEY_FMT.format(yesterday);
|
|
4934
5195
|
return /* @__PURE__ */ jsxs9(
|
|
4935
5196
|
"div",
|
|
4936
5197
|
{
|
|
@@ -4957,15 +5218,11 @@ function MessageList({
|
|
|
4957
5218
|
);
|
|
4958
5219
|
}
|
|
4959
5220
|
const itemDate = new Date(item.createdAt);
|
|
4960
|
-
const dateKey =
|
|
5221
|
+
const dateKey = DATE_KEY_FMT.format(itemDate);
|
|
4961
5222
|
const isNewBucket = dateKey !== lastDateKey;
|
|
4962
5223
|
if (isNewBucket) lastDateKey = dateKey;
|
|
4963
5224
|
const showDateSep = isNewBucket && dateKey !== todayKey;
|
|
4964
|
-
const dateLabel = dateKey === yesterdayKey ? t("widget.yesterday") :
|
|
4965
|
-
weekday: "long",
|
|
4966
|
-
month: "short",
|
|
4967
|
-
day: "numeric"
|
|
4968
|
-
});
|
|
5225
|
+
const dateLabel = dateKey === yesterdayKey ? t("widget.yesterday") : displayDateFormatter(getLocale()).format(itemDate);
|
|
4969
5226
|
const sender = item.visitorId ? "visitor" : item.aiAgentId ? "ai" : "team";
|
|
4970
5227
|
return /* @__PURE__ */ jsxs9(
|
|
4971
5228
|
React.Fragment,
|
|
@@ -4982,7 +5239,7 @@ function MessageList({
|
|
|
4982
5239
|
text: item.text ?? "",
|
|
4983
5240
|
sender,
|
|
4984
5241
|
parts: parseParts(item.parts),
|
|
4985
|
-
metadata:
|
|
5242
|
+
metadata: parseTimelineItemMetadata(
|
|
4986
5243
|
item.metadata
|
|
4987
5244
|
),
|
|
4988
5245
|
onQuickReplyTap: handleQuickReplyTap
|
|
@@ -5064,6 +5321,7 @@ function MessagePreview({
|
|
|
5064
5321
|
const dismissPreview = useWidgetStore((s) => s.dismissPreview);
|
|
5065
5322
|
const setActiveConversation = useWidgetStore((s) => s.setActiveConversation);
|
|
5066
5323
|
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
5324
|
+
const client = useWidgetClient();
|
|
5067
5325
|
const senderName = preview?.senderName || agentName;
|
|
5068
5326
|
const senderImage = preview?.senderImage || null;
|
|
5069
5327
|
const [closing, setClosing] = useState14(false);
|
|
@@ -5091,14 +5349,34 @@ function MessagePreview({
|
|
|
5091
5349
|
setActiveConversation(targetConvId);
|
|
5092
5350
|
onOpen();
|
|
5093
5351
|
};
|
|
5094
|
-
const
|
|
5095
|
-
|
|
5352
|
+
const submitQuickReply = (optionId) => {
|
|
5353
|
+
const convId = preview.conversationId;
|
|
5354
|
+
const stepId = preview.quickReplies?.stepId;
|
|
5355
|
+
if (stepId && !convId.startsWith(EPHEMERAL_CONV_PREFIX)) {
|
|
5356
|
+
client.widget.workflowReply.mutate({ conversationId: convId, stepId, optionId }).catch((err) => {
|
|
5357
|
+
console.warn("[helpway] workflowReply from preview failed:", err);
|
|
5358
|
+
});
|
|
5359
|
+
}
|
|
5360
|
+
dismissPreview();
|
|
5361
|
+
setActiveConversation(convId);
|
|
5362
|
+
onOpen();
|
|
5363
|
+
};
|
|
5364
|
+
const messages = (preview.messages?.length ? preview.messages : [{ text: preview.text }]).filter(
|
|
5365
|
+
(m) => m.text.trim().length > 0
|
|
5366
|
+
);
|
|
5367
|
+
const qr = preview.quickReplies && preview.quickReplies.options.length > 0 ? preview.quickReplies : null;
|
|
5096
5368
|
const placementClass = placement === "anchored" ? "hw-preview--anchored " : "";
|
|
5097
5369
|
return /* @__PURE__ */ jsxs10(
|
|
5098
5370
|
"div",
|
|
5099
5371
|
{
|
|
5100
5372
|
className: `hw-preview ${placementClass}${closing ? "hw-preview--closing" : ""}`,
|
|
5101
5373
|
onClick: handleClick,
|
|
5374
|
+
onKeyDown: (e) => {
|
|
5375
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
5376
|
+
if (e.target !== e.currentTarget) return;
|
|
5377
|
+
e.preventDefault();
|
|
5378
|
+
handleClick();
|
|
5379
|
+
},
|
|
5102
5380
|
role: "button",
|
|
5103
5381
|
tabIndex: 0,
|
|
5104
5382
|
children: [
|
|
@@ -5116,19 +5394,23 @@ function MessagePreview({
|
|
|
5116
5394
|
}
|
|
5117
5395
|
)
|
|
5118
5396
|
] }),
|
|
5119
|
-
messages.map((m
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5397
|
+
messages.map((m) => (
|
|
5398
|
+
/* Keyed by content, not index: the card's bodies are the sender's own
|
|
5399
|
+
consecutive messages, so two identical ones would already be a bug
|
|
5400
|
+
upstream, and an index key hands React the wrong bubble to reuse the
|
|
5401
|
+
moment a new message lands mid-animation. */
|
|
5402
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-preview-body", children: truncatePreviewBody(m.text) }, m.text)
|
|
5403
|
+
)),
|
|
5404
|
+
qr && /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
5405
|
+
qr.prompt && /* @__PURE__ */ jsx15("div", { className: "hw-preview-body", children: qr.prompt }),
|
|
5406
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-preview-quick-replies hw-quick-replies", children: qr.options.map((opt) => /* @__PURE__ */ jsx15(
|
|
5123
5407
|
"button",
|
|
5124
5408
|
{
|
|
5125
5409
|
type: "button",
|
|
5126
5410
|
className: "hw-quick-reply-btn",
|
|
5127
5411
|
onClick: (e) => {
|
|
5128
5412
|
e.stopPropagation();
|
|
5129
|
-
|
|
5130
|
-
setActiveConversation(preview.conversationId);
|
|
5131
|
-
onOpen();
|
|
5413
|
+
submitQuickReply(opt.id);
|
|
5132
5414
|
},
|
|
5133
5415
|
children: opt.label
|
|
5134
5416
|
},
|
|
@@ -5198,7 +5480,14 @@ function WidgetLogo({
|
|
|
5198
5480
|
);
|
|
5199
5481
|
}
|
|
5200
5482
|
if (agentConfig?.avatarUrl) {
|
|
5201
|
-
return /* @__PURE__ */ jsx16(
|
|
5483
|
+
return /* @__PURE__ */ jsx16(
|
|
5484
|
+
"img",
|
|
5485
|
+
{
|
|
5486
|
+
src: agentConfig.avatarUrl,
|
|
5487
|
+
alt: "",
|
|
5488
|
+
className: `hw-agent-img ${logoClass} ${className ?? ""}`
|
|
5489
|
+
}
|
|
5490
|
+
);
|
|
5202
5491
|
}
|
|
5203
5492
|
if (agentConfig?.avatarPreset) {
|
|
5204
5493
|
return /* @__PURE__ */ jsx16(
|
|
@@ -5350,9 +5639,11 @@ function DefaultWidget({
|
|
|
5350
5639
|
const activeId = useWidgetStore((s) => s.activeConversationId);
|
|
5351
5640
|
const isDismissed = useWidgetStore((s) => s.isDismissed);
|
|
5352
5641
|
const { totalUnread } = useUnread();
|
|
5642
|
+
const awaitingReply = useAwaitingReply();
|
|
5353
5643
|
const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_CONTENT_TABS;
|
|
5354
5644
|
const { announcementTabs, markEntrySeen, getUnseenEntries } = useAnnouncements();
|
|
5355
5645
|
const unseenAnnouncementCount = useWidgetStore((s) => s.unseenAnnouncementCount);
|
|
5646
|
+
const incomingPreview = useWidgetStore((s) => !!s.incomingPreview);
|
|
5356
5647
|
const visitorContact = useWidgetStore((s) => s.visitor?.contact);
|
|
5357
5648
|
if (process.env.NODE_ENV !== "production") {
|
|
5358
5649
|
console.debug("[Widget]", {
|
|
@@ -5434,14 +5725,7 @@ function DefaultWidget({
|
|
|
5434
5725
|
const mostRecent = conversations[0];
|
|
5435
5726
|
if (mostRecent) openConversation(mostRecent.id);
|
|
5436
5727
|
else openNewConversation();
|
|
5437
|
-
}, [
|
|
5438
|
-
isOpen,
|
|
5439
|
-
isReady,
|
|
5440
|
-
subView,
|
|
5441
|
-
conversations,
|
|
5442
|
-
openConversation,
|
|
5443
|
-
openNewConversation
|
|
5444
|
-
]);
|
|
5728
|
+
}, [isOpen, isReady, subView, conversations, openConversation, openNewConversation]);
|
|
5445
5729
|
const dockComposer = useComposer(activeId);
|
|
5446
5730
|
const dockRef = useRef15(dockComposer);
|
|
5447
5731
|
useEffect15(() => {
|
|
@@ -5814,7 +6098,13 @@ function DefaultWidget({
|
|
|
5814
6098
|
}
|
|
5815
6099
|
),
|
|
5816
6100
|
/* @__PURE__ */ jsxs11("div", { className: "hw-header-identity", children: [
|
|
5817
|
-
/* @__PURE__ */ jsx16(
|
|
6101
|
+
/* @__PURE__ */ jsx16(
|
|
6102
|
+
"div",
|
|
6103
|
+
{
|
|
6104
|
+
className: `hw-header-bot-icon${hasTeamAgent ? " hw-header-bot-icon--team" : ""}`,
|
|
6105
|
+
children: hasTeamAgent && humanImage ? /* @__PURE__ */ jsx16("img", { src: humanImage, alt: headerName, className: "hw-header-agent-img" }) : hasTeamAgent ? /* @__PURE__ */ jsx16("span", { className: "hw-header-agent-initials", children: headerName.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase() }) : /* @__PURE__ */ jsx16(WidgetLogo, {})
|
|
6106
|
+
}
|
|
6107
|
+
),
|
|
5818
6108
|
/* @__PURE__ */ jsxs11("div", { className: "hw-header-info", children: [
|
|
5819
6109
|
/* @__PURE__ */ jsx16("div", { className: "hw-header-name", children: headerName }),
|
|
5820
6110
|
/* @__PURE__ */ jsx16("div", { className: "hw-header-status", children: subtitleText })
|
|
@@ -5860,7 +6150,7 @@ function DefaultWidget({
|
|
|
5860
6150
|
},
|
|
5861
6151
|
children: [
|
|
5862
6152
|
/* @__PURE__ */ jsxs11("span", { className: "hw-header-menu-conv-top", children: [
|
|
5863
|
-
/* @__PURE__ */ jsx16("span", { className: "hw-header-menu-conv-name", children:
|
|
6153
|
+
/* @__PURE__ */ jsx16("span", { className: "hw-header-menu-conv-name", children: conversationIdentity(conv).humanName ?? companyName }),
|
|
5864
6154
|
conv.lastMessageAt && /* @__PURE__ */ jsx16("span", { className: "hw-header-menu-conv-time", children: formatRelativeTime(conv.lastMessageAt) })
|
|
5865
6155
|
] }),
|
|
5866
6156
|
/* @__PURE__ */ jsx16("span", { className: "hw-header-menu-conv-preview", children: conv.lastMessageText ?? t("widget.no_preview") })
|
|
@@ -6044,35 +6334,25 @@ function DefaultWidget({
|
|
|
6044
6334
|
]
|
|
6045
6335
|
}
|
|
6046
6336
|
),
|
|
6047
|
-
isReady && !isOpen && !isDismissed && !hideLauncher && /*
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
AnnouncementPreviews,
|
|
6063
|
-
{
|
|
6064
|
-
avatar: /* @__PURE__ */ jsx16(WidgetLogo, {}),
|
|
6065
|
-
onOpen: (slug, tabId) => {
|
|
6066
|
-
markEntrySeen(slug);
|
|
6067
|
-
handleBubbleClick();
|
|
6068
|
-
setTimeout(() => {
|
|
6069
|
-
switchTab(`content:${tabId}`);
|
|
6070
|
-
setContentDetailSlug(slug);
|
|
6071
|
-
setSubView("content-detail");
|
|
6072
|
-
}, 50);
|
|
6337
|
+
isReady && !isOpen && !isDismissed && !hideLauncher && /* @__PURE__ */ jsxs11("div", { className: "hw-preview-dock", children: [
|
|
6338
|
+
/* @__PURE__ */ jsx16(
|
|
6339
|
+
AnnouncementPreviews,
|
|
6340
|
+
{
|
|
6341
|
+
maxVisible: incomingPreview ? 1 : 2,
|
|
6342
|
+
avatar: /* @__PURE__ */ jsx16(WidgetLogo, {}),
|
|
6343
|
+
onOpen: (slug, tabId) => {
|
|
6344
|
+
markEntrySeen(slug);
|
|
6345
|
+
handleBubbleClick();
|
|
6346
|
+
setTimeout(() => {
|
|
6347
|
+
switchTab(`content:${tabId}`);
|
|
6348
|
+
setContentDetailSlug(slug);
|
|
6349
|
+
setSubView("content-detail");
|
|
6350
|
+
}, 50);
|
|
6351
|
+
}
|
|
6073
6352
|
}
|
|
6074
|
-
|
|
6075
|
-
|
|
6353
|
+
),
|
|
6354
|
+
/* @__PURE__ */ jsx16(MessagePreview, { onOpen: handleBubbleClick, avatar: /* @__PURE__ */ jsx16(WidgetLogo, {}), autoDismissMs: null })
|
|
6355
|
+
] }),
|
|
6076
6356
|
/* @__PURE__ */ jsx16(WidgetDebugOverlay, {}),
|
|
6077
6357
|
isReady && !isDismissed && (!hideLauncher || isOpen) && /* @__PURE__ */ jsxs11(
|
|
6078
6358
|
"button",
|
|
@@ -6106,9 +6386,9 @@ function DefaultWidget({
|
|
|
6106
6386
|
}
|
|
6107
6387
|
),
|
|
6108
6388
|
launcherStyle !== "icon" && !isOpen && /* @__PURE__ */ jsx16("span", { className: "hw-bubble-label", children: launcherStyle === "help" ? t("widget.help") : companyName }),
|
|
6109
|
-
!isOpen && (totalUnread > 0 || unseenAnnouncementCount > 0) && /* @__PURE__ */ jsxs11("div", { className: "hw-bubble-badge", children: [
|
|
6389
|
+
!isOpen && (totalUnread > 0 || awaitingReply > 0 || unseenAnnouncementCount > 0) && /* @__PURE__ */ jsxs11("div", { className: "hw-bubble-badge", children: [
|
|
6110
6390
|
totalUnread > 0 ? totalUnread : "",
|
|
6111
|
-
totalUnread === 0 && unseenAnnouncementCount > 0 && /* @__PURE__ */ jsx16("span", { className: "hw-bubble-badge-dot" })
|
|
6391
|
+
totalUnread === 0 && (awaitingReply > 0 || unseenAnnouncementCount > 0) && /* @__PURE__ */ jsx16("span", { className: "hw-bubble-badge-dot" })
|
|
6112
6392
|
] })
|
|
6113
6393
|
]
|
|
6114
6394
|
}
|
|
@@ -6215,11 +6495,12 @@ function MessagesView({
|
|
|
6215
6495
|
}
|
|
6216
6496
|
function ConvCardBody({ conv }) {
|
|
6217
6497
|
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
6218
|
-
const
|
|
6219
|
-
const
|
|
6498
|
+
const { humanName, humanImage } = conversationIdentity(conv);
|
|
6499
|
+
const isTeam = !!humanName;
|
|
6500
|
+
const displayName = humanName ?? agentName;
|
|
6220
6501
|
const preview = conv.lastMessageText ?? t("widget.no_preview");
|
|
6221
6502
|
return /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
6222
|
-
/* @__PURE__ */ jsx16("div", { className: `hw-conv-card-avatar${isTeam ? " hw-conv-card-avatar--team" : ""}`, children: isTeam ?
|
|
6503
|
+
/* @__PURE__ */ jsx16("div", { className: `hw-conv-card-avatar${isTeam ? " hw-conv-card-avatar--team" : ""}`, children: isTeam ? humanImage ? /* @__PURE__ */ jsx16("img", { src: humanImage, alt: displayName, className: "hw-conv-card-avatar-img" }) : /* @__PURE__ */ jsx16("span", { className: "hw-conv-card-avatar-initials", children: displayName.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase() }) : /* @__PURE__ */ jsx16(WidgetLogo, {}) }),
|
|
6223
6504
|
/* @__PURE__ */ jsxs11("div", { className: "hw-conv-card-content", children: [
|
|
6224
6505
|
/* @__PURE__ */ jsxs11("div", { className: "hw-conv-card-top", children: [
|
|
6225
6506
|
/* @__PURE__ */ jsx16("span", { className: "hw-conv-card-name", children: displayName }),
|
|
@@ -6234,6 +6515,7 @@ function ConversationCard({
|
|
|
6234
6515
|
onSelect
|
|
6235
6516
|
}) {
|
|
6236
6517
|
const hasUnread = conv.unreadCount > 0;
|
|
6518
|
+
const awaiting = !hasUnread && isAwaitingVisitorReply(conv);
|
|
6237
6519
|
return /* @__PURE__ */ jsxs11(
|
|
6238
6520
|
"button",
|
|
6239
6521
|
{
|
|
@@ -6242,7 +6524,8 @@ function ConversationCard({
|
|
|
6242
6524
|
onClick: () => onSelect(conv.id),
|
|
6243
6525
|
children: [
|
|
6244
6526
|
/* @__PURE__ */ jsx16("div", { className: "hw-conv-card-row", children: /* @__PURE__ */ jsx16(ConvCardBody, { conv }) }),
|
|
6245
|
-
hasUnread && /* @__PURE__ */ jsx16("div", { className: "hw-conv-card-badge", children: conv.unreadCount })
|
|
6527
|
+
hasUnread && /* @__PURE__ */ jsx16("div", { className: "hw-conv-card-badge", children: conv.unreadCount }),
|
|
6528
|
+
awaiting && /* @__PURE__ */ jsx16("div", { className: "hw-awaiting", children: t("widget.awaiting_your_reply") })
|
|
6246
6529
|
]
|
|
6247
6530
|
}
|
|
6248
6531
|
);
|
|
@@ -6253,6 +6536,7 @@ function ConversationRow({
|
|
|
6253
6536
|
isLast
|
|
6254
6537
|
}) {
|
|
6255
6538
|
const hasUnread = conv.unreadCount > 0;
|
|
6539
|
+
const awaiting = !hasUnread && isAwaitingVisitorReply(conv);
|
|
6256
6540
|
return /* @__PURE__ */ jsxs11(
|
|
6257
6541
|
"button",
|
|
6258
6542
|
{
|
|
@@ -6261,7 +6545,8 @@ function ConversationRow({
|
|
|
6261
6545
|
onClick: () => onSelect(conv.id),
|
|
6262
6546
|
children: [
|
|
6263
6547
|
/* @__PURE__ */ jsx16(ConvCardBody, { conv }),
|
|
6264
|
-
hasUnread && /* @__PURE__ */ jsx16("div", { className: "hw-recent-row-badge", children: conv.unreadCount })
|
|
6548
|
+
hasUnread && /* @__PURE__ */ jsx16("div", { className: "hw-recent-row-badge", children: conv.unreadCount }),
|
|
6549
|
+
awaiting && /* @__PURE__ */ jsx16("div", { className: "hw-awaiting", children: t("widget.awaiting_your_reply") })
|
|
6265
6550
|
]
|
|
6266
6551
|
}
|
|
6267
6552
|
);
|
|
@@ -6314,7 +6599,20 @@ function InlineEmailPrompt({ conversationId }) {
|
|
|
6314
6599
|
};
|
|
6315
6600
|
if (isSuccess) {
|
|
6316
6601
|
return /* @__PURE__ */ jsxs11("div", { className: "hw-email-card hw-email-card--success", children: [
|
|
6317
|
-
/* @__PURE__ */ jsx16(
|
|
6602
|
+
/* @__PURE__ */ jsx16(
|
|
6603
|
+
"svg",
|
|
6604
|
+
{
|
|
6605
|
+
width: "15",
|
|
6606
|
+
height: "15",
|
|
6607
|
+
viewBox: "0 0 24 24",
|
|
6608
|
+
fill: "none",
|
|
6609
|
+
stroke: "#22c55e",
|
|
6610
|
+
strokeWidth: 2.5,
|
|
6611
|
+
strokeLinecap: "round",
|
|
6612
|
+
strokeLinejoin: "round",
|
|
6613
|
+
children: /* @__PURE__ */ jsx16("polyline", { points: "20 6 9 17 4 12" })
|
|
6614
|
+
}
|
|
6615
|
+
),
|
|
6318
6616
|
t("widget.email_saved")
|
|
6319
6617
|
] });
|
|
6320
6618
|
}
|
|
@@ -6346,7 +6644,41 @@ function InlineEmailPrompt({ conversationId }) {
|
|
|
6346
6644
|
onClick: handleSubmit,
|
|
6347
6645
|
disabled: isSubmitting || !email.trim(),
|
|
6348
6646
|
"aria-label": t("widget.email_continue"),
|
|
6349
|
-
children: isSubmitting ? /* @__PURE__ */ jsx16(
|
|
6647
|
+
children: isSubmitting ? /* @__PURE__ */ jsx16(
|
|
6648
|
+
"svg",
|
|
6649
|
+
{
|
|
6650
|
+
width: "14",
|
|
6651
|
+
height: "14",
|
|
6652
|
+
viewBox: "0 0 24 24",
|
|
6653
|
+
fill: "none",
|
|
6654
|
+
stroke: "currentColor",
|
|
6655
|
+
strokeWidth: 2,
|
|
6656
|
+
"aria-hidden": "true",
|
|
6657
|
+
children: /* @__PURE__ */ jsx16("circle", { cx: "12", cy: "12", r: "10", strokeDasharray: "32", strokeDashoffset: "32", children: /* @__PURE__ */ jsx16(
|
|
6658
|
+
"animate",
|
|
6659
|
+
{
|
|
6660
|
+
attributeName: "stroke-dashoffset",
|
|
6661
|
+
values: "32;0",
|
|
6662
|
+
dur: "1s",
|
|
6663
|
+
repeatCount: "indefinite"
|
|
6664
|
+
}
|
|
6665
|
+
) })
|
|
6666
|
+
}
|
|
6667
|
+
) : /* @__PURE__ */ jsx16(
|
|
6668
|
+
"svg",
|
|
6669
|
+
{
|
|
6670
|
+
width: "15",
|
|
6671
|
+
height: "15",
|
|
6672
|
+
viewBox: "0 0 24 24",
|
|
6673
|
+
fill: "none",
|
|
6674
|
+
stroke: "currentColor",
|
|
6675
|
+
strokeWidth: 2.2,
|
|
6676
|
+
strokeLinecap: "round",
|
|
6677
|
+
strokeLinejoin: "round",
|
|
6678
|
+
"aria-hidden": "true",
|
|
6679
|
+
children: /* @__PURE__ */ jsx16("path", { d: "M5 12h13M12 5l7 7-7 7" })
|
|
6680
|
+
}
|
|
6681
|
+
)
|
|
6350
6682
|
}
|
|
6351
6683
|
)
|
|
6352
6684
|
] })
|
|
@@ -6360,14 +6692,7 @@ function NewConversationView({
|
|
|
6360
6692
|
welcomeMessage
|
|
6361
6693
|
}) {
|
|
6362
6694
|
return /* @__PURE__ */ jsxs11("div", { className: "hw-new", children: [
|
|
6363
|
-
/* @__PURE__ */ jsx16("div", { className: "hw-new-welcome", children: /* @__PURE__ */ jsx16(
|
|
6364
|
-
MessageBubble,
|
|
6365
|
-
{
|
|
6366
|
-
text: welcomeMessage,
|
|
6367
|
-
sender: "ai",
|
|
6368
|
-
parts: null
|
|
6369
|
-
}
|
|
6370
|
-
) }),
|
|
6695
|
+
/* @__PURE__ */ jsx16("div", { className: "hw-new-welcome", children: /* @__PURE__ */ jsx16(MessageBubble, { text: welcomeMessage, sender: "ai", parts: null }) }),
|
|
6371
6696
|
/* @__PURE__ */ jsx16(
|
|
6372
6697
|
Composer,
|
|
6373
6698
|
{
|
|
@@ -6441,8 +6766,8 @@ function ConversationView({
|
|
|
6441
6766
|
MessageList,
|
|
6442
6767
|
{
|
|
6443
6768
|
items,
|
|
6444
|
-
isTyping,
|
|
6445
|
-
isAiProcessing,
|
|
6769
|
+
isTyping: isTyping && !needsEmail,
|
|
6770
|
+
isAiProcessing: isAiProcessing && !needsEmail,
|
|
6446
6771
|
streamingText: streamingText || void 0,
|
|
6447
6772
|
hasMore,
|
|
6448
6773
|
isLoadingMore: isLoading,
|
|
@@ -6555,9 +6880,7 @@ function WhatsNewCard({
|
|
|
6555
6880
|
const unseen = getUnseenEntries();
|
|
6556
6881
|
if (unseen.length === 0) return null;
|
|
6557
6882
|
const display = unseen.slice(0, 3);
|
|
6558
|
-
const badgeFieldMap = new Map(
|
|
6559
|
-
announcementTabs.map((t2) => [t2.id, t2.display?.badgeField])
|
|
6560
|
-
);
|
|
6883
|
+
const badgeFieldMap = new Map(announcementTabs.map((t2) => [t2.id, t2.display?.badgeField]));
|
|
6561
6884
|
return /* @__PURE__ */ jsxs11("div", { className: "hw-whats-new", children: [
|
|
6562
6885
|
/* @__PURE__ */ jsxs11("div", { className: "hw-whats-new-header", children: [
|
|
6563
6886
|
/* @__PURE__ */ jsx16("span", { className: "hw-whats-new-title", children: resolveLabel2("widget.whats_new") }),
|
|
@@ -6618,7 +6941,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
6618
6941
|
}
|
|
6619
6942
|
|
|
6620
6943
|
// src/themed/styles.css
|
|
6621
|
-
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: #fafaf9;\n --hw-bg-hover: #f5f5f4;\n --hw-border: #ebe9e5;\n --hw-border-md: #e5e5e5;\n --hw-text: #1c1b19;\n --hw-text-1: #111;\n --hw-text-2: #666;\n --hw-text-3: #8a847c;\n --hw-text-4: #a8a29a;\n --hw-radius: 20px;\n --hw-visitor-bubble-bg: #f5f5f4;\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: 14px 12px 14px 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: 0;\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: 32px;\n height: 32px;\n flex-shrink: 0;\n color: var(--hw-text);\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 9px;\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: 15px;\n font-weight: 600;\n line-height: 1.3;\n}\n.hw-header-status {\n font-size: 11px;\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: 0;\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: 0;\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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 14px 8px;\n background: var(--hw-bg-subtle);\n display: flex;\n flex-direction: column;\n gap: 14px;\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: 16px;\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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: var(--hw-border);\n color: var(--hw-text-3);\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-2);\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-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-dots {\n display: flex;\n gap: 3px;\n padding: 6px 2px;\n width: fit-content;\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 gap: 0;\n border: 1px solid var(--hw-border, 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: var(--hw-bg-hover, rgba(0, 0, 0, 0.02));\n}\n.hw-link-preview-img {\n width: 100%;\n height: 56px;\n flex: 0 0 56px;\n object-fit: cover;\n object-position: top;\n border-radius: 0;\n}\n.hw-link-preview-body {\n padding: 8px 10px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n justify-content: center;\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: 12.5px;\n font-weight: 600;\n line-height: 1.3;\n color: var(--hw-text, #1a1a1a);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.hw-link-preview-desc {\n font-size: 11.5px;\n line-height: 1.4;\n color: var(--hw-text-2, #6b7280);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.hw-link-preview-url {\n font-size: 11px;\n color: var(--hw-text-2);\n}\n.hw-msg-links {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-width: 240px;\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 max-width: min(100%, 340px);\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: none;\n box-shadow: none;\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-title {\n font-size: 14px;\n font-weight: 550;\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-row {\n max-width: 300px;\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 9px;\n padding: 3px 3px 3px 12px;\n border-radius: 999px;\n border: 1px solid var(--hw-border, rgba(0,0,0,0.1));\n background: var(--hw-bg-subtle, #fafafa);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n.hw-email-card-row:focus-within {\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 {\n flex: 1;\n min-width: 0;\n padding: 6px 0;\n border: 0;\n background: transparent;\n color: var(--hw-text, #1a1a1a);\n font: inherit;\n font-size: 13px;\n outline: none;\n}\n.hw-email-card-input::placeholder {\n color: var(--hw-text-3, #999);\n}\n.hw-email-card-row:has(.hw-email-card-input--error) {\n border-color: #ef4444;\n}\n.hw-email-card-submit {\n flex: none;\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 50%;\n background: var(--hw-brand, #0a0a0a);\n color: var(--hw-on-brand, #fff);\n cursor: pointer;\n transition: opacity 0.15s, transform 0.15s;\n}\n.hw-email-card-submit:hover:not(:disabled) {\n transform: scale(1.06);\n}\n.hw-email-card-submit:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.hw-email-card--success {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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: 2147483001;\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-avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\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 padding: 0 14px 14px;\n margin-top: 0;\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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.hw-markdown ol {\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-table-wrap {\n margin: 10px 0;\n overflow-x: auto;\n border: 1px solid var(--hw-border, rgba(0, 0, 0, 0.08));\n border-radius: 10px;\n}\n.hw-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n.hw-table th {\n text-align: left;\n font-weight: 600;\n font-size: 12px;\n padding: 8px 12px;\n background: var(--hw-bg-hover, #f5f5f4);\n border-bottom: 1px solid var(--hw-border, rgba(0, 0, 0, 0.08));\n}\n.hw-table td {\n padding: 8px 12px;\n border-bottom: 1px solid var(--hw-border, rgba(0, 0, 0, 0.06));\n vertical-align: top;\n}\n.hw-table tbody tr:last-child td {\n border-bottom: none;\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: 7px;\n padding: 7px 14px;\n background: var(--hw-bg-hover);\n color: var(--hw-text-2);\n font-size: 11.5px;\n font-weight: 500;\n letter-spacing: -0.01em;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex-shrink: 0;\n animation: hw-disconnect-in 0.18s cubic-bezier(0.22, 1, 0.36, 1);\n}\n@keyframes hw-disconnect-in {\n from {\n opacity: 0;\n transform: translateY(-100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.hw-disconnect-spinner {\n width: 9px;\n height: 9px;\n border: 1.5px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n opacity: 0.75;\n flex-shrink: 0;\n animation: hw-spin 0.7s linear infinite;\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-disconnect {\n animation: none;\n }\n .hw-disconnect-spinner {\n animation: none;\n border-top-color: currentColor;\n opacity: 0.5;\n }\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: inherit;\n text-decoration: underline;\n text-decoration-thickness: 1px;\n text-underline-offset: 2px;\n text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);\n word-break: normal;\n overflow-wrap: anywhere;\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-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.hw-widget[data-hw-placement=docked] {\n --hw-dock-width: 600px;\n --hw-dock-bar-width: 480px;\n --hw-dock-inset: 24px;\n --hw-bar-max-height: 148px;\n --hw-dock-surface: #ffffff;\n --hw-dock-on-surface: #111111;\n --hw-dock-pill-bg: rgba(44, 44, 48, 0.66);\n --hw-dock-pill-fg: rgba(255, 255, 255, 0.94);\n --hw-dock-pill-border: rgba(255, 255, 255, 0.14);\n}\n.hw-widget[data-hw-placement=docked] {\n z-index: 2147483000;\n}\n.hw-widget[data-hw-placement=docked] .hw-dock {\n position: fixed;\n left: 0;\n right: 0;\n bottom: var(--hw-dock-inset);\n z-index: 2147483000;\n display: flex;\n flex-direction: column;\n align-items: center;\n pointer-events: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-dock > * {\n pointer-events: auto;\n}\n.hw-dock-suggestions {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 9px;\n width: var(--hw-dock-bar-width, var(--hw-dock-width));\n max-width: calc(100vw - 32px);\n margin-bottom: 14px;\n}\n.hw-dock-pill-row {\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n animation: hw-dock-pill-in 0.42s cubic-bezier(0.2, 0.9, 0.3, 1) both;\n}\n.hw-dock-pill-dismiss {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n padding: 0;\n border: 0;\n background: none;\n color: var(--hw-dock-pill-fg);\n cursor: pointer;\n align-self: flex-start;\n margin-top: 8px;\n opacity: 0;\n transform: scale(0.85);\n transition:\n opacity 0.12s linear,\n transform 0.12s cubic-bezier(0.25, 1, 0.5, 1),\n color 0.12s linear;\n}\n.hw-dock-pill-dismiss svg {\n width: 11px;\n height: 11px;\n}\n.hw-dock-suggestions:hover .hw-dock-pill-dismiss,\n.hw-dock-suggestions:focus-within .hw-dock-pill-dismiss {\n opacity: 1;\n transform: none;\n}\n.hw-dock-pill-dismiss:hover {\n color: var(--hw-dock-on-surface);\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-dock-pill-dismiss {\n transition: none;\n }\n}\n@media (hover: none) {\n .hw-dock-pill-dismiss {\n opacity: 1;\n transform: none;\n }\n}\n.hw-dock-pill {\n align-self: flex-start;\n padding: 10px 18px;\n border: 1px solid var(--hw-dock-pill-border, transparent);\n border-radius: 999px;\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n font-weight: 500;\n text-align: left;\n background: var(--hw-dock-pill-bg);\n color: var(--hw-dock-pill-fg);\n backdrop-filter: blur(10px) saturate(1.2);\n -webkit-backdrop-filter: blur(10px) saturate(1.2);\n box-shadow: 0 4px 14px -8px rgba(12, 11, 10, 0.28);\n transition:\n background 0.16s,\n border-color 0.16s,\n transform 0.16s;\n}\n.hw-dock-pill {\n backdrop-filter: blur(18px);\n -webkit-backdrop-filter: blur(18px);\n}\n.hw-dock-pill:hover {\n background: color-mix(in srgb, var(--hw-dock-pill-bg) 100%, var(--hw-dock-on-surface) 8%);\n border-color: color-mix(in srgb, var(--hw-dock-pill-border) 100%, var(--hw-dock-on-surface) 10%);\n transform: translateX(3px);\n}\n@keyframes hw-dock-pill-in {\n from {\n opacity: 0;\n transform: translateY(10px) scale(0.97);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n.hw-dock-bar {\n display: flex;\n align-items: flex-end;\n gap: 10px;\n width: var(--hw-dock-bar-width, var(--hw-dock-width));\n max-width: calc(100vw - 32px);\n min-height: 52px;\n padding: 10px 10px 10px 18px;\n border: 0;\n border-radius: 26px;\n background: var(--hw-dock-surface);\n color: var(--hw-dock-on-surface);\n box-shadow:\n inset 0 1px 0 color-mix(in srgb, var(--hw-dock-on-surface) 9%, transparent),\n 0 0 0 1px color-mix(in srgb, var(--hw-dock-on-surface) 7%, transparent),\n 0 2px 6px rgba(12, 11, 10, 0.18),\n 0 20px 48px -14px rgba(12, 11, 10, 0.45);\n transition:\n border-radius 0.18s ease,\n box-shadow 0.2s cubic-bezier(0.2, 0.8, 0.2, 1),\n width 0.26s cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.hw-dock-bar:focus-within {\n box-shadow:\n inset 0 1px 0 color-mix(in srgb, var(--hw-dock-on-surface) 9%, transparent),\n 0 0 0 1px color-mix(in srgb, var(--hw-primary, #fb923c) 60%, transparent),\n 0 2px 6px rgba(12, 11, 10, 0.18),\n 0 20px 48px -14px rgba(12, 11, 10, 0.45);\n}\n.hw-dock-bar[data-grown=true] {\n border-radius: 20px;\n}\n.hw-dock-input {\n flex: 1;\n min-width: 0;\n min-height: 20px;\n max-height: var(--hw-bar-max-height);\n padding: 6px 0;\n border: 0;\n outline: none;\n resize: none;\n overflow-y: auto;\n background: transparent;\n color: var(--hw-dock-on-surface);\n font: inherit;\n font-size: 14px;\n line-height: 1.45;\n transition: height 0.12s ease;\n}\n.hw-dock-input::placeholder {\n color: color-mix(in srgb, var(--hw-dock-on-surface) 45%, transparent);\n}\n.hw-dock-send {\n flex: none;\n width: 32px;\n height: 32px;\n margin-bottom: 1px;\n border: 0;\n border-radius: 50%;\n display: grid;\n place-items: center;\n cursor: pointer;\n background: var(--hw-primary, #fb923c);\n color: var(--hw-on-brand, #fff);\n transition: transform 0.16s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.16s;\n}\n.hw-dock-send:hover:not(:disabled) {\n transform: scale(1.06);\n}\n.hw-dock-send:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.hw-widget[data-hw-placement=docked] .hw-window {\n position: fixed;\n left: 50%;\n right: auto;\n margin-left: calc(var(--hw-dock-width) / -2);\n bottom: calc(var(--hw-dock-inset) + 66px);\n width: var(--hw-dock-width);\n max-width: calc(100vw - 32px);\n height: 420px;\n}\n@media (max-width: 640px) {\n .hw-widget[data-hw-placement=docked] .hw-window {\n left: 16px;\n right: 16px;\n margin-left: 0;\n width: auto;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-bubble {\n display: none;\n}\n.hw-widget[data-hw-placement=docked][data-hw-open=true] .hw-window {\n bottom: calc(var(--hw-dock-inset) + 52px + 12px);\n}\n.hw-widget[data-hw-placement=docked][data-hw-open=true] .hw-dock-suggestions {\n display: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-dock-pill,\n .hw-dock-bar,\n .hw-dock-input,\n .hw-dock-send {\n animation: none;\n transition: none;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-composer,\n.hw-widget[data-hw-placement=docked] .hw-tabs,\n.hw-widget[data-hw-placement=docked] .hw-footer-tabs {\n display: none;\n}\n.hw-starters {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n border-radius: 14px;\n overflow: hidden;\n background: var(--hw-bg);\n box-shadow: inset 0 0 0 1px var(--hw-border);\n}\n.hw-starter {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 11px 14px;\n border: 0;\n border-radius: 0;\n cursor: pointer;\n background: transparent;\n color: var(--hw-text);\n font: inherit;\n text-align: left;\n animation: hw-starter-in 0.3s cubic-bezier(0.2, 0.8, 0.2, 1) both;\n transition: background 0.12s;\n}\n.hw-starter + .hw-starter {\n box-shadow: inset 0 1px 0 var(--hw-border);\n}\n.hw-starter:hover {\n background: var(--hw-bg-hover);\n}\n.hw-starter-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n.hw-starter-k {\n font-size: 13px;\n font-weight: 550;\n line-height: 1.35;\n color: var(--hw-text);\n}\n.hw-starter-q {\n font-size: 12px;\n line-height: 1.35;\n color: var(--hw-text-3, var(--hw-text-muted));\n}\n.hw-starter svg {\n flex: none;\n color: var(--hw-text-3, var(--hw-text-muted));\n opacity: 0.45;\n transition: opacity 0.15s, transform 0.15s;\n}\n.hw-starter:hover svg {\n opacity: 0.9;\n transform: translateX(2px);\n}\n@keyframes hw-starter-in {\n from {\n opacity: 0;\n transform: translateY(6px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-header-back {\n display: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-starter {\n animation: none;\n }\n}\n@media (prefers-color-scheme: dark) {\n .hw-widget:not([data-theme=light])[data-hw-placement=docked] {\n --hw-dock-surface: #1f1f23;\n --hw-dock-on-surface: #f4f4f6;\n --hw-dock-pill-bg: rgba(255, 255, 255, 0.1);\n --hw-dock-pill-fg: #e4e4e7;\n --hw-dock-pill-border: rgba(255, 255, 255, 0.14);\n }\n}\n.hw-widget[data-theme=dark][data-hw-placement=docked] {\n --hw-dock-surface: #1f1f23;\n --hw-dock-on-surface: #f4f4f6;\n}\n.hw-widget[data-hw-placement=docked] .hw-window {\n --hw-bg: rgba(255, 255, 255, 0.08);\n --hw-bg-subtle: transparent;\n --hw-bg-hover: rgba(255, 255, 255, 0.1);\n --hw-border: rgba(255, 255, 255, 0.14);\n --hw-border-md: rgba(255, 255, 255, 0.22);\n --hw-text: rgba(255, 255, 255, 0.94);\n --hw-text-1: #ffffff;\n --hw-text-2: rgba(255, 255, 255, 0.72);\n --hw-text-3: rgba(255, 255, 255, 0.62);\n --hw-text-4: rgba(255, 255, 255, 0.46);\n --hw-visitor-bubble-bg: rgba(255, 255, 255, 0.16);\n --hw-visitor-bubble-text: #ffffff;\n --hw-brand: rgba(255, 255, 255, 0.92);\n --hw-on-brand: #17161a;\n --hw-focus-border: rgba(255, 255, 255, 0.34);\n --hw-focus-ring: rgba(255, 255, 255, 0.1);\n height: 500px;\n max-height: calc(100vh - 180px);\n border-radius: 24px;\n color: var(--hw-text);\n background:\n linear-gradient(\n 180deg,\n rgba(40, 40, 44, 0.72) 0%,\n rgba(46, 46, 50, 0.7) 55%,\n rgba(52, 52, 56, 0.68) 100%);\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n box-shadow: 0 24px 60px -20px rgba(12, 11, 10, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.1);\n}\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n .hw-widget[data-hw-placement=docked] .hw-window {\n background: #2c2c2e;\n }\n}\n@media (max-width: 640px) {\n .hw-widget[data-hw-placement=docked] .hw-window {\n height: min(60vh, 460px);\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-header--sub {\n padding: 14px 12px 8px 16px;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-status {\n display: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-name {\n font-size: 15.5px;\n font-weight: 560;\n letter-spacing: -0.006em;\n color: var(--hw-text-1);\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu-conv-name,\n.hw-widget[data-hw-placement=docked] .hw-event-name {\n font-weight: 545;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-bot-icon {\n border-radius: 50%;\n overflow: hidden;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-close:hover,\n.hw-widget[data-hw-placement=docked] .hw-header-menu-btn:hover {\n background: rgba(255, 255, 255, 0.12);\n color: #ffffff;\n}\n.hw-widget[data-hw-placement=docked] .hw-messages {\n padding: 4px 22px 16px;\n gap: 18px;\n -webkit-mask-image:\n linear-gradient(\n 180deg,\n transparent 0,\n #000 16px);\n mask-image:\n linear-gradient(\n 180deg,\n transparent 0,\n #000 16px);\n}\n.hw-widget[data-hw-placement=docked] .hw-msg--ai .hw-msg-bubble,\n.hw-widget[data-hw-placement=docked] .hw-msg--team .hw-msg-bubble {\n padding: 0;\n background: transparent;\n border-radius: 0;\n font-size: 15px;\n line-height: 1.55;\n color: var(--hw-text);\n}\n.hw-widget[data-hw-placement=docked] .hw-msg--visitor .hw-msg-bubble {\n background: rgba(255, 255, 255, 0.16);\n color: #ffffff;\n font-size: 14.5px;\n line-height: 1.5;\n}\n.hw-widget[data-hw-placement=docked] .hw-msg-bubble pre,\n.hw-widget[data-hw-placement=docked] .hw-msg-bubble code {\n background: rgba(0, 0, 0, 0.28);\n color: var(--hw-text-1);\n}\n.hw-widget[data-hw-placement=docked] .hw-email-card-row {\n background: rgba(0, 0, 0, 0.26);\n border-color: rgba(255, 255, 255, 0.14);\n}\n.hw-widget[data-hw-placement=docked] .hw-window :focus-visible {\n outline-color: rgba(255, 255, 255, 0.55);\n}\n.hw-widget[data-hw-placement=docked] .hw-email-card-input:focus,\n.hw-widget[data-hw-placement=docked] .hw-email-card-input:focus-visible {\n outline: none;\n box-shadow: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-email-card-row:focus-within {\n border-color: rgba(255, 255, 255, 0.42);\n box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.08);\n}\n.hw-widget[data-hw-placement=docked] .hw-email-card-submit {\n background: #ffffff;\n color: #17161a;\n}\n.hw-widget[data-hw-placement=docked] .hw-window .hw-header--sub {\n position: relative;\n z-index: 3;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu {\n background: #3a3a3f;\n box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.16), 0 18px 44px -12px rgba(12, 11, 10, 0.62);\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu button:hover {\n background: rgba(255, 255, 255, 0.11);\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu button.hw-header-menu-conv[data-active=true] {\n background: rgba(255, 255, 255, 0.09);\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu-convs {\n border-bottom-color: rgba(255, 255, 255, 0.12);\n}\n.hw-widget[data-hw-placement=docked] .hw-event--card {\n margin: 0;\n background: rgba(255, 255, 255, 0.08);\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);\n}\n.hw-widget[data-hw-placement=docked] .hw-event-avatar {\n background: rgba(255, 255, 255, 0.14);\n color: var(--hw-text-1);\n}\n.hw-widget[data-hw-placement=docked] .hw-preview {\n position: fixed;\n left: 50%;\n right: auto;\n margin-left: calc(var(--hw-dock-bar-width, var(--hw-dock-width)) / -2);\n bottom: calc(var(--hw-dock-inset) + 52px + 12px);\n width: var(--hw-dock-bar-width, var(--hw-dock-width));\n max-width: calc(100vw - 32px);\n border: 0;\n border-radius: 24px;\n color: rgba(255, 255, 255, 0.94);\n background:\n linear-gradient(\n 180deg,\n rgba(40, 40, 44, 0.74) 0%,\n rgba(52, 52, 56, 0.7) 100%);\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n box-shadow: 0 24px 60px -20px rgba(12, 11, 10, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.1);\n}\n.hw-widget[data-hw-placement=docked] .hw-preview-name,\n.hw-widget[data-hw-placement=docked] .hw-preview-body {\n color: rgba(255, 255, 255, 0.94);\n}\n.hw-widget[data-hw-placement=docked] .hw-preview-close {\n color: rgba(255, 255, 255, 0.6);\n}\n.hw-widget[data-hw-placement=docked] .hw-preview-close:hover {\n background: rgba(255, 255, 255, 0.12);\n color: #ffffff;\n}\n.hw-widget[data-hw-placement=docked] .hw-preview-footer {\n color: rgba(255, 255, 255, 0.55);\n border-top-color: rgba(255, 255, 255, 0.1);\n}\n@media (max-width: 640px) {\n .hw-widget[data-hw-placement=docked] .hw-preview {\n left: 16px;\n right: 16px;\n margin-left: 0;\n width: auto;\n }\n}\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n .hw-widget[data-hw-placement=docked] .hw-preview {\n background: #2c2c2e;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-quick-reply-btn {\n padding: 7px 14px;\n font-size: 13px;\n font-weight: 550;\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.94);\n box-shadow: 0 1px 3px rgba(12, 11, 10, 0.22);\n color: #17161a;\n}\n.hw-widget[data-hw-placement=docked] .hw-quick-reply-btn:hover:not(:disabled) {\n background: #ffffff;\n box-shadow: 0 4px 12px rgba(12, 11, 10, 0.28);\n transform: translateY(-1px);\n}\n.hw-widget[data-hw-placement=docked] .hw-quick-reply-btn[data-tapped=true] {\n background: rgba(255, 255, 255, 0.22);\n color: #ffffff;\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);\n transform: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-quick-reply-btn svg {\n opacity: 0.55;\n}\n.hw-widget[data-hw-placement=docked] .hw-offer {\n padding: 7px 14px;\n font-size: 13px;\n background: rgba(255, 255, 255, 0.94);\n color: #17161a;\n box-shadow: 0 1px 3px rgba(12, 11, 10, 0.22);\n transition:\n background 0.15s,\n box-shadow 0.15s,\n transform 0.15s;\n}\n.hw-widget[data-hw-placement=docked] .hw-offer:hover {\n background: #ffffff;\n color: #17161a;\n box-shadow: 0 4px 12px rgba(12, 11, 10, 0.28);\n transform: translateY(-1px);\n}\n.hw-widget[data-hw-placement=docked] .hw-offer svg {\n opacity: 0.55;\n}\n.hw-widget[data-hw-placement=docked] .hw-dock-bar {\n --hw-dock-on-surface: rgba(255, 255, 255, 0.94);\n color: rgba(255, 255, 255, 0.94);\n background:\n linear-gradient(\n 180deg,\n rgba(44, 44, 48, 0.74) 0%,\n rgba(52, 52, 56, 0.72) 100%);\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12), 0 18px 40px -16px rgba(12, 11, 10, 0.45);\n}\n.hw-widget[data-hw-placement=docked][data-hw-open=true] .hw-dock-bar {\n width: var(--hw-dock-width);\n}\n.hw-widget[data-hw-placement=docked] .hw-dock-bar:focus-within {\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.26), 0 18px 40px -16px rgba(12, 11, 10, 0.5);\n}\n.hw-widget[data-hw-placement=docked][data-hw-open=true] .hw-dock-bar {\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14), 0 22px 52px -18px rgba(12, 11, 10, 0.52);\n}\n.hw-widget[data-hw-placement=docked] .hw-dock-send:not(:disabled) {\n background: #ffffff;\n color: #17161a;\n}\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n .hw-widget[data-hw-placement=docked] .hw-dock-bar {\n background: #2c2c2e;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-window {\n transform-origin: 50% 100%;\n animation: hw-dock-panel-in 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n}\n.hw-widget[data-hw-placement=docked] .hw-window--closing {\n animation: hw-dock-panel-out 0.18s cubic-bezier(0.4, 0, 1, 1) forwards;\n}\n@keyframes hw-dock-panel-in {\n from {\n opacity: 0;\n transform: translateY(14px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n@keyframes hw-dock-panel-out {\n from {\n opacity: 1;\n transform: none;\n }\n to {\n opacity: 0;\n transform: translateY(8px) scale(0.99);\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-window .hw-header--sub {\n animation: hw-dock-settle 0.32s cubic-bezier(0.16, 1, 0.3, 1) 0.06s both;\n}\n.hw-widget[data-hw-placement=docked] .hw-window .hw-messages {\n animation: hw-dock-settle 0.34s cubic-bezier(0.16, 1, 0.3, 1) 0.11s both;\n}\n.hw-widget[data-hw-placement=docked] .hw-window--closing .hw-header--sub,\n.hw-widget[data-hw-placement=docked] .hw-window--closing .hw-messages {\n animation: none;\n}\n@keyframes hw-dock-settle {\n from {\n opacity: 0;\n transform: translateY(7px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-widget[data-hw-placement=docked] .hw-window,\n .hw-widget[data-hw-placement=docked] .hw-window--closing,\n .hw-widget[data-hw-placement=docked] .hw-window .hw-header--sub,\n .hw-widget[data-hw-placement=docked] .hw-window .hw-messages {\n animation: none;\n }\n}\n.hw-dock-bar {\n flex-wrap: wrap;\n padding-left: 18px;\n padding-right: 8px;\n}\n.hw-dock-error {\n width: var(--hw-dock-width);\n max-width: calc(100vw - 32px);\n margin-bottom: 8px;\n padding: 8px 14px;\n border-radius: 14px;\n background: rgba(190, 24, 40, 0.92);\n color: #ffffff;\n font-size: 12.5px;\n line-height: 1.35;\n box-shadow: 0 10px 26px -12px rgba(12, 11, 10, 0.5);\n animation: hw-dock-settle 0.22s cubic-bezier(0.16, 1, 0.3, 1) both;\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-dock-error {\n animation: none;\n }\n}\n.hw-dock-previews {\n flex: 0 0 100%;\n order: -1;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n padding: 2px 0 8px;\n}\n.hw-dock-actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: 2px;\n margin-bottom: 1px;\n}\n.hw-dock-tool {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border: 0;\n border-radius: 50%;\n background: transparent;\n color: color-mix(in srgb, var(--hw-dock-on-surface) 52%, transparent);\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n}\n.hw-dock-tool:hover:not(:disabled) {\n background: color-mix(in srgb, var(--hw-dock-on-surface) 8%, transparent);\n color: var(--hw-dock-on-surface);\n}\n.hw-dock-tool:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.hw-dock-tool[data-active=true] {\n color: #e11d48;\n background: rgba(225, 29, 72, 0.12);\n animation: hw-dock-listening 1.4s ease-in-out infinite;\n}\n@keyframes hw-dock-listening {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(225, 29, 72, 0.35);\n }\n 50% {\n box-shadow: 0 0 0 4px rgba(225, 29, 72, 0);\n }\n}\n.hw-dock-send:disabled {\n opacity: 1;\n background: color-mix(in srgb, var(--hw-dock-on-surface) 9%, transparent);\n color: color-mix(in srgb, var(--hw-dock-on-surface) 38%, transparent);\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-dock-tool[data-active=true] {\n animation: none;\n }\n .hw-dock-bar {\n transition: none;\n }\n}\n.hw-dock-input:focus,\n.hw-dock-input:focus-visible {\n outline: none;\n box-shadow: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-powered {\n display: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-disconnect {\n border-radius: 20px 20px 0 0;\n}\n.hw-msg-meta {\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.hw-msg-author {\n font-weight: 550;\n}\n.hw-msg-meta-sep {\n opacity: 0.55;\n}\n.hw-header-actions {\n position: relative;\n display: flex;\n align-items: center;\n gap: 2px;\n}\n.hw-header-menu-btn {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n background: transparent;\n color: var(--hw-text-2, var(--hw-text-muted));\n transition: background 0.15s, color 0.15s;\n}\n.hw-header-menu-btn:hover {\n background: var(--hw-bg-hover);\n color: var(--hw-text);\n}\n.hw-header-menu {\n position: absolute;\n top: 36px;\n right: 0;\n z-index: 6;\n min-width: 236px;\n max-width: 288px;\n padding: 5px;\n border-radius: 14px;\n background: var(--hw-bg);\n color: var(--hw-text);\n box-shadow: 0 0 0 1px var(--hw-border), 0 12px 32px -10px rgba(0, 0, 0, 0.32);\n animation: hw-menu-in 0.16s cubic-bezier(0.2, 0.8, 0.2, 1) both;\n}\n@keyframes hw-menu-in {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n.hw-header-menu button {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n border-radius: 9px;\n cursor: pointer;\n background: transparent;\n color: var(--hw-text);\n font: inherit;\n font-size: 13px;\n text-align: left;\n transition: background 0.14s;\n}\n.hw-header-menu button:hover {\n background: var(--hw-bg-hover);\n}\n.hw-header-menu button svg {\n flex: none;\n color: var(--hw-text-3, var(--hw-text-muted));\n}\n.hw-header-menu button:hover svg {\n color: var(--hw-brand, var(--hw-primary));\n}\n.hw-header-menu-convs {\n display: flex;\n flex-direction: column;\n max-height: 168px;\n overflow-y: auto;\n padding-bottom: 5px;\n margin-bottom: 5px;\n border-bottom: 1px solid var(--hw-border);\n}\n.hw-header-menu button.hw-header-menu-conv {\n flex-direction: column;\n align-items: stretch;\n gap: 2px;\n padding: 8px 10px;\n}\n.hw-header-menu button.hw-header-menu-conv[data-active=true] {\n background: var(--hw-bg-hover);\n}\n.hw-header-menu-conv-top {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n}\n.hw-header-menu-conv-name {\n overflow: hidden;\n font-size: 12.5px;\n font-weight: 600;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.hw-header-menu-conv-time {\n flex: none;\n font-size: 11px;\n color: var(--hw-text-3, var(--hw-text-muted));\n}\n.hw-header-menu-conv-preview {\n overflow: hidden;\n font-size: 12px;\n color: var(--hw-text-2);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.hw-offers {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 10px;\n}\n.hw-offer {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px;\n border: 0;\n border-radius: 999px;\n cursor: pointer;\n background: var(--hw-bg-hover);\n color: var(--hw-text);\n font: inherit;\n font-size: 12.5px;\n font-weight: 550;\n transition: background 0.15s, color 0.15s;\n}\n.hw-offer:hover {\n background: var(--hw-brand, var(--hw-primary));\n color: var(--hw-on-brand, #fff);\n}\n.hw-offer svg {\n flex: none;\n}\n.hw-sources {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-top: 8px;\n}\n.hw-source {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 10px;\n border-radius: 9px;\n background: transparent;\n color: var(--hw-text);\n text-decoration: none;\n transition: background 0.15s;\n}\na.hw-source {\n cursor: pointer;\n}\na.hw-source:hover {\n background: var(--hw-bg-hover);\n}\n.hw-source-n {\n display: grid;\n place-items: center;\n flex: none;\n width: 16px;\n height: 16px;\n border-radius: 4px;\n background: var(--hw-brand, var(--hw-primary));\n color: var(--hw-on-brand, #fff);\n font-size: 10px;\n font-weight: 700;\n font-variant-numeric: tabular-nums;\n}\n.hw-source-title {\n flex: 1;\n min-width: 0;\n font-size: 12px;\n font-weight: 550;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n');
|
|
6944
|
+
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: #fafaf9;\n --hw-bg-hover: #f5f5f4;\n --hw-border: #ebe9e5;\n --hw-border-md: #e5e5e5;\n --hw-text: #1c1b19;\n --hw-text-1: #111;\n --hw-text-2: #666;\n --hw-text-3: #8a847c;\n --hw-text-4: #a8a29a;\n --hw-radius: 20px;\n --hw-visitor-bubble-bg: #f5f5f4;\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: 14px 12px 14px 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: 0;\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: 32px;\n height: 32px;\n flex-shrink: 0;\n color: var(--hw-text);\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 9px;\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: 15px;\n font-weight: 600;\n line-height: 1.3;\n}\n.hw-header-status {\n font-size: 11px;\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: 0;\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: 0;\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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 14px 8px;\n background: var(--hw-bg-subtle);\n display: flex;\n flex-direction: column;\n gap: 14px;\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: 16px;\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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: var(--hw-border);\n color: var(--hw-text-3);\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-2);\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-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-dots {\n display: flex;\n gap: 3px;\n padding: 6px 2px;\n width: fit-content;\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 gap: 0;\n border: 1px solid var(--hw-border, 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: var(--hw-bg-hover, rgba(0, 0, 0, 0.02));\n}\n.hw-link-preview-img {\n width: 100%;\n height: 56px;\n flex: 0 0 56px;\n object-fit: cover;\n object-position: top;\n border-radius: 0;\n}\n.hw-link-preview-body {\n padding: 8px 10px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n justify-content: center;\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: 12.5px;\n font-weight: 600;\n line-height: 1.3;\n color: var(--hw-text, #1a1a1a);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.hw-link-preview-desc {\n font-size: 11.5px;\n line-height: 1.4;\n color: var(--hw-text-2, #6b7280);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.hw-link-preview-url {\n font-size: 11px;\n color: var(--hw-text-2);\n}\n.hw-msg-links {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-width: 240px;\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 max-width: min(100%, 340px);\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: none;\n box-shadow: none;\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-title {\n font-size: 14px;\n font-weight: 550;\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-row {\n max-width: 300px;\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 9px;\n padding: 3px 3px 3px 12px;\n border-radius: 999px;\n border: 1px solid var(--hw-border, rgba(0,0,0,0.1));\n background: var(--hw-bg-subtle, #fafafa);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n.hw-email-card-row:focus-within {\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 {\n flex: 1;\n min-width: 0;\n padding: 6px 0;\n border: 0;\n background: transparent;\n color: var(--hw-text, #1a1a1a);\n font: inherit;\n font-size: 13px;\n outline: none;\n}\n.hw-email-card-input::placeholder {\n color: var(--hw-text-3, #999);\n}\n.hw-email-card-row:has(.hw-email-card-input--error) {\n border-color: #ef4444;\n}\n.hw-email-card-submit {\n flex: none;\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 50%;\n background: var(--hw-brand, #0a0a0a);\n color: var(--hw-on-brand, #fff);\n cursor: pointer;\n transition: opacity 0.15s, transform 0.15s;\n}\n.hw-email-card-submit:hover:not(:disabled) {\n transform: scale(1.06);\n}\n.hw-email-card-submit:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.hw-email-card--success {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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: 2147483001;\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-avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\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 padding: 0 14px 14px;\n margin-top: 0;\n}\n.hw-awaiting {\n margin-top: 2px;\n padding-left: 44px;\n font-size: 11px;\n line-height: 1.4;\n color: var(--hw-text-3, var(--hw-text-muted));\n}\n.hw-preview-dock {\n position: absolute;\n bottom: calc(100% + 12px);\n right: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 8px;\n pointer-events: none;\n}\n.hw-preview-dock > .hw-preview,\n.hw-preview-dock > .hw-preview-stack {\n position: relative;\n bottom: auto;\n right: auto;\n pointer-events: auto;\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-more {\n align-self: flex-end;\n padding: 4px 10px;\n border: 0;\n border-radius: 999px;\n background: var(--hw-bg);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), inset 0 0 0 1px var(--hw-border);\n color: var(--hw-text-2);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n transition: background 0.12s, color 0.12s;\n}\n.hw-preview-more:hover {\n background: var(--hw-bg-hover);\n color: var(--hw-text);\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: 0;\n box-shadow: inset 0 0 0 1px var(--hw-border);\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.hw-markdown ol {\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-table-wrap {\n margin: 10px 0;\n overflow-x: auto;\n border: 1px solid var(--hw-border, rgba(0, 0, 0, 0.08));\n border-radius: 10px;\n}\n.hw-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n.hw-table th {\n text-align: left;\n font-weight: 600;\n font-size: 12px;\n padding: 8px 12px;\n background: var(--hw-bg-hover, #f5f5f4);\n border-bottom: 1px solid var(--hw-border, rgba(0, 0, 0, 0.08));\n}\n.hw-table td {\n padding: 8px 12px;\n border-bottom: 1px solid var(--hw-border, rgba(0, 0, 0, 0.06));\n vertical-align: top;\n}\n.hw-table tbody tr:last-child td {\n border-bottom: none;\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: 7px;\n padding: 7px 14px;\n background: var(--hw-bg-hover);\n color: var(--hw-text-2);\n font-size: 11.5px;\n font-weight: 500;\n letter-spacing: -0.01em;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n flex-shrink: 0;\n animation: hw-disconnect-in 0.18s cubic-bezier(0.22, 1, 0.36, 1);\n}\n@keyframes hw-disconnect-in {\n from {\n opacity: 0;\n transform: translateY(-100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.hw-disconnect-spinner {\n width: 9px;\n height: 9px;\n border: 1.5px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n opacity: 0.75;\n flex-shrink: 0;\n animation: hw-spin 0.7s linear infinite;\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-disconnect {\n animation: none;\n }\n .hw-disconnect-spinner {\n animation: none;\n border-top-color: currentColor;\n opacity: 0.5;\n }\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: inherit;\n text-decoration: underline;\n text-decoration-thickness: 1px;\n text-underline-offset: 2px;\n text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);\n word-break: normal;\n overflow-wrap: anywhere;\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-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.hw-widget[data-hw-placement=docked] {\n --hw-dock-width: 600px;\n --hw-dock-bar-width: 480px;\n --hw-dock-inset: 24px;\n --hw-bar-max-height: 148px;\n --hw-dock-surface: #ffffff;\n --hw-dock-on-surface: #111111;\n --hw-dock-pill-bg: rgba(44, 44, 48, 0.66);\n --hw-dock-pill-fg: rgba(255, 255, 255, 0.94);\n --hw-dock-pill-border: rgba(255, 255, 255, 0.14);\n}\n.hw-widget[data-hw-placement=docked] {\n z-index: 2147483000;\n}\n.hw-widget[data-hw-placement=docked] .hw-dock {\n position: fixed;\n left: 0;\n right: 0;\n bottom: var(--hw-dock-inset);\n z-index: 2147483000;\n display: flex;\n flex-direction: column;\n align-items: center;\n pointer-events: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-dock > * {\n pointer-events: auto;\n}\n.hw-dock-suggestions {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 9px;\n width: var(--hw-dock-bar-width, var(--hw-dock-width));\n max-width: calc(100vw - 32px);\n margin-bottom: 14px;\n}\n.hw-dock-pill-row {\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n animation: hw-dock-pill-in 0.42s cubic-bezier(0.2, 0.9, 0.3, 1) both;\n}\n.hw-dock-pill-dismiss {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n padding: 0;\n border: 0;\n background: none;\n color: var(--hw-dock-pill-fg);\n cursor: pointer;\n align-self: flex-start;\n margin-top: 8px;\n opacity: 0;\n transform: scale(0.85);\n transition:\n opacity 0.12s linear,\n transform 0.12s cubic-bezier(0.25, 1, 0.5, 1),\n color 0.12s linear;\n}\n.hw-dock-pill-dismiss svg {\n width: 11px;\n height: 11px;\n}\n.hw-dock-suggestions:hover .hw-dock-pill-dismiss,\n.hw-dock-suggestions:focus-within .hw-dock-pill-dismiss {\n opacity: 1;\n transform: none;\n}\n.hw-dock-pill-dismiss:hover {\n color: var(--hw-dock-on-surface);\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-dock-pill-dismiss {\n transition: none;\n }\n}\n@media (hover: none) {\n .hw-dock-pill-dismiss {\n opacity: 1;\n transform: none;\n }\n}\n.hw-dock-pill {\n align-self: flex-start;\n padding: 10px 18px;\n border: 1px solid var(--hw-dock-pill-border, transparent);\n border-radius: 999px;\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n font-weight: 500;\n text-align: left;\n background: var(--hw-dock-pill-bg);\n color: var(--hw-dock-pill-fg);\n backdrop-filter: blur(10px) saturate(1.2);\n -webkit-backdrop-filter: blur(10px) saturate(1.2);\n box-shadow: 0 4px 14px -8px rgba(12, 11, 10, 0.28);\n transition:\n background 0.16s,\n border-color 0.16s,\n transform 0.16s;\n}\n.hw-dock-pill {\n backdrop-filter: blur(18px);\n -webkit-backdrop-filter: blur(18px);\n}\n.hw-dock-pill:hover {\n background: color-mix(in srgb, var(--hw-dock-pill-bg) 100%, var(--hw-dock-on-surface) 8%);\n border-color: color-mix(in srgb, var(--hw-dock-pill-border) 100%, var(--hw-dock-on-surface) 10%);\n transform: translateX(3px);\n}\n@keyframes hw-dock-pill-in {\n from {\n opacity: 0;\n transform: translateY(10px) scale(0.97);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n.hw-dock-bar {\n display: flex;\n align-items: flex-end;\n gap: 10px;\n width: var(--hw-dock-bar-width, var(--hw-dock-width));\n max-width: calc(100vw - 32px);\n min-height: 52px;\n padding: 10px 10px 10px 18px;\n border: 0;\n border-radius: 26px;\n background: var(--hw-dock-surface);\n color: var(--hw-dock-on-surface);\n box-shadow:\n inset 0 1px 0 color-mix(in srgb, var(--hw-dock-on-surface) 9%, transparent),\n 0 0 0 1px color-mix(in srgb, var(--hw-dock-on-surface) 7%, transparent),\n 0 2px 6px rgba(12, 11, 10, 0.18),\n 0 20px 48px -14px rgba(12, 11, 10, 0.45);\n transition:\n border-radius 0.18s ease,\n box-shadow 0.2s cubic-bezier(0.2, 0.8, 0.2, 1),\n width 0.26s cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.hw-dock-bar:focus-within {\n box-shadow:\n inset 0 1px 0 color-mix(in srgb, var(--hw-dock-on-surface) 9%, transparent),\n 0 0 0 1px color-mix(in srgb, var(--hw-primary, #fb923c) 60%, transparent),\n 0 2px 6px rgba(12, 11, 10, 0.18),\n 0 20px 48px -14px rgba(12, 11, 10, 0.45);\n}\n.hw-dock-bar[data-grown=true] {\n border-radius: 20px;\n}\n.hw-dock-input {\n flex: 1;\n min-width: 0;\n min-height: 20px;\n max-height: var(--hw-bar-max-height);\n padding: 6px 0;\n border: 0;\n outline: none;\n resize: none;\n overflow-y: auto;\n background: transparent;\n color: var(--hw-dock-on-surface);\n font: inherit;\n font-size: 14px;\n line-height: 1.45;\n transition: height 0.12s ease;\n}\n.hw-dock-input::placeholder {\n color: color-mix(in srgb, var(--hw-dock-on-surface) 45%, transparent);\n}\n.hw-dock-send {\n flex: none;\n width: 32px;\n height: 32px;\n margin-bottom: 1px;\n border: 0;\n border-radius: 50%;\n display: grid;\n place-items: center;\n cursor: pointer;\n background: var(--hw-primary, #fb923c);\n color: var(--hw-on-brand, #fff);\n transition: transform 0.16s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.16s;\n}\n.hw-dock-send:hover:not(:disabled) {\n transform: scale(1.06);\n}\n.hw-dock-send:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.hw-widget[data-hw-placement=docked] .hw-window {\n position: fixed;\n left: 50%;\n right: auto;\n margin-left: calc(var(--hw-dock-width) / -2);\n bottom: calc(var(--hw-dock-inset) + 66px);\n width: var(--hw-dock-width);\n max-width: calc(100vw - 32px);\n height: 420px;\n}\n@media (max-width: 640px) {\n .hw-widget[data-hw-placement=docked] .hw-window {\n left: 16px;\n right: 16px;\n margin-left: 0;\n width: auto;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-bubble {\n display: none;\n}\n.hw-widget[data-hw-placement=docked][data-hw-open=true] .hw-window {\n bottom: calc(var(--hw-dock-inset) + 52px + 12px);\n}\n.hw-widget[data-hw-placement=docked][data-hw-open=true] .hw-dock-suggestions {\n display: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-dock-pill,\n .hw-dock-bar,\n .hw-dock-input,\n .hw-dock-send {\n animation: none;\n transition: none;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-composer,\n.hw-widget[data-hw-placement=docked] .hw-tabs,\n.hw-widget[data-hw-placement=docked] .hw-footer-tabs {\n display: none;\n}\n.hw-starters {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n border-radius: 14px;\n overflow: hidden;\n background: var(--hw-bg);\n box-shadow: inset 0 0 0 1px var(--hw-border);\n}\n.hw-starter {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 11px 14px;\n border: 0;\n border-radius: 0;\n cursor: pointer;\n background: transparent;\n color: var(--hw-text);\n font: inherit;\n text-align: left;\n animation: hw-starter-in 0.3s cubic-bezier(0.2, 0.8, 0.2, 1) both;\n transition: background 0.12s;\n}\n.hw-starter + .hw-starter {\n box-shadow: inset 0 1px 0 var(--hw-border);\n}\n.hw-starter:hover {\n background: var(--hw-bg-hover);\n}\n.hw-starter-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n.hw-starter-k {\n font-size: 13px;\n font-weight: 550;\n line-height: 1.35;\n color: var(--hw-text);\n}\n.hw-starter-q {\n font-size: 12px;\n line-height: 1.35;\n color: var(--hw-text-3, var(--hw-text-muted));\n}\n.hw-starter svg {\n flex: none;\n color: var(--hw-text-3, var(--hw-text-muted));\n opacity: 0.45;\n transition: opacity 0.15s, transform 0.15s;\n}\n.hw-starter:hover svg {\n opacity: 0.9;\n transform: translateX(2px);\n}\n@keyframes hw-starter-in {\n from {\n opacity: 0;\n transform: translateY(6px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-header-back {\n display: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-starter {\n animation: none;\n }\n}\n@media (prefers-color-scheme: dark) {\n .hw-widget:not([data-theme=light])[data-hw-placement=docked] {\n --hw-dock-surface: #1f1f23;\n --hw-dock-on-surface: #f4f4f6;\n --hw-dock-pill-bg: rgba(255, 255, 255, 0.1);\n --hw-dock-pill-fg: #e4e4e7;\n --hw-dock-pill-border: rgba(255, 255, 255, 0.14);\n }\n}\n.hw-widget[data-theme=dark][data-hw-placement=docked] {\n --hw-dock-surface: #1f1f23;\n --hw-dock-on-surface: #f4f4f6;\n}\n.hw-widget[data-hw-placement=docked] .hw-window {\n --hw-bg: rgba(255, 255, 255, 0.08);\n --hw-bg-subtle: transparent;\n --hw-bg-hover: rgba(255, 255, 255, 0.1);\n --hw-border: rgba(255, 255, 255, 0.14);\n --hw-border-md: rgba(255, 255, 255, 0.22);\n --hw-text: rgba(255, 255, 255, 0.94);\n --hw-text-1: #ffffff;\n --hw-text-2: rgba(255, 255, 255, 0.72);\n --hw-text-3: rgba(255, 255, 255, 0.62);\n --hw-text-4: rgba(255, 255, 255, 0.46);\n --hw-visitor-bubble-bg: rgba(255, 255, 255, 0.16);\n --hw-visitor-bubble-text: #ffffff;\n --hw-brand: rgba(255, 255, 255, 0.92);\n --hw-on-brand: #17161a;\n --hw-focus-border: rgba(255, 255, 255, 0.34);\n --hw-focus-ring: rgba(255, 255, 255, 0.1);\n height: 500px;\n max-height: calc(100vh - 180px);\n border-radius: 24px;\n color: var(--hw-text);\n background:\n linear-gradient(\n 180deg,\n rgba(40, 40, 44, 0.72) 0%,\n rgba(46, 46, 50, 0.7) 55%,\n rgba(52, 52, 56, 0.68) 100%);\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n box-shadow: 0 24px 60px -20px rgba(12, 11, 10, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.1);\n}\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n .hw-widget[data-hw-placement=docked] .hw-window {\n background: #2c2c2e;\n }\n}\n@media (max-width: 640px) {\n .hw-widget[data-hw-placement=docked] .hw-window {\n height: min(60vh, 460px);\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-header--sub {\n padding: 14px 12px 8px 16px;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-status {\n display: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-name {\n font-size: 15.5px;\n font-weight: 560;\n letter-spacing: -0.006em;\n color: var(--hw-text-1);\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu-conv-name,\n.hw-widget[data-hw-placement=docked] .hw-event-name {\n font-weight: 545;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-bot-icon {\n border-radius: 50%;\n overflow: hidden;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-close:hover,\n.hw-widget[data-hw-placement=docked] .hw-header-menu-btn:hover {\n background: rgba(255, 255, 255, 0.12);\n color: #ffffff;\n}\n.hw-widget[data-hw-placement=docked] .hw-messages {\n padding: 4px 22px 16px;\n gap: 18px;\n -webkit-mask-image:\n linear-gradient(\n 180deg,\n transparent 0,\n #000 16px);\n mask-image:\n linear-gradient(\n 180deg,\n transparent 0,\n #000 16px);\n}\n.hw-widget[data-hw-placement=docked] .hw-msg--ai .hw-msg-bubble,\n.hw-widget[data-hw-placement=docked] .hw-msg--team .hw-msg-bubble {\n padding: 0;\n background: transparent;\n border-radius: 0;\n font-size: 15px;\n line-height: 1.55;\n color: var(--hw-text);\n}\n.hw-widget[data-hw-placement=docked] .hw-msg--visitor .hw-msg-bubble {\n background: rgba(255, 255, 255, 0.16);\n color: #ffffff;\n font-size: 14.5px;\n line-height: 1.5;\n}\n.hw-widget[data-hw-placement=docked] .hw-msg-bubble pre,\n.hw-widget[data-hw-placement=docked] .hw-msg-bubble code {\n background: rgba(0, 0, 0, 0.28);\n color: var(--hw-text-1);\n}\n.hw-widget[data-hw-placement=docked] .hw-email-card-row {\n background: rgba(0, 0, 0, 0.26);\n border-color: rgba(255, 255, 255, 0.14);\n}\n.hw-widget[data-hw-placement=docked] .hw-window :focus-visible {\n outline-color: rgba(255, 255, 255, 0.55);\n}\n.hw-widget[data-hw-placement=docked] .hw-email-card-input:focus,\n.hw-widget[data-hw-placement=docked] .hw-email-card-input:focus-visible {\n outline: none;\n box-shadow: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-email-card-row:focus-within {\n border-color: rgba(255, 255, 255, 0.42);\n box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.08);\n}\n.hw-widget[data-hw-placement=docked] .hw-email-card-submit {\n background: #ffffff;\n color: #17161a;\n}\n.hw-widget[data-hw-placement=docked] .hw-window .hw-header--sub {\n position: relative;\n z-index: 3;\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu {\n background: #3a3a3f;\n box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.16), 0 18px 44px -12px rgba(12, 11, 10, 0.62);\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu button:hover {\n background: rgba(255, 255, 255, 0.11);\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu button.hw-header-menu-conv[data-active=true] {\n background: rgba(255, 255, 255, 0.09);\n}\n.hw-widget[data-hw-placement=docked] .hw-header-menu-convs {\n border-bottom-color: rgba(255, 255, 255, 0.12);\n}\n.hw-widget[data-hw-placement=docked] .hw-event--card {\n margin: 0;\n background: rgba(255, 255, 255, 0.08);\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);\n}\n.hw-widget[data-hw-placement=docked] .hw-event-avatar {\n background: rgba(255, 255, 255, 0.14);\n color: var(--hw-text-1);\n}\n.hw-widget[data-hw-placement=docked] .hw-preview {\n position: fixed;\n left: 50%;\n right: auto;\n margin-left: calc(var(--hw-dock-bar-width, var(--hw-dock-width)) / -2);\n bottom: calc(var(--hw-dock-inset) + 52px + 12px);\n width: var(--hw-dock-bar-width, var(--hw-dock-width));\n max-width: calc(100vw - 32px);\n border: 0;\n border-radius: 24px;\n color: rgba(255, 255, 255, 0.94);\n background:\n linear-gradient(\n 180deg,\n rgba(40, 40, 44, 0.74) 0%,\n rgba(52, 52, 56, 0.7) 100%);\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n box-shadow: 0 24px 60px -20px rgba(12, 11, 10, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.1);\n}\n.hw-widget[data-hw-placement=docked] .hw-preview-name,\n.hw-widget[data-hw-placement=docked] .hw-preview-body {\n color: rgba(255, 255, 255, 0.94);\n}\n.hw-widget[data-hw-placement=docked] .hw-preview-close {\n color: rgba(255, 255, 255, 0.6);\n}\n.hw-widget[data-hw-placement=docked] .hw-preview-close:hover {\n background: rgba(255, 255, 255, 0.12);\n color: #ffffff;\n}\n.hw-widget[data-hw-placement=docked] .hw-preview-footer {\n color: rgba(255, 255, 255, 0.55);\n border-top-color: rgba(255, 255, 255, 0.1);\n}\n@media (max-width: 640px) {\n .hw-widget[data-hw-placement=docked] .hw-preview {\n left: 16px;\n right: 16px;\n margin-left: 0;\n width: auto;\n }\n}\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n .hw-widget[data-hw-placement=docked] .hw-preview {\n background: #2c2c2e;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-quick-reply-btn {\n padding: 7px 14px;\n font-size: 13px;\n font-weight: 550;\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.94);\n box-shadow: 0 1px 3px rgba(12, 11, 10, 0.22);\n color: #17161a;\n}\n.hw-widget[data-hw-placement=docked] .hw-quick-reply-btn:hover:not(:disabled) {\n background: #ffffff;\n box-shadow: 0 4px 12px rgba(12, 11, 10, 0.28);\n transform: translateY(-1px);\n}\n.hw-widget[data-hw-placement=docked] .hw-quick-reply-btn[data-tapped=true] {\n background: rgba(255, 255, 255, 0.22);\n color: #ffffff;\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);\n transform: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-quick-reply-btn svg {\n opacity: 0.55;\n}\n.hw-widget[data-hw-placement=docked] .hw-offer {\n padding: 7px 14px;\n font-size: 13px;\n background: rgba(255, 255, 255, 0.94);\n color: #17161a;\n box-shadow: 0 1px 3px rgba(12, 11, 10, 0.22);\n transition:\n background 0.15s,\n box-shadow 0.15s,\n transform 0.15s;\n}\n.hw-widget[data-hw-placement=docked] .hw-offer:hover {\n background: #ffffff;\n color: #17161a;\n box-shadow: 0 4px 12px rgba(12, 11, 10, 0.28);\n transform: translateY(-1px);\n}\n.hw-widget[data-hw-placement=docked] .hw-offer svg {\n opacity: 0.55;\n}\n.hw-widget[data-hw-placement=docked] .hw-dock-bar {\n --hw-dock-on-surface: rgba(255, 255, 255, 0.94);\n color: rgba(255, 255, 255, 0.94);\n background:\n linear-gradient(\n 180deg,\n rgba(44, 44, 48, 0.74) 0%,\n rgba(52, 52, 56, 0.72) 100%);\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12), 0 18px 40px -16px rgba(12, 11, 10, 0.45);\n}\n.hw-widget[data-hw-placement=docked][data-hw-open=true] .hw-dock-bar {\n width: var(--hw-dock-width);\n}\n.hw-widget[data-hw-placement=docked] .hw-dock-bar:focus-within {\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.26), 0 18px 40px -16px rgba(12, 11, 10, 0.5);\n}\n.hw-widget[data-hw-placement=docked][data-hw-open=true] .hw-dock-bar {\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14), 0 22px 52px -18px rgba(12, 11, 10, 0.52);\n}\n.hw-widget[data-hw-placement=docked] .hw-dock-send:not(:disabled) {\n background: #ffffff;\n color: #17161a;\n}\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n .hw-widget[data-hw-placement=docked] .hw-dock-bar {\n background: #2c2c2e;\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-window {\n transform-origin: 50% 100%;\n animation: hw-dock-panel-in 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n}\n.hw-widget[data-hw-placement=docked] .hw-window--closing {\n animation: hw-dock-panel-out 0.18s cubic-bezier(0.4, 0, 1, 1) forwards;\n}\n@keyframes hw-dock-panel-in {\n from {\n opacity: 0;\n transform: translateY(14px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n@keyframes hw-dock-panel-out {\n from {\n opacity: 1;\n transform: none;\n }\n to {\n opacity: 0;\n transform: translateY(8px) scale(0.99);\n }\n}\n.hw-widget[data-hw-placement=docked] .hw-window .hw-header--sub {\n animation: hw-dock-settle 0.32s cubic-bezier(0.16, 1, 0.3, 1) 0.06s both;\n}\n.hw-widget[data-hw-placement=docked] .hw-window .hw-messages {\n animation: hw-dock-settle 0.34s cubic-bezier(0.16, 1, 0.3, 1) 0.11s both;\n}\n.hw-widget[data-hw-placement=docked] .hw-window--closing .hw-header--sub,\n.hw-widget[data-hw-placement=docked] .hw-window--closing .hw-messages {\n animation: none;\n}\n@keyframes hw-dock-settle {\n from {\n opacity: 0;\n transform: translateY(7px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-widget[data-hw-placement=docked] .hw-window,\n .hw-widget[data-hw-placement=docked] .hw-window--closing,\n .hw-widget[data-hw-placement=docked] .hw-window .hw-header--sub,\n .hw-widget[data-hw-placement=docked] .hw-window .hw-messages {\n animation: none;\n }\n}\n.hw-dock-bar {\n flex-wrap: wrap;\n padding-left: 18px;\n padding-right: 8px;\n}\n.hw-dock-error {\n width: var(--hw-dock-width);\n max-width: calc(100vw - 32px);\n margin-bottom: 8px;\n padding: 8px 14px;\n border-radius: 14px;\n background: rgba(190, 24, 40, 0.92);\n color: #ffffff;\n font-size: 12.5px;\n line-height: 1.35;\n box-shadow: 0 10px 26px -12px rgba(12, 11, 10, 0.5);\n animation: hw-dock-settle 0.22s cubic-bezier(0.16, 1, 0.3, 1) both;\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-dock-error {\n animation: none;\n }\n}\n.hw-dock-previews {\n flex: 0 0 100%;\n order: -1;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n padding: 2px 0 8px;\n}\n.hw-dock-actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: 2px;\n margin-bottom: 1px;\n}\n.hw-dock-tool {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border: 0;\n border-radius: 50%;\n background: transparent;\n color: color-mix(in srgb, var(--hw-dock-on-surface) 52%, transparent);\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n}\n.hw-dock-tool:hover:not(:disabled) {\n background: color-mix(in srgb, var(--hw-dock-on-surface) 8%, transparent);\n color: var(--hw-dock-on-surface);\n}\n.hw-dock-tool:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.hw-dock-tool[data-active=true] {\n color: #e11d48;\n background: rgba(225, 29, 72, 0.12);\n animation: hw-dock-listening 1.4s ease-in-out infinite;\n}\n@keyframes hw-dock-listening {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(225, 29, 72, 0.35);\n }\n 50% {\n box-shadow: 0 0 0 4px rgba(225, 29, 72, 0);\n }\n}\n.hw-dock-send:disabled {\n opacity: 1;\n background: color-mix(in srgb, var(--hw-dock-on-surface) 9%, transparent);\n color: color-mix(in srgb, var(--hw-dock-on-surface) 38%, transparent);\n}\n@media (prefers-reduced-motion: reduce) {\n .hw-dock-tool[data-active=true] {\n animation: none;\n }\n .hw-dock-bar {\n transition: none;\n }\n}\n.hw-dock-input:focus,\n.hw-dock-input:focus-visible {\n outline: none;\n box-shadow: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-powered {\n display: none;\n}\n.hw-widget[data-hw-placement=docked] .hw-disconnect {\n border-radius: 20px 20px 0 0;\n}\n.hw-msg-meta {\n display: flex;\n align-items: center;\n gap: 5px;\n}\n.hw-msg-author {\n font-weight: 550;\n}\n.hw-msg-meta-sep {\n opacity: 0.55;\n}\n.hw-header-actions {\n position: relative;\n display: flex;\n align-items: center;\n gap: 2px;\n}\n.hw-header-menu-btn {\n display: grid;\n place-items: center;\n width: 30px;\n height: 30px;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n background: transparent;\n color: var(--hw-text-2, var(--hw-text-muted));\n transition: background 0.15s, color 0.15s;\n}\n.hw-header-menu-btn:hover {\n background: var(--hw-bg-hover);\n color: var(--hw-text);\n}\n.hw-header-menu {\n position: absolute;\n top: 36px;\n right: 0;\n z-index: 6;\n min-width: 236px;\n max-width: 288px;\n padding: 5px;\n border-radius: 14px;\n background: var(--hw-bg);\n color: var(--hw-text);\n box-shadow: 0 0 0 1px var(--hw-border), 0 12px 32px -10px rgba(0, 0, 0, 0.32);\n animation: hw-menu-in 0.16s cubic-bezier(0.2, 0.8, 0.2, 1) both;\n}\n@keyframes hw-menu-in {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n.hw-header-menu button {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n border-radius: 9px;\n cursor: pointer;\n background: transparent;\n color: var(--hw-text);\n font: inherit;\n font-size: 13px;\n text-align: left;\n transition: background 0.14s;\n}\n.hw-header-menu button:hover {\n background: var(--hw-bg-hover);\n}\n.hw-header-menu button svg {\n flex: none;\n color: var(--hw-text-3, var(--hw-text-muted));\n}\n.hw-header-menu button:hover svg {\n color: var(--hw-brand, var(--hw-primary));\n}\n.hw-header-menu-convs {\n display: flex;\n flex-direction: column;\n max-height: 168px;\n overflow-y: auto;\n padding-bottom: 5px;\n margin-bottom: 5px;\n border-bottom: 1px solid var(--hw-border);\n}\n.hw-header-menu button.hw-header-menu-conv {\n flex-direction: column;\n align-items: stretch;\n gap: 2px;\n padding: 8px 10px;\n}\n.hw-header-menu button.hw-header-menu-conv[data-active=true] {\n background: var(--hw-bg-hover);\n}\n.hw-header-menu-conv-top {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n}\n.hw-header-menu-conv-name {\n overflow: hidden;\n font-size: 12.5px;\n font-weight: 600;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.hw-header-menu-conv-time {\n flex: none;\n font-size: 11px;\n color: var(--hw-text-3, var(--hw-text-muted));\n}\n.hw-header-menu-conv-preview {\n overflow: hidden;\n font-size: 12px;\n color: var(--hw-text-2);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.hw-offers {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 10px;\n}\n.hw-offer {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px;\n border: 0;\n border-radius: 999px;\n cursor: pointer;\n background: var(--hw-bg-hover);\n color: var(--hw-text);\n font: inherit;\n font-size: 12.5px;\n font-weight: 550;\n transition: background 0.15s, color 0.15s;\n}\n.hw-offer:hover {\n background: var(--hw-brand, var(--hw-primary));\n color: var(--hw-on-brand, #fff);\n}\n.hw-offer svg {\n flex: none;\n}\n.hw-sources {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-top: 8px;\n}\n.hw-source {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 10px;\n border-radius: 9px;\n background: transparent;\n color: var(--hw-text);\n text-decoration: none;\n transition: background 0.15s;\n}\na.hw-source {\n cursor: pointer;\n}\na.hw-source:hover {\n background: var(--hw-bg-hover);\n}\n.hw-source-n {\n display: grid;\n place-items: center;\n flex: none;\n width: 16px;\n height: 16px;\n border-radius: 4px;\n background: var(--hw-brand, var(--hw-primary));\n color: var(--hw-on-brand, #fff);\n font-size: 10px;\n font-weight: 700;\n font-variant-numeric: tabular-nums;\n}\n.hw-source-title {\n flex: 1;\n min-width: 0;\n font-size: 12px;\n font-weight: 550;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n');
|
|
6622
6945
|
|
|
6623
6946
|
// src/helpway-widget.tsx
|
|
6624
6947
|
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
@@ -6670,12 +6993,16 @@ function HelpwayWidget({
|
|
|
6670
6993
|
}
|
|
6671
6994
|
|
|
6672
6995
|
// src/hooks/use-realtime.ts
|
|
6673
|
-
import { useEffect as useEffect16 } from "react";
|
|
6996
|
+
import { useEffect as useEffect16, useRef as useRef16 } from "react";
|
|
6674
6997
|
function useRealtime(handler) {
|
|
6675
6998
|
const { ws } = useWidgetContext();
|
|
6999
|
+
const handlerRef = useRef16(handler);
|
|
7000
|
+
useEffect16(() => {
|
|
7001
|
+
handlerRef.current = handler;
|
|
7002
|
+
});
|
|
6676
7003
|
useEffect16(() => {
|
|
6677
|
-
return ws.onEvent(
|
|
6678
|
-
}, [ws
|
|
7004
|
+
return ws.onEvent((event) => handlerRef.current(event));
|
|
7005
|
+
}, [ws]);
|
|
6679
7006
|
}
|
|
6680
7007
|
export {
|
|
6681
7008
|
AnnouncementPreviews,
|
|
@@ -6695,6 +7022,7 @@ export {
|
|
|
6695
7022
|
getOrCreateVisitorId,
|
|
6696
7023
|
linkifyText,
|
|
6697
7024
|
renderMarkdown,
|
|
7025
|
+
useAwaitingReply,
|
|
6698
7026
|
useComposer,
|
|
6699
7027
|
useConversations,
|
|
6700
7028
|
useIdentify,
|