@helpway/react 0.15.3 → 0.17.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 +73 -7
- package/dist/index.js +1190 -874
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/themed/styles.css +110 -7
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.17.0".length > 0 ? "0.17.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,75 +514,375 @@ 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
|
-
|
|
527
|
-
|
|
528
|
-
const
|
|
529
|
-
const
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
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 {
|
|
534
734
|
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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,
|
|
551
886
|
view: "home",
|
|
552
887
|
incomingPreview: loadPersistedPreview(),
|
|
553
888
|
announcementPreviews: [],
|
|
@@ -929,6 +1264,9 @@ function createWidgetStore() {
|
|
|
929
1264
|
const isIncoming = !event.item.visitorId;
|
|
930
1265
|
const currentState = get();
|
|
931
1266
|
const isViewingThis = currentState.isOpen && currentState.activeConversationId === event.conversationId;
|
|
1267
|
+
const qr = previewQuickReplies(
|
|
1268
|
+
event.item.metadata
|
|
1269
|
+
);
|
|
932
1270
|
set((s) => ({
|
|
933
1271
|
conversations: s.conversations.map(
|
|
934
1272
|
(c) => c.id === event.conversationId ? {
|
|
@@ -942,11 +1280,18 @@ function createWidgetStore() {
|
|
|
942
1280
|
// Show preview bubble if widget is closed and message is incoming
|
|
943
1281
|
...isIncoming && !currentState.isOpen ? {
|
|
944
1282
|
incomingPreview: {
|
|
945
|
-
|
|
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 ?? "",
|
|
946
1290
|
conversationId: event.conversationId,
|
|
947
1291
|
timestamp: Date.now(),
|
|
948
1292
|
senderName: event.item.userName ?? null,
|
|
949
|
-
senderImage: event.item.userImage ?? null
|
|
1293
|
+
senderImage: event.item.userImage ?? null,
|
|
1294
|
+
...qr ? { quickReplies: qr } : {}
|
|
950
1295
|
}
|
|
951
1296
|
} : {}
|
|
952
1297
|
}));
|
|
@@ -1150,296 +1495,125 @@ function applyTheme(host, theme) {
|
|
|
1150
1495
|
setVar(host, "--hw-position-right", "auto");
|
|
1151
1496
|
setVar(host, "--hw-position-left", "20px");
|
|
1152
1497
|
setVar(host, "--hw-window-right", "auto");
|
|
1153
|
-
setVar(host, "--hw-window-left", "0");
|
|
1154
|
-
} else if (theme.position === "bottom-right") {
|
|
1155
|
-
host.style.removeProperty("--hw-position-right");
|
|
1156
|
-
host.style.removeProperty("--hw-position-left");
|
|
1157
|
-
host.style.removeProperty("--hw-window-right");
|
|
1158
|
-
host.style.removeProperty("--hw-window-left");
|
|
1159
|
-
}
|
|
1160
|
-
if (theme.placement) host.dataset.hwPlacement = theme.placement;
|
|
1161
|
-
if (theme.colorScheme === "light" || theme.colorScheme === "dark") {
|
|
1162
|
-
host.dataset.theme = theme.colorScheme;
|
|
1163
|
-
} else if (theme.colorScheme === "system") {
|
|
1164
|
-
delete host.dataset.theme;
|
|
1165
|
-
}
|
|
1166
|
-
if (theme.cssVariables) {
|
|
1167
|
-
for (const [key, value] of Object.entries(theme.cssVariables)) {
|
|
1168
|
-
if (key.startsWith("--")) host.style.setProperty(key, value);
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
// ../widget-core/src/events.ts
|
|
1174
|
-
var WidgetEventEmitter = class {
|
|
1175
|
-
listeners = /* @__PURE__ */ new Map();
|
|
1176
|
-
on(event, fn) {
|
|
1177
|
-
if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
1178
|
-
this.listeners.get(event).add(fn);
|
|
1179
|
-
}
|
|
1180
|
-
off(event, fn) {
|
|
1181
|
-
this.listeners.get(event)?.delete(fn);
|
|
1182
|
-
}
|
|
1183
|
-
emit(event, ...args) {
|
|
1184
|
-
const data = args[0];
|
|
1185
|
-
this.listeners.get(event)?.forEach((fn) => {
|
|
1186
|
-
try {
|
|
1187
|
-
fn(data);
|
|
1188
|
-
} catch (err) {
|
|
1189
|
-
console.error(`[Helpway] Event handler error (${event}):`, err);
|
|
1190
|
-
}
|
|
1191
|
-
});
|
|
1192
|
-
}
|
|
1193
|
-
removeAll() {
|
|
1194
|
-
this.listeners.clear();
|
|
1195
|
-
}
|
|
1196
|
-
};
|
|
1197
|
-
|
|
1198
|
-
// ../widget-core/src/i18n.ts
|
|
1199
|
-
var en = {
|
|
1200
|
-
// Navigation & tabs
|
|
1201
|
-
"widget.home": "Home",
|
|
1202
|
-
"widget.messages": "Messages",
|
|
1203
|
-
"widget.help": "Help",
|
|
1204
|
-
// Home screen
|
|
1205
|
-
"widget.send_us_message": "Send us a message",
|
|
1206
|
-
"widget.reply_time": "We typically reply in a few minutes",
|
|
1207
|
-
"widget.recent_conversations": "Recent conversations",
|
|
1208
|
-
"widget.see_all": "See all conversations",
|
|
1209
|
-
"widget.whats_new": "What's New",
|
|
1210
|
-
"widget.view_all": "View all",
|
|
1211
|
-
// Messages tab
|
|
1212
|
-
"widget.no_messages": "No messages yet",
|
|
1213
|
-
"widget.no_messages_desc": "Start a conversation to get help",
|
|
1214
|
-
"widget.start_conversation": "Start a conversation",
|
|
1215
|
-
"widget.no_preview": "No messages yet",
|
|
1216
|
-
// Conversation
|
|
1217
|
-
"widget.new_conversation": "New conversation",
|
|
1218
|
-
"widget.talk_to_human": "Talk to a human",
|
|
1219
|
-
"widget.talk_to_human_message": "I'd like to talk to a human, please.",
|
|
1220
|
-
"widget.aria_options": "Conversation options",
|
|
1221
|
-
"widget.resolved_text": "This conversation has been resolved",
|
|
1222
|
-
"widget.send_followup": "Send a follow-up",
|
|
1223
|
-
"widget.start_a_conversation": "Start a conversation",
|
|
1224
|
-
// Composer
|
|
1225
|
-
"widget.placeholder": "Send a message...",
|
|
1226
|
-
"widget.placeholder_new": "How can we help?",
|
|
1227
|
-
"widget.drop_files": "Drop files here",
|
|
1228
|
-
// CSAT
|
|
1229
|
-
"widget.csat_label": "How was your experience?",
|
|
1230
|
-
"widget.csat_thanks": "Thanks for your feedback!",
|
|
1231
|
-
// Inline email collection (after AI reply)
|
|
1232
|
-
"widget.email_title": "Don't miss our reply",
|
|
1233
|
-
"widget.email_subtitle": "We'll email you when we respond",
|
|
1234
|
-
"widget.email_placeholder": "you@email.com",
|
|
1235
|
-
"widget.email_continue": "Send",
|
|
1236
|
-
"widget.email_saved": "You'll be notified by email",
|
|
1237
|
-
"widget.email_dismiss": "No thanks",
|
|
1238
|
-
// Errors
|
|
1239
|
-
"widget.error_title": "Something went wrong",
|
|
1240
|
-
"widget.error_desc": "Failed to load. Please try again.",
|
|
1241
|
-
"widget.retry": "Retry",
|
|
1242
|
-
"widget.reconnecting": "Reconnecting...",
|
|
1243
|
-
"widget.send_error": "Message not sent",
|
|
1244
|
-
// Date separators (today is implicit — never rendered)
|
|
1245
|
-
"widget.yesterday": "Yesterday",
|
|
1246
|
-
// Sender labels
|
|
1247
|
-
"widget.helpway_ai": "Helpway AI",
|
|
1248
|
-
"widget.support": "Support",
|
|
1249
|
-
// Events
|
|
1250
|
-
"widget.joined": "joined the conversation",
|
|
1251
|
-
"widget.left": "left the conversation",
|
|
1252
|
-
// Content/search
|
|
1253
|
-
"widget.content": "Content",
|
|
1254
|
-
"widget.search": "Search...",
|
|
1255
|
-
"widget.no_results": "No results found",
|
|
1256
|
-
"widget.try_different": "Try a different search term",
|
|
1257
|
-
"widget.nothing_yet": "Nothing here yet",
|
|
1258
|
-
"widget.check_back": "Check back later for updates",
|
|
1259
|
-
"widget.load_more": "Load more",
|
|
1260
|
-
"widget.loading": "Loading...",
|
|
1261
|
-
// Copy
|
|
1262
|
-
"widget.copy": "Copy message",
|
|
1263
|
-
"widget.copied": "Copied",
|
|
1264
|
-
// File upload
|
|
1265
|
-
"widget.file_too_large": "File too large (max 10 MB)",
|
|
1266
|
-
"widget.click_to_open": "Click to open",
|
|
1267
|
-
"widget.caption_required": "Add a message to send with your attachment",
|
|
1268
|
-
// Accessibility
|
|
1269
|
-
"widget.aria_chat": "Support chat",
|
|
1270
|
-
"widget.aria_close": "Close",
|
|
1271
|
-
"widget.aria_back": "Back",
|
|
1272
|
-
"widget.aria_send": "Send message",
|
|
1273
|
-
"widget.aria_open_image": "Open image",
|
|
1274
|
-
"widget.aria_attach": "Attach file",
|
|
1275
|
-
"widget.aria_dictate": "Dictate message",
|
|
1276
|
-
"widget.aria_input": "Message input",
|
|
1277
|
-
"widget.aria_remove": "Remove",
|
|
1278
|
-
"widget.aria_dismiss": "Dismiss",
|
|
1279
|
-
"widget.aria_open": "Open support",
|
|
1280
|
-
"widget.aria_close_support": "Close support",
|
|
1281
|
-
"widget.aria_good": "Good",
|
|
1282
|
-
"widget.aria_bad": "Bad",
|
|
1283
|
-
"widget.aria_messages": "Messages",
|
|
1284
|
-
// Time (relative)
|
|
1285
|
-
"widget.time_now": "now",
|
|
1286
|
-
"widget.time_yesterday": "Yesterday",
|
|
1287
|
-
// Powered by
|
|
1288
|
-
"widget.powered_by": "Powered by",
|
|
1289
|
-
// Hero / home screen
|
|
1290
|
-
/* One line, not two. The second line was "How can we help?" — the exact string
|
|
1291
|
-
the composer's own placeholder shows, two inches below it. The input is what
|
|
1292
|
-
asks the question; the greeting only has to say hello. */
|
|
1293
|
-
"widget.welcome_message": "Hi there \u{1F44B}",
|
|
1294
|
-
"widget.subtitle_text": "Usually replies in minutes"
|
|
1295
|
-
};
|
|
1296
|
-
var currentLocale = "en";
|
|
1297
|
-
var translations = {};
|
|
1298
|
-
var isLoaded = false;
|
|
1299
|
-
var revision = 0;
|
|
1300
|
-
var listeners = [];
|
|
1301
|
-
function t(key, params) {
|
|
1302
|
-
const value = translations[key] ?? en[key] ?? key;
|
|
1303
|
-
if (!params) return value;
|
|
1304
|
-
return value.replace(/\{\{(\w+)\}\}/g, (_, k) => {
|
|
1305
|
-
return params[k]?.toString() ?? `{{${k}}}`;
|
|
1306
|
-
});
|
|
1307
|
-
}
|
|
1308
|
-
function getLocale() {
|
|
1309
|
-
return currentLocale;
|
|
1310
|
-
}
|
|
1311
|
-
function getI18nRevision() {
|
|
1312
|
-
return revision;
|
|
1313
|
-
}
|
|
1314
|
-
function onLocaleChange(fn) {
|
|
1315
|
-
listeners.push(fn);
|
|
1316
|
-
return () => {
|
|
1317
|
-
const idx = listeners.indexOf(fn);
|
|
1318
|
-
if (idx >= 0) listeners.splice(idx, 1);
|
|
1319
|
-
};
|
|
1320
|
-
}
|
|
1321
|
-
async function initI18n(options) {
|
|
1322
|
-
if (options?.cdnBase) {
|
|
1323
|
-
cdnBase = options.cdnBase;
|
|
1324
|
-
}
|
|
1325
|
-
const detected = options?.locale ?? (typeof navigator !== "undefined" ? navigator.language : "en");
|
|
1326
|
-
currentLocale = normalizeLocale(detected);
|
|
1327
|
-
if (currentLocale === "en") {
|
|
1328
|
-
isLoaded = true;
|
|
1329
|
-
notify();
|
|
1330
|
-
return;
|
|
1331
|
-
}
|
|
1332
|
-
try {
|
|
1333
|
-
const data = await fetchTranslations(currentLocale);
|
|
1334
|
-
if (data) {
|
|
1335
|
-
for (const [key, value] of Object.entries(data)) {
|
|
1336
|
-
if (typeof value === "string") {
|
|
1337
|
-
translations[`widget.${key}`] = value;
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
} catch (err) {
|
|
1342
|
-
console.warn(`[Helpway] Failed to fetch ${currentLocale} translations, using English`, err);
|
|
1343
|
-
}
|
|
1344
|
-
isLoaded = true;
|
|
1345
|
-
notify();
|
|
1346
|
-
}
|
|
1347
|
-
async function setLocale(locale) {
|
|
1348
|
-
const normalized = normalizeLocale(locale);
|
|
1349
|
-
if (normalized === currentLocale) return;
|
|
1350
|
-
currentLocale = normalized;
|
|
1351
|
-
translations = {};
|
|
1352
|
-
if (normalized === "en") {
|
|
1353
|
-
notify();
|
|
1354
|
-
return;
|
|
1355
|
-
}
|
|
1356
|
-
try {
|
|
1357
|
-
const data = await fetchTranslations(normalized);
|
|
1358
|
-
if (data) {
|
|
1359
|
-
for (const [key, value] of Object.entries(data)) {
|
|
1360
|
-
if (typeof value === "string") {
|
|
1361
|
-
translations[`widget.${key}`] = value;
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
} catch {
|
|
1366
|
-
}
|
|
1367
|
-
notify();
|
|
1368
|
-
}
|
|
1369
|
-
var cdnBase = "https://cdn.better-i18n.com/helpway/widget";
|
|
1370
|
-
async function fetchTranslations(locale) {
|
|
1371
|
-
const url = `${cdnBase}/${locale}/translations.json`;
|
|
1372
|
-
let res = await fetch(url);
|
|
1373
|
-
if (!res.ok && locale.includes("-")) {
|
|
1374
|
-
const base = locale.split("-")[0];
|
|
1375
|
-
res = await fetch(`${cdnBase}/${base}/translations.json`);
|
|
1376
|
-
}
|
|
1377
|
-
if (!res.ok) return null;
|
|
1378
|
-
const data = await res.json();
|
|
1379
|
-
const widgetNs = data.widget;
|
|
1380
|
-
if (widgetNs && typeof widgetNs === "object" && !Array.isArray(widgetNs)) {
|
|
1381
|
-
const result = {};
|
|
1382
|
-
for (const [k, v] of Object.entries(widgetNs)) {
|
|
1383
|
-
if (typeof v === "string") result[k] = v;
|
|
1384
|
-
}
|
|
1385
|
-
return result;
|
|
1386
|
-
}
|
|
1387
|
-
return null;
|
|
1388
|
-
}
|
|
1389
|
-
function normalizeLocale(input) {
|
|
1390
|
-
const regional = ["pt-br", "zh-cn", "zh-tw", "zh-hk"];
|
|
1391
|
-
const lower = input.toLowerCase().replace("_", "-");
|
|
1392
|
-
for (const r of regional) {
|
|
1393
|
-
if (lower.startsWith(r)) return r;
|
|
1394
|
-
}
|
|
1395
|
-
return lower.split("-")[0] ?? "en";
|
|
1396
|
-
}
|
|
1397
|
-
function notify() {
|
|
1398
|
-
revision++;
|
|
1399
|
-
for (const fn of listeners) {
|
|
1400
|
-
try {
|
|
1401
|
-
fn();
|
|
1402
|
-
} catch {
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
// ../widget-core/src/utils.ts
|
|
1408
|
-
function formatRelativeTime(date) {
|
|
1409
|
-
const now = Date.now();
|
|
1410
|
-
const then = typeof date === "string" ? new Date(date).getTime() : date.getTime();
|
|
1411
|
-
const diffMs = now - then;
|
|
1412
|
-
const diffMin = Math.floor(diffMs / 6e4);
|
|
1413
|
-
const diffHour = Math.floor(diffMs / 36e5);
|
|
1414
|
-
const diffDay = Math.floor(diffMs / 864e5);
|
|
1415
|
-
if (diffMin < 1) return t("widget.time_now");
|
|
1416
|
-
if (diffMin < 60) return `${diffMin}m`;
|
|
1417
|
-
if (diffHour < 24) return `${diffHour}h`;
|
|
1418
|
-
if (diffDay === 1) return t("widget.time_yesterday");
|
|
1419
|
-
if (diffDay < 7) return `${diffDay}d`;
|
|
1420
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
1421
|
-
return d.toLocaleDateString(getLocale(), { month: "short", day: "numeric" });
|
|
1422
|
-
}
|
|
1423
|
-
function formatTime(date) {
|
|
1424
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
1425
|
-
return d.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
|
|
1426
|
-
}
|
|
1427
|
-
function resolveLabel(label) {
|
|
1428
|
-
if (!label.startsWith("widget.")) return label;
|
|
1429
|
-
const resolved = t(label);
|
|
1430
|
-
if (resolved === label) {
|
|
1431
|
-
return label.replace("widget.", "").replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase());
|
|
1498
|
+
setVar(host, "--hw-window-left", "0");
|
|
1499
|
+
} else if (theme.position === "bottom-right") {
|
|
1500
|
+
host.style.removeProperty("--hw-position-right");
|
|
1501
|
+
host.style.removeProperty("--hw-position-left");
|
|
1502
|
+
host.style.removeProperty("--hw-window-right");
|
|
1503
|
+
host.style.removeProperty("--hw-window-left");
|
|
1504
|
+
}
|
|
1505
|
+
if (theme.placement) host.dataset.hwPlacement = theme.placement;
|
|
1506
|
+
if (theme.colorScheme === "light" || theme.colorScheme === "dark") {
|
|
1507
|
+
host.dataset.theme = theme.colorScheme;
|
|
1508
|
+
} else if (theme.colorScheme === "system") {
|
|
1509
|
+
delete host.dataset.theme;
|
|
1510
|
+
}
|
|
1511
|
+
if (theme.cssVariables) {
|
|
1512
|
+
for (const [key, value] of Object.entries(theme.cssVariables)) {
|
|
1513
|
+
if (key.startsWith("--")) host.style.setProperty(key, value);
|
|
1514
|
+
}
|
|
1432
1515
|
}
|
|
1433
|
-
return resolved;
|
|
1434
1516
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1517
|
+
|
|
1518
|
+
// ../widget-core/src/events.ts
|
|
1519
|
+
var WidgetEventEmitter = class {
|
|
1520
|
+
listeners = /* @__PURE__ */ new Map();
|
|
1521
|
+
on(event, fn) {
|
|
1522
|
+
if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
1523
|
+
this.listeners.get(event).add(fn);
|
|
1441
1524
|
}
|
|
1442
|
-
|
|
1525
|
+
off(event, fn) {
|
|
1526
|
+
this.listeners.get(event)?.delete(fn);
|
|
1527
|
+
}
|
|
1528
|
+
emit(event, ...args) {
|
|
1529
|
+
const data = args[0];
|
|
1530
|
+
this.listeners.get(event)?.forEach((fn) => {
|
|
1531
|
+
try {
|
|
1532
|
+
fn(data);
|
|
1533
|
+
} catch (err) {
|
|
1534
|
+
console.error(`[Helpway] Event handler error (${event}):`, err);
|
|
1535
|
+
}
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
removeAll() {
|
|
1539
|
+
this.listeners.clear();
|
|
1540
|
+
}
|
|
1541
|
+
};
|
|
1542
|
+
|
|
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;
|
|
1562
|
+
};
|
|
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;
|
|
1587
|
+
}
|
|
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 });
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
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();
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1443
1617
|
}
|
|
1444
1618
|
|
|
1445
1619
|
// src/provider.tsx
|
|
@@ -1491,6 +1665,8 @@ function SupportProvider({
|
|
|
1491
1665
|
const [hasBootstrapError, setHasBootstrapError] = useState(false);
|
|
1492
1666
|
const [wsDisconnected, setWsDisconnected] = useState(false);
|
|
1493
1667
|
const [bootstrapAttempt, setBootstrapAttempt] = useState(0);
|
|
1668
|
+
const sourceLocaleRef = useRef(locale);
|
|
1669
|
+
const getSourceLocale = useCallback(() => sourceLocaleRef.current, []);
|
|
1494
1670
|
if (!initRef.current) {
|
|
1495
1671
|
const resolvedApiUrl = apiUrl ?? inferApiUrl();
|
|
1496
1672
|
const client2 = createWidgetClient({
|
|
@@ -1518,6 +1694,7 @@ function SupportProvider({
|
|
|
1518
1694
|
const metaLocale = data.metadata?.locale;
|
|
1519
1695
|
if (typeof metaLocale === "string" && metaLocale.length > 0) {
|
|
1520
1696
|
setLocale(metaLocale);
|
|
1697
|
+
sourceLocaleRef.current = metaLocale;
|
|
1521
1698
|
}
|
|
1522
1699
|
} catch (err) {
|
|
1523
1700
|
console.error("[Helpway] identify failed:", err);
|
|
@@ -1545,7 +1722,7 @@ function SupportProvider({
|
|
|
1545
1722
|
store.getState().setReady(data.visitor, data.website, data.agentConfig);
|
|
1546
1723
|
setHasBootstrapError(false);
|
|
1547
1724
|
if (data.visitor?.id) {
|
|
1548
|
-
syncVisitorId(apiKey, data.visitor.id);
|
|
1725
|
+
syncVisitorId(apiKey, data.visitor.signedId ?? data.visitor.id);
|
|
1549
1726
|
}
|
|
1550
1727
|
const convData = await client.widget.listConversations.query();
|
|
1551
1728
|
if (cancelled) return;
|
|
@@ -1558,11 +1735,20 @@ function SupportProvider({
|
|
|
1558
1735
|
lastMessageSenderType: c.lastMessageSenderType,
|
|
1559
1736
|
lastMessageSenderName: c.lastMessageSenderName,
|
|
1560
1737
|
lastMessageSenderImage: c.lastMessageSenderImage,
|
|
1561
|
-
|
|
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
|
|
1562
1750
|
});
|
|
1563
|
-
store.getState().setConversations(
|
|
1564
|
-
convData.conversations.map(mapConversation)
|
|
1565
|
-
);
|
|
1751
|
+
store.getState().setConversations(convData.conversations.map(mapConversation));
|
|
1566
1752
|
if (data.website?.id && data.visitor?.id) {
|
|
1567
1753
|
ws.configure({ websiteId: data.website.id, visitorId: data.visitor.id });
|
|
1568
1754
|
ws.connect();
|
|
@@ -1601,27 +1787,19 @@ function SupportProvider({
|
|
|
1601
1787
|
} catch {
|
|
1602
1788
|
}
|
|
1603
1789
|
}
|
|
1604
|
-
|
|
1605
|
-
client.widget.updatePage.mutate({
|
|
1606
|
-
url: window.location.href,
|
|
1607
|
-
title: document.title || window.location.pathname
|
|
1608
|
-
}).catch(() => {
|
|
1609
|
-
});
|
|
1610
|
-
}
|
|
1790
|
+
pageTracker?.navigate();
|
|
1611
1791
|
if (initialConversationId && !cancelled) {
|
|
1612
1792
|
if (deepLinkToken) {
|
|
1613
1793
|
try {
|
|
1614
1794
|
const redeemed = await client.widget.redeemDeepLink.mutate({ token: deepLinkToken });
|
|
1615
1795
|
if (!cancelled && redeemed?.visitorId && redeemed.visitorId !== data.visitor?.id) {
|
|
1616
|
-
syncVisitorId(apiKey, redeemed.visitorId);
|
|
1796
|
+
syncVisitorId(apiKey, redeemed.signedVisitorId ?? redeemed.visitorId);
|
|
1617
1797
|
const freshData = await client.widget.bootstrap.query();
|
|
1618
1798
|
if (!cancelled) {
|
|
1619
1799
|
store.getState().setReady(freshData.visitor, freshData.website, freshData.agentConfig);
|
|
1620
1800
|
const freshConvs = await client.widget.listConversations.query();
|
|
1621
1801
|
if (!cancelled) {
|
|
1622
|
-
store.getState().setConversations(
|
|
1623
|
-
freshConvs.conversations.map(mapConversation)
|
|
1624
|
-
);
|
|
1802
|
+
store.getState().setConversations(freshConvs.conversations.map(mapConversation));
|
|
1625
1803
|
}
|
|
1626
1804
|
}
|
|
1627
1805
|
}
|
|
@@ -1643,19 +1821,29 @@ function SupportProvider({
|
|
|
1643
1821
|
}
|
|
1644
1822
|
}
|
|
1645
1823
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
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(() => {
|
|
1656
1840
|
});
|
|
1657
|
-
}
|
|
1841
|
+
}
|
|
1842
|
+
});
|
|
1843
|
+
const reportPage = () => {
|
|
1844
|
+
pageTracker?.navigate();
|
|
1658
1845
|
};
|
|
1846
|
+
bootstrap();
|
|
1659
1847
|
const origPush = window.history.pushState.bind(window.history);
|
|
1660
1848
|
const origReplace = window.history.replaceState.bind(window.history);
|
|
1661
1849
|
window.history.pushState = function patchedPush(...args) {
|
|
@@ -1710,7 +1898,7 @@ function SupportProvider({
|
|
|
1710
1898
|
unsub();
|
|
1711
1899
|
clearInterval(wsCheck);
|
|
1712
1900
|
if (markSeenTimer) clearTimeout(markSeenTimer);
|
|
1713
|
-
|
|
1901
|
+
pageTracker?.stop();
|
|
1714
1902
|
window.history.pushState = origPush;
|
|
1715
1903
|
window.history.replaceState = origReplace;
|
|
1716
1904
|
window.removeEventListener("popstate", reportPage);
|
|
@@ -1720,6 +1908,7 @@ function SupportProvider({
|
|
|
1720
1908
|
useEffect(() => {
|
|
1721
1909
|
if (locale != null) {
|
|
1722
1910
|
setLocale(locale);
|
|
1911
|
+
sourceLocaleRef.current = locale;
|
|
1723
1912
|
}
|
|
1724
1913
|
}, [locale]);
|
|
1725
1914
|
useEffect(() => {
|
|
@@ -1793,7 +1982,8 @@ function SupportProvider({
|
|
|
1793
1982
|
emitter,
|
|
1794
1983
|
hasBootstrapError,
|
|
1795
1984
|
wsDisconnected,
|
|
1796
|
-
retryBootstrap
|
|
1985
|
+
retryBootstrap,
|
|
1986
|
+
getSourceLocale
|
|
1797
1987
|
};
|
|
1798
1988
|
return /* @__PURE__ */ jsx(WidgetContext.Provider, { value: ctxValue, children });
|
|
1799
1989
|
}
|
|
@@ -1893,7 +2083,7 @@ function inferApiUrl() {
|
|
|
1893
2083
|
}
|
|
1894
2084
|
|
|
1895
2085
|
// src/themed/default-widget.tsx
|
|
1896
|
-
import { useCallback as useCallback13, useEffect as useEffect15, useRef as useRef15, useState as useState15 } from "react";
|
|
2086
|
+
import { createContext as createContext2, useCallback as useCallback13, useContext as useContext2, useEffect as useEffect15, useRef as useRef15, useState as useState15 } from "react";
|
|
1897
2087
|
|
|
1898
2088
|
// src/hooks/use-announcements.ts
|
|
1899
2089
|
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useRef as useRef2 } from "react";
|
|
@@ -2056,6 +2246,11 @@ function useAnnouncements() {
|
|
|
2056
2246
|
};
|
|
2057
2247
|
}
|
|
2058
2248
|
|
|
2249
|
+
// src/hooks/use-awaiting-reply.ts
|
|
2250
|
+
function useAwaitingReply() {
|
|
2251
|
+
return useWidgetStore((s) => awaitingReplyCount(s.conversations));
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2059
2254
|
// src/hooks/use-composer.ts
|
|
2060
2255
|
import { useCallback as useCallback3, useState as useState2 } from "react";
|
|
2061
2256
|
function currentPagePayload() {
|
|
@@ -2082,7 +2277,7 @@ var ACCEPTED_TYPES = [
|
|
|
2082
2277
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
2083
2278
|
].join(",");
|
|
2084
2279
|
function useComposer(boundConversationId) {
|
|
2085
|
-
const { client, ws, store } = useWidgetContext();
|
|
2280
|
+
const { client, ws, store, getSourceLocale } = useWidgetContext();
|
|
2086
2281
|
const conversationId = boundConversationId;
|
|
2087
2282
|
const [text, setText] = useState2("");
|
|
2088
2283
|
const [isSubmitting, setIsSubmitting] = useState2(false);
|
|
@@ -2207,12 +2402,14 @@ function useComposer(boundConversationId) {
|
|
|
2207
2402
|
} catch {
|
|
2208
2403
|
}
|
|
2209
2404
|
} else if (isTempConversation) {
|
|
2405
|
+
const sourceLocale = getSourceLocale();
|
|
2210
2406
|
const result = await client.widget.createConversation.mutate({
|
|
2211
2407
|
...hasText ? { text: trimmed } : {},
|
|
2212
2408
|
...hasAttachments ? { parts: readyParts } : {},
|
|
2213
2409
|
/* The first message is the one that most needs this — someone
|
|
2214
2410
|
lands on a page and immediately asks what it is. */
|
|
2215
|
-
...currentPagePayload()
|
|
2411
|
+
...currentPagePayload(),
|
|
2412
|
+
...sourceLocale ? { sourceLocale } : {}
|
|
2216
2413
|
});
|
|
2217
2414
|
const conv = result.conversation;
|
|
2218
2415
|
store.getState().remapConversationId(conversationId2, conv.id);
|
|
@@ -2250,7 +2447,7 @@ function useComposer(boundConversationId) {
|
|
|
2250
2447
|
setIsSubmitting(false);
|
|
2251
2448
|
}
|
|
2252
2449
|
},
|
|
2253
|
-
[text, attachments, boundConversationId, isSubmitting, client, ws, store]
|
|
2450
|
+
[text, attachments, boundConversationId, isSubmitting, client, ws, store, getSourceLocale]
|
|
2254
2451
|
);
|
|
2255
2452
|
const clearSendError = useCallback3(() => setSendError(null), []);
|
|
2256
2453
|
return {
|
|
@@ -2283,15 +2480,17 @@ function fileToBase64(file) {
|
|
|
2283
2480
|
// src/hooks/use-conversations.ts
|
|
2284
2481
|
import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
2285
2482
|
function useConversations() {
|
|
2286
|
-
const { client, store } = useWidgetContext();
|
|
2483
|
+
const { client, store, getSourceLocale } = useWidgetContext();
|
|
2287
2484
|
const conversations = useWidgetStore((s) => s.conversations);
|
|
2288
2485
|
const setActiveConversation = useWidgetStore((s) => s.setActiveConversation);
|
|
2289
2486
|
const [isCreating, setIsCreating] = useState3(false);
|
|
2290
2487
|
const clientRef = useRef3(client);
|
|
2291
2488
|
const storeRef = useRef3(store);
|
|
2489
|
+
const getSourceLocaleRef = useRef3(getSourceLocale);
|
|
2292
2490
|
useEffect3(() => {
|
|
2293
2491
|
clientRef.current = client;
|
|
2294
2492
|
storeRef.current = store;
|
|
2493
|
+
getSourceLocaleRef.current = getSourceLocale;
|
|
2295
2494
|
});
|
|
2296
2495
|
const create = useCallback4(async (text) => {
|
|
2297
2496
|
setIsCreating(true);
|
|
@@ -2331,7 +2530,11 @@ function useConversations() {
|
|
|
2331
2530
|
store2.setMessages(tempConversationId, [optimisticMsg]);
|
|
2332
2531
|
store2.setActiveConversation(tempConversationId);
|
|
2333
2532
|
try {
|
|
2334
|
-
const
|
|
2533
|
+
const sourceLocale = getSourceLocaleRef.current();
|
|
2534
|
+
const result = await clientRef.current.widget.createConversation.mutate({
|
|
2535
|
+
text,
|
|
2536
|
+
...sourceLocale ? { sourceLocale } : {}
|
|
2537
|
+
});
|
|
2335
2538
|
const conv = result.conversation;
|
|
2336
2539
|
storeRef.current.getState().remapConversationId(tempConversationId, conv.id);
|
|
2337
2540
|
if (result.item) {
|
|
@@ -2533,6 +2736,9 @@ function useWidget() {
|
|
|
2533
2736
|
return { isReady, isConnecting, visitor, website, agentConfig, identify };
|
|
2534
2737
|
}
|
|
2535
2738
|
|
|
2739
|
+
// src/shell/docked-bar.tsx
|
|
2740
|
+
import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef7, useState as useState7 } from "react";
|
|
2741
|
+
|
|
2536
2742
|
// src/themed/composer.tsx
|
|
2537
2743
|
import { useCallback as useCallback7, useRef as useRef6, useState as useState6 } from "react";
|
|
2538
2744
|
|
|
@@ -2966,274 +3172,27 @@ function PreviewThumb({ attachment: a, onRemove }) {
|
|
|
2966
3172
|
type: "button",
|
|
2967
3173
|
className: "hw-composer-preview-remove",
|
|
2968
3174
|
onClick: onRemove,
|
|
2969
|
-
"aria-label": t("widget.aria_remove"),
|
|
2970
|
-
children: /* @__PURE__ */ jsx3(XIcon, {})
|
|
2971
|
-
}
|
|
2972
|
-
)
|
|
2973
|
-
] });
|
|
2974
|
-
}
|
|
2975
|
-
function extractFiles(data) {
|
|
2976
|
-
const files = [];
|
|
2977
|
-
if (data.files) {
|
|
2978
|
-
for (let i = 0; i < data.files.length; i++) {
|
|
2979
|
-
const file = data.files[i];
|
|
2980
|
-
if (file) files.push(file);
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
|
-
return files;
|
|
2984
|
-
}
|
|
2985
|
-
|
|
2986
|
-
// src/themed/debug-overlay.tsx
|
|
2987
|
-
import { useEffect as useEffect6, useMemo as useMemo2, useRef as useRef7, useState as useState7 } from "react";
|
|
2988
|
-
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2989
|
-
var MAX_EVENTS = 60;
|
|
2990
|
-
function isDebugEnabled() {
|
|
2991
|
-
if (typeof window === "undefined") return false;
|
|
2992
|
-
if (typeof window.localStorage !== "undefined" && window.localStorage.getItem("hw:debug") === "1") {
|
|
2993
|
-
return true;
|
|
2994
|
-
}
|
|
2995
|
-
const search = window.location?.search ?? "";
|
|
2996
|
-
return search.includes("hwdebug=1") || search.includes("debug=hw");
|
|
2997
|
-
}
|
|
2998
|
-
function senderOf(item) {
|
|
2999
|
-
if (item.visitorId) return "visitor";
|
|
3000
|
-
if (item.aiAgentId) return "ai";
|
|
3001
|
-
if (item.userId) return "team";
|
|
3002
|
-
return item.type;
|
|
3003
|
-
}
|
|
3004
|
-
function WidgetDebugOverlay() {
|
|
3005
|
-
const [enabled, setEnabled] = useState7(false);
|
|
3006
|
-
const [open, setOpen] = useState7(true);
|
|
3007
|
-
const [events, setEvents] = useState7([]);
|
|
3008
|
-
const eventsRef = useRef7([]);
|
|
3009
|
-
const activeId = useWidgetStore((s) => s.activeConversationId);
|
|
3010
|
-
const messagesMap = useWidgetStore((s) => s.messages);
|
|
3011
|
-
const typingUsers = useWidgetStore((s) => s.typingUsers);
|
|
3012
|
-
const aiProcessingMap = useWidgetStore((s) => s.aiProcessing);
|
|
3013
|
-
const { store } = useWidgetContext();
|
|
3014
|
-
useEffect6(() => {
|
|
3015
|
-
setEnabled(isDebugEnabled());
|
|
3016
|
-
}, []);
|
|
3017
|
-
const pushEvent = useMemo2(
|
|
3018
|
-
() => (ev) => {
|
|
3019
|
-
const e = {
|
|
3020
|
-
...ev,
|
|
3021
|
-
id: `${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
3022
|
-
t: Date.now()
|
|
3023
|
-
};
|
|
3024
|
-
eventsRef.current = [e, ...eventsRef.current].slice(0, MAX_EVENTS);
|
|
3025
|
-
setEvents(eventsRef.current);
|
|
3026
|
-
},
|
|
3027
|
-
[]
|
|
3028
|
-
);
|
|
3029
|
-
useEffect6(() => {
|
|
3030
|
-
if (!enabled) return;
|
|
3031
|
-
if (typeof window === "undefined" || typeof window.fetch !== "function") return;
|
|
3032
|
-
const originalFetch = window.fetch.bind(window);
|
|
3033
|
-
const patched = (async (input, init) => {
|
|
3034
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
3035
|
-
const isTrpc = url.includes("/trpc/");
|
|
3036
|
-
if (isTrpc) {
|
|
3037
|
-
const method = init?.method ?? (typeof input !== "string" && !(input instanceof URL) ? input.method : "GET");
|
|
3038
|
-
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
3039
|
-
pushEvent({ kind: "trpc", label: `\u2192 ${method} ${label}`, detail: shortJson(init?.body) });
|
|
3040
|
-
}
|
|
3041
|
-
try {
|
|
3042
|
-
const res = await originalFetch(input, init);
|
|
3043
|
-
if (isTrpc) {
|
|
3044
|
-
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
3045
|
-
pushEvent({ kind: "trpc", label: `\u2190 ${res.status} ${label}` });
|
|
3046
|
-
}
|
|
3047
|
-
return res;
|
|
3048
|
-
} catch (err) {
|
|
3049
|
-
if (isTrpc) {
|
|
3050
|
-
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
3051
|
-
pushEvent({ kind: "error", label: `\u2718 ${label}`, detail: err instanceof Error ? err.message : String(err) });
|
|
3052
|
-
}
|
|
3053
|
-
throw err;
|
|
3054
|
-
}
|
|
3055
|
-
});
|
|
3056
|
-
window.fetch = patched;
|
|
3057
|
-
return () => {
|
|
3058
|
-
window.fetch = originalFetch;
|
|
3059
|
-
};
|
|
3060
|
-
}, [enabled, pushEvent]);
|
|
3061
|
-
useEffect6(() => {
|
|
3062
|
-
if (!enabled) return;
|
|
3063
|
-
const original = store.getState().handleRealtimeEvent;
|
|
3064
|
-
store.setState({
|
|
3065
|
-
handleRealtimeEvent: (ev) => {
|
|
3066
|
-
pushEvent({ kind: "ws", label: ev.type, detail: shortJson(ev) });
|
|
3067
|
-
original(ev);
|
|
3068
|
-
}
|
|
3069
|
-
});
|
|
3070
|
-
return () => {
|
|
3071
|
-
store.setState({ handleRealtimeEvent: original });
|
|
3072
|
-
};
|
|
3073
|
-
}, [enabled, store, pushEvent]);
|
|
3074
|
-
const activeMessages = activeId ? messagesMap.get(activeId) ?? [] : [];
|
|
3075
|
-
const lastMsgSignature = useMemo2(
|
|
3076
|
-
() => activeMessages.map((m) => `${m.id}:${senderOf(m)}:${m.createdAt}`).join("|"),
|
|
3077
|
-
[activeMessages]
|
|
3078
|
-
);
|
|
3079
|
-
const prevSigRef = useRef7(lastMsgSignature);
|
|
3080
|
-
useEffect6(() => {
|
|
3081
|
-
if (!enabled) return;
|
|
3082
|
-
if (prevSigRef.current !== lastMsgSignature) {
|
|
3083
|
-
prevSigRef.current = lastMsgSignature;
|
|
3084
|
-
pushEvent({
|
|
3085
|
-
kind: "store",
|
|
3086
|
-
label: `messages[${activeMessages.length}]`,
|
|
3087
|
-
detail: activeMessages.map((m, i) => `${i}:${senderOf(m)}=${(m.text ?? "").slice(0, 24)}`).join(" | ")
|
|
3088
|
-
});
|
|
3089
|
-
}
|
|
3090
|
-
}, [lastMsgSignature, activeMessages, enabled, pushEvent]);
|
|
3091
|
-
if (!enabled) return null;
|
|
3092
|
-
const isTyping = activeId ? typingUsers.get(activeId) : false;
|
|
3093
|
-
const isAi = activeId ? aiProcessingMap.get(activeId) : false;
|
|
3094
|
-
return /* @__PURE__ */ jsxs3("div", { style: styles.wrap, children: [
|
|
3095
|
-
/* @__PURE__ */ jsxs3("div", { style: styles.header, children: [
|
|
3096
|
-
/* @__PURE__ */ jsx4("strong", { children: "hw debug" }),
|
|
3097
|
-
/* @__PURE__ */ jsxs3("span", { style: styles.meta, children: [
|
|
3098
|
-
" ",
|
|
3099
|
-
"\xB7 conv ",
|
|
3100
|
-
activeId ? activeId.slice(0, 10) : "\u2014",
|
|
3101
|
-
" \xB7 items ",
|
|
3102
|
-
activeMessages.length,
|
|
3103
|
-
" \xB7 typing ",
|
|
3104
|
-
isTyping ? "Y" : "n",
|
|
3105
|
-
" \xB7 ai ",
|
|
3106
|
-
isAi ? "Y" : "n"
|
|
3107
|
-
] }),
|
|
3108
|
-
/* @__PURE__ */ jsx4("button", { type: "button", style: styles.btn, onClick: () => setOpen((v) => !v), children: open ? "hide" : "show" }),
|
|
3109
|
-
/* @__PURE__ */ jsx4("button", { type: "button", style: styles.btn, onClick: () => {
|
|
3110
|
-
eventsRef.current = [];
|
|
3111
|
-
setEvents([]);
|
|
3112
|
-
}, children: "clear" })
|
|
3113
|
-
] }),
|
|
3114
|
-
open && /* @__PURE__ */ jsxs3("div", { style: styles.body, children: [
|
|
3115
|
-
/* @__PURE__ */ jsxs3("div", { style: styles.section, children: [
|
|
3116
|
-
/* @__PURE__ */ jsx4("div", { style: styles.sectionTitle, children: "messages (active)" }),
|
|
3117
|
-
activeMessages.length === 0 ? /* @__PURE__ */ jsx4("div", { style: styles.empty, children: "empty" }) : activeMessages.map((m, i) => /* @__PURE__ */ jsxs3("div", { style: styles.row, children: [
|
|
3118
|
-
/* @__PURE__ */ jsx4("span", { style: { ...styles.badge, background: colorFor(senderOf(m)) }, children: i }),
|
|
3119
|
-
/* @__PURE__ */ jsx4("span", { style: styles.sender, children: senderOf(m) }),
|
|
3120
|
-
/* @__PURE__ */ jsx4("span", { style: styles.ts, children: m.createdAt.slice(11, 23) }),
|
|
3121
|
-
/* @__PURE__ */ jsx4("span", { style: styles.text, children: (m.text ?? "").slice(0, 60) })
|
|
3122
|
-
] }, m.id))
|
|
3123
|
-
] }),
|
|
3124
|
-
/* @__PURE__ */ jsxs3("div", { style: styles.section, children: [
|
|
3125
|
-
/* @__PURE__ */ jsx4("div", { style: styles.sectionTitle, children: "events" }),
|
|
3126
|
-
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: [
|
|
3127
|
-
/* @__PURE__ */ jsx4("span", { style: { ...styles.badge, background: kindColor(e.kind) }, children: e.kind }),
|
|
3128
|
-
/* @__PURE__ */ jsx4("span", { style: styles.ts, children: new Date(e.t).toISOString().slice(11, 23) }),
|
|
3129
|
-
/* @__PURE__ */ jsx4("span", { style: styles.evLabel, children: e.label }),
|
|
3130
|
-
e.detail && /* @__PURE__ */ jsx4("span", { style: styles.detail, children: e.detail })
|
|
3131
|
-
] }, e.id))
|
|
3132
|
-
] })
|
|
3133
|
-
] })
|
|
3134
|
-
] });
|
|
3135
|
-
}
|
|
3136
|
-
function shortJson(v) {
|
|
3137
|
-
if (v === void 0) return "";
|
|
3138
|
-
try {
|
|
3139
|
-
const s = JSON.stringify(v);
|
|
3140
|
-
if (!s) return "";
|
|
3141
|
-
return s.length > 180 ? `${s.slice(0, 177)}\u2026` : s;
|
|
3142
|
-
} catch {
|
|
3143
|
-
return String(v);
|
|
3144
|
-
}
|
|
3145
|
-
}
|
|
3146
|
-
function colorFor(sender) {
|
|
3147
|
-
switch (sender) {
|
|
3148
|
-
case "visitor":
|
|
3149
|
-
return "#1d4ed8";
|
|
3150
|
-
case "ai":
|
|
3151
|
-
return "#7c3aed";
|
|
3152
|
-
case "team":
|
|
3153
|
-
return "#16a34a";
|
|
3154
|
-
default:
|
|
3155
|
-
return "#6b7280";
|
|
3156
|
-
}
|
|
3157
|
-
}
|
|
3158
|
-
function kindColor(kind) {
|
|
3159
|
-
switch (kind) {
|
|
3160
|
-
case "trpc":
|
|
3161
|
-
return "#0ea5e9";
|
|
3162
|
-
case "ws":
|
|
3163
|
-
return "#f97316";
|
|
3164
|
-
case "store":
|
|
3165
|
-
return "#64748b";
|
|
3166
|
-
case "error":
|
|
3167
|
-
return "#dc2626";
|
|
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
|
+
}
|
|
3168
3188
|
}
|
|
3189
|
+
return files;
|
|
3169
3190
|
}
|
|
3170
|
-
var styles = {
|
|
3171
|
-
wrap: {
|
|
3172
|
-
position: "fixed",
|
|
3173
|
-
right: 12,
|
|
3174
|
-
bottom: 12,
|
|
3175
|
-
zIndex: 2147483e3,
|
|
3176
|
-
width: 420,
|
|
3177
|
-
maxHeight: "70vh",
|
|
3178
|
-
background: "rgba(9,9,11,0.94)",
|
|
3179
|
-
color: "#e5e7eb",
|
|
3180
|
-
borderRadius: 10,
|
|
3181
|
-
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
3182
|
-
fontSize: 11,
|
|
3183
|
-
boxShadow: "0 12px 30px rgba(0,0,0,0.35)",
|
|
3184
|
-
overflow: "hidden",
|
|
3185
|
-
pointerEvents: "auto"
|
|
3186
|
-
},
|
|
3187
|
-
header: {
|
|
3188
|
-
display: "flex",
|
|
3189
|
-
alignItems: "center",
|
|
3190
|
-
gap: 6,
|
|
3191
|
-
padding: "6px 10px",
|
|
3192
|
-
background: "#18181b",
|
|
3193
|
-
borderBottom: "1px solid #27272a"
|
|
3194
|
-
},
|
|
3195
|
-
meta: { flex: 1, color: "#a1a1aa", fontSize: 10 },
|
|
3196
|
-
btn: {
|
|
3197
|
-
background: "#27272a",
|
|
3198
|
-
color: "#e4e4e7",
|
|
3199
|
-
border: "1px solid #3f3f46",
|
|
3200
|
-
borderRadius: 4,
|
|
3201
|
-
padding: "2px 8px",
|
|
3202
|
-
cursor: "pointer",
|
|
3203
|
-
fontSize: 10
|
|
3204
|
-
},
|
|
3205
|
-
body: { display: "flex", flexDirection: "column", maxHeight: "calc(70vh - 32px)", overflow: "auto" },
|
|
3206
|
-
section: { borderBottom: "1px solid #27272a", padding: "6px 10px" },
|
|
3207
|
-
sectionTitle: { color: "#a1a1aa", fontSize: 10, textTransform: "uppercase", letterSpacing: 0.6, marginBottom: 4 },
|
|
3208
|
-
row: {
|
|
3209
|
-
display: "grid",
|
|
3210
|
-
gridTemplateColumns: "32px 56px 72px 1fr",
|
|
3211
|
-
gap: 6,
|
|
3212
|
-
alignItems: "baseline",
|
|
3213
|
-
padding: "2px 0",
|
|
3214
|
-
borderTop: "1px dashed #27272a"
|
|
3215
|
-
},
|
|
3216
|
-
badge: {
|
|
3217
|
-
display: "inline-block",
|
|
3218
|
-
borderRadius: 3,
|
|
3219
|
-
padding: "1px 4px",
|
|
3220
|
-
color: "white",
|
|
3221
|
-
fontSize: 9,
|
|
3222
|
-
textAlign: "center"
|
|
3223
|
-
},
|
|
3224
|
-
sender: { color: "#d4d4d8" },
|
|
3225
|
-
ts: { color: "#71717a", fontSize: 10 },
|
|
3226
|
-
text: { color: "#e4e4e7", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" },
|
|
3227
|
-
evLabel: { color: "#e4e4e7" },
|
|
3228
|
-
detail: { gridColumn: "1 / -1", color: "#a1a1aa", fontSize: 10, whiteSpace: "pre-wrap", wordBreak: "break-all" },
|
|
3229
|
-
empty: { color: "#52525b", fontStyle: "italic", fontSize: 10 }
|
|
3230
|
-
};
|
|
3231
3191
|
|
|
3232
3192
|
// src/shell/docked-bar.tsx
|
|
3233
|
-
import {
|
|
3234
|
-
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";
|
|
3235
3194
|
function useDismissableOffer(suggestions) {
|
|
3236
|
-
const [dismissedKey, setDismissedKey] =
|
|
3195
|
+
const [dismissedKey, setDismissedKey] = useState7(null);
|
|
3237
3196
|
const questions = (suggestions ?? []).map(
|
|
3238
3197
|
(entry) => typeof entry === "string" ? entry : entry.question
|
|
3239
3198
|
);
|
|
@@ -3249,14 +3208,14 @@ function recognitionCtor() {
|
|
|
3249
3208
|
return scope.SpeechRecognition ?? scope.webkitSpeechRecognition ?? null;
|
|
3250
3209
|
}
|
|
3251
3210
|
function useDictation(onText) {
|
|
3252
|
-
const [listening, setListening] =
|
|
3253
|
-
const recRef =
|
|
3254
|
-
const onTextRef =
|
|
3255
|
-
|
|
3211
|
+
const [listening, setListening] = useState7(false);
|
|
3212
|
+
const recRef = useRef7(null);
|
|
3213
|
+
const onTextRef = useRef7(onText);
|
|
3214
|
+
useEffect6(() => {
|
|
3256
3215
|
onTextRef.current = onText;
|
|
3257
3216
|
}, [onText]);
|
|
3258
|
-
const [supported] =
|
|
3259
|
-
|
|
3217
|
+
const [supported] = useState7(() => recognitionCtor() !== null);
|
|
3218
|
+
useEffect6(
|
|
3260
3219
|
() => () => {
|
|
3261
3220
|
recRef.current?.stop();
|
|
3262
3221
|
recRef.current = null;
|
|
@@ -3321,12 +3280,13 @@ function DockedBar({
|
|
|
3321
3280
|
onRemoveAttachment,
|
|
3322
3281
|
onReopen,
|
|
3323
3282
|
sendError,
|
|
3324
|
-
onClearSendError
|
|
3283
|
+
onClearSendError,
|
|
3284
|
+
leading
|
|
3325
3285
|
}) {
|
|
3326
|
-
const [focused, setFocused] =
|
|
3327
|
-
const inputRef =
|
|
3328
|
-
const boxRef =
|
|
3329
|
-
const fileInputRef =
|
|
3286
|
+
const [focused, setFocused] = useState7(false);
|
|
3287
|
+
const inputRef = useRef7(null);
|
|
3288
|
+
const boxRef = useRef7(null);
|
|
3289
|
+
const fileInputRef = useRef7(null);
|
|
3330
3290
|
const { questions: visibleQuestions, dismiss: dismissOffer } = useDismissableOffer(suggestions);
|
|
3331
3291
|
const dictation = useDictation((chunk) => {
|
|
3332
3292
|
const current = inputRef.current?.value ?? value;
|
|
@@ -3342,7 +3302,7 @@ function DockedBar({
|
|
|
3342
3302
|
el.style.height = `${next}px`;
|
|
3343
3303
|
box.dataset.grown = next > GROWN_AT ? "true" : "false";
|
|
3344
3304
|
}, []);
|
|
3345
|
-
|
|
3305
|
+
useEffect6(grow, [grow, value]);
|
|
3346
3306
|
const handleKeyDown = useCallback8(
|
|
3347
3307
|
(event) => {
|
|
3348
3308
|
if (event.key !== "Enter" || event.shiftKey) return;
|
|
@@ -3372,19 +3332,19 @@ function DockedBar({
|
|
|
3372
3332
|
const uploading = attachments?.some((a) => a.isUploading) ?? false;
|
|
3373
3333
|
const hasAttachment = attachments?.some((a) => a.part !== null) ?? false;
|
|
3374
3334
|
const canSend = (!!value.trim() || hasAttachment) && !uploading && !disabled;
|
|
3375
|
-
return /* @__PURE__ */
|
|
3376
|
-
showSuggestions && /* @__PURE__ */
|
|
3335
|
+
return /* @__PURE__ */ jsxs3("div", { className: "hw-dock", onFocus: () => setFocused(true), onBlur: onDockBlur, children: [
|
|
3336
|
+
showSuggestions && /* @__PURE__ */ jsx4("div", { className: "hw-dock-suggestions", children: visibleQuestions.map((question, index) => (
|
|
3377
3337
|
/* The pill stays a button and the dismiss is a sibling, not a nested
|
|
3378
3338
|
button — a button inside a button is invalid and the inner click
|
|
3379
3339
|
would still fire the outer one. Only the first row carries the ×,
|
|
3380
3340
|
since it closes the whole offer. */
|
|
3381
|
-
/* @__PURE__ */
|
|
3341
|
+
/* @__PURE__ */ jsxs3(
|
|
3382
3342
|
"span",
|
|
3383
3343
|
{
|
|
3384
3344
|
className: "hw-dock-pill-row",
|
|
3385
3345
|
style: { animationDelay: `${120 + index * 90}ms` },
|
|
3386
3346
|
children: [
|
|
3387
|
-
/* @__PURE__ */
|
|
3347
|
+
/* @__PURE__ */ jsx4(
|
|
3388
3348
|
"button",
|
|
3389
3349
|
{
|
|
3390
3350
|
type: "button",
|
|
@@ -3393,14 +3353,14 @@ function DockedBar({
|
|
|
3393
3353
|
children: question
|
|
3394
3354
|
}
|
|
3395
3355
|
),
|
|
3396
|
-
index === 0 && /* @__PURE__ */
|
|
3356
|
+
index === 0 && /* @__PURE__ */ jsx4(
|
|
3397
3357
|
"button",
|
|
3398
3358
|
{
|
|
3399
3359
|
type: "button",
|
|
3400
3360
|
className: "hw-dock-pill-dismiss",
|
|
3401
3361
|
"aria-label": t("widget.aria_dismiss"),
|
|
3402
3362
|
onClick: dismissOffer,
|
|
3403
|
-
children: /* @__PURE__ */
|
|
3363
|
+
children: /* @__PURE__ */ jsx4(
|
|
3404
3364
|
"svg",
|
|
3405
3365
|
{
|
|
3406
3366
|
viewBox: "0 0 24 24",
|
|
@@ -3409,7 +3369,7 @@ function DockedBar({
|
|
|
3409
3369
|
strokeWidth: "2.5",
|
|
3410
3370
|
strokeLinecap: "round",
|
|
3411
3371
|
"aria-hidden": "true",
|
|
3412
|
-
children: /* @__PURE__ */
|
|
3372
|
+
children: /* @__PURE__ */ jsx4("path", { d: "M18 6 6 18M6 6l12 12" })
|
|
3413
3373
|
}
|
|
3414
3374
|
)
|
|
3415
3375
|
}
|
|
@@ -3419,8 +3379,8 @@ function DockedBar({
|
|
|
3419
3379
|
question
|
|
3420
3380
|
)
|
|
3421
3381
|
)) }),
|
|
3422
|
-
sendError && /* @__PURE__ */
|
|
3423
|
-
/* @__PURE__ */
|
|
3382
|
+
sendError && /* @__PURE__ */ jsx4("div", { className: "hw-dock-error", role: "alert", children: sendError }),
|
|
3383
|
+
/* @__PURE__ */ jsxs3(
|
|
3424
3384
|
"div",
|
|
3425
3385
|
{
|
|
3426
3386
|
className: "hw-dock-bar",
|
|
@@ -3429,7 +3389,7 @@ function DockedBar({
|
|
|
3429
3389
|
onMouseDown: onReopen,
|
|
3430
3390
|
onTouchStart: onReopen,
|
|
3431
3391
|
children: [
|
|
3432
|
-
!!attachments?.length && /* @__PURE__ */
|
|
3392
|
+
!!attachments?.length && /* @__PURE__ */ jsx4("div", { className: "hw-dock-previews", children: attachments.map((a) => /* @__PURE__ */ jsx4(
|
|
3433
3393
|
PreviewThumb,
|
|
3434
3394
|
{
|
|
3435
3395
|
attachment: a,
|
|
@@ -3437,7 +3397,8 @@ function DockedBar({
|
|
|
3437
3397
|
},
|
|
3438
3398
|
a.id
|
|
3439
3399
|
)) }),
|
|
3440
|
-
/* @__PURE__ */
|
|
3400
|
+
leading && /* @__PURE__ */ jsx4("span", { className: "hw-dock-lead", "aria-hidden": "true", children: leading }),
|
|
3401
|
+
/* @__PURE__ */ jsx4(
|
|
3441
3402
|
"textarea",
|
|
3442
3403
|
{
|
|
3443
3404
|
ref: inputRef,
|
|
@@ -3455,8 +3416,8 @@ function DockedBar({
|
|
|
3455
3416
|
onPaste: handlePaste
|
|
3456
3417
|
}
|
|
3457
3418
|
),
|
|
3458
|
-
/* @__PURE__ */
|
|
3459
|
-
dictation.supported && /* @__PURE__ */
|
|
3419
|
+
/* @__PURE__ */ jsxs3("div", { className: "hw-dock-actions", children: [
|
|
3420
|
+
dictation.supported && /* @__PURE__ */ jsx4(
|
|
3460
3421
|
"button",
|
|
3461
3422
|
{
|
|
3462
3423
|
type: "button",
|
|
@@ -3466,11 +3427,11 @@ function DockedBar({
|
|
|
3466
3427
|
"aria-pressed": dictation.listening,
|
|
3467
3428
|
disabled,
|
|
3468
3429
|
onClick: dictation.toggle,
|
|
3469
|
-
children: /* @__PURE__ */
|
|
3430
|
+
children: /* @__PURE__ */ jsx4(MicGlyph, {})
|
|
3470
3431
|
}
|
|
3471
3432
|
),
|
|
3472
|
-
onAddFiles && /* @__PURE__ */
|
|
3473
|
-
/* @__PURE__ */
|
|
3433
|
+
onAddFiles && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
3434
|
+
/* @__PURE__ */ jsx4(
|
|
3474
3435
|
"button",
|
|
3475
3436
|
{
|
|
3476
3437
|
type: "button",
|
|
@@ -3478,10 +3439,10 @@ function DockedBar({
|
|
|
3478
3439
|
"aria-label": t("widget.aria_attach"),
|
|
3479
3440
|
disabled,
|
|
3480
3441
|
onClick: () => fileInputRef.current?.click(),
|
|
3481
|
-
children: /* @__PURE__ */
|
|
3442
|
+
children: /* @__PURE__ */ jsx4(PaperclipIcon, { size: 17 })
|
|
3482
3443
|
}
|
|
3483
3444
|
),
|
|
3484
|
-
/* @__PURE__ */
|
|
3445
|
+
/* @__PURE__ */ jsx4(
|
|
3485
3446
|
"input",
|
|
3486
3447
|
{
|
|
3487
3448
|
ref: fileInputRef,
|
|
@@ -3497,7 +3458,7 @@ function DockedBar({
|
|
|
3497
3458
|
}
|
|
3498
3459
|
)
|
|
3499
3460
|
] }),
|
|
3500
|
-
/* @__PURE__ */
|
|
3461
|
+
/* @__PURE__ */ jsx4(
|
|
3501
3462
|
"button",
|
|
3502
3463
|
{
|
|
3503
3464
|
type: "button",
|
|
@@ -3505,7 +3466,7 @@ function DockedBar({
|
|
|
3505
3466
|
"aria-label": t("widget.aria_send"),
|
|
3506
3467
|
disabled: !canSend,
|
|
3507
3468
|
onClick: onSubmit,
|
|
3508
|
-
children: /* @__PURE__ */
|
|
3469
|
+
children: /* @__PURE__ */ jsx4(ArrowUpIcon, { size: 16 })
|
|
3509
3470
|
}
|
|
3510
3471
|
)
|
|
3511
3472
|
] })
|
|
@@ -3515,7 +3476,7 @@ function DockedBar({
|
|
|
3515
3476
|
] });
|
|
3516
3477
|
}
|
|
3517
3478
|
function MicGlyph() {
|
|
3518
|
-
return /* @__PURE__ */
|
|
3479
|
+
return /* @__PURE__ */ jsxs3(
|
|
3519
3480
|
"svg",
|
|
3520
3481
|
{
|
|
3521
3482
|
width: "17",
|
|
@@ -3528,19 +3489,121 @@ function MicGlyph() {
|
|
|
3528
3489
|
strokeLinejoin: "round",
|
|
3529
3490
|
"aria-hidden": "true",
|
|
3530
3491
|
children: [
|
|
3531
|
-
/* @__PURE__ */
|
|
3532
|
-
/* @__PURE__ */
|
|
3533
|
-
/* @__PURE__ */
|
|
3492
|
+
/* @__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" }),
|
|
3493
|
+
/* @__PURE__ */ jsx4("path", { d: "M5.5 11v.5a6.5 6.5 0 0 0 13 0V11" }),
|
|
3494
|
+
/* @__PURE__ */ jsx4("path", { d: "M12 18v3" })
|
|
3495
|
+
]
|
|
3496
|
+
}
|
|
3497
|
+
);
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3500
|
+
// src/themed/announcement-previews.tsx
|
|
3501
|
+
import { useState as useState8 } from "react";
|
|
3502
|
+
|
|
3503
|
+
// src/themed/strip-markdown.ts
|
|
3504
|
+
function stripMarkdown(text) {
|
|
3505
|
+
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();
|
|
3506
|
+
}
|
|
3507
|
+
|
|
3508
|
+
// src/themed/announcement-previews.tsx
|
|
3509
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3510
|
+
function AnnouncementPreviews({
|
|
3511
|
+
onOpen,
|
|
3512
|
+
avatar,
|
|
3513
|
+
placement = "launcher",
|
|
3514
|
+
footer,
|
|
3515
|
+
maxVisible = Number.POSITIVE_INFINITY
|
|
3516
|
+
}) {
|
|
3517
|
+
const previews = useWidgetStore((s) => s.announcementPreviews);
|
|
3518
|
+
const dismissPreview = useWidgetStore((s) => s.dismissAnnouncementPreview);
|
|
3519
|
+
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
3520
|
+
if (previews.length === 0) return null;
|
|
3521
|
+
const stackPlacementClass = placement === "anchored" ? "hw-preview-stack--anchored " : "";
|
|
3522
|
+
const { visible, hidden } = splitAnnouncementStack(previews, maxVisible);
|
|
3523
|
+
const next = hidden[0];
|
|
3524
|
+
return /* @__PURE__ */ jsxs4("div", { className: `hw-preview-stack ${stackPlacementClass}`.trim(), children: [
|
|
3525
|
+
visible.map((preview) => /* @__PURE__ */ jsx5(
|
|
3526
|
+
AnnouncementPreviewItem,
|
|
3527
|
+
{
|
|
3528
|
+
preview,
|
|
3529
|
+
agentName,
|
|
3530
|
+
avatar,
|
|
3531
|
+
placement,
|
|
3532
|
+
footer,
|
|
3533
|
+
onOpen,
|
|
3534
|
+
onDismiss: (slug) => dismissPreview(slug)
|
|
3535
|
+
},
|
|
3536
|
+
preview.slug
|
|
3537
|
+
)),
|
|
3538
|
+
next && /* @__PURE__ */ jsx5(
|
|
3539
|
+
"button",
|
|
3540
|
+
{
|
|
3541
|
+
type: "button",
|
|
3542
|
+
className: "hw-preview-more",
|
|
3543
|
+
onClick: () => onOpen(next.slug, next.tabId),
|
|
3544
|
+
children: hidden.length === 1 ? t("widget.more_announcements_one") : t("widget.more_announcements", { count: hidden.length })
|
|
3545
|
+
}
|
|
3546
|
+
)
|
|
3547
|
+
] });
|
|
3548
|
+
}
|
|
3549
|
+
function AnnouncementPreviewItem({
|
|
3550
|
+
preview,
|
|
3551
|
+
agentName,
|
|
3552
|
+
avatar,
|
|
3553
|
+
placement,
|
|
3554
|
+
footer,
|
|
3555
|
+
onOpen,
|
|
3556
|
+
onDismiss
|
|
3557
|
+
}) {
|
|
3558
|
+
const [closing, setClosing] = useState8(false);
|
|
3559
|
+
const handleClose = (e) => {
|
|
3560
|
+
e.stopPropagation();
|
|
3561
|
+
setClosing(true);
|
|
3562
|
+
setTimeout(() => {
|
|
3563
|
+
onDismiss(preview.slug);
|
|
3564
|
+
setClosing(false);
|
|
3565
|
+
}, 200);
|
|
3566
|
+
};
|
|
3567
|
+
const placementClass = placement === "anchored" ? "hw-preview--anchored " : "";
|
|
3568
|
+
return /* @__PURE__ */ jsxs4(
|
|
3569
|
+
"div",
|
|
3570
|
+
{
|
|
3571
|
+
className: `hw-preview hw-preview--announcement ${placementClass}${closing ? "hw-preview--closing" : ""}`.trim(),
|
|
3572
|
+
onClick: () => onOpen(preview.slug, preview.tabId),
|
|
3573
|
+
role: "button",
|
|
3574
|
+
tabIndex: 0,
|
|
3575
|
+
children: [
|
|
3576
|
+
/* @__PURE__ */ jsxs4("div", { className: "hw-preview-header", children: [
|
|
3577
|
+
/* @__PURE__ */ jsx5("div", { className: "hw-preview-avatar", children: avatar }),
|
|
3578
|
+
/* @__PURE__ */ jsx5("div", { className: "hw-preview-name", children: agentName }),
|
|
3579
|
+
/* @__PURE__ */ jsx5(
|
|
3580
|
+
"button",
|
|
3581
|
+
{
|
|
3582
|
+
type: "button",
|
|
3583
|
+
className: "hw-preview-close",
|
|
3584
|
+
onClick: handleClose,
|
|
3585
|
+
"aria-label": t("widget.aria_dismiss"),
|
|
3586
|
+
children: /* @__PURE__ */ jsx5(XIcon, { size: 20 })
|
|
3587
|
+
}
|
|
3588
|
+
)
|
|
3589
|
+
] }),
|
|
3590
|
+
/* @__PURE__ */ jsx5("div", { className: "hw-preview-body hw-preview-body--title", children: preview.title }),
|
|
3591
|
+
preview.body && (() => {
|
|
3592
|
+
const clean = stripMarkdown(preview.body);
|
|
3593
|
+
return /* @__PURE__ */ jsx5("div", { className: "hw-preview-body hw-preview-body--desc", children: truncatePreviewBody(clean) });
|
|
3594
|
+
})(),
|
|
3595
|
+
preview.badge && /* @__PURE__ */ jsx5("div", { className: "hw-announcement-badge", children: preview.badge }),
|
|
3596
|
+
footer != null && footer !== false && /* @__PURE__ */ jsx5("div", { className: "hw-preview-footer", children: footer })
|
|
3534
3597
|
]
|
|
3535
3598
|
}
|
|
3536
3599
|
);
|
|
3537
3600
|
}
|
|
3538
3601
|
|
|
3539
3602
|
// src/themed/content/content-tab-view.tsx
|
|
3540
|
-
import { useCallback as useCallback12, useEffect as
|
|
3603
|
+
import { useCallback as useCallback12, useEffect as useEffect10 } from "react";
|
|
3541
3604
|
|
|
3542
3605
|
// src/hooks/use-content-tab.ts
|
|
3543
|
-
import { useCallback as useCallback9, useEffect as
|
|
3606
|
+
import { useCallback as useCallback9, useEffect as useEffect7, useState as useState9 } from "react";
|
|
3544
3607
|
var EMPTY_TABS2 = [];
|
|
3545
3608
|
function listKey(tabId, lang) {
|
|
3546
3609
|
return `flat:${tabId}:${lang}:list`;
|
|
@@ -3655,7 +3718,7 @@ function useContentTab(tabId) {
|
|
|
3655
3718
|
const clearDetail = useCallback9(() => {
|
|
3656
3719
|
setDetail(null);
|
|
3657
3720
|
}, []);
|
|
3658
|
-
|
|
3721
|
+
useEffect7(() => {
|
|
3659
3722
|
if (tab && entries.length === 0) {
|
|
3660
3723
|
fetchEntries({ page: 1, reset: true });
|
|
3661
3724
|
}
|
|
@@ -3676,7 +3739,7 @@ function useContentTab(tabId) {
|
|
|
3676
3739
|
}
|
|
3677
3740
|
|
|
3678
3741
|
// src/themed/content/simple-markdown.tsx
|
|
3679
|
-
import { useEffect as
|
|
3742
|
+
import { useEffect as useEffect8, useRef as useRef8 } from "react";
|
|
3680
3743
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
3681
3744
|
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>`;
|
|
3682
3745
|
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>`;
|
|
@@ -3791,9 +3854,9 @@ function MarkdownContent({
|
|
|
3791
3854
|
bodyMarkdown,
|
|
3792
3855
|
className
|
|
3793
3856
|
}) {
|
|
3794
|
-
const rootRef =
|
|
3857
|
+
const rootRef = useRef8(null);
|
|
3795
3858
|
const html = bodyHtml ?? (bodyMarkdown ? renderMarkdown(bodyMarkdown) : "");
|
|
3796
|
-
|
|
3859
|
+
useEffect8(() => {
|
|
3797
3860
|
const root = rootRef.current;
|
|
3798
3861
|
if (!root) return;
|
|
3799
3862
|
const isWhitespaceOnly = (el) => {
|
|
@@ -3812,7 +3875,7 @@ function MarkdownContent({
|
|
|
3812
3875
|
};
|
|
3813
3876
|
removeEmpties();
|
|
3814
3877
|
}, [html]);
|
|
3815
|
-
|
|
3878
|
+
useEffect8(() => {
|
|
3816
3879
|
const root = rootRef.current;
|
|
3817
3880
|
if (!root) return;
|
|
3818
3881
|
const handler = (e) => {
|
|
@@ -3942,7 +4005,7 @@ function SkeletonSection({
|
|
|
3942
4005
|
}
|
|
3943
4006
|
|
|
3944
4007
|
// src/themed/content/content-list-view.tsx
|
|
3945
|
-
import { useCallback as useCallback10, useRef as
|
|
4008
|
+
import { useCallback as useCallback10, useRef as useRef9, useState as useState10 } from "react";
|
|
3946
4009
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3947
4010
|
function ContentListView({
|
|
3948
4011
|
entries,
|
|
@@ -3955,7 +4018,7 @@ function ContentListView({
|
|
|
3955
4018
|
display
|
|
3956
4019
|
}) {
|
|
3957
4020
|
const [searchText, setSearchText] = useState10("");
|
|
3958
|
-
const debounceRef =
|
|
4021
|
+
const debounceRef = useRef9(void 0);
|
|
3959
4022
|
const handleSearch = useCallback10(
|
|
3960
4023
|
(value) => {
|
|
3961
4024
|
setSearchText(value);
|
|
@@ -4036,10 +4099,10 @@ function ContentEntryCard({
|
|
|
4036
4099
|
}
|
|
4037
4100
|
|
|
4038
4101
|
// src/themed/content/grouped-content-tab-view.tsx
|
|
4039
|
-
import { useEffect as
|
|
4102
|
+
import { useEffect as useEffect9, useRef as useRef11 } from "react";
|
|
4040
4103
|
|
|
4041
4104
|
// src/hooks/use-grouped-content-tab.ts
|
|
4042
|
-
import { useCallback as useCallback11, useRef as
|
|
4105
|
+
import { useCallback as useCallback11, useRef as useRef10, useState as useState11 } from "react";
|
|
4043
4106
|
var EMPTY_TABS3 = [];
|
|
4044
4107
|
function categoriesKey(tabId, lang) {
|
|
4045
4108
|
return `grouped:${tabId}:${lang}:categories`;
|
|
@@ -4068,11 +4131,11 @@ function useGroupedContentTab(tabId) {
|
|
|
4068
4131
|
const [items, setItems] = useState11([]);
|
|
4069
4132
|
const [isItemsLoading, setIsItemsLoading] = useState11(false);
|
|
4070
4133
|
const [itemsHasMore, setItemsHasMore] = useState11(false);
|
|
4071
|
-
const itemsPageRef =
|
|
4134
|
+
const itemsPageRef = useRef10(1);
|
|
4072
4135
|
const [detail, setDetail] = useState11(null);
|
|
4073
4136
|
const [isLoadingDetail, setIsLoadingDetail] = useState11(false);
|
|
4074
4137
|
const [activeCategory, setActiveCategory] = useState11(null);
|
|
4075
|
-
const allCategoriesRef =
|
|
4138
|
+
const allCategoriesRef = useRef10(cachedCategories ?? []);
|
|
4076
4139
|
const fetchCategories = useCallback11(async () => {
|
|
4077
4140
|
if (!tab) return;
|
|
4078
4141
|
setIsCategoriesLoading(true);
|
|
@@ -4280,16 +4343,16 @@ function GroupedContentTabView({
|
|
|
4280
4343
|
fetchDetail,
|
|
4281
4344
|
clearCategory
|
|
4282
4345
|
} = useGroupedContentTab(tab.id);
|
|
4283
|
-
|
|
4346
|
+
useEffect9(() => {
|
|
4284
4347
|
initFetch();
|
|
4285
4348
|
}, [initFetch]);
|
|
4286
|
-
|
|
4349
|
+
useEffect9(() => {
|
|
4287
4350
|
if (detailSlug && subView === "content-detail") {
|
|
4288
4351
|
fetchDetail(detailSlug);
|
|
4289
4352
|
}
|
|
4290
4353
|
}, [detailSlug, subView, fetchDetail]);
|
|
4291
|
-
const prevSubView =
|
|
4292
|
-
|
|
4354
|
+
const prevSubView = useRef11(subView);
|
|
4355
|
+
useEffect9(() => {
|
|
4293
4356
|
if (prevSubView.current === "content-category" && subView === null) {
|
|
4294
4357
|
clearCategory();
|
|
4295
4358
|
}
|
|
@@ -4383,7 +4446,7 @@ function FlatContentTabView({
|
|
|
4383
4446
|
loadMore,
|
|
4384
4447
|
fetchDetail
|
|
4385
4448
|
} = useContentTab(tab.id);
|
|
4386
|
-
|
|
4449
|
+
useEffect10(() => {
|
|
4387
4450
|
if (detailSlug) fetchDetail(detailSlug);
|
|
4388
4451
|
}, [detailSlug, fetchDetail]);
|
|
4389
4452
|
const handleSearch = useCallback12(
|
|
@@ -4424,94 +4487,252 @@ function ContentTabIconComponent({ icon }) {
|
|
|
4424
4487
|
const Icon = ICON_MAP[icon] ?? BookIcon;
|
|
4425
4488
|
return /* @__PURE__ */ jsx11(Icon, {});
|
|
4426
4489
|
}
|
|
4427
|
-
|
|
4428
|
-
// src/themed/
|
|
4429
|
-
import { useState as useState12 } from "react";
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
function
|
|
4433
|
-
|
|
4490
|
+
|
|
4491
|
+
// src/themed/debug-overlay.tsx
|
|
4492
|
+
import { useEffect as useEffect11, useMemo as useMemo2, useRef as useRef12, useState as useState12 } from "react";
|
|
4493
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4494
|
+
var MAX_EVENTS = 60;
|
|
4495
|
+
function isDebugEnabled() {
|
|
4496
|
+
if (typeof window === "undefined") return false;
|
|
4497
|
+
if (typeof window.localStorage !== "undefined" && window.localStorage.getItem("hw:debug") === "1") {
|
|
4498
|
+
return true;
|
|
4499
|
+
}
|
|
4500
|
+
const search = window.location?.search ?? "";
|
|
4501
|
+
return search.includes("hwdebug=1") || search.includes("debug=hw");
|
|
4502
|
+
}
|
|
4503
|
+
function senderOf(item) {
|
|
4504
|
+
if (item.visitorId) return "visitor";
|
|
4505
|
+
if (item.aiAgentId) return "ai";
|
|
4506
|
+
if (item.userId) return "team";
|
|
4507
|
+
return item.type;
|
|
4508
|
+
}
|
|
4509
|
+
function WidgetDebugOverlay() {
|
|
4510
|
+
const [enabled, setEnabled] = useState12(false);
|
|
4511
|
+
const [open, setOpen] = useState12(true);
|
|
4512
|
+
const [events, setEvents] = useState12([]);
|
|
4513
|
+
const eventsRef = useRef12([]);
|
|
4514
|
+
const activeId = useWidgetStore((s) => s.activeConversationId);
|
|
4515
|
+
const messagesMap = useWidgetStore((s) => s.messages);
|
|
4516
|
+
const typingUsers = useWidgetStore((s) => s.typingUsers);
|
|
4517
|
+
const aiProcessingMap = useWidgetStore((s) => s.aiProcessing);
|
|
4518
|
+
const { store } = useWidgetContext();
|
|
4519
|
+
useEffect11(() => {
|
|
4520
|
+
setEnabled(isDebugEnabled());
|
|
4521
|
+
}, []);
|
|
4522
|
+
const pushEvent = useMemo2(
|
|
4523
|
+
() => (ev) => {
|
|
4524
|
+
const e = {
|
|
4525
|
+
...ev,
|
|
4526
|
+
id: `${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
4527
|
+
t: Date.now()
|
|
4528
|
+
};
|
|
4529
|
+
eventsRef.current = [e, ...eventsRef.current].slice(0, MAX_EVENTS);
|
|
4530
|
+
setEvents(eventsRef.current);
|
|
4531
|
+
},
|
|
4532
|
+
[]
|
|
4533
|
+
);
|
|
4534
|
+
useEffect11(() => {
|
|
4535
|
+
if (!enabled) return;
|
|
4536
|
+
if (typeof window === "undefined" || typeof window.fetch !== "function") return;
|
|
4537
|
+
const originalFetch = window.fetch.bind(window);
|
|
4538
|
+
const patched = (async (input, init) => {
|
|
4539
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
4540
|
+
const isTrpc = url.includes("/trpc/");
|
|
4541
|
+
if (isTrpc) {
|
|
4542
|
+
const method = init?.method ?? (typeof input !== "string" && !(input instanceof URL) ? input.method : "GET");
|
|
4543
|
+
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
4544
|
+
pushEvent({ kind: "trpc", label: `\u2192 ${method} ${label}`, detail: shortJson(init?.body) });
|
|
4545
|
+
}
|
|
4546
|
+
try {
|
|
4547
|
+
const res = await originalFetch(input, init);
|
|
4548
|
+
if (isTrpc) {
|
|
4549
|
+
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
4550
|
+
pushEvent({ kind: "trpc", label: `\u2190 ${res.status} ${label}` });
|
|
4551
|
+
}
|
|
4552
|
+
return res;
|
|
4553
|
+
} catch (err) {
|
|
4554
|
+
if (isTrpc) {
|
|
4555
|
+
const label = url.split("/trpc/")[1]?.split("?")[0] ?? url;
|
|
4556
|
+
pushEvent({ kind: "error", label: `\u2718 ${label}`, detail: err instanceof Error ? err.message : String(err) });
|
|
4557
|
+
}
|
|
4558
|
+
throw err;
|
|
4559
|
+
}
|
|
4560
|
+
});
|
|
4561
|
+
window.fetch = patched;
|
|
4562
|
+
return () => {
|
|
4563
|
+
window.fetch = originalFetch;
|
|
4564
|
+
};
|
|
4565
|
+
}, [enabled, pushEvent]);
|
|
4566
|
+
useEffect11(() => {
|
|
4567
|
+
if (!enabled) return;
|
|
4568
|
+
const original = store.getState().handleRealtimeEvent;
|
|
4569
|
+
store.setState({
|
|
4570
|
+
handleRealtimeEvent: (ev) => {
|
|
4571
|
+
pushEvent({ kind: "ws", label: ev.type, detail: shortJson(ev) });
|
|
4572
|
+
original(ev);
|
|
4573
|
+
}
|
|
4574
|
+
});
|
|
4575
|
+
return () => {
|
|
4576
|
+
store.setState({ handleRealtimeEvent: original });
|
|
4577
|
+
};
|
|
4578
|
+
}, [enabled, store, pushEvent]);
|
|
4579
|
+
const activeMessages = activeId ? messagesMap.get(activeId) ?? [] : [];
|
|
4580
|
+
const lastMsgSignature = useMemo2(
|
|
4581
|
+
() => activeMessages.map((m) => `${m.id}:${senderOf(m)}:${m.createdAt}`).join("|"),
|
|
4582
|
+
[activeMessages]
|
|
4583
|
+
);
|
|
4584
|
+
const prevSigRef = useRef12(lastMsgSignature);
|
|
4585
|
+
useEffect11(() => {
|
|
4586
|
+
if (!enabled) return;
|
|
4587
|
+
if (prevSigRef.current !== lastMsgSignature) {
|
|
4588
|
+
prevSigRef.current = lastMsgSignature;
|
|
4589
|
+
pushEvent({
|
|
4590
|
+
kind: "store",
|
|
4591
|
+
label: `messages[${activeMessages.length}]`,
|
|
4592
|
+
detail: activeMessages.map((m, i) => `${i}:${senderOf(m)}=${(m.text ?? "").slice(0, 24)}`).join(" | ")
|
|
4593
|
+
});
|
|
4594
|
+
}
|
|
4595
|
+
}, [lastMsgSignature, activeMessages, enabled, pushEvent]);
|
|
4596
|
+
if (!enabled) return null;
|
|
4597
|
+
const isTyping = activeId ? typingUsers.get(activeId) : false;
|
|
4598
|
+
const isAi = activeId ? aiProcessingMap.get(activeId) : false;
|
|
4599
|
+
return /* @__PURE__ */ jsxs7("div", { style: styles.wrap, children: [
|
|
4600
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.header, children: [
|
|
4601
|
+
/* @__PURE__ */ jsx12("strong", { children: "hw debug" }),
|
|
4602
|
+
/* @__PURE__ */ jsxs7("span", { style: styles.meta, children: [
|
|
4603
|
+
" ",
|
|
4604
|
+
"\xB7 conv ",
|
|
4605
|
+
activeId ? activeId.slice(0, 10) : "\u2014",
|
|
4606
|
+
" \xB7 items ",
|
|
4607
|
+
activeMessages.length,
|
|
4608
|
+
" \xB7 typing ",
|
|
4609
|
+
isTyping ? "Y" : "n",
|
|
4610
|
+
" \xB7 ai ",
|
|
4611
|
+
isAi ? "Y" : "n"
|
|
4612
|
+
] }),
|
|
4613
|
+
/* @__PURE__ */ jsx12("button", { type: "button", style: styles.btn, onClick: () => setOpen((v) => !v), children: open ? "hide" : "show" }),
|
|
4614
|
+
/* @__PURE__ */ jsx12("button", { type: "button", style: styles.btn, onClick: () => {
|
|
4615
|
+
eventsRef.current = [];
|
|
4616
|
+
setEvents([]);
|
|
4617
|
+
}, children: "clear" })
|
|
4618
|
+
] }),
|
|
4619
|
+
open && /* @__PURE__ */ jsxs7("div", { style: styles.body, children: [
|
|
4620
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.section, children: [
|
|
4621
|
+
/* @__PURE__ */ jsx12("div", { style: styles.sectionTitle, children: "messages (active)" }),
|
|
4622
|
+
activeMessages.length === 0 ? /* @__PURE__ */ jsx12("div", { style: styles.empty, children: "empty" }) : activeMessages.map((m, i) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
4623
|
+
/* @__PURE__ */ jsx12("span", { style: { ...styles.badge, background: colorFor(senderOf(m)) }, children: i }),
|
|
4624
|
+
/* @__PURE__ */ jsx12("span", { style: styles.sender, children: senderOf(m) }),
|
|
4625
|
+
/* @__PURE__ */ jsx12("span", { style: styles.ts, children: m.createdAt.slice(11, 23) }),
|
|
4626
|
+
/* @__PURE__ */ jsx12("span", { style: styles.text, children: (m.text ?? "").slice(0, 60) })
|
|
4627
|
+
] }, m.id))
|
|
4628
|
+
] }),
|
|
4629
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.section, children: [
|
|
4630
|
+
/* @__PURE__ */ jsx12("div", { style: styles.sectionTitle, children: "events" }),
|
|
4631
|
+
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: [
|
|
4632
|
+
/* @__PURE__ */ jsx12("span", { style: { ...styles.badge, background: kindColor(e.kind) }, children: e.kind }),
|
|
4633
|
+
/* @__PURE__ */ jsx12("span", { style: styles.ts, children: new Date(e.t).toISOString().slice(11, 23) }),
|
|
4634
|
+
/* @__PURE__ */ jsx12("span", { style: styles.evLabel, children: e.label }),
|
|
4635
|
+
e.detail && /* @__PURE__ */ jsx12("span", { style: styles.detail, children: e.detail })
|
|
4636
|
+
] }, e.id))
|
|
4637
|
+
] })
|
|
4638
|
+
] })
|
|
4639
|
+
] });
|
|
4640
|
+
}
|
|
4641
|
+
function shortJson(v) {
|
|
4642
|
+
if (v === void 0) return "";
|
|
4643
|
+
try {
|
|
4644
|
+
const s = JSON.stringify(v);
|
|
4645
|
+
if (!s) return "";
|
|
4646
|
+
return s.length > 180 ? `${s.slice(0, 177)}\u2026` : s;
|
|
4647
|
+
} catch {
|
|
4648
|
+
return String(v);
|
|
4649
|
+
}
|
|
4434
4650
|
}
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
4447
|
-
if (previews.length === 0) return null;
|
|
4448
|
-
const stackPlacementClass = placement === "anchored" ? "hw-preview-stack--anchored " : "";
|
|
4449
|
-
return /* @__PURE__ */ jsx12("div", { className: `hw-preview-stack ${stackPlacementClass}`.trim(), children: previews.map((preview) => /* @__PURE__ */ jsx12(
|
|
4450
|
-
AnnouncementPreviewItem,
|
|
4451
|
-
{
|
|
4452
|
-
preview,
|
|
4453
|
-
agentName,
|
|
4454
|
-
avatar,
|
|
4455
|
-
placement,
|
|
4456
|
-
footer,
|
|
4457
|
-
onOpen,
|
|
4458
|
-
onDismiss: (slug) => dismissPreview(slug)
|
|
4459
|
-
},
|
|
4460
|
-
preview.slug
|
|
4461
|
-
)) });
|
|
4651
|
+
function colorFor(sender) {
|
|
4652
|
+
switch (sender) {
|
|
4653
|
+
case "visitor":
|
|
4654
|
+
return "#1d4ed8";
|
|
4655
|
+
case "ai":
|
|
4656
|
+
return "#7c3aed";
|
|
4657
|
+
case "team":
|
|
4658
|
+
return "#16a34a";
|
|
4659
|
+
default:
|
|
4660
|
+
return "#6b7280";
|
|
4661
|
+
}
|
|
4462
4662
|
}
|
|
4463
|
-
function
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
e.stopPropagation();
|
|
4475
|
-
setClosing(true);
|
|
4476
|
-
setTimeout(() => {
|
|
4477
|
-
onDismiss(preview.slug);
|
|
4478
|
-
setClosing(false);
|
|
4479
|
-
}, 200);
|
|
4480
|
-
};
|
|
4481
|
-
const placementClass = placement === "anchored" ? "hw-preview--anchored " : "";
|
|
4482
|
-
return /* @__PURE__ */ jsxs7(
|
|
4483
|
-
"div",
|
|
4484
|
-
{
|
|
4485
|
-
className: `hw-preview hw-preview--announcement ${placementClass}${closing ? "hw-preview--closing" : ""}`.trim(),
|
|
4486
|
-
onClick: () => onOpen(preview.slug, preview.tabId),
|
|
4487
|
-
role: "button",
|
|
4488
|
-
tabIndex: 0,
|
|
4489
|
-
children: [
|
|
4490
|
-
/* @__PURE__ */ jsxs7("div", { className: "hw-preview-header", children: [
|
|
4491
|
-
/* @__PURE__ */ jsx12("div", { className: "hw-preview-avatar", children: avatar }),
|
|
4492
|
-
/* @__PURE__ */ jsx12("div", { className: "hw-preview-name", children: agentName }),
|
|
4493
|
-
/* @__PURE__ */ jsx12(
|
|
4494
|
-
"button",
|
|
4495
|
-
{
|
|
4496
|
-
type: "button",
|
|
4497
|
-
className: "hw-preview-close",
|
|
4498
|
-
onClick: handleClose,
|
|
4499
|
-
"aria-label": t("widget.aria_dismiss"),
|
|
4500
|
-
children: /* @__PURE__ */ jsx12(XIcon, { size: 20 })
|
|
4501
|
-
}
|
|
4502
|
-
)
|
|
4503
|
-
] }),
|
|
4504
|
-
/* @__PURE__ */ jsx12("div", { className: "hw-preview-body hw-preview-body--title", children: preview.title }),
|
|
4505
|
-
preview.body && (() => {
|
|
4506
|
-
const clean = stripMarkdown(preview.body);
|
|
4507
|
-
return /* @__PURE__ */ jsx12("div", { className: "hw-preview-body hw-preview-body--desc", children: clean.length > 120 ? `${clean.slice(0, 120)}\u2026` : clean });
|
|
4508
|
-
})(),
|
|
4509
|
-
preview.badge && /* @__PURE__ */ jsx12("div", { className: "hw-announcement-badge", children: preview.badge }),
|
|
4510
|
-
footer != null && footer !== false && /* @__PURE__ */ jsx12("div", { className: "hw-preview-footer", children: footer })
|
|
4511
|
-
]
|
|
4512
|
-
}
|
|
4513
|
-
);
|
|
4663
|
+
function kindColor(kind) {
|
|
4664
|
+
switch (kind) {
|
|
4665
|
+
case "trpc":
|
|
4666
|
+
return "#0ea5e9";
|
|
4667
|
+
case "ws":
|
|
4668
|
+
return "#f97316";
|
|
4669
|
+
case "store":
|
|
4670
|
+
return "#64748b";
|
|
4671
|
+
case "error":
|
|
4672
|
+
return "#dc2626";
|
|
4673
|
+
}
|
|
4514
4674
|
}
|
|
4675
|
+
var styles = {
|
|
4676
|
+
wrap: {
|
|
4677
|
+
position: "fixed",
|
|
4678
|
+
right: 12,
|
|
4679
|
+
bottom: 12,
|
|
4680
|
+
zIndex: 2147483e3,
|
|
4681
|
+
width: 420,
|
|
4682
|
+
maxHeight: "70vh",
|
|
4683
|
+
background: "rgba(9,9,11,0.94)",
|
|
4684
|
+
color: "#e5e7eb",
|
|
4685
|
+
borderRadius: 10,
|
|
4686
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
4687
|
+
fontSize: 11,
|
|
4688
|
+
boxShadow: "0 12px 30px rgba(0,0,0,0.35)",
|
|
4689
|
+
overflow: "hidden",
|
|
4690
|
+
pointerEvents: "auto"
|
|
4691
|
+
},
|
|
4692
|
+
header: {
|
|
4693
|
+
display: "flex",
|
|
4694
|
+
alignItems: "center",
|
|
4695
|
+
gap: 6,
|
|
4696
|
+
padding: "6px 10px",
|
|
4697
|
+
background: "#18181b",
|
|
4698
|
+
borderBottom: "1px solid #27272a"
|
|
4699
|
+
},
|
|
4700
|
+
meta: { flex: 1, color: "#a1a1aa", fontSize: 10 },
|
|
4701
|
+
btn: {
|
|
4702
|
+
background: "#27272a",
|
|
4703
|
+
color: "#e4e4e7",
|
|
4704
|
+
border: "1px solid #3f3f46",
|
|
4705
|
+
borderRadius: 4,
|
|
4706
|
+
padding: "2px 8px",
|
|
4707
|
+
cursor: "pointer",
|
|
4708
|
+
fontSize: 10
|
|
4709
|
+
},
|
|
4710
|
+
body: { display: "flex", flexDirection: "column", maxHeight: "calc(70vh - 32px)", overflow: "auto" },
|
|
4711
|
+
section: { borderBottom: "1px solid #27272a", padding: "6px 10px" },
|
|
4712
|
+
sectionTitle: { color: "#a1a1aa", fontSize: 10, textTransform: "uppercase", letterSpacing: 0.6, marginBottom: 4 },
|
|
4713
|
+
row: {
|
|
4714
|
+
display: "grid",
|
|
4715
|
+
gridTemplateColumns: "32px 56px 72px 1fr",
|
|
4716
|
+
gap: 6,
|
|
4717
|
+
alignItems: "baseline",
|
|
4718
|
+
padding: "2px 0",
|
|
4719
|
+
borderTop: "1px dashed #27272a"
|
|
4720
|
+
},
|
|
4721
|
+
badge: {
|
|
4722
|
+
display: "inline-block",
|
|
4723
|
+
borderRadius: 3,
|
|
4724
|
+
padding: "1px 4px",
|
|
4725
|
+
color: "white",
|
|
4726
|
+
fontSize: 9,
|
|
4727
|
+
textAlign: "center"
|
|
4728
|
+
},
|
|
4729
|
+
sender: { color: "#d4d4d8" },
|
|
4730
|
+
ts: { color: "#71717a", fontSize: 10 },
|
|
4731
|
+
text: { color: "#e4e4e7", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" },
|
|
4732
|
+
evLabel: { color: "#e4e4e7" },
|
|
4733
|
+
detail: { gridColumn: "1 / -1", color: "#a1a1aa", fontSize: 10, whiteSpace: "pre-wrap", wordBreak: "break-all" },
|
|
4734
|
+
empty: { color: "#52525b", fontStyle: "italic", fontSize: 10 }
|
|
4735
|
+
};
|
|
4515
4736
|
|
|
4516
4737
|
// src/themed/message-bubble.tsx
|
|
4517
4738
|
import { useEffect as useEffect12, useLayoutEffect, useRef as useRef13, useState as useState13 } from "react";
|
|
@@ -4864,15 +5085,18 @@ function parseParts(raw) {
|
|
|
4864
5085
|
return null;
|
|
4865
5086
|
}
|
|
4866
5087
|
}
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
5088
|
+
var DATE_KEY_FMT = new Intl.DateTimeFormat("en-CA");
|
|
5089
|
+
var displayFmtCache = /* @__PURE__ */ new Map();
|
|
5090
|
+
function displayDateFormatter(locale) {
|
|
5091
|
+
const hit = displayFmtCache.get(locale);
|
|
5092
|
+
if (hit) return hit;
|
|
5093
|
+
const fmt = new Intl.DateTimeFormat(locale, {
|
|
5094
|
+
weekday: "long",
|
|
5095
|
+
month: "short",
|
|
5096
|
+
day: "numeric"
|
|
5097
|
+
});
|
|
5098
|
+
displayFmtCache.set(locale, fmt);
|
|
5099
|
+
return fmt;
|
|
4876
5100
|
}
|
|
4877
5101
|
function MessageList({
|
|
4878
5102
|
items,
|
|
@@ -4966,10 +5190,10 @@ function MessageList({
|
|
|
4966
5190
|
);
|
|
4967
5191
|
}
|
|
4968
5192
|
let lastDateKey = "";
|
|
4969
|
-
const todayKey = (/* @__PURE__ */ new Date())
|
|
5193
|
+
const todayKey = DATE_KEY_FMT.format(/* @__PURE__ */ new Date());
|
|
4970
5194
|
const yesterday = /* @__PURE__ */ new Date();
|
|
4971
5195
|
yesterday.setDate(yesterday.getDate() - 1);
|
|
4972
|
-
const yesterdayKey =
|
|
5196
|
+
const yesterdayKey = DATE_KEY_FMT.format(yesterday);
|
|
4973
5197
|
return /* @__PURE__ */ jsxs9(
|
|
4974
5198
|
"div",
|
|
4975
5199
|
{
|
|
@@ -4996,15 +5220,11 @@ function MessageList({
|
|
|
4996
5220
|
);
|
|
4997
5221
|
}
|
|
4998
5222
|
const itemDate = new Date(item.createdAt);
|
|
4999
|
-
const dateKey =
|
|
5223
|
+
const dateKey = DATE_KEY_FMT.format(itemDate);
|
|
5000
5224
|
const isNewBucket = dateKey !== lastDateKey;
|
|
5001
5225
|
if (isNewBucket) lastDateKey = dateKey;
|
|
5002
5226
|
const showDateSep = isNewBucket && dateKey !== todayKey;
|
|
5003
|
-
const dateLabel = dateKey === yesterdayKey ? t("widget.yesterday") :
|
|
5004
|
-
weekday: "long",
|
|
5005
|
-
month: "short",
|
|
5006
|
-
day: "numeric"
|
|
5007
|
-
});
|
|
5227
|
+
const dateLabel = dateKey === yesterdayKey ? t("widget.yesterday") : displayDateFormatter(getLocale()).format(itemDate);
|
|
5008
5228
|
const sender = item.visitorId ? "visitor" : item.aiAgentId ? "ai" : "team";
|
|
5009
5229
|
return /* @__PURE__ */ jsxs9(
|
|
5010
5230
|
React.Fragment,
|
|
@@ -5021,7 +5241,7 @@ function MessageList({
|
|
|
5021
5241
|
text: item.text ?? "",
|
|
5022
5242
|
sender,
|
|
5023
5243
|
parts: parseParts(item.parts),
|
|
5024
|
-
metadata:
|
|
5244
|
+
metadata: parseTimelineItemMetadata(
|
|
5025
5245
|
item.metadata
|
|
5026
5246
|
),
|
|
5027
5247
|
onQuickReplyTap: handleQuickReplyTap
|
|
@@ -5078,7 +5298,15 @@ function EventCard({ text }) {
|
|
|
5078
5298
|
if (data) {
|
|
5079
5299
|
const message = data.action === "joined" ? t("widget.joined") : t("widget.left");
|
|
5080
5300
|
return /* @__PURE__ */ jsxs9("div", { className: "hw-event hw-event--card", children: [
|
|
5081
|
-
/* @__PURE__ */ jsx14("div", { className: "hw-event-avatar", children: data.image ? /* @__PURE__ */ jsx14(
|
|
5301
|
+
/* @__PURE__ */ jsx14("div", { className: "hw-event-avatar", children: data.image ? /* @__PURE__ */ jsx14(
|
|
5302
|
+
"img",
|
|
5303
|
+
{
|
|
5304
|
+
src: data.image,
|
|
5305
|
+
alt: "",
|
|
5306
|
+
className: "hw-event-avatar-img",
|
|
5307
|
+
referrerPolicy: "no-referrer"
|
|
5308
|
+
}
|
|
5309
|
+
) : /* @__PURE__ */ jsx14("span", { children: getInitials(data.name) }) }),
|
|
5082
5310
|
/* @__PURE__ */ jsxs9("div", { className: "hw-event-body", children: [
|
|
5083
5311
|
/* @__PURE__ */ jsx14("span", { className: "hw-event-name", children: data.name }),
|
|
5084
5312
|
" ",
|
|
@@ -5103,6 +5331,7 @@ function MessagePreview({
|
|
|
5103
5331
|
const dismissPreview = useWidgetStore((s) => s.dismissPreview);
|
|
5104
5332
|
const setActiveConversation = useWidgetStore((s) => s.setActiveConversation);
|
|
5105
5333
|
const agentName = useWidgetStore((s) => s.agentConfig?.name) ?? "Support";
|
|
5334
|
+
const client = useWidgetClient();
|
|
5106
5335
|
const senderName = preview?.senderName || agentName;
|
|
5107
5336
|
const senderImage = preview?.senderImage || null;
|
|
5108
5337
|
const [closing, setClosing] = useState14(false);
|
|
@@ -5130,19 +5359,39 @@ function MessagePreview({
|
|
|
5130
5359
|
setActiveConversation(targetConvId);
|
|
5131
5360
|
onOpen();
|
|
5132
5361
|
};
|
|
5133
|
-
const
|
|
5134
|
-
|
|
5362
|
+
const submitQuickReply = (optionId) => {
|
|
5363
|
+
const convId = preview.conversationId;
|
|
5364
|
+
const stepId = preview.quickReplies?.stepId;
|
|
5365
|
+
if (stepId && !convId.startsWith(EPHEMERAL_CONV_PREFIX)) {
|
|
5366
|
+
client.widget.workflowReply.mutate({ conversationId: convId, stepId, optionId }).catch((err) => {
|
|
5367
|
+
console.warn("[helpway] workflowReply from preview failed:", err);
|
|
5368
|
+
});
|
|
5369
|
+
}
|
|
5370
|
+
dismissPreview();
|
|
5371
|
+
setActiveConversation(convId);
|
|
5372
|
+
onOpen();
|
|
5373
|
+
};
|
|
5374
|
+
const messages = (preview.messages?.length ? preview.messages : [{ text: preview.text }]).filter(
|
|
5375
|
+
(m) => m.text.trim().length > 0
|
|
5376
|
+
);
|
|
5377
|
+
const qr = preview.quickReplies && preview.quickReplies.options.length > 0 ? preview.quickReplies : null;
|
|
5135
5378
|
const placementClass = placement === "anchored" ? "hw-preview--anchored " : "";
|
|
5136
5379
|
return /* @__PURE__ */ jsxs10(
|
|
5137
5380
|
"div",
|
|
5138
5381
|
{
|
|
5139
5382
|
className: `hw-preview ${placementClass}${closing ? "hw-preview--closing" : ""}`,
|
|
5140
5383
|
onClick: handleClick,
|
|
5384
|
+
onKeyDown: (e) => {
|
|
5385
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
5386
|
+
if (e.target !== e.currentTarget) return;
|
|
5387
|
+
e.preventDefault();
|
|
5388
|
+
handleClick();
|
|
5389
|
+
},
|
|
5141
5390
|
role: "button",
|
|
5142
5391
|
tabIndex: 0,
|
|
5143
5392
|
children: [
|
|
5144
5393
|
/* @__PURE__ */ jsxs10("div", { className: "hw-preview-header", children: [
|
|
5145
|
-
/* @__PURE__ */ jsx15("div", { className: "hw-preview-avatar", children: senderImage ? /* @__PURE__ */ jsx15("img", { src: senderImage, alt: "" }) : avatar }),
|
|
5394
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-preview-avatar", children: senderImage ? /* @__PURE__ */ jsx15("img", { src: senderImage, alt: "", referrerPolicy: "no-referrer" }) : avatar }),
|
|
5146
5395
|
/* @__PURE__ */ jsx15("div", { className: "hw-preview-name", children: senderName }),
|
|
5147
5396
|
/* @__PURE__ */ jsx15(
|
|
5148
5397
|
"button",
|
|
@@ -5155,19 +5404,23 @@ function MessagePreview({
|
|
|
5155
5404
|
}
|
|
5156
5405
|
)
|
|
5157
5406
|
] }),
|
|
5158
|
-
messages.map((m
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5407
|
+
messages.map((m) => (
|
|
5408
|
+
/* Keyed by content, not index: the card's bodies are the sender's own
|
|
5409
|
+
consecutive messages, so two identical ones would already be a bug
|
|
5410
|
+
upstream, and an index key hands React the wrong bubble to reuse the
|
|
5411
|
+
moment a new message lands mid-animation. */
|
|
5412
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-preview-body", children: truncatePreviewBody(m.text) }, m.text)
|
|
5413
|
+
)),
|
|
5414
|
+
qr && /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
5415
|
+
qr.prompt && /* @__PURE__ */ jsx15("div", { className: "hw-preview-body", children: qr.prompt }),
|
|
5416
|
+
/* @__PURE__ */ jsx15("div", { className: "hw-preview-quick-replies hw-quick-replies", children: qr.options.map((opt) => /* @__PURE__ */ jsx15(
|
|
5162
5417
|
"button",
|
|
5163
5418
|
{
|
|
5164
5419
|
type: "button",
|
|
5165
5420
|
className: "hw-quick-reply-btn",
|
|
5166
5421
|
onClick: (e) => {
|
|
5167
5422
|
e.stopPropagation();
|
|
5168
|
-
|
|
5169
|
-
setActiveConversation(preview.conversationId);
|
|
5170
|
-
onOpen();
|
|
5423
|
+
submitQuickReply(opt.id);
|
|
5171
5424
|
},
|
|
5172
5425
|
children: opt.label
|
|
5173
5426
|
},
|
|
@@ -5213,10 +5466,13 @@ function HelpwayMark({ className }) {
|
|
|
5213
5466
|
}
|
|
5214
5467
|
);
|
|
5215
5468
|
}
|
|
5469
|
+
var AgentAvatarContext = createContext2(null);
|
|
5470
|
+
var AgentAvatarProvider = AgentAvatarContext.Provider;
|
|
5216
5471
|
function WidgetLogo({
|
|
5217
5472
|
className,
|
|
5218
5473
|
forceAgent = false
|
|
5219
5474
|
}) {
|
|
5475
|
+
const customAvatar = useContext2(AgentAvatarContext);
|
|
5220
5476
|
const agentConfig = useWidgetStore((s) => s.agentConfig);
|
|
5221
5477
|
const logoUrl = useWidgetStore((s) => s.website?.logoUrl);
|
|
5222
5478
|
const activeId = useWidgetStore((s) => s.activeConversationId);
|
|
@@ -5232,12 +5488,30 @@ function WidgetLogo({
|
|
|
5232
5488
|
{
|
|
5233
5489
|
src: assignee.assigneeImage,
|
|
5234
5490
|
alt: assignee.assigneeName ?? "",
|
|
5491
|
+
referrerPolicy: "no-referrer",
|
|
5235
5492
|
className: `hw-agent-img ${className ?? ""}`
|
|
5236
5493
|
}
|
|
5237
5494
|
);
|
|
5238
5495
|
}
|
|
5496
|
+
if (customAvatar) {
|
|
5497
|
+
return /* @__PURE__ */ jsx16(
|
|
5498
|
+
"span",
|
|
5499
|
+
{
|
|
5500
|
+
className: `hw-agent-icon hw-agent-custom ${className ?? ""}`,
|
|
5501
|
+
style: { display: "flex", alignItems: "center", justifyContent: "center" },
|
|
5502
|
+
children: customAvatar
|
|
5503
|
+
}
|
|
5504
|
+
);
|
|
5505
|
+
}
|
|
5239
5506
|
if (agentConfig?.avatarUrl) {
|
|
5240
|
-
return /* @__PURE__ */ jsx16(
|
|
5507
|
+
return /* @__PURE__ */ jsx16(
|
|
5508
|
+
"img",
|
|
5509
|
+
{
|
|
5510
|
+
src: agentConfig.avatarUrl,
|
|
5511
|
+
alt: "",
|
|
5512
|
+
className: `hw-agent-img ${logoClass} ${className ?? ""}`
|
|
5513
|
+
}
|
|
5514
|
+
);
|
|
5241
5515
|
}
|
|
5242
5516
|
if (agentConfig?.avatarPreset) {
|
|
5243
5517
|
return /* @__PURE__ */ jsx16(
|
|
@@ -5383,15 +5657,18 @@ function DefaultWidget({
|
|
|
5383
5657
|
dockSuggestions
|
|
5384
5658
|
} = {}) {
|
|
5385
5659
|
const { isReady, website, agentConfig } = useWidget();
|
|
5660
|
+
const customAvatar = useContext2(AgentAvatarContext);
|
|
5386
5661
|
useI18n();
|
|
5387
5662
|
const { client, store, hasBootstrapError, wsDisconnected, retryBootstrap } = useWidgetContext();
|
|
5388
5663
|
const { conversations, create, isCreating, setActiveConversation } = useConversations();
|
|
5389
5664
|
const activeId = useWidgetStore((s) => s.activeConversationId);
|
|
5390
5665
|
const isDismissed = useWidgetStore((s) => s.isDismissed);
|
|
5391
5666
|
const { totalUnread } = useUnread();
|
|
5667
|
+
const awaitingReply = useAwaitingReply();
|
|
5392
5668
|
const contentTabs = useWidgetStore((s) => s.agentConfig?.contentTabs) ?? EMPTY_CONTENT_TABS;
|
|
5393
5669
|
const { announcementTabs, markEntrySeen, getUnseenEntries } = useAnnouncements();
|
|
5394
5670
|
const unseenAnnouncementCount = useWidgetStore((s) => s.unseenAnnouncementCount);
|
|
5671
|
+
const incomingPreview = useWidgetStore((s) => !!s.incomingPreview);
|
|
5395
5672
|
const visitorContact = useWidgetStore((s) => s.visitor?.contact);
|
|
5396
5673
|
if (process.env.NODE_ENV !== "production") {
|
|
5397
5674
|
console.debug("[Widget]", {
|
|
@@ -5473,14 +5750,7 @@ function DefaultWidget({
|
|
|
5473
5750
|
const mostRecent = conversations[0];
|
|
5474
5751
|
if (mostRecent) openConversation(mostRecent.id);
|
|
5475
5752
|
else openNewConversation();
|
|
5476
|
-
}, [
|
|
5477
|
-
isOpen,
|
|
5478
|
-
isReady,
|
|
5479
|
-
subView,
|
|
5480
|
-
conversations,
|
|
5481
|
-
openConversation,
|
|
5482
|
-
openNewConversation
|
|
5483
|
-
]);
|
|
5753
|
+
}, [isOpen, isReady, subView, conversations, openConversation, openNewConversation]);
|
|
5484
5754
|
const dockComposer = useComposer(activeId);
|
|
5485
5755
|
const dockRef = useRef15(dockComposer);
|
|
5486
5756
|
useEffect15(() => {
|
|
@@ -5762,7 +6032,8 @@ function DefaultWidget({
|
|
|
5762
6032
|
onRemoveAttachment: dockComposer.removeAttachment,
|
|
5763
6033
|
onReopen: reopenFromDock,
|
|
5764
6034
|
sendError: dockComposer.sendError,
|
|
5765
|
-
onClearSendError: dockComposer.clearSendError
|
|
6035
|
+
onClearSendError: dockComposer.clearSendError,
|
|
6036
|
+
leading: customAvatar
|
|
5766
6037
|
}
|
|
5767
6038
|
),
|
|
5768
6039
|
isOpen && !isReady && !hasBootstrapError && /* @__PURE__ */ jsx16("div", { className: `hw-window ${isClosing ? "hw-window--closing" : ""}`, children: /* @__PURE__ */ jsxs11("div", { className: "hw-skeleton-loading", children: [
|
|
@@ -5853,7 +6124,13 @@ function DefaultWidget({
|
|
|
5853
6124
|
}
|
|
5854
6125
|
),
|
|
5855
6126
|
/* @__PURE__ */ jsxs11("div", { className: "hw-header-identity", children: [
|
|
5856
|
-
/* @__PURE__ */ jsx16(
|
|
6127
|
+
/* @__PURE__ */ jsx16(
|
|
6128
|
+
"div",
|
|
6129
|
+
{
|
|
6130
|
+
className: `hw-header-bot-icon${hasTeamAgent ? " hw-header-bot-icon--team" : ""}`,
|
|
6131
|
+
children: hasTeamAgent && humanImage ? /* @__PURE__ */ jsx16("img", { src: humanImage, alt: headerName, className: "hw-header-agent-img", referrerPolicy: "no-referrer" }) : hasTeamAgent ? /* @__PURE__ */ jsx16("span", { className: "hw-header-agent-initials", children: headerName.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase() }) : /* @__PURE__ */ jsx16(WidgetLogo, {})
|
|
6132
|
+
}
|
|
6133
|
+
),
|
|
5857
6134
|
/* @__PURE__ */ jsxs11("div", { className: "hw-header-info", children: [
|
|
5858
6135
|
/* @__PURE__ */ jsx16("div", { className: "hw-header-name", children: headerName }),
|
|
5859
6136
|
/* @__PURE__ */ jsx16("div", { className: "hw-header-status", children: subtitleText })
|
|
@@ -6083,35 +6360,25 @@ function DefaultWidget({
|
|
|
6083
6360
|
]
|
|
6084
6361
|
}
|
|
6085
6362
|
),
|
|
6086
|
-
isReady && !isOpen && !isDismissed && !hideLauncher && /*
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
AnnouncementPreviews,
|
|
6102
|
-
{
|
|
6103
|
-
avatar: /* @__PURE__ */ jsx16(WidgetLogo, {}),
|
|
6104
|
-
onOpen: (slug, tabId) => {
|
|
6105
|
-
markEntrySeen(slug);
|
|
6106
|
-
handleBubbleClick();
|
|
6107
|
-
setTimeout(() => {
|
|
6108
|
-
switchTab(`content:${tabId}`);
|
|
6109
|
-
setContentDetailSlug(slug);
|
|
6110
|
-
setSubView("content-detail");
|
|
6111
|
-
}, 50);
|
|
6363
|
+
isReady && !isOpen && !isDismissed && !hideLauncher && /* @__PURE__ */ jsxs11("div", { className: "hw-preview-dock", children: [
|
|
6364
|
+
/* @__PURE__ */ jsx16(
|
|
6365
|
+
AnnouncementPreviews,
|
|
6366
|
+
{
|
|
6367
|
+
maxVisible: incomingPreview ? 1 : 2,
|
|
6368
|
+
avatar: /* @__PURE__ */ jsx16(WidgetLogo, {}),
|
|
6369
|
+
onOpen: (slug, tabId) => {
|
|
6370
|
+
markEntrySeen(slug);
|
|
6371
|
+
handleBubbleClick();
|
|
6372
|
+
setTimeout(() => {
|
|
6373
|
+
switchTab(`content:${tabId}`);
|
|
6374
|
+
setContentDetailSlug(slug);
|
|
6375
|
+
setSubView("content-detail");
|
|
6376
|
+
}, 50);
|
|
6377
|
+
}
|
|
6112
6378
|
}
|
|
6113
|
-
|
|
6114
|
-
|
|
6379
|
+
),
|
|
6380
|
+
/* @__PURE__ */ jsx16(MessagePreview, { onOpen: handleBubbleClick, avatar: /* @__PURE__ */ jsx16(WidgetLogo, {}), autoDismissMs: null })
|
|
6381
|
+
] }),
|
|
6115
6382
|
/* @__PURE__ */ jsx16(WidgetDebugOverlay, {}),
|
|
6116
6383
|
isReady && !isDismissed && (!hideLauncher || isOpen) && /* @__PURE__ */ jsxs11(
|
|
6117
6384
|
"button",
|
|
@@ -6145,9 +6412,9 @@ function DefaultWidget({
|
|
|
6145
6412
|
}
|
|
6146
6413
|
),
|
|
6147
6414
|
launcherStyle !== "icon" && !isOpen && /* @__PURE__ */ jsx16("span", { className: "hw-bubble-label", children: launcherStyle === "help" ? t("widget.help") : companyName }),
|
|
6148
|
-
!isOpen && (totalUnread > 0 || unseenAnnouncementCount > 0) && /* @__PURE__ */ jsxs11("div", { className: "hw-bubble-badge", children: [
|
|
6415
|
+
!isOpen && (totalUnread > 0 || awaitingReply > 0 || unseenAnnouncementCount > 0) && /* @__PURE__ */ jsxs11("div", { className: "hw-bubble-badge", children: [
|
|
6149
6416
|
totalUnread > 0 ? totalUnread : "",
|
|
6150
|
-
totalUnread === 0 && unseenAnnouncementCount > 0 && /* @__PURE__ */ jsx16("span", { className: "hw-bubble-badge-dot" })
|
|
6417
|
+
totalUnread === 0 && (awaitingReply > 0 || unseenAnnouncementCount > 0) && /* @__PURE__ */ jsx16("span", { className: "hw-bubble-badge-dot" })
|
|
6151
6418
|
] })
|
|
6152
6419
|
]
|
|
6153
6420
|
}
|
|
@@ -6259,7 +6526,7 @@ function ConvCardBody({ conv }) {
|
|
|
6259
6526
|
const displayName = humanName ?? agentName;
|
|
6260
6527
|
const preview = conv.lastMessageText ?? t("widget.no_preview");
|
|
6261
6528
|
return /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
6262
|
-
/* @__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, {}) }),
|
|
6529
|
+
/* @__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", referrerPolicy: "no-referrer" }) : /* @__PURE__ */ jsx16("span", { className: "hw-conv-card-avatar-initials", children: displayName.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase() }) : /* @__PURE__ */ jsx16(WidgetLogo, {}) }),
|
|
6263
6530
|
/* @__PURE__ */ jsxs11("div", { className: "hw-conv-card-content", children: [
|
|
6264
6531
|
/* @__PURE__ */ jsxs11("div", { className: "hw-conv-card-top", children: [
|
|
6265
6532
|
/* @__PURE__ */ jsx16("span", { className: "hw-conv-card-name", children: displayName }),
|
|
@@ -6274,6 +6541,7 @@ function ConversationCard({
|
|
|
6274
6541
|
onSelect
|
|
6275
6542
|
}) {
|
|
6276
6543
|
const hasUnread = conv.unreadCount > 0;
|
|
6544
|
+
const awaiting = !hasUnread && isAwaitingVisitorReply(conv);
|
|
6277
6545
|
return /* @__PURE__ */ jsxs11(
|
|
6278
6546
|
"button",
|
|
6279
6547
|
{
|
|
@@ -6282,7 +6550,8 @@ function ConversationCard({
|
|
|
6282
6550
|
onClick: () => onSelect(conv.id),
|
|
6283
6551
|
children: [
|
|
6284
6552
|
/* @__PURE__ */ jsx16("div", { className: "hw-conv-card-row", children: /* @__PURE__ */ jsx16(ConvCardBody, { conv }) }),
|
|
6285
|
-
hasUnread && /* @__PURE__ */ jsx16("div", { className: "hw-conv-card-badge", children: conv.unreadCount })
|
|
6553
|
+
hasUnread && /* @__PURE__ */ jsx16("div", { className: "hw-conv-card-badge", children: conv.unreadCount }),
|
|
6554
|
+
awaiting && /* @__PURE__ */ jsx16("div", { className: "hw-awaiting", children: t("widget.awaiting_your_reply") })
|
|
6286
6555
|
]
|
|
6287
6556
|
}
|
|
6288
6557
|
);
|
|
@@ -6293,6 +6562,7 @@ function ConversationRow({
|
|
|
6293
6562
|
isLast
|
|
6294
6563
|
}) {
|
|
6295
6564
|
const hasUnread = conv.unreadCount > 0;
|
|
6565
|
+
const awaiting = !hasUnread && isAwaitingVisitorReply(conv);
|
|
6296
6566
|
return /* @__PURE__ */ jsxs11(
|
|
6297
6567
|
"button",
|
|
6298
6568
|
{
|
|
@@ -6301,7 +6571,8 @@ function ConversationRow({
|
|
|
6301
6571
|
onClick: () => onSelect(conv.id),
|
|
6302
6572
|
children: [
|
|
6303
6573
|
/* @__PURE__ */ jsx16(ConvCardBody, { conv }),
|
|
6304
|
-
hasUnread && /* @__PURE__ */ jsx16("div", { className: "hw-recent-row-badge", children: conv.unreadCount })
|
|
6574
|
+
hasUnread && /* @__PURE__ */ jsx16("div", { className: "hw-recent-row-badge", children: conv.unreadCount }),
|
|
6575
|
+
awaiting && /* @__PURE__ */ jsx16("div", { className: "hw-awaiting", children: t("widget.awaiting_your_reply") })
|
|
6305
6576
|
]
|
|
6306
6577
|
}
|
|
6307
6578
|
);
|
|
@@ -6354,7 +6625,20 @@ function InlineEmailPrompt({ conversationId }) {
|
|
|
6354
6625
|
};
|
|
6355
6626
|
if (isSuccess) {
|
|
6356
6627
|
return /* @__PURE__ */ jsxs11("div", { className: "hw-email-card hw-email-card--success", children: [
|
|
6357
|
-
/* @__PURE__ */ jsx16(
|
|
6628
|
+
/* @__PURE__ */ jsx16(
|
|
6629
|
+
"svg",
|
|
6630
|
+
{
|
|
6631
|
+
width: "15",
|
|
6632
|
+
height: "15",
|
|
6633
|
+
viewBox: "0 0 24 24",
|
|
6634
|
+
fill: "none",
|
|
6635
|
+
stroke: "#22c55e",
|
|
6636
|
+
strokeWidth: 2.5,
|
|
6637
|
+
strokeLinecap: "round",
|
|
6638
|
+
strokeLinejoin: "round",
|
|
6639
|
+
children: /* @__PURE__ */ jsx16("polyline", { points: "20 6 9 17 4 12" })
|
|
6640
|
+
}
|
|
6641
|
+
),
|
|
6358
6642
|
t("widget.email_saved")
|
|
6359
6643
|
] });
|
|
6360
6644
|
}
|
|
@@ -6386,7 +6670,41 @@ function InlineEmailPrompt({ conversationId }) {
|
|
|
6386
6670
|
onClick: handleSubmit,
|
|
6387
6671
|
disabled: isSubmitting || !email.trim(),
|
|
6388
6672
|
"aria-label": t("widget.email_continue"),
|
|
6389
|
-
children: isSubmitting ? /* @__PURE__ */ jsx16(
|
|
6673
|
+
children: isSubmitting ? /* @__PURE__ */ jsx16(
|
|
6674
|
+
"svg",
|
|
6675
|
+
{
|
|
6676
|
+
width: "14",
|
|
6677
|
+
height: "14",
|
|
6678
|
+
viewBox: "0 0 24 24",
|
|
6679
|
+
fill: "none",
|
|
6680
|
+
stroke: "currentColor",
|
|
6681
|
+
strokeWidth: 2,
|
|
6682
|
+
"aria-hidden": "true",
|
|
6683
|
+
children: /* @__PURE__ */ jsx16("circle", { cx: "12", cy: "12", r: "10", strokeDasharray: "32", strokeDashoffset: "32", children: /* @__PURE__ */ jsx16(
|
|
6684
|
+
"animate",
|
|
6685
|
+
{
|
|
6686
|
+
attributeName: "stroke-dashoffset",
|
|
6687
|
+
values: "32;0",
|
|
6688
|
+
dur: "1s",
|
|
6689
|
+
repeatCount: "indefinite"
|
|
6690
|
+
}
|
|
6691
|
+
) })
|
|
6692
|
+
}
|
|
6693
|
+
) : /* @__PURE__ */ jsx16(
|
|
6694
|
+
"svg",
|
|
6695
|
+
{
|
|
6696
|
+
width: "15",
|
|
6697
|
+
height: "15",
|
|
6698
|
+
viewBox: "0 0 24 24",
|
|
6699
|
+
fill: "none",
|
|
6700
|
+
stroke: "currentColor",
|
|
6701
|
+
strokeWidth: 2.2,
|
|
6702
|
+
strokeLinecap: "round",
|
|
6703
|
+
strokeLinejoin: "round",
|
|
6704
|
+
"aria-hidden": "true",
|
|
6705
|
+
children: /* @__PURE__ */ jsx16("path", { d: "M5 12h13M12 5l7 7-7 7" })
|
|
6706
|
+
}
|
|
6707
|
+
)
|
|
6390
6708
|
}
|
|
6391
6709
|
)
|
|
6392
6710
|
] })
|
|
@@ -6400,14 +6718,7 @@ function NewConversationView({
|
|
|
6400
6718
|
welcomeMessage
|
|
6401
6719
|
}) {
|
|
6402
6720
|
return /* @__PURE__ */ jsxs11("div", { className: "hw-new", children: [
|
|
6403
|
-
/* @__PURE__ */ jsx16("div", { className: "hw-new-welcome", children: /* @__PURE__ */ jsx16(
|
|
6404
|
-
MessageBubble,
|
|
6405
|
-
{
|
|
6406
|
-
text: welcomeMessage,
|
|
6407
|
-
sender: "ai",
|
|
6408
|
-
parts: null
|
|
6409
|
-
}
|
|
6410
|
-
) }),
|
|
6721
|
+
/* @__PURE__ */ jsx16("div", { className: "hw-new-welcome", children: /* @__PURE__ */ jsx16(MessageBubble, { text: welcomeMessage, sender: "ai", parts: null }) }),
|
|
6411
6722
|
/* @__PURE__ */ jsx16(
|
|
6412
6723
|
Composer,
|
|
6413
6724
|
{
|
|
@@ -6595,9 +6906,7 @@ function WhatsNewCard({
|
|
|
6595
6906
|
const unseen = getUnseenEntries();
|
|
6596
6907
|
if (unseen.length === 0) return null;
|
|
6597
6908
|
const display = unseen.slice(0, 3);
|
|
6598
|
-
const badgeFieldMap = new Map(
|
|
6599
|
-
announcementTabs.map((t2) => [t2.id, t2.display?.badgeField])
|
|
6600
|
-
);
|
|
6909
|
+
const badgeFieldMap = new Map(announcementTabs.map((t2) => [t2.id, t2.display?.badgeField]));
|
|
6601
6910
|
return /* @__PURE__ */ jsxs11("div", { className: "hw-whats-new", children: [
|
|
6602
6911
|
/* @__PURE__ */ jsxs11("div", { className: "hw-whats-new-header", children: [
|
|
6603
6912
|
/* @__PURE__ */ jsx16("span", { className: "hw-whats-new-title", children: resolveLabel2("widget.whats_new") }),
|
|
@@ -6658,7 +6967,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
6658
6967
|
}
|
|
6659
6968
|
|
|
6660
6969
|
// src/themed/styles.css
|
|
6661
|
-
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');
|
|
6970
|
+
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 :is(.hw-header-bot-icon, .hw-hero-bot-icon, .hw-conv-card-avatar, .hw-event-avatar, .hw-bubble-icon--bot):has(> .hw-agent-custom) {\n border-radius: 50%;\n background: transparent;\n padding: 0;\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:not(.hw-agent-custom 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.hw-hero-bot-icon > .hw-agent-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.hw-header-bot-icon > .hw-agent-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:not(.hw-agent-custom 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:not(.hw-agent-custom 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:not(.hw-agent-custom 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:not(.hw-agent-custom 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-lead {\n flex: none;\n display: grid;\n place-items: center;\n width: 32px;\n height: 32px;\n margin-left: -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');
|
|
6662
6971
|
|
|
6663
6972
|
// src/helpway-widget.tsx
|
|
6664
6973
|
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
@@ -6673,6 +6982,7 @@ function HelpwayWidget({
|
|
|
6673
6982
|
placement,
|
|
6674
6983
|
colorScheme,
|
|
6675
6984
|
dockSuggestions,
|
|
6985
|
+
agentAvatar,
|
|
6676
6986
|
customLauncherSelector,
|
|
6677
6987
|
onOpen,
|
|
6678
6988
|
onClose,
|
|
@@ -6696,7 +7006,7 @@ function HelpwayWidget({
|
|
|
6696
7006
|
onClose,
|
|
6697
7007
|
onUnreadChange,
|
|
6698
7008
|
theme,
|
|
6699
|
-
children: /* @__PURE__ */ jsx17(
|
|
7009
|
+
children: /* @__PURE__ */ jsx17(AgentAvatarProvider, { value: agentAvatar ?? null, children: /* @__PURE__ */ jsx17(
|
|
6700
7010
|
DefaultWidget,
|
|
6701
7011
|
{
|
|
6702
7012
|
hideLauncher,
|
|
@@ -6704,20 +7014,25 @@ function HelpwayWidget({
|
|
|
6704
7014
|
colorScheme,
|
|
6705
7015
|
dockSuggestions
|
|
6706
7016
|
}
|
|
6707
|
-
)
|
|
7017
|
+
) })
|
|
6708
7018
|
}
|
|
6709
7019
|
);
|
|
6710
7020
|
}
|
|
6711
7021
|
|
|
6712
7022
|
// src/hooks/use-realtime.ts
|
|
6713
|
-
import { useEffect as useEffect16 } from "react";
|
|
7023
|
+
import { useEffect as useEffect16, useRef as useRef16 } from "react";
|
|
6714
7024
|
function useRealtime(handler) {
|
|
6715
7025
|
const { ws } = useWidgetContext();
|
|
7026
|
+
const handlerRef = useRef16(handler);
|
|
7027
|
+
useEffect16(() => {
|
|
7028
|
+
handlerRef.current = handler;
|
|
7029
|
+
});
|
|
6716
7030
|
useEffect16(() => {
|
|
6717
|
-
return ws.onEvent(
|
|
6718
|
-
}, [ws
|
|
7031
|
+
return ws.onEvent((event) => handlerRef.current(event));
|
|
7032
|
+
}, [ws]);
|
|
6719
7033
|
}
|
|
6720
7034
|
export {
|
|
7035
|
+
AgentAvatarProvider,
|
|
6721
7036
|
AnnouncementPreviews,
|
|
6722
7037
|
Composer,
|
|
6723
7038
|
DefaultWidget,
|
|
@@ -6735,6 +7050,7 @@ export {
|
|
|
6735
7050
|
getOrCreateVisitorId,
|
|
6736
7051
|
linkifyText,
|
|
6737
7052
|
renderMarkdown,
|
|
7053
|
+
useAwaitingReply,
|
|
6738
7054
|
useComposer,
|
|
6739
7055
|
useConversations,
|
|
6740
7056
|
useIdentify,
|