@chatwidgetai/chat-widget 0.2.9 → 0.3.1

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.
Files changed (37) hide show
  1. package/dist/ai-chat-widget.umd.js +1546 -331
  2. package/dist/ai-chat-widget.umd.js.map +1 -1
  3. package/dist/api/client.d.ts +2 -2
  4. package/dist/api/client.d.ts.map +1 -1
  5. package/dist/components/ChatWidget.d.ts +2 -1
  6. package/dist/components/ChatWidget.d.ts.map +1 -1
  7. package/dist/components/ChatWindow.d.ts +0 -1
  8. package/dist/components/ChatWindow.d.ts.map +1 -1
  9. package/dist/components/DataPolicyView.d.ts +14 -0
  10. package/dist/components/DataPolicyView.d.ts.map +1 -0
  11. package/dist/hooks/useChat/action-handler.d.ts +6 -0
  12. package/dist/hooks/useChat/action-handler.d.ts.map +1 -0
  13. package/dist/hooks/useChat/action-lifecycle.d.ts +19 -0
  14. package/dist/hooks/useChat/action-lifecycle.d.ts.map +1 -0
  15. package/dist/hooks/useChat/error-utils.d.ts +7 -0
  16. package/dist/hooks/useChat/error-utils.d.ts.map +1 -0
  17. package/dist/hooks/{useChat.d.ts → useChat/index.d.ts} +2 -2
  18. package/dist/hooks/useChat/index.d.ts.map +1 -0
  19. package/dist/hooks/useChat/message-hydration.d.ts +4 -0
  20. package/dist/hooks/useChat/message-hydration.d.ts.map +1 -0
  21. package/dist/hooks/useChat/stream-handlers.d.ts +27 -0
  22. package/dist/hooks/useChat/stream-handlers.d.ts.map +1 -0
  23. package/dist/hooks/useChat/stream-state.d.ts +8 -0
  24. package/dist/hooks/useChat/stream-state.d.ts.map +1 -0
  25. package/dist/hooks/useChat/types.d.ts +26 -0
  26. package/dist/hooks/useChat/types.d.ts.map +1 -0
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.esm.js +1546 -331
  30. package/dist/index.esm.js.map +1 -1
  31. package/dist/index.js +1546 -331
  32. package/dist/index.js.map +1 -1
  33. package/dist/types/index.d.ts +10 -3
  34. package/dist/types/index.d.ts.map +1 -1
  35. package/dist/utils/sse-parser.d.ts.map +1 -1
  36. package/package.json +7 -3
  37. package/dist/hooks/useChat.d.ts.map +0 -1
@@ -16696,11 +16696,14 @@
16696
16696
  const reader = response.body.getReader();
16697
16697
  const decoder = new TextDecoder();
16698
16698
  let buffer = "";
16699
+ let eventCount = 0;
16699
16700
  try {
16700
16701
  while (true) {
16701
16702
  const { done, value } = await reader.read();
16702
- if (done)
16703
+ if (done) {
16704
+ console.log(`[SSE Parser] Stream ended normally after ${eventCount} events`);
16703
16705
  break;
16706
+ }
16704
16707
  buffer += decoder.decode(value, { stream: true });
16705
16708
  const chunks = buffer.split("\n\n");
16706
16709
  buffer = chunks.pop() || "";
@@ -16712,6 +16715,7 @@
16712
16715
  const data = JSON.parse(line.slice(6));
16713
16716
  if (validator) {
16714
16717
  if (validator(data)) {
16718
+ eventCount++;
16715
16719
  yield data;
16716
16720
  }
16717
16721
  else {
@@ -16719,6 +16723,7 @@
16719
16723
  }
16720
16724
  }
16721
16725
  else {
16726
+ eventCount++;
16722
16727
  yield data;
16723
16728
  }
16724
16729
  }
@@ -16731,6 +16736,10 @@
16731
16736
  }
16732
16737
  }
16733
16738
  }
16739
+ catch (error) {
16740
+ console.error(`[SSE Parser] Stream error after ${eventCount} events:`, error);
16741
+ throw error;
16742
+ }
16734
16743
  finally {
16735
16744
  reader.releaseLock();
16736
16745
  }
@@ -16864,7 +16873,7 @@
16864
16873
  const result = await response.json();
16865
16874
  return result.file;
16866
16875
  }
16867
- async *sendAgentMessageStream(conversationId, message, fileIds) {
16876
+ async *sendAgentMessageStream(conversationId, message, fileIds, signal) {
16868
16877
  const headers = {
16869
16878
  'Content-Type': 'application/json',
16870
16879
  };
@@ -16880,6 +16889,7 @@
16880
16889
  fileIds,
16881
16890
  timeZone: this.getTimeZone(),
16882
16891
  }),
16892
+ signal,
16883
16893
  });
16884
16894
  if (!response.ok) {
16885
16895
  throw await buildApiError(response, 'Failed to send agent message');
@@ -16888,7 +16898,7 @@
16888
16898
  return typeof data === 'object' && data !== null && 'type' in data;
16889
16899
  });
16890
16900
  }
16891
- async *continueAgentMessageStream(conversationId, toolCallId, state) {
16901
+ async *continueAgentMessageStream(conversationId, toolCallId, state, signal) {
16892
16902
  const headers = {
16893
16903
  'Content-Type': 'application/json',
16894
16904
  };
@@ -16904,6 +16914,7 @@
16904
16914
  state,
16905
16915
  timeZone: this.getTimeZone(),
16906
16916
  }),
16917
+ signal,
16907
16918
  });
16908
16919
  if (!response.ok) {
16909
16920
  throw await buildApiError(response, 'Failed to continue agent');
@@ -43804,18 +43815,14 @@
43804
43815
  .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
43805
43816
  .join(' ');
43806
43817
  };
43807
- const GearIcon = ({ spinning = false }) => (jsxRuntimeExports.jsxs("svg", { className: `ai-chat-tool-gear ${spinning ? 'spinning' : ''}`, width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M12 20a8 8 0 1 0 0-16 8 8 0 0 0 0 16Z" }), jsxRuntimeExports.jsx("path", { d: "M12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z" }), jsxRuntimeExports.jsx("path", { d: "M12 2v2" }), jsxRuntimeExports.jsx("path", { d: "M12 22v-2" }), jsxRuntimeExports.jsx("path", { d: "m17 20.66-1-1.73" }), jsxRuntimeExports.jsx("path", { d: "M11 10.27 7 3.34" }), jsxRuntimeExports.jsx("path", { d: "m20.66 17-1.73-1" }), jsxRuntimeExports.jsx("path", { d: "m3.34 7 1.73 1" }), jsxRuntimeExports.jsx("path", { d: "M14 12h8" }), jsxRuntimeExports.jsx("path", { d: "M2 12h2" }), jsxRuntimeExports.jsx("path", { d: "m20.66 7-1.73 1" }), jsxRuntimeExports.jsx("path", { d: "m3.34 17 1.73-1" }), jsxRuntimeExports.jsx("path", { d: "m17 3.34-1 1.73" }), jsxRuntimeExports.jsx("path", { d: "m11 13.73-4 6.93" })] }));
43808
- const CheckIcon$2 = () => (jsxRuntimeExports.jsx("svg", { className: "ai-chat-tool-check", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
43809
- const ErrorIcon = () => (jsxRuntimeExports.jsx("svg", { className: "ai-chat-tool-error", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }));
43810
43818
  function ToolIndicator({ badges, className = '' }) {
43811
- const isAnyLoading = badges.some(b => b.status === 'loading');
43812
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-tool-row ${className}`, children: [jsxRuntimeExports.jsx(GearIcon, { spinning: isAnyLoading }), jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-badges", children: badges.map((badge) => (jsxRuntimeExports.jsxs("div", { className: `ai-chat-tool-badge ${badge.status}`, children: [badge.status !== 'loading' && (badge.status === 'error' ? jsxRuntimeExports.jsx(ErrorIcon, {}) : jsxRuntimeExports.jsx(CheckIcon$2, {})), jsxRuntimeExports.jsx("span", { className: "tool-name", children: formatToolName(badge.name) })] }, badge.id))) })] }));
43819
+ return (jsxRuntimeExports.jsx("div", { className: `ai-chat-tool-row ${className}`, children: jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-badges", children: badges.map((badge) => (jsxRuntimeExports.jsx("div", { className: `ai-chat-tool-badge ${badge.status}`, children: jsxRuntimeExports.jsx("span", { className: "tool-name", children: formatToolName(badge.name) }) }, badge.id))) }) }));
43813
43820
  }
43814
43821
 
43815
43822
  // SVG Icon components
43816
43823
  const ThumbsUpIcon = () => (jsxRuntimeExports.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3" }) }));
43817
43824
  const ThumbsDownIcon = () => (jsxRuntimeExports.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17" }) }));
43818
- const CheckIcon$1 = () => (jsxRuntimeExports.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
43825
+ const CheckIcon$2 = () => (jsxRuntimeExports.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
43819
43826
  const FeedbackButtons = ({ messageId, currentFeedback, onFeedback, }) => {
43820
43827
  const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
43821
43828
  const [submitted, setSubmitted] = reactExports.useState(false);
@@ -43836,17 +43843,10 @@
43836
43843
  setIsSubmitting(false);
43837
43844
  }
43838
43845
  };
43839
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-feedback ${submitted ? 'submitted' : ''}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-feedback-buttons", children: [jsxRuntimeExports.jsx("button", { className: `ai-chat-feedback-button ${currentFeedback === 'positive' ? 'active' : ''}`, onClick: () => handleFeedback('positive'), disabled: isDisabled, "aria-label": "Helpful", title: "This was helpful", children: jsxRuntimeExports.jsx(ThumbsUpIcon, {}) }), jsxRuntimeExports.jsx("button", { className: `ai-chat-feedback-button ${currentFeedback === 'negative' ? 'active' : ''}`, onClick: () => handleFeedback('negative'), disabled: isDisabled, "aria-label": "Not helpful", title: "This was not helpful", children: jsxRuntimeExports.jsx(ThumbsDownIcon, {}) })] }), submitted && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-feedback-message", "aria-live": "polite", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-feedback-checkmark", children: jsxRuntimeExports.jsx(CheckIcon$1, {}) }), jsxRuntimeExports.jsx("span", { className: "ai-chat-feedback-text", children: "Thanks for feedback" })] }))] }));
43840
- };
43841
-
43842
- const Sources = ({ sources, displayMode = 'with-score' }) => {
43843
- const [isExpanded, setIsExpanded] = reactExports.useState(false);
43844
- if (!sources || sources.length === 0 || displayMode === 'none')
43845
- return null;
43846
- return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-sources", children: [jsxRuntimeExports.jsxs("button", { className: "ai-chat-sources-toggle", onClick: () => setIsExpanded(!isExpanded), "aria-expanded": isExpanded, children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-sources-icon", children: isExpanded ? '▼' : '▶' }), jsxRuntimeExports.jsxs("span", { className: "ai-chat-sources-title", children: [sources.length, " source", sources.length > 1 ? 's' : ''] })] }), isExpanded && displayMode !== 'minimal' && (jsxRuntimeExports.jsx("div", { className: "ai-chat-sources-list", children: sources.map((source, index) => (jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-item", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-number", children: [index + 1, "."] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-details", children: [displayMode === 'with-score' && source.score && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-score", children: ["Score: ", (source.score * 100).toFixed(0), "%"] })), (displayMode === 'with-content' || displayMode === 'full') && source.doc.pageContent && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-content", children: [source.doc.pageContent.substring(0, 100), source.doc.pageContent.length > 100 ? '...' : ''] })), displayMode === 'full' && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [source.score && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-source-score", children: ["Score: ", (source.score * 100).toFixed(0), "%"] })), source.doc.metadata && Object.keys(source.doc.metadata).length > 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-source-metadata", children: Object.entries(source.doc.metadata).map(([key, value]) => (jsxRuntimeExports.jsxs("span", { className: "ai-chat-source-meta-item", children: [key, ": ", String(value)] }, key))) }))] }))] })] }, `${source.kbId}-${source.doc.id}-${index}`))) }))] }));
43846
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-feedback ${submitted ? 'submitted' : ''}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-feedback-buttons", children: [jsxRuntimeExports.jsx("button", { className: `ai-chat-feedback-button ${currentFeedback === 'positive' ? 'active' : ''}`, onClick: () => handleFeedback('positive'), disabled: isDisabled, "aria-label": "Helpful", title: "This was helpful", children: jsxRuntimeExports.jsx(ThumbsUpIcon, {}) }), jsxRuntimeExports.jsx("button", { className: `ai-chat-feedback-button ${currentFeedback === 'negative' ? 'active' : ''}`, onClick: () => handleFeedback('negative'), disabled: isDisabled, "aria-label": "Not helpful", title: "This was not helpful", children: jsxRuntimeExports.jsx(ThumbsDownIcon, {}) })] }), submitted && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-feedback-message", "aria-live": "polite", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-feedback-checkmark", children: jsxRuntimeExports.jsx(CheckIcon$2, {}) }), jsxRuntimeExports.jsx("span", { className: "ai-chat-feedback-text", children: "Thanks for feedback" })] }))] }));
43847
43847
  };
43848
43848
 
43849
- const Message = ({ message, showTimestamp = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', onFeedback, getActionRenderer, }) => {
43849
+ const Message = ({ message, showTimestamp = true, enableFeedback = true, onFeedback, }) => {
43850
43850
  const formatTime = (timestamp) => {
43851
43851
  const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
43852
43852
  return date.toLocaleTimeString('en-US', {
@@ -43866,15 +43866,15 @@
43866
43866
  return null;
43867
43867
  }
43868
43868
  // AI message rendering
43869
+ // Note: Actions are rendered by ToolMessageGroup for tool messages, not here
43869
43870
  if (isAssistant) {
43870
43871
  const aiContent = message.message.content || '';
43871
43872
  const hasContent = aiContent.trim().length > 0;
43872
43873
  if (!hasContent)
43873
43874
  return null;
43874
- const actionRenderer = message.action && getActionRenderer
43875
- ? getActionRenderer(message.action.implementation)
43876
- : undefined;
43877
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-message assistant ${isError ? 'error' : ''}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-message-content", children: [isError && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-error-indicator", children: [jsxRuntimeExports.jsx("span", { className: "error-icon", children: "\u26A0\uFE0F" }), jsxRuntimeExports.jsx("span", { className: "error-text", children: "Error" })] })), jsxRuntimeExports.jsx(Markdown, { remarkPlugins: [remarkGfm], children: aiContent })] }), actionRenderer && message.action && actionRenderer(message), showTimestamp && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message-meta", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }), enableFeedback && onFeedback && (jsxRuntimeExports.jsx(FeedbackButtons, { messageId: message.id, currentFeedback: message.feedback, onFeedback: onFeedback }))] })), showSources && message.sources?.length > 0 && (jsxRuntimeExports.jsx(Sources, { sources: message.sources, displayMode: sourceDisplayMode }))] }));
43875
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-message assistant ${isError ? 'error' : ''}`, children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-message-content", children: jsxRuntimeExports.jsx(Markdown, { remarkPlugins: [remarkGfm], components: {
43876
+ table: ({ children, ...props }) => (jsxRuntimeExports.jsx("div", { className: "table-wrapper", children: jsxRuntimeExports.jsx("div", { className: "table-scroll", children: jsxRuntimeExports.jsx("table", { ...props, children: children }) }) })),
43877
+ }, children: aiContent }) }), showTimestamp && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message-meta", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }), enableFeedback && onFeedback && (jsxRuntimeExports.jsx(FeedbackButtons, { messageId: message.id, currentFeedback: message.feedback, onFeedback: onFeedback }))] }))] }));
43878
43878
  }
43879
43879
  // System message rendering
43880
43880
  if (isSystem) {
@@ -43888,30 +43888,85 @@
43888
43888
  return null;
43889
43889
  };
43890
43890
 
43891
- const ToolMessageGroup = ({ messages, getActionRenderer }) => {
43891
+ // Centralized action state logic
43892
+ function isActionComplete(state) {
43893
+ if (!state)
43894
+ return false;
43895
+ const TERMINAL_STATUSES = [
43896
+ 'completed', 'booked', 'scheduled', 'cancelled', 'failed', 'error',
43897
+ 'displaying', 'clicked', 'contacted', 'submitted', 'sent'
43898
+ ];
43899
+ const status = state.status;
43900
+ if (typeof status === 'string' && TERMINAL_STATUSES.includes(status)) {
43901
+ return true;
43902
+ }
43903
+ // For non-halting actions (query_contact_directory, etc.) with results/success
43904
+ if (!status && (state.success !== undefined || state.results !== undefined)) {
43905
+ return true;
43906
+ }
43907
+ return false;
43908
+ }
43909
+ function isActionLoading(message) {
43910
+ if (!message.action)
43911
+ return false;
43912
+ if (message.action.done)
43913
+ return false;
43914
+ if (message.isStreaming)
43915
+ return true;
43916
+ const state = message.action.state;
43917
+ return !isActionComplete(state);
43918
+ }
43919
+ const ToolMessageGroup = ({ messages, getActionRenderer, showToolIndicator = true, accentColor, variant }) => {
43892
43920
  const actionMessages = messages.filter(message => message.action);
43921
+ // Debug logging
43922
+ console.log('[DEBUG ToolMessageGroup] ========================================');
43923
+ console.log('[DEBUG ToolMessageGroup] Total messages:', messages.length);
43924
+ console.log('[DEBUG ToolMessageGroup] Messages with action:', actionMessages.length);
43925
+ console.log('[DEBUG ToolMessageGroup] hasGetActionRenderer:', !!getActionRenderer);
43926
+ messages.forEach((msg, i) => {
43927
+ console.log(`[DEBUG ToolMessageGroup] Message ${i}:`, {
43928
+ id: msg.id,
43929
+ role: msg.message.role,
43930
+ hasAction: !!msg.action,
43931
+ actionImpl: msg.action?.implementation,
43932
+ toolExecuting: msg.toolExecuting,
43933
+ });
43934
+ });
43935
+ actionMessages.forEach((msg, i) => {
43936
+ const impl = msg.action?.implementation || '';
43937
+ const renderer = getActionRenderer?.(impl);
43938
+ console.log(`[DEBUG ToolMessageGroup] Action ${i}:`, {
43939
+ implementation: impl,
43940
+ hasRenderer: !!renderer,
43941
+ rendererType: renderer ? typeof renderer : 'undefined',
43942
+ state: msg.action?.state,
43943
+ });
43944
+ });
43945
+ // If tool indicator is hidden AND there are no action cards to render, don't render anything
43946
+ if (!showToolIndicator && actionMessages.length === 0) {
43947
+ return null;
43948
+ }
43893
43949
  const badges = messages.map((message) => {
43894
43950
  const toolName = message.toolExecuting || message.message.name || 'Tool';
43895
43951
  const hasError = message.isError || false;
43896
- const actionState = message.action?.state;
43897
- const actionStatus = actionState?.status;
43898
- const terminalStatuses = ['completed', 'booked', 'scheduled', 'failed', 'cancelled'];
43899
- const isTerminalStatus = actionStatus && terminalStatuses.includes(actionStatus);
43900
- const isDone = message.action ? (message.action.done ?? isTerminalStatus ?? false) : !message.isStreaming;
43901
- const isLoading = !isDone;
43952
+ const loading = isActionLoading(message);
43902
43953
  return {
43903
43954
  id: message.id,
43904
43955
  name: toolName,
43905
- status: isLoading ? 'loading' : hasError ? 'error' : 'completed',
43956
+ status: loading ? 'loading' : hasError ? 'error' : 'completed',
43906
43957
  };
43907
43958
  });
43908
- return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message tool", children: [jsxRuntimeExports.jsx(ToolIndicator, { badges: badges }), actionMessages.map((message) => {
43909
- if (!message.action || !getActionRenderer)
43959
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-message tool", children: [showToolIndicator && jsxRuntimeExports.jsx(ToolIndicator, { badges: badges }), actionMessages.map((message) => {
43960
+ if (!message.action || !getActionRenderer) {
43961
+ console.log('[ToolMessageGroup] Skipping - no action or renderer:', { hasAction: !!message.action, hasGetRenderer: !!getActionRenderer });
43910
43962
  return null;
43963
+ }
43911
43964
  const renderer = getActionRenderer(message.action.implementation);
43912
- if (!renderer)
43965
+ if (!renderer) {
43966
+ console.log('[ToolMessageGroup] No renderer for:', message.action.implementation);
43913
43967
  return null;
43914
- return (jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-action", children: renderer(message) }, `action-${message.id}`));
43968
+ }
43969
+ return (jsxRuntimeExports.jsx("div", { className: "ai-chat-tool-action", children: renderer(message, accentColor, variant) }, `action-${message.id}`));
43915
43970
  })] }));
43916
43971
  };
43917
43972
 
@@ -43973,12 +44028,16 @@
43973
44028
  };
43974
44029
 
43975
44030
  const MessageList = (props) => {
43976
- const { messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeTitle, welcomeMessage, suggestedQuestions, accentColor, onSuggestedQuestionClick, onActionClick, onFeedback, onScrollStateChange, getActionRenderer, } = props;
44031
+ const { messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, showToolCalls = false, enableFeedback = true, welcomeTitle, welcomeMessage, suggestedQuestions, accentColor, onSuggestedQuestionClick, onActionClick, onFeedback, onScrollStateChange, getActionRenderer, variant, } = props;
43977
44032
  const containerRef = reactExports.useRef(null);
43978
44033
  const messagesEndRef = reactExports.useRef(null);
43979
44034
  const [showScrollButton, setShowScrollButton] = reactExports.useState(false);
43980
44035
  const prevMessageCountRef = reactExports.useRef(0);
43981
- const hasActiveAction = reactExports.useMemo(() => messages.some(msg => msg.action?.state?.status && !['completed', 'booked', 'failed'].includes(msg.action.state.status)), [messages]);
44036
+ const hasActiveAction = reactExports.useMemo(() => {
44037
+ // Find the last tool message and check if its action is still active (not done)
44038
+ const lastToolMsg = [...messages].reverse().find(msg => msg.message.role === 'tool');
44039
+ return lastToolMsg?.action && lastToolMsg.action.done !== true;
44040
+ }, [messages]);
43982
44041
  const checkScrollPosition = reactExports.useCallback(() => {
43983
44042
  const c = containerRef.current;
43984
44043
  if (!c)
@@ -44014,39 +44073,70 @@
44014
44073
  checkScrollPosition();
44015
44074
  }, [messages, isTyping, checkScrollPosition]);
44016
44075
  const groupedMessages = reactExports.useMemo(() => {
44076
+ console.log('[DEBUG MessageList] ========================================');
44077
+ console.log('[DEBUG MessageList] Processing messages:', messages.length);
44078
+ messages.forEach((m, i) => {
44079
+ console.log(`[DEBUG MessageList] Message ${i}:`, {
44080
+ id: m.id,
44081
+ role: m.message.role,
44082
+ hasAction: !!m.action,
44083
+ actionImpl: m.action?.implementation,
44084
+ content: (m.message.content || '').substring(0, 50),
44085
+ });
44086
+ });
44017
44087
  const result = [];
44018
44088
  let toolGroup = [];
44019
- const flush = () => { if (toolGroup.length) {
44020
- result.push({ type: 'tool-group', messages: [...toolGroup] });
44021
- toolGroup = [];
44022
- } };
44089
+ const flush = () => {
44090
+ if (toolGroup.length) {
44091
+ console.log('[DEBUG MessageList] Flushing tool group with', toolGroup.length, 'messages');
44092
+ result.push({ type: 'tool-group', messages: [...toolGroup] });
44093
+ toolGroup = [];
44094
+ }
44095
+ };
44023
44096
  for (const m of messages) {
44024
- if (m.message.role === 'tool')
44097
+ if (m.message.role === 'tool') {
44098
+ console.log('[DEBUG MessageList] Adding to tool group:', m.id);
44025
44099
  toolGroup.push(m);
44100
+ }
44026
44101
  else if (m.message.role === 'user') {
44027
44102
  flush();
44028
44103
  result.push({ type: 'message', message: m });
44029
44104
  }
44030
- else if (m.message.role === 'assistant' && (m.message.content || '').trim()) {
44031
- flush();
44032
- result.push({ type: 'message', message: m });
44105
+ else if (m.message.role === 'assistant') {
44106
+ // Include assistant messages if they have content OR are still streaming (content may arrive)
44107
+ const hasContent = (m.message.content || '').trim().length > 0;
44108
+ if (hasContent || m.isStreaming) {
44109
+ flush();
44110
+ result.push({ type: 'message', message: m });
44111
+ }
44112
+ // Don't flush on empty assistant messages - let tools continue grouping
44033
44113
  }
44034
- else if (m.message.role !== 'assistant') {
44114
+ else {
44035
44115
  flush();
44036
44116
  result.push({ type: 'message', message: m });
44037
44117
  }
44038
44118
  }
44039
44119
  flush();
44120
+ console.log('[DEBUG MessageList] Final grouped result:', result.length, 'items');
44121
+ result.forEach((item, i) => {
44122
+ if (item.type === 'tool-group') {
44123
+ console.log(`[DEBUG MessageList] Group ${i}: tool-group with ${item.messages.length} messages`);
44124
+ }
44125
+ else {
44126
+ console.log(`[DEBUG MessageList] Group ${i}: message (${item.message.message.role})`);
44127
+ }
44128
+ });
44040
44129
  return result;
44041
44130
  }, [messages]);
44042
44131
  const hasSuggestions = messages.length === 0 && onSuggestedQuestionClick && suggestedQuestions?.length;
44043
44132
  const showWelcome = welcomeTitle || welcomeMessage || hasSuggestions;
44044
44133
  return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "ai-chat-messages", role: "log", "aria-live": "polite", children: [showWelcome && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-welcome", children: [welcomeTitle && jsxRuntimeExports.jsx("div", { className: "ai-chat-welcome-title", children: welcomeTitle }), welcomeMessage && jsxRuntimeExports.jsx("div", { className: "ai-chat-welcome-text", children: welcomeMessage }), hasSuggestions && jsxRuntimeExports.jsx(SuggestedQuestions, { questions: suggestedQuestions, onQuestionClick: onSuggestedQuestionClick })] })), groupedMessages.map((item, i) => {
44045
- if (item.type === 'tool-group')
44046
- return jsxRuntimeExports.jsx(ToolMessageGroup, { messages: item.messages, getActionRenderer: getActionRenderer }, `tg-${i}`);
44134
+ if (item.type === 'tool-group') {
44135
+ return jsxRuntimeExports.jsx(ToolMessageGroup, { messages: item.messages, getActionRenderer: getActionRenderer, showToolIndicator: showToolCalls, accentColor: accentColor, variant: variant }, `tg-${i}`);
44136
+ }
44047
44137
  const isLast = i === groupedMessages.length - 1;
44048
44138
  const hasFollowUp = item.message.message.role === 'assistant' && item.message.suggestions?.length && isLast && !isTyping;
44049
- return (jsxRuntimeExports.jsxs(React.Fragment, { children: [jsxRuntimeExports.jsx(Message, { message: item.message, showTimestamp: showTimestamps, enableFeedback: enableFeedback, showSources: showSources, sourceDisplayMode: sourceDisplayMode, onFeedback: onFeedback, getActionRenderer: getActionRenderer }), hasFollowUp && onSuggestedQuestionClick && jsxRuntimeExports.jsx(FollowUpSuggestions, { suggestions: item.message.suggestions, onQuestionClick: onSuggestedQuestionClick, onActionClick: onActionClick, accentColor: accentColor })] }, item.message.id));
44139
+ return (jsxRuntimeExports.jsxs(React.Fragment, { children: [jsxRuntimeExports.jsx(Message, { message: item.message, showTimestamp: showTimestamps, onFeedback: onFeedback, getActionRenderer: getActionRenderer, accentColor: accentColor }), hasFollowUp && onSuggestedQuestionClick && jsxRuntimeExports.jsx(FollowUpSuggestions, { suggestions: item.message.suggestions, onQuestionClick: onSuggestedQuestionClick, onActionClick: onActionClick, accentColor: accentColor })] }, item.message.id));
44050
44140
  }), isTyping && showTypingIndicator && !hasActiveAction && messages.length > 0 && jsxRuntimeExports.jsx(TypingIndicator, {}), jsxRuntimeExports.jsx("div", { ref: messagesEndRef })] }));
44051
44141
  };
44052
44142
 
@@ -44061,7 +44151,7 @@
44061
44151
  return (bytes / 1024).toFixed(1) + ' KB';
44062
44152
  return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
44063
44153
  };
44064
- const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, separateFromChat = true, }) => {
44154
+ const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, separateFromChat = true, showDataPolicy = true, onDataPolicyClick, }) => {
44065
44155
  const [value, setValue] = reactExports.useState('');
44066
44156
  const [selectedFiles, setSelectedFiles] = reactExports.useState([]);
44067
44157
  const textareaRef = reactExports.useRef(null);
@@ -44096,10 +44186,10 @@
44096
44186
  }
44097
44187
  };
44098
44188
  const canSend = value.trim() || selectedFiles.length > 0;
44099
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-input-container ${separateFromChat ? 'separate' : 'integrated'}`, children: [selectedFiles.length > 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-file-list", children: selectedFiles.map((file, index) => (jsxRuntimeExports.jsxs("div", { className: "ai-chat-file-item", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-file-extension", children: getFileExtension(file.name) }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-file-info", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-file-name", children: file.name }), jsxRuntimeExports.jsx("span", { className: "ai-chat-file-size", children: formatFileSize(file.size) })] }), jsxRuntimeExports.jsx("button", { className: "ai-chat-file-remove", onClick: () => handleRemoveFile(index), "aria-label": "Remove file", children: jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: jsxRuntimeExports.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }, index))) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-input-wrapper", children: [enableFileUpload && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", onChange: handleFileSelect, style: { display: 'none' }, multiple: true, accept: ALLOWED_EXTENSIONS.join(',') }), jsxRuntimeExports.jsx("button", { className: "ai-chat-file-button", onClick: () => fileInputRef.current?.click(), disabled: disabled, "aria-label": "Attach file", children: jsxRuntimeExports.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntimeExports.jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) }) })] })), jsxRuntimeExports.jsx("textarea", { ref: textareaRef, className: "ai-chat-input", value: value, onChange: (e) => setValue(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 2, wrap: "soft", "aria-label": "Message input" }), jsxRuntimeExports.jsx("button", { className: `ai-chat-send-button ${canSend ? 'active' : ''}`, onClick: handleSend, disabled: disabled || !canSend, "aria-label": "Send message", children: jsxRuntimeExports.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: [jsxRuntimeExports.jsx("path", { d: "M12 19V5" }), jsxRuntimeExports.jsx("path", { d: "M5 12l7-7 7 7" })] }) })] })] }));
44189
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-input-container ${separateFromChat ? 'separate' : 'integrated'}`, children: [selectedFiles.length > 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-file-list", children: selectedFiles.map((file, index) => (jsxRuntimeExports.jsxs("div", { className: "ai-chat-file-item", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-file-extension", children: getFileExtension(file.name) }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-file-info", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-file-name", children: file.name }), jsxRuntimeExports.jsx("span", { className: "ai-chat-file-size", children: formatFileSize(file.size) })] }), jsxRuntimeExports.jsx("button", { className: "ai-chat-file-remove", onClick: () => handleRemoveFile(index), "aria-label": "Remove file", children: jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: jsxRuntimeExports.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }, index))) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-input-wrapper", children: [enableFileUpload && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", onChange: handleFileSelect, style: { display: 'none' }, multiple: true, accept: ALLOWED_EXTENSIONS.join(',') }), jsxRuntimeExports.jsx("button", { className: "ai-chat-file-button", onClick: () => fileInputRef.current?.click(), disabled: disabled, "aria-label": "Attach file", children: jsxRuntimeExports.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntimeExports.jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) }) })] })), jsxRuntimeExports.jsx("textarea", { ref: textareaRef, className: "ai-chat-input", value: value, onChange: (e) => setValue(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 2, wrap: "soft", "aria-label": "Message input" }), jsxRuntimeExports.jsx("button", { className: `ai-chat-send-button ${canSend ? 'active' : ''}`, onClick: handleSend, disabled: disabled || !canSend, "aria-label": "Send message", children: jsxRuntimeExports.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: [jsxRuntimeExports.jsx("path", { d: "M12 19V5" }), jsxRuntimeExports.jsx("path", { d: "M5 12l7-7 7 7" })] }) })] }), showDataPolicy && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy", children: [jsxRuntimeExports.jsx("span", { children: "KI-generierte Antworten k\u00F6nnen unzutreffend sein." }), onDataPolicyClick && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [' ', jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-data-policy-link", onClick: onDataPolicyClick, children: "Datenschutzhinweis" })] }))] }))] }));
44100
44190
  };
44101
44191
 
44102
- function groupSlotsByDate(slots) {
44192
+ function groupSlotsByDate$1(slots) {
44103
44193
  const grouped = new Map();
44104
44194
  for (const slot of slots) {
44105
44195
  if (!slot || typeof slot !== 'object' || !slot.startTime || typeof slot.startTime !== 'string') {
@@ -44113,7 +44203,7 @@
44113
44203
  }
44114
44204
  return grouped;
44115
44205
  }
44116
- function formatDate(dateStr) {
44206
+ function formatDate$1(dateStr) {
44117
44207
  try {
44118
44208
  const date = new Date(dateStr);
44119
44209
  return new Intl.DateTimeFormat("en-US", {
@@ -44126,16 +44216,16 @@
44126
44216
  return dateStr;
44127
44217
  }
44128
44218
  }
44129
- function CalendarIcon() {
44219
+ function CalendarIcon$1() {
44130
44220
  return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z", clipRule: "evenodd" }) }));
44131
44221
  }
44132
- function CheckIcon() {
44222
+ function CheckIcon$1() {
44133
44223
  return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon-success", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }));
44134
44224
  }
44135
- function ExternalLinkIcon() {
44225
+ function ExternalLinkIcon$2() {
44136
44226
  return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), jsxRuntimeExports.jsx("polyline", { points: "15 3 21 3 21 9" }), jsxRuntimeExports.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })] }));
44137
44227
  }
44138
- function Skeleton({ width, height, borderRadius = '4px' }) {
44228
+ function Skeleton$1({ width, height, borderRadius = '4px' }) {
44139
44229
  return (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-skeleton-item", style: { width, height, borderRadius } }));
44140
44230
  }
44141
44231
  function GoogleCalendarCard({ action, onComplete, accentColor, className = '' }) {
@@ -44152,13 +44242,12 @@
44152
44242
  : [];
44153
44243
  const allowTopic = state.allowTopic !== false;
44154
44244
  const isBooked = state.status === "booked";
44155
- const slotsByDate = groupSlotsByDate(availableSlots);
44245
+ const slotsByDate = groupSlotsByDate$1(availableSlots);
44156
44246
  const dates = Array.from(slotsByDate.keys()).sort();
44157
44247
  const [selectedDate, setSelectedDate] = reactExports.useState(dates[0] ?? "");
44158
44248
  const [selectedSlot, setSelectedSlot] = reactExports.useState(null);
44159
44249
  const [topic, setTopic] = reactExports.useState("");
44160
44250
  const [error, setError] = reactExports.useState(null);
44161
- const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
44162
44251
  const slotsForSelectedDate = selectedDate ? slotsByDate.get(selectedDate) ?? [] : [];
44163
44252
  const accentStyle = accentColor ? { '--action-accent': accentColor } : {};
44164
44253
  const onConfirm = () => {
@@ -44171,8 +44260,245 @@
44171
44260
  return;
44172
44261
  }
44173
44262
  setError(null);
44263
+ onComplete?.(action.toolCallId, {
44264
+ ...action.state,
44265
+ selectedSlot: {
44266
+ startTime: selectedSlot.startTime,
44267
+ endTime: selectedSlot.endTime,
44268
+ },
44269
+ topic: allowTopic ? topic.trim() : null,
44270
+ });
44271
+ };
44272
+ // Booked state
44273
+ if (isBooked) {
44274
+ const bookedSlot = state.selectedSlot;
44275
+ const bookedTopic = state.topic;
44276
+ const eventLink = state.bookedEventLink;
44277
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-booked ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-success-icon-wrapper", children: jsxRuntimeExports.jsx(CheckIcon$1, {}) }), "Appointment Confirmed"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [bookedTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TOPIC" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedTopic })] })), bookedSlot && bookedSlot.startTime && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TIME" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedSlot.displayTime || new Date(bookedSlot.startTime).toLocaleString() })] })), eventLink && (jsxRuntimeExports.jsxs("a", { href: eventLink, target: "_blank", rel: "noopener noreferrer", className: "ai-chat-action-link-button", children: ["View in Google Calendar", jsxRuntimeExports.jsx(ExternalLinkIcon$2, {})] }))] })] }));
44278
+ }
44279
+ // Skeleton loading state - show when waiting for backend after user confirms
44280
+ const isWaitingForBackend = !action.done && state.selectedSlot && !isBooked;
44281
+ if (isWaitingForBackend) {
44282
+ return (jsxRuntimeExports.jsx("div", { className: `ai-chat-action-card ai-chat-action-skeleton ${className}`, style: accentStyle, children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-header", children: [jsxRuntimeExports.jsx(Skeleton$1, { width: "28px", height: "28px", borderRadius: "50%" }), jsxRuntimeExports.jsx(Skeleton$1, { width: "180px", height: "20px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton$1, { width: "60px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton$1, { width: "120px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton$1, { width: "50px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton$1, { width: "200px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.jsx(Skeleton$1, { width: "100%", height: "44px", borderRadius: "999px" })] }) }));
44283
+ }
44284
+ // Booking form
44285
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-google-calendar ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon$1, {}), "Schedule an Appointment"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [allowTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { htmlFor: `topic-${action.toolCallId}`, className: "ai-chat-action-label", children: "Meeting Topic" }), jsxRuntimeExports.jsx("input", { id: `topic-${action.toolCallId}`, type: "text", className: "ai-chat-action-input", placeholder: "e.g., Product Demo", value: topic, onChange: (e) => setTopic(e.target.value) })] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Date" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-date-grid", children: dates.slice(0, 7).map((date) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-date-btn ${selectedDate === date ? "active" : ""}`, onClick: () => {
44286
+ setSelectedDate(date);
44287
+ setSelectedSlot(null);
44288
+ }, children: formatDate$1(date) }, date))) })] }), selectedDate && slotsForSelectedDate.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Time" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-time-grid", children: slotsForSelectedDate.map((slot) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-time-btn ${selectedSlot?.startTime === slot.startTime ? "active" : ""}`, onClick: () => setSelectedSlot(slot), children: slot.displayTime || new Date(slot.startTime).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }, slot.startTime))) })] })), error && jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: error }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: onConfirm, disabled: !selectedSlot, children: "Confirm Appointment" }), availableSlots.length === 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "No available time slots found." }))] })] }));
44289
+ }
44290
+
44291
+ function groupSlotsByDate(slots) {
44292
+ const grouped = new Map();
44293
+ for (const slot of slots) {
44294
+ if (!slot || typeof slot !== 'object' || !slot.startTime || typeof slot.startTime !== 'string') {
44295
+ continue;
44296
+ }
44297
+ const date = slot.startTime.slice(0, 10);
44298
+ if (!grouped.has(date)) {
44299
+ grouped.set(date, []);
44300
+ }
44301
+ grouped.get(date).push(slot);
44302
+ }
44303
+ return grouped;
44304
+ }
44305
+ function formatDate(dateStr) {
44306
+ try {
44307
+ const date = new Date(dateStr);
44308
+ return new Intl.DateTimeFormat("en-US", {
44309
+ weekday: "short",
44310
+ month: "short",
44311
+ day: "numeric",
44312
+ }).format(date);
44313
+ }
44314
+ catch {
44315
+ return dateStr;
44316
+ }
44317
+ }
44318
+ function CalendarIcon() {
44319
+ return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z", clipRule: "evenodd" }) }));
44320
+ }
44321
+ function MailIcon() {
44322
+ return (jsxRuntimeExports.jsxs("svg", { className: "ai-chat-action-icon", viewBox: "0 0 20 20", fill: "currentColor", children: [jsxRuntimeExports.jsx("path", { d: "M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z" }), jsxRuntimeExports.jsx("path", { d: "M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" })] }));
44323
+ }
44324
+ function CheckIcon() {
44325
+ return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon-success", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }));
44326
+ }
44327
+ function ErrorIcon() {
44328
+ return (jsxRuntimeExports.jsx("svg", { className: "ai-chat-action-icon-error", viewBox: "0 0 20 20", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", clipRule: "evenodd" }) }));
44329
+ }
44330
+ function ExternalLinkIcon$1() {
44331
+ return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), jsxRuntimeExports.jsx("polyline", { points: "15 3 21 3 21 9" }), jsxRuntimeExports.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })] }));
44332
+ }
44333
+ function Skeleton({ width, height, borderRadius = '4px' }) {
44334
+ return (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-skeleton-item", style: { width, height, borderRadius } }));
44335
+ }
44336
+ function PinInputGroup({ values, onChange, disabled }) {
44337
+ const inputRefs = reactExports.useRef([]);
44338
+ const handleChange = (index, value) => {
44339
+ // Only allow digits
44340
+ const digit = value.replace(/[^0-9]/g, '');
44341
+ const newValues = [...values];
44342
+ newValues[index] = digit.slice(-1);
44343
+ onChange(newValues);
44344
+ // Auto-focus next input
44345
+ if (digit && index < 5) {
44346
+ inputRefs.current[index + 1]?.focus();
44347
+ }
44348
+ };
44349
+ const handleKeyDown = (index, e) => {
44350
+ if (e.key === 'Backspace' && !values[index] && index > 0) {
44351
+ inputRefs.current[index - 1]?.focus();
44352
+ }
44353
+ };
44354
+ const handlePaste = (e) => {
44355
+ e.preventDefault();
44356
+ const pastedData = e.clipboardData.getData('text').replace(/[^0-9]/g, '').slice(0, 6);
44357
+ const newValues = pastedData.split('').concat(Array(6 - pastedData.length).fill(''));
44358
+ onChange(newValues);
44359
+ // Focus the next empty input or the last one
44360
+ const nextIndex = Math.min(pastedData.length, 5);
44361
+ inputRefs.current[nextIndex]?.focus();
44362
+ };
44363
+ return (jsxRuntimeExports.jsx("div", { className: "ai-chat-pin-input-group", children: values.map((value, index) => (jsxRuntimeExports.jsx("input", { ref: (el) => {
44364
+ inputRefs.current[index] = el;
44365
+ }, type: "text", inputMode: "numeric", maxLength: 1, className: "ai-chat-pin-input", value: value, onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), onPaste: handlePaste, disabled: disabled, autoFocus: index === 0 }, index))) }));
44366
+ }
44367
+ function MicrosoftCalendarCard({ action, onComplete, accentColor, className = '' }) {
44368
+ const state = action.state;
44369
+ const phase = state.phase || "awaiting_email";
44370
+ const allowTopic = state.allowTopic !== false;
44371
+ const accentStyle = accentColor ? { '--action-accent': accentColor } : {};
44372
+ // Debug: Log state changes
44373
+ const prevStateRef = reactExports.useRef(null);
44374
+ reactExports.useEffect(() => {
44375
+ if (JSON.stringify(prevStateRef.current) !== JSON.stringify(state)) {
44376
+ console.log('[MicrosoftCalendarCard] State updated:', {
44377
+ phase: state.phase,
44378
+ hasError: !!state.errorMessage,
44379
+ error: state.errorMessage,
44380
+ slotsCount: state.availableSlots?.length || 0
44381
+ });
44382
+ prevStateRef.current = state;
44383
+ }
44384
+ }, [state]);
44385
+ // Email phase state
44386
+ const [email, setEmail] = reactExports.useState("");
44387
+ const [emailError, setEmailError] = reactExports.useState(null);
44388
+ // OTP phase state
44389
+ const [otpValues, setOtpValues] = reactExports.useState(Array(6).fill(''));
44390
+ const [otpError, setOtpError] = reactExports.useState(null);
44391
+ // Loading states
44392
+ const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
44393
+ // Reset loading state when phase changes (backend has responded)
44394
+ // Use useEffect for reliable re-rendering
44395
+ reactExports.useEffect(() => {
44396
+ console.log('[MicrosoftCalendarCard] Phase changed to:', phase);
44397
+ setIsSubmitting(false);
44398
+ // Clear errors when transitioning to new phase
44399
+ if (phase === "awaiting_email") {
44400
+ setEmailError(null);
44401
+ setOtpError(null);
44402
+ setSelectionError(null);
44403
+ }
44404
+ else if (phase === "awaiting_otp") {
44405
+ setOtpError(state.errorMessage || null);
44406
+ setEmailError(null);
44407
+ setSelectionError(null);
44408
+ // Clear OTP input for fresh attempt
44409
+ setOtpValues(Array(6).fill(''));
44410
+ }
44411
+ else if (phase === "awaiting_options") {
44412
+ setEmailError(null);
44413
+ setOtpError(null);
44414
+ setSelectionError(null);
44415
+ }
44416
+ else if (phase === "awaiting_booking") {
44417
+ setSelectionError(state.errorMessage || null);
44418
+ setEmailError(null);
44419
+ setOtpError(null);
44420
+ }
44421
+ else if (phase === "booked" || phase === "cancelled" || phase === "error") {
44422
+ setEmailError(null);
44423
+ setOtpError(null);
44424
+ setSelectionError(null);
44425
+ setSelectedId(null); // Reset selection
44426
+ }
44427
+ }, [phase, state.errorMessage]);
44428
+ // Selection phase state
44429
+ const rawSlots = state.availableSlots;
44430
+ const availableSlots = Array.isArray(rawSlots)
44431
+ ? rawSlots.filter((slot) => slot !== null &&
44432
+ slot !== undefined &&
44433
+ typeof slot === "object" &&
44434
+ "startTime" in slot &&
44435
+ "endTime" in slot &&
44436
+ typeof slot.startTime === "string" &&
44437
+ typeof slot.endTime === "string")
44438
+ : [];
44439
+ const slotsByDate = groupSlotsByDate(availableSlots);
44440
+ const dates = Array.from(slotsByDate.keys()).sort();
44441
+ const [selectedDate, setSelectedDate] = reactExports.useState(dates[0] ?? "");
44442
+ const [selectedSlot, setSelectedSlot] = reactExports.useState(null);
44443
+ const [topic, setTopic] = reactExports.useState("");
44444
+ const [selectionError, setSelectionError] = reactExports.useState(null);
44445
+ // Cancellation phase state
44446
+ const [selectedId, setSelectedId] = reactExports.useState(null);
44447
+ const slotsForSelectedDate = selectedDate ? slotsByDate.get(selectedDate) ?? [] : [];
44448
+ // Phase 1: Email Input
44449
+ const handleEmailSubmit = () => {
44450
+ const trimmedEmail = email.trim();
44451
+ if (!trimmedEmail) {
44452
+ setEmailError("Please enter your email address");
44453
+ return;
44454
+ }
44455
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmedEmail)) {
44456
+ setEmailError("Please enter a valid email address");
44457
+ return;
44458
+ }
44459
+ setEmailError(null);
44460
+ setIsSubmitting(true);
44461
+ console.log('[MicrosoftCalendarCard] Submitting email:', trimmedEmail);
44462
+ setTimeout(() => {
44463
+ onComplete?.(action.toolCallId, {
44464
+ ...action.state,
44465
+ email: trimmedEmail,
44466
+ });
44467
+ }, 50);
44468
+ };
44469
+ // Phase 2: OTP Verification
44470
+ const handleOtpSubmit = () => {
44471
+ const otpCode = otpValues.join('');
44472
+ if (otpCode.length !== 6) {
44473
+ setOtpError("Please enter the 6-digit code");
44474
+ return;
44475
+ }
44476
+ setOtpError(null);
44477
+ setIsSubmitting(true);
44478
+ console.log('[MicrosoftCalendarCard] Submitting OTP code');
44479
+ setTimeout(() => {
44480
+ onComplete?.(action.toolCallId, {
44481
+ ...action.state,
44482
+ otpCode,
44483
+ });
44484
+ }, 50);
44485
+ };
44486
+ // Phase 3: Appointment Selection
44487
+ const handleAppointmentConfirm = () => {
44488
+ if (!selectedSlot) {
44489
+ setSelectionError("Please select a time slot");
44490
+ return;
44491
+ }
44492
+ if (allowTopic && !topic.trim()) {
44493
+ setSelectionError("Please enter a meeting topic");
44494
+ return;
44495
+ }
44496
+ setSelectionError(null);
44174
44497
  setIsSubmitting(true);
44175
- // Small delay to ensure UI updates
44498
+ console.log('[MicrosoftCalendarCard] Confirming appointment:', {
44499
+ slot: selectedSlot,
44500
+ topic: topic.trim()
44501
+ });
44176
44502
  setTimeout(() => {
44177
44503
  onComplete?.(action.toolCallId, {
44178
44504
  ...action.state,
@@ -44184,22 +44510,566 @@
44184
44510
  });
44185
44511
  }, 50);
44186
44512
  };
44187
- // Booked state
44188
- if (isBooked) {
44513
+ // Handle "Use different email" button
44514
+ const handleUseDifferentEmail = () => {
44515
+ setEmail("");
44516
+ setEmailError(null);
44517
+ setOtpValues(Array(6).fill(''));
44518
+ setOtpError(null);
44519
+ onComplete?.(action.toolCallId, {
44520
+ phase: "awaiting_email",
44521
+ email: null,
44522
+ otpVerified: false,
44523
+ otpAttempts: 0,
44524
+ availableSlots: [],
44525
+ selectedSlot: null,
44526
+ topic: null,
44527
+ bookedEventId: null,
44528
+ bookedEventLink: null,
44529
+ allowTopic,
44530
+ errorMessage: null,
44531
+ });
44532
+ };
44533
+ // Phase 5: Booked Confirmation
44534
+ if (phase === "booked") {
44189
44535
  const bookedSlot = state.selectedSlot;
44190
44536
  const bookedTopic = state.topic;
44191
44537
  const eventLink = state.bookedEventLink;
44192
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-booked ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-success-icon-wrapper", children: jsxRuntimeExports.jsx(CheckIcon, {}) }), "Appointment Confirmed"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [bookedTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TOPIC" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedTopic })] })), bookedSlot && bookedSlot.startTime && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TIME" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedSlot.displayTime || new Date(bookedSlot.startTime).toLocaleString() })] })), eventLink && (jsxRuntimeExports.jsxs("a", { href: eventLink, target: "_blank", rel: "noopener noreferrer", className: "ai-chat-action-link-button", children: ["View in Google Calendar", jsxRuntimeExports.jsx(ExternalLinkIcon, {})] }))] })] }));
44193
- }
44194
- // Skeleton loading state
44538
+ const bookedEmail = state.email;
44539
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-booked ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-success-icon-wrapper", children: jsxRuntimeExports.jsx(CheckIcon, {}) }), "Appointment Confirmed"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [bookedTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TOPIC" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedTopic })] })), bookedSlot && bookedSlot.startTime && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "TIME" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: bookedSlot.displayTime || new Date(bookedSlot.startTime).toLocaleString() })] })), bookedEmail && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-hint", children: ["A calendar invitation has been sent to ", bookedEmail] })), eventLink && (jsxRuntimeExports.jsxs("a", { href: eventLink, target: "_blank", rel: "noopener noreferrer", className: "ai-chat-action-link-button", children: ["View in Outlook Calendar", jsxRuntimeExports.jsx(ExternalLinkIcon$1, {})] }))] })] }));
44540
+ }
44541
+ // Phase 6: Cancelled Confirmation
44542
+ if (phase === "cancelled") {
44543
+ const cancelledSubject = state.cancelledEventSubject;
44544
+ const userEmail = state.email;
44545
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-booked ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-success-icon-wrapper", children: jsxRuntimeExports.jsx(CheckIcon, {}) }), "Appointment Cancelled"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [cancelledSubject && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-detail-box", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-action-label-small", children: "CANCELLED" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-action-value-large", children: cancelledSubject })] })), userEmail && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-hint", children: ["A cancellation notice has been sent to ", userEmail] }))] })] }));
44546
+ }
44547
+ // Error State
44548
+ if (phase === "error") {
44549
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-action-error ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(ErrorIcon, {}), "Error"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error-message", children: state.errorMessage || "An error occurred. Please try again." }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button-secondary", type: "button", onClick: () => {
44550
+ setEmail("");
44551
+ setEmailError(null);
44552
+ setOtpValues(Array(6).fill(''));
44553
+ setOtpError(null);
44554
+ onComplete?.(action.toolCallId, {
44555
+ phase: "awaiting_email",
44556
+ email: null,
44557
+ otpVerified: false,
44558
+ otpAttempts: 0,
44559
+ availableSlots: [],
44560
+ selectedSlot: null,
44561
+ topic: null,
44562
+ bookedEventId: null,
44563
+ bookedEventLink: null,
44564
+ allowTopic,
44565
+ errorMessage: null,
44566
+ });
44567
+ }, children: "Start Over" })] })] }));
44568
+ }
44569
+ // Loading State
44195
44570
  if (isSubmitting) {
44196
- return (jsxRuntimeExports.jsx("div", { className: `ai-chat-action-card ai-chat-action-skeleton ${className}`, style: accentStyle, children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-header", children: [jsxRuntimeExports.jsx(Skeleton, { width: "28px", height: "28px", borderRadius: "50%" }), jsxRuntimeExports.jsx(Skeleton, { width: "180px", height: "20px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton, { width: "60px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton, { width: "120px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton, { width: "50px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton, { width: "200px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.jsx(Skeleton, { width: "100%", height: "44px", borderRadius: "999px" })] }) }));
44571
+ return (jsxRuntimeExports.jsx("div", { className: `ai-chat-action-card ai-chat-action-skeleton ${className}`, style: accentStyle, children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-header", children: [jsxRuntimeExports.jsx(Skeleton, { width: "28px", height: "28px", borderRadius: "50%" }), jsxRuntimeExports.jsx(Skeleton, { width: "180px", height: "20px", borderRadius: "4px" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-skeleton-box", children: [jsxRuntimeExports.jsx(Skeleton, { width: "60px", height: "12px", borderRadius: "4px" }), jsxRuntimeExports.jsx(Skeleton, { width: "120px", height: "18px", borderRadius: "4px" })] }), jsxRuntimeExports.jsx(Skeleton, { width: "100%", height: "44px", borderRadius: "999px" })] }) }));
44572
+ }
44573
+ // Phase 1: Email Input
44574
+ if (phase === "awaiting_email") {
44575
+ const displayError = state.errorMessage || emailError;
44576
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Schedule an Appointment"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "We'll send a verification code to your email" }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { htmlFor: `email-${action.toolCallId}`, className: "ai-chat-action-label", children: "Email Address" }), jsxRuntimeExports.jsx("input", { id: `email-${action.toolCallId}`, type: "email", className: "ai-chat-action-input", placeholder: "your@email.com", value: email, onChange: (e) => {
44577
+ setEmail(e.target.value);
44578
+ setEmailError(null);
44579
+ }, onKeyPress: (e) => {
44580
+ if (e.key === 'Enter') {
44581
+ handleEmailSubmit();
44582
+ }
44583
+ }, autoFocus: true })] }), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: handleEmailSubmit, children: "Continue" })] })] }));
44584
+ }
44585
+ // Phase 2: OTP Input
44586
+ if (phase === "awaiting_otp") {
44587
+ const displayError = state.errorMessage || otpError;
44588
+ const userEmail = state.email;
44589
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(MailIcon, {}), "Verify Your Email"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-hint", children: ["We sent a 6-digit code to ", jsxRuntimeExports.jsx("strong", { children: userEmail })] }), jsxRuntimeExports.jsx(PinInputGroup, { values: otpValues, onChange: (newValues) => {
44590
+ setOtpValues(newValues);
44591
+ setOtpError(null);
44592
+ // Auto-submit when all 6 digits are entered
44593
+ if (newValues.every(v => v.length === 1)) {
44594
+ console.log('[MicrosoftCalendarCard] Auto-submitting OTP (all 6 digits entered)');
44595
+ setIsSubmitting(true);
44596
+ const code = newValues.join('');
44597
+ setTimeout(() => {
44598
+ onComplete?.(action.toolCallId, {
44599
+ ...action.state,
44600
+ otpCode: code,
44601
+ });
44602
+ }, 100);
44603
+ }
44604
+ }, disabled: isSubmitting }), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: handleOtpSubmit, disabled: otpValues.join('').length !== 6, children: "Verify Code" }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button-secondary", type: "button", onClick: handleUseDifferentEmail, children: "Use different email" })] })] }));
44605
+ }
44606
+ // Phase 3: Options Menu (with inline cancel buttons and confirmation)
44607
+ if (phase === "awaiting_options") {
44608
+ const userAppointments = state.userAppointments || [];
44609
+ const maxAppointments = state.maxAppointmentsPerUser || 3;
44610
+ const appointmentCount = userAppointments.length;
44611
+ const canBook = appointmentCount < maxAppointments;
44612
+ const hasAppointments = appointmentCount > 0;
44613
+ const displayError = state.errorMessage || selectionError;
44614
+ // If confirming cancellation, show confirmation dialog
44615
+ if (selectedId) {
44616
+ const appointmentToCancel = userAppointments.find(appt => appt.id === selectedId);
44617
+ if (!appointmentToCancel) {
44618
+ setSelectedId(null); // Reset if appointment not found
44619
+ }
44620
+ else {
44621
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Confirm Cancellation"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "Are you sure you want to cancel this appointment?" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-item", style: { marginBottom: '16px' }, children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-appointment-info", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-subject", children: appointmentToCancel.subject }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-time", children: appointmentToCancel.displayTime })] }) }), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-button-group", children: [jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: () => {
44622
+ setIsSubmitting(true);
44623
+ onComplete?.(action.toolCallId, {
44624
+ ...action.state,
44625
+ selectedOption: "cancel",
44626
+ selectedAppointmentId: selectedId,
44627
+ });
44628
+ }, disabled: isSubmitting, children: isSubmitting ? 'Cancelling...' : 'Confirm Cancellation' }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button-secondary", type: "button", onClick: () => {
44629
+ setSelectedId(null);
44630
+ setSelectionError(null);
44631
+ }, disabled: isSubmitting, children: "Go Back" })] })] })] }));
44632
+ }
44633
+ }
44634
+ // Normal view with inline cancel buttons
44635
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Manage Your Appointments"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-hint", children: ["You have ", appointmentCount, " active appointment", appointmentCount !== 1 ? 's' : '', canBook && ` (${maxAppointments - appointmentCount} slot${maxAppointments - appointmentCount !== 1 ? 's' : ''} remaining)`] }), hasAppointments && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-appointment-list", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-label", children: "Your Upcoming Appointments" }), userAppointments.map((appt) => (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-appointment-item", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-appointment-info", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-subject", children: appt.subject }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-appointment-time", children: appt.displayTime })] }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button-secondary", type: "button", onClick: () => {
44636
+ setSelectedId(appt.id);
44637
+ setSelectionError(null);
44638
+ }, children: "Cancel" })] }, appt.id)))] })), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), canBook && (jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: () => {
44639
+ setIsSubmitting(true);
44640
+ onComplete?.(action.toolCallId, {
44641
+ ...action.state,
44642
+ selectedOption: "book",
44643
+ });
44644
+ }, disabled: isSubmitting, children: isSubmitting ? 'Loading...' : 'Book New Appointment' })), !canBook && !hasAppointments && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "No appointments found." }))] })] }));
44645
+ }
44646
+ // Phase 4: Appointment Selection (Booking)
44647
+ if (phase === "awaiting_booking") {
44648
+ const displayError = state.errorMessage || selectionError;
44649
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Select Appointment Time"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [allowTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { htmlFor: `topic-${action.toolCallId}`, className: "ai-chat-action-label", children: "Meeting Topic" }), jsxRuntimeExports.jsx("input", { id: `topic-${action.toolCallId}`, type: "text", className: "ai-chat-action-input", placeholder: "e.g., Product Demo", value: topic, onChange: (e) => setTopic(e.target.value) })] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Date" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-date-grid", children: dates.slice(0, 7).map((date) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-date-btn ${selectedDate === date ? "active" : ""}`, onClick: () => {
44650
+ setSelectedDate(date);
44651
+ setSelectedSlot(null);
44652
+ }, children: formatDate(date) }, date))) })] }), selectedDate && slotsForSelectedDate.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Time" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-time-grid", children: slotsForSelectedDate.map((slot) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-time-btn ${selectedSlot?.startTime === slot.startTime ? "active" : ""}`, onClick: () => setSelectedSlot(slot), children: slot.displayTime || new Date(slot.startTime).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }, slot.startTime))) })] })), displayError && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: displayError })), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: handleAppointmentConfirm, disabled: !selectedSlot, children: "Confirm Appointment" }), availableSlots.length === 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "No available time slots found." }))] })] }));
44653
+ }
44654
+ // Fallback
44655
+ return null;
44656
+ }
44657
+
44658
+ function truncate(text, maxLength) {
44659
+ if (text.length <= maxLength)
44660
+ return text;
44661
+ return text.slice(0, maxLength).trim() + '...';
44662
+ }
44663
+ function ExternalLinkIcon() {
44664
+ return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }), jsxRuntimeExports.jsx("polyline", { points: "15 3 21 3 21 9" }), jsxRuntimeExports.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })] }));
44665
+ }
44666
+ function SingleLinkPreview({ link, onLinkClick, accentColor }) {
44667
+ const domain = (() => {
44668
+ if (!link.url)
44669
+ return '';
44670
+ try {
44671
+ return new URL(link.url).hostname.replace('www.', '');
44672
+ }
44673
+ catch {
44674
+ return link.url;
44675
+ }
44676
+ })();
44677
+ const style = accentColor ? { '--action-accent': accentColor } : undefined;
44678
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-card ai-chat-link-preview", onClick: onLinkClick, style: style, role: "link", tabIndex: 0, onKeyDown: (e) => e.key === 'Enter' && onLinkClick(), children: [link.image && (jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview__image", children: jsxRuntimeExports.jsx("img", { src: link.image, alt: link.title, onError: (e) => {
44679
+ e.currentTarget.parentElement.style.display = 'none';
44680
+ } }) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-link-preview__content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-link-preview__site", children: [link.favicon && (jsxRuntimeExports.jsx("img", { src: link.favicon, alt: "", className: "ai-chat-link-preview__favicon", onError: (e) => {
44681
+ e.currentTarget.style.display = 'none';
44682
+ } })), jsxRuntimeExports.jsx("span", { className: "ai-chat-link-preview__domain", children: link.siteName || domain })] }), jsxRuntimeExports.jsx("h4", { className: "ai-chat-link-preview__title", children: link.title }), link.description && (jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__description", children: truncate(link.description, 120) }))] }), jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview__arrow", children: jsxRuntimeExports.jsx(ExternalLinkIcon, {}) })] }));
44683
+ }
44684
+ function LinkPreviewCard({ action, onComplete, accentColor }) {
44685
+ const rawState = action.state;
44686
+ const hasCompletedRef = reactExports.useRef(false);
44687
+ // Provide safe defaults if state is missing
44688
+ const state = {
44689
+ links: rawState?.links || [],
44690
+ context: rawState?.context,
44691
+ status: rawState?.status || 'displaying',
44692
+ error: rawState?.error,
44693
+ };
44694
+ const isError = state.status === 'error';
44695
+ // Auto-complete on mount so AI can continue generating text response
44696
+ reactExports.useEffect(() => {
44697
+ if (!action.done && !hasCompletedRef.current && onComplete && state.links.length > 0) {
44698
+ hasCompletedRef.current = true;
44699
+ // Signal completion immediately - the card is displayed, AI can continue
44700
+ onComplete(action.toolCallId, { ...state, status: 'displaying' });
44701
+ }
44702
+ }, [action.done, action.toolCallId, onComplete, state]);
44703
+ const handleLinkClick = (url) => {
44704
+ if (url) {
44705
+ window.open(url, '_blank', 'noopener,noreferrer');
44706
+ }
44707
+ onComplete?.(action.toolCallId, { ...state, status: 'clicked' });
44708
+ };
44709
+ if (isError) {
44710
+ return (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-card ai-chat-link-preview ai-chat-link-preview--error", children: jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview__content", children: jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__error-text", children: state.error || 'Failed to load preview' }) }) }));
44197
44711
  }
44198
- // Booking form
44199
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ${className}`, style: accentStyle, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-header", children: [jsxRuntimeExports.jsx(CalendarIcon, {}), "Schedule an Appointment"] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-body", children: [allowTopic && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { htmlFor: `topic-${action.toolCallId}`, className: "ai-chat-action-label", children: "Meeting Topic" }), jsxRuntimeExports.jsx("input", { id: `topic-${action.toolCallId}`, type: "text", className: "ai-chat-action-input", placeholder: "e.g., Product Demo", value: topic, onChange: (e) => setTopic(e.target.value) })] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Date" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-date-grid", children: dates.slice(0, 7).map((date) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-date-btn ${selectedDate === date ? "active" : ""}`, onClick: () => {
44200
- setSelectedDate(date);
44201
- setSelectedSlot(null);
44202
- }, children: formatDate(date) }, date))) })] }), selectedDate && slotsForSelectedDate.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-field", children: [jsxRuntimeExports.jsx("label", { className: "ai-chat-action-label", children: "Select Time" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-action-time-grid", children: slotsForSelectedDate.map((slot) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-action-time-btn ${selectedSlot?.startTime === slot.startTime ? "active" : ""}`, onClick: () => setSelectedSlot(slot), children: slot.displayTime || new Date(slot.startTime).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }, slot.startTime))) })] })), error && jsxRuntimeExports.jsx("div", { className: "ai-chat-action-error", children: error }), jsxRuntimeExports.jsx("button", { className: "ai-chat-action-button", type: "button", onClick: onConfirm, disabled: !selectedSlot, children: "Confirm Appointment" }), availableSlots.length === 0 && (jsxRuntimeExports.jsx("div", { className: "ai-chat-action-hint", children: "No available time slots found." }))] })] }));
44712
+ if (state.links.length === 0) {
44713
+ return null;
44714
+ }
44715
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-link-preview-container", children: [state.context && (jsxRuntimeExports.jsx("p", { className: "ai-chat-link-preview__context", style: { marginBottom: '8px', fontSize: '0.9em', color: 'var(--ai-chat-fg-muted)' }, children: state.context })), jsxRuntimeExports.jsx("div", { className: "ai-chat-link-preview-grid", style: {
44716
+ display: 'grid',
44717
+ gridTemplateColumns: state.links.length === 1 ? '1fr' : state.links.length === 2 ? 'repeat(2, 1fr)' : 'repeat(3, 1fr)',
44718
+ gap: '12px',
44719
+ }, children: state.links.map((link, index) => (jsxRuntimeExports.jsx(SingleLinkPreview, { link: link, onLinkClick: () => handleLinkClick(link.url), accentColor: accentColor }, index))) })] }));
44720
+ }
44721
+
44722
+ function PlayIcon() {
44723
+ return (jsxRuntimeExports.jsx("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "currentColor", stroke: "none", children: jsxRuntimeExports.jsx("path", { d: "M8 5v14l11-7z" }) }));
44724
+ }
44725
+ function getProviderLabel(provider) {
44726
+ switch (provider) {
44727
+ case 'youtube':
44728
+ return 'YouTube';
44729
+ case 'vimeo':
44730
+ return 'Vimeo';
44731
+ case 'loom':
44732
+ return 'Loom';
44733
+ case 'direct':
44734
+ return 'Video';
44735
+ default:
44736
+ return 'Video';
44737
+ }
44738
+ }
44739
+ function VideoPlayerCard({ action, onComplete, accentColor }) {
44740
+ const rawState = action.state;
44741
+ const hasCompletedRef = reactExports.useRef(false);
44742
+ const [isPlaying, setIsPlaying] = reactExports.useState(false);
44743
+ // Provide safe defaults if state is missing
44744
+ const state = {
44745
+ url: rawState?.url || '',
44746
+ title: rawState?.title,
44747
+ context: rawState?.context,
44748
+ provider: rawState?.provider || 'direct',
44749
+ embedUrl: rawState?.embedUrl || '',
44750
+ thumbnailUrl: rawState?.thumbnailUrl,
44751
+ videoId: rawState?.videoId,
44752
+ status: rawState?.status || 'displaying',
44753
+ error: rawState?.error,
44754
+ };
44755
+ const isError = state.status === 'error';
44756
+ // Auto-complete on mount so AI can continue generating text response
44757
+ reactExports.useEffect(() => {
44758
+ if (!action.done && !hasCompletedRef.current && onComplete && state.embedUrl) {
44759
+ hasCompletedRef.current = true;
44760
+ onComplete(action.toolCallId, { ...state, status: 'displaying' });
44761
+ }
44762
+ }, [action.done, action.toolCallId, onComplete, state]);
44763
+ const handlePlay = () => {
44764
+ setIsPlaying(true);
44765
+ onComplete?.(action.toolCallId, { ...state, status: 'played' });
44766
+ };
44767
+ const style = accentColor ? { '--action-accent': accentColor } : undefined;
44768
+ // Build embed URL with autoplay when playing
44769
+ const getEmbedSrc = () => {
44770
+ if (!isPlaying)
44771
+ return '';
44772
+ let src = state.embedUrl;
44773
+ const separator = src.includes('?') ? '&' : '?';
44774
+ switch (state.provider) {
44775
+ case 'youtube':
44776
+ return `${src}${separator}autoplay=1&rel=0`;
44777
+ case 'vimeo':
44778
+ return `${src}${separator}autoplay=1`;
44779
+ case 'loom':
44780
+ return `${src}${separator}autoplay=1`;
44781
+ default:
44782
+ return src;
44783
+ }
44784
+ };
44785
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-action-card ai-chat-video-player", style: style, children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__container", children: isError ? (jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__error", children: jsxRuntimeExports.jsx("span", { children: state.error || 'Could not load video' }) })) : !isPlaying && state.thumbnailUrl ? (jsxRuntimeExports.jsxs("div", { className: "ai-chat-video-player__thumbnail", onClick: handlePlay, children: [jsxRuntimeExports.jsx("img", { src: state.thumbnailUrl, alt: state.title || 'Video thumbnail' }), jsxRuntimeExports.jsx("button", { className: "ai-chat-video-player__play-btn", "aria-label": "Play video", children: jsxRuntimeExports.jsx(PlayIcon, {}) }), jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__provider-badge", children: getProviderLabel(state.provider) })] })) : !isPlaying ? (jsxRuntimeExports.jsxs("div", { className: "ai-chat-video-player__placeholder", onClick: handlePlay, children: [jsxRuntimeExports.jsx("button", { className: "ai-chat-video-player__play-btn", "aria-label": "Play video", children: jsxRuntimeExports.jsx(PlayIcon, {}) }), jsxRuntimeExports.jsx("span", { className: "ai-chat-video-player__click-text", children: "Click to play" }), jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__provider-badge", children: getProviderLabel(state.provider) })] })) : state.provider === 'direct' ? (jsxRuntimeExports.jsx("video", { src: state.embedUrl, controls: true, autoPlay: true, className: "ai-chat-video-player__video" })) : (jsxRuntimeExports.jsx("iframe", { src: getEmbedSrc(), className: "ai-chat-video-player__iframe", allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share", allowFullScreen: true, title: state.title || 'Video player' })) }), state.context && (jsxRuntimeExports.jsx("div", { className: "ai-chat-video-player__context", children: state.context }))] }));
44786
+ }
44787
+
44788
+ function MapPinIcon() {
44789
+ return (jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" }), jsxRuntimeExports.jsx("circle", { cx: "12", cy: "10", r: "3" })] }));
44790
+ }
44791
+ function PhoneIcon() {
44792
+ return (jsxRuntimeExports.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" }) }));
44793
+ }
44794
+ function ClockIcon() {
44795
+ return (jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10" }), jsxRuntimeExports.jsx("polyline", { points: "12 6 12 12 16 14" })] }));
44796
+ }
44797
+ function NavigationIcon() {
44798
+ return (jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polygon", { points: "3 11 22 2 13 21 11 13 3 11" }) }));
44799
+ }
44800
+ function GlobeIcon() {
44801
+ return (jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10" }), jsxRuntimeExports.jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12" }), jsxRuntimeExports.jsx("path", { d: "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })] }));
44802
+ }
44803
+ function ChevronIcon({ direction }) {
44804
+ return (jsxRuntimeExports.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { transform: direction === 'up' ? 'rotate(180deg)' : 'none' }, children: jsxRuntimeExports.jsx("polyline", { points: "6 9 12 15 18 9" }) }));
44805
+ }
44806
+ function getOpenStatus(hours) {
44807
+ if (!hours || hours.length === 0)
44808
+ return null;
44809
+ const now = new Date();
44810
+ const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
44811
+ const today = dayNames[now.getDay()];
44812
+ const todayHours = hours.find(h => h.day === today);
44813
+ if (!todayHours || todayHours.closed)
44814
+ return false;
44815
+ const currentTime = now.getHours() * 100 + now.getMinutes();
44816
+ const openTime = parseInt(todayHours.open.replace(':', ''));
44817
+ const closeTime = parseInt(todayHours.close.replace(':', ''));
44818
+ return currentTime >= openTime && currentTime < closeTime;
44819
+ }
44820
+ function HoursDisplay({ hours, compact = false }) {
44821
+ const [expanded, setExpanded] = reactExports.useState(false);
44822
+ const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
44823
+ const today = dayNames[new Date().getDay()];
44824
+ const todayHours = hours.find(h => h.day === today);
44825
+ if (compact && !expanded) {
44826
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__hours", children: [jsxRuntimeExports.jsx(ClockIcon, {}), jsxRuntimeExports.jsx("span", { children: todayHours?.closed ? 'Closed today' : `${todayHours?.open} - ${todayHours?.close}` })] }));
44827
+ }
44828
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__hours", children: [jsxRuntimeExports.jsx(ClockIcon, {}), jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__hours-list", children: [jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => setExpanded(!expanded), className: "ai-chat-location-card__hours-toggle", children: ["Today: ", todayHours?.closed ? 'Closed' : `${todayHours?.open} - ${todayHours?.close}`, jsxRuntimeExports.jsx(ChevronIcon, { direction: expanded ? 'up' : 'down' })] }), expanded && (jsxRuntimeExports.jsx("ul", { className: "ai-chat-location-card__hours-full", children: hours.map(h => (jsxRuntimeExports.jsxs("li", { className: h.day === today ? 'ai-chat-location-card__hours-today' : '', children: [jsxRuntimeExports.jsx("span", { children: h.day }), jsxRuntimeExports.jsx("span", { children: h.closed ? 'Closed' : `${h.open} - ${h.close}` })] }, h.day))) }))] })] }));
44829
+ }
44830
+ function LocationItem({ location, settings, accentColor, onDirections, showMap = true, compact = false, }) {
44831
+ const openStatus = getOpenStatus(location.hours);
44832
+ const mapHeight = settings.mapHeight || 180;
44833
+ const mapZoom = settings.mapZoom || 15;
44834
+ const getMapEmbedUrl = () => {
44835
+ const query = location.lat && location.lng
44836
+ ? `${location.lat},${location.lng}`
44837
+ : encodeURIComponent(location.address);
44838
+ return `https://www.google.com/maps/embed/v1/place?key=AIzaSyBFw0Qbyq9zTFTd-tUY6dZWTgaQzuU17R8&q=${query}&zoom=${mapZoom}`;
44839
+ };
44840
+ const handleCall = () => {
44841
+ if (location.phone) {
44842
+ window.location.href = `tel:${location.phone}`;
44843
+ }
44844
+ };
44845
+ const style = accentColor ? { '--action-accent': accentColor } : undefined;
44846
+ // Use smaller map height in compact mode
44847
+ const effectiveMapHeight = compact ? Math.min(mapHeight, 140) : mapHeight;
44848
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-location-card ${compact ? 'ai-chat-location-card--compact' : ''}`, style: style, children: [showMap && settings.showMap !== false && (jsxRuntimeExports.jsx("div", { className: "ai-chat-location-card__map", style: { height: effectiveMapHeight }, children: jsxRuntimeExports.jsx("iframe", { src: getMapEmbedUrl(), allowFullScreen: true, loading: "lazy", referrerPolicy: "no-referrer-when-downgrade", title: `Map of ${location.name}` }) })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__header", children: [jsxRuntimeExports.jsx("h4", { className: "ai-chat-location-card__name", children: location.name }), location.type && (jsxRuntimeExports.jsx("span", { className: "ai-chat-location-card__type", children: location.type })), openStatus !== null && (jsxRuntimeExports.jsx("span", { className: `ai-chat-location-card__status ai-chat-location-card__status--${openStatus ? 'open' : 'closed'}`, children: openStatus ? 'Open' : 'Closed' }))] }), jsxRuntimeExports.jsxs("p", { className: "ai-chat-location-card__address", children: [jsxRuntimeExports.jsx(MapPinIcon, {}), location.address] }), location.description && (jsxRuntimeExports.jsx("p", { className: "ai-chat-location-card__description", children: location.description })), settings.showHours !== false && location.hours && location.hours.length > 0 && (jsxRuntimeExports.jsx(HoursDisplay, { hours: location.hours, compact: compact })), settings.showPhone !== false && location.phone && (jsxRuntimeExports.jsxs("button", { type: "button", className: "ai-chat-location-card__phone", onClick: handleCall, children: [jsxRuntimeExports.jsx(PhoneIcon, {}), location.phone] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card__actions", children: [settings.showDirectionsButton !== false && (jsxRuntimeExports.jsxs("button", { type: "button", className: "ai-chat-location-card__button", style: accentColor ? { backgroundColor: accentColor } : undefined, onClick: onDirections, children: [jsxRuntimeExports.jsx(NavigationIcon, {}), compact ? 'Directions' : 'Get Directions'] })), !compact && location.website && (jsxRuntimeExports.jsxs("a", { href: location.website, target: "_blank", rel: "noopener noreferrer", className: "ai-chat-location-card__link", children: [jsxRuntimeExports.jsx(GlobeIcon, {}), "Website"] }))] })] })] }));
44849
+ }
44850
+ function LocationCard({ action, onComplete, accentColor, maxColumns = 3 }) {
44851
+ const rawState = action.state;
44852
+ const hasCompletedRef = reactExports.useRef(false);
44853
+ const state = {
44854
+ locations: rawState?.locations || [],
44855
+ settings: rawState?.settings || {},
44856
+ matchInfo: rawState?.matchInfo,
44857
+ status: rawState?.status || 'displaying',
44858
+ };
44859
+ const { locations, settings } = state;
44860
+ const layout = settings.multiLocationLayout || 'stack';
44861
+ const isSingleLocation = locations.length === 1;
44862
+ const stackColumns = Math.min(Math.max(locations.length, 1), maxColumns);
44863
+ reactExports.useEffect(() => {
44864
+ if (!action.done && !hasCompletedRef.current && onComplete && locations.length > 0) {
44865
+ hasCompletedRef.current = true;
44866
+ onComplete(action.toolCallId, { ...state, status: 'displaying' });
44867
+ }
44868
+ }, [action.done, action.toolCallId, onComplete, state, locations.length]);
44869
+ const handleDirections = (location) => {
44870
+ const url = location.lat && location.lng
44871
+ ? `https://www.google.com/maps/dir/?api=1&destination=${location.lat},${location.lng}`
44872
+ : `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(location.address)}`;
44873
+ window.open(url, '_blank', 'noopener,noreferrer');
44874
+ onComplete?.(action.toolCallId, { ...state, status: 'directions_opened' });
44875
+ };
44876
+ if (locations.length === 0) {
44877
+ return (jsxRuntimeExports.jsx("div", { className: "ai-chat-location-card ai-chat-location-card--error", children: jsxRuntimeExports.jsx("p", { children: "No locations to display" }) }));
44878
+ }
44879
+ if (isSingleLocation) {
44880
+ return (jsxRuntimeExports.jsx(LocationItem, { location: locations[0], settings: settings, accentColor: accentColor, onDirections: () => handleDirections(locations[0]), showMap: true }));
44881
+ }
44882
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-location-card-list ai-chat-location-card-list--${layout}`, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-location-card-list__header", children: [jsxRuntimeExports.jsx(MapPinIcon, {}), jsxRuntimeExports.jsxs("span", { children: [locations.length, " Locations"] })] }), layout === 'stack' && (jsxRuntimeExports.jsx("div", { className: `ai-chat-location-card-list__stack ai-chat-location-card-list__stack--cols-${stackColumns}`, children: locations.map((location) => (jsxRuntimeExports.jsx(LocationItem, { location: location, settings: settings, accentColor: accentColor, onDirections: () => handleDirections(location), showMap: settings.showMap !== false, compact: locations.length > 2 }, location.id))) })), layout === 'grid' && (jsxRuntimeExports.jsx("div", { className: "ai-chat-location-card-list__grid", children: locations.map((location) => (jsxRuntimeExports.jsx(LocationItem, { location: location, settings: settings, accentColor: accentColor, onDirections: () => handleDirections(location), showMap: false, compact: true }, location.id))) })), layout === 'carousel' && (jsxRuntimeExports.jsx("div", { className: "ai-chat-location-card-list__carousel", children: locations.map((location) => (jsxRuntimeExports.jsx(LocationItem, { location: location, settings: settings, accentColor: accentColor, onDirections: () => handleDirections(location), showMap: true, compact: false }, location.id))) }))] }));
44883
+ }
44884
+
44885
+ function UsersIcon() {
44886
+ return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }), jsxRuntimeExports.jsx("circle", { cx: "9", cy: "7", r: "4" }), jsxRuntimeExports.jsx("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87" }), jsxRuntimeExports.jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] }));
44887
+ }
44888
+ const AVATAR_COLORS = [
44889
+ { bg: '#E8F5E9', text: '#2E7D32' }, // Green
44890
+ { bg: '#E3F2FD', text: '#1565C0' }, // Blue
44891
+ { bg: '#FFF3E0', text: '#E65100' }, // Orange
44892
+ { bg: '#F3E5F5', text: '#7B1FA2' }, // Purple
44893
+ { bg: '#FFEBEE', text: '#C62828' }, // Red
44894
+ { bg: '#E0F7FA', text: '#00838F' }, // Cyan
44895
+ { bg: '#FFF8E1', text: '#F9A825' }, // Amber
44896
+ { bg: '#FCE4EC', text: '#AD1457' }, // Pink
44897
+ ];
44898
+ function getInitials(name) {
44899
+ const parts = name.trim().split(/\s+/);
44900
+ if (parts.length === 1) {
44901
+ return parts[0].substring(0, 2).toUpperCase();
44902
+ }
44903
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
44904
+ }
44905
+ function getColorFromName(name) {
44906
+ let hash = 0;
44907
+ for (let i = 0; i < name.length; i++) {
44908
+ hash = name.charCodeAt(i) + ((hash << 5) - hash);
44909
+ }
44910
+ return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
44911
+ }
44912
+ function ContactItem({ contact, settings, accentColor, onEmail, onPhone, compact = false, layout = 'vertical', }) {
44913
+ const style = accentColor ? { '--action-accent': accentColor } : undefined;
44914
+ const layoutClass = layout === 'horizontal'
44915
+ ? 'ai-chat-contact-card--horizontal'
44916
+ : 'ai-chat-contact-card--vertical';
44917
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-action-card ai-chat-contact-card ${layoutClass} ${compact ? 'ai-chat-contact-card--compact' : ''}`, style: style, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card__image-section", children: [contact.profilePictureUrl ? (jsxRuntimeExports.jsx("img", { src: contact.profilePictureUrl, alt: contact.name, className: "ai-chat-contact-card__image", onError: (e) => {
44918
+ e.currentTarget.style.display = 'none';
44919
+ const placeholder = e.currentTarget.parentElement?.querySelector('.ai-chat-contact-card__initials');
44920
+ if (placeholder) {
44921
+ placeholder.style.display = 'flex';
44922
+ }
44923
+ } })) : null, (() => {
44924
+ const colors = getColorFromName(contact.name);
44925
+ return (jsxRuntimeExports.jsx("div", { className: "ai-chat-contact-card__initials", style: {
44926
+ display: contact.profilePictureUrl ? 'none' : 'flex',
44927
+ backgroundColor: colors.bg,
44928
+ color: colors.text,
44929
+ }, children: getInitials(contact.name) }));
44930
+ })()] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card__info", children: [jsxRuntimeExports.jsx("h4", { className: "ai-chat-contact-card__name", children: contact.name }), settings.showRole !== false && contact.role && (jsxRuntimeExports.jsx("p", { className: "ai-chat-contact-card__role", children: contact.role })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card__details", children: [settings.showEmail !== false && contact.email && (jsxRuntimeExports.jsx("a", { href: `mailto:${contact.email}`, className: "ai-chat-contact-card__detail", onClick: onEmail, children: contact.email })), settings.showPhone !== false && contact.phone && (jsxRuntimeExports.jsx("a", { href: `tel:${contact.phone}`, className: "ai-chat-contact-card__detail", onClick: onPhone, children: contact.phone }))] }), settings.showResponsibilities !== false && contact.responsibilities && contact.responsibilities.length > 0 && !compact && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card__responsibilities", children: [contact.responsibilities.slice(0, 3).map((resp, idx) => (jsxRuntimeExports.jsx("span", { className: "ai-chat-contact-card__responsibility-tag", children: resp }, idx))), contact.responsibilities.length > 3 && (jsxRuntimeExports.jsxs("span", { className: "ai-chat-contact-card__responsibility-more", children: ["+", contact.responsibilities.length - 3, " more"] }))] }))] })] }));
44931
+ }
44932
+ function ContactCard({ action, onComplete, accentColor, maxColumns = 3 }) {
44933
+ const rawState = action.state;
44934
+ const hasCompletedRef = reactExports.useRef(false);
44935
+ const state = {
44936
+ contacts: rawState?.contacts || [],
44937
+ settings: rawState?.settings || {},
44938
+ query: rawState?.query,
44939
+ status: rawState?.status || 'displaying',
44940
+ };
44941
+ const { contacts, settings } = state;
44942
+ const isSingleContact = contacts.length === 1;
44943
+ const stackColumns = Math.min(Math.max(contacts.length, 1), maxColumns);
44944
+ reactExports.useEffect(() => {
44945
+ if (!action.done && !hasCompletedRef.current && onComplete) {
44946
+ hasCompletedRef.current = true;
44947
+ onComplete(action.toolCallId, { ...state, status: 'displaying' });
44948
+ }
44949
+ }, [action.done, action.toolCallId, onComplete, state]);
44950
+ const handleContact = () => {
44951
+ onComplete?.(action.toolCallId, { ...state, status: 'contacted' });
44952
+ };
44953
+ if (contacts.length === 0) {
44954
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card ai-chat-contact-card--empty", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-contact-card__empty-icon", children: jsxRuntimeExports.jsx(UsersIcon, {}) }), jsxRuntimeExports.jsxs("p", { className: "ai-chat-contact-card__empty-text", children: ["No contacts found", state.query ? ` for "${state.query}"` : ''] })] }));
44955
+ }
44956
+ if (isSingleContact) {
44957
+ return (jsxRuntimeExports.jsx(ContactItem, { contact: contacts[0], settings: settings, accentColor: accentColor, onEmail: handleContact, onPhone: handleContact, layout: settings.layout || 'horizontal' }));
44958
+ }
44959
+ const isWidget = maxColumns === 1;
44960
+ const stackClassName = isWidget
44961
+ ? 'ai-chat-contact-card-list__stack ai-chat-contact-card-list__stack--widget'
44962
+ : 'ai-chat-contact-card-list__stack';
44963
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card-list", style: { containerType: 'inline-size' }, children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-contact-card-list__header", children: [jsxRuntimeExports.jsx(UsersIcon, {}), jsxRuntimeExports.jsxs("span", { children: [contacts.length, " Contacts"] })] }), jsxRuntimeExports.jsx("div", { className: stackClassName, style: isWidget ? undefined : {
44964
+ gridTemplateColumns: `repeat(${stackColumns}, minmax(0, 1fr))`,
44965
+ }, children: contacts.map((contact) => (jsxRuntimeExports.jsx(ContactItem, { contact: contact, settings: settings, accentColor: accentColor, onEmail: handleContact, onPhone: handleContact, compact: true, layout: settings.layout || 'vertical' }, contact.id))) })] }));
44966
+ }
44967
+
44968
+ function FormCard({ action, onComplete, accentColor }) {
44969
+ const state = action.state;
44970
+ const [currentStep, setCurrentStep] = reactExports.useState(0);
44971
+ const [answers, setAnswers] = reactExports.useState({});
44972
+ const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
44973
+ const questions = state.questions || [];
44974
+ const currentQuestion = questions[currentStep];
44975
+ const totalQuestions = questions.length;
44976
+ const handleAnswerChange = (questionId, value) => {
44977
+ setAnswers((prev) => ({ ...prev, [questionId]: value }));
44978
+ };
44979
+ const handleNext = () => {
44980
+ if (currentStep < totalQuestions - 1) {
44981
+ setCurrentStep((prev) => prev + 1);
44982
+ }
44983
+ };
44984
+ const handlePrev = () => {
44985
+ if (currentStep > 0) {
44986
+ setCurrentStep((prev) => prev - 1);
44987
+ }
44988
+ };
44989
+ const handleSubmit = () => {
44990
+ if (!onComplete)
44991
+ return;
44992
+ setIsSubmitting(true);
44993
+ const formattedAnswers = Object.entries(answers).map(([questionId, value]) => ({
44994
+ questionId,
44995
+ value,
44996
+ }));
44997
+ onComplete(action.toolCallId, {
44998
+ ...state,
44999
+ status: 'submitted',
45000
+ answers: formattedAnswers,
45001
+ });
45002
+ };
45003
+ const handleSkip = () => {
45004
+ if (!onComplete || !state.settings.allowSkip)
45005
+ return;
45006
+ onComplete(action.toolCallId, {
45007
+ ...state,
45008
+ status: 'skipped',
45009
+ });
45010
+ };
45011
+ const isCurrentAnswered = () => {
45012
+ if (!currentQuestion)
45013
+ return false;
45014
+ const answer = answers[currentQuestion.id];
45015
+ if (!answer)
45016
+ return !currentQuestion.required;
45017
+ if (Array.isArray(answer))
45018
+ return answer.length > 0 || !currentQuestion.required;
45019
+ return answer.trim() !== '' || !currentQuestion.required;
45020
+ };
45021
+ const canSubmit = () => {
45022
+ return questions.every((q) => {
45023
+ const answer = answers[q.id];
45024
+ if (!q.required)
45025
+ return true;
45026
+ if (!answer)
45027
+ return false;
45028
+ if (Array.isArray(answer))
45029
+ return answer.length > 0;
45030
+ return answer.trim() !== '';
45031
+ });
45032
+ };
45033
+ // Error state
45034
+ if (state.status === 'error') {
45035
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card ai-chat-form-card--error", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\u26A0\uFE0F" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: "Form Error" })] }), jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__error", children: state.error || 'Could not load form' })] }));
45036
+ }
45037
+ // Submitted state
45038
+ if (state.status === 'submitted' || action.done) {
45039
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card ai-chat-form-card--submitted", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\u2713" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: state.title })] }), jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__success", children: state.settings.successMessage || 'Thank you for your response!' })] }));
45040
+ }
45041
+ // Skipped state
45042
+ if (state.status === 'skipped') {
45043
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card ai-chat-form-card--skipped", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\u21B7" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: state.title })] }), jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__skipped-text", children: "Form skipped" })] }));
45044
+ }
45045
+ // No questions
45046
+ if (totalQuestions === 0) {
45047
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card ai-chat-form-card--empty", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\uD83D\uDCCB" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: state.title })] }), jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__empty-text", children: "This form has no questions." })] }));
45048
+ }
45049
+ return (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__header", children: [jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__icon", children: "\uD83D\uDCCB" }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__title", children: state.title })] }), state.description && (jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__description", children: state.description })), state.context && (jsxRuntimeExports.jsx("p", { className: "ai-chat-form-card__context", children: state.context })), state.settings.showProgress && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__progress", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__progress-bar", style: {
45050
+ width: `${((currentStep + 1) / totalQuestions) * 100}%`,
45051
+ backgroundColor: accentColor || 'var(--ai-chat-accent-color, #3b82f6)',
45052
+ } }), jsxRuntimeExports.jsxs("span", { className: "ai-chat-form-card__progress-text", children: [currentStep + 1, " of ", totalQuestions] })] })), jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__question", children: [jsxRuntimeExports.jsxs("p", { className: "ai-chat-form-card__question-text", children: [currentQuestion.text, currentQuestion.required && jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__required", children: "*" })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__answer", children: [currentQuestion.type === 'text' && (jsxRuntimeExports.jsx("textarea", { className: "ai-chat-form-card__textarea", placeholder: currentQuestion.placeholder || 'Type your answer...', value: answers[currentQuestion.id] || '', onChange: (e) => handleAnswerChange(currentQuestion.id, e.target.value), rows: 3 })), currentQuestion.type === 'single_choice' && currentQuestion.options && (jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__options", children: currentQuestion.options.map((option) => (jsxRuntimeExports.jsxs("label", { className: "ai-chat-form-card__option", children: [jsxRuntimeExports.jsx("input", { type: "radio", name: currentQuestion.id, value: option.value, checked: answers[currentQuestion.id] === option.value, onChange: () => handleAnswerChange(currentQuestion.id, option.value) }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__option-text", children: option.text })] }, option.id))) })), currentQuestion.type === 'multiple_choice' && currentQuestion.options && (jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__options", children: currentQuestion.options.map((option) => {
45053
+ const currentAnswers = answers[currentQuestion.id] || [];
45054
+ const isChecked = currentAnswers.includes(option.value);
45055
+ return (jsxRuntimeExports.jsxs("label", { className: "ai-chat-form-card__option", children: [jsxRuntimeExports.jsx("input", { type: "checkbox", value: option.value, checked: isChecked, onChange: () => {
45056
+ const newAnswers = isChecked
45057
+ ? currentAnswers.filter((v) => v !== option.value)
45058
+ : [...currentAnswers, option.value];
45059
+ handleAnswerChange(currentQuestion.id, newAnswers);
45060
+ } }), jsxRuntimeExports.jsx("span", { className: "ai-chat-form-card__option-text", children: option.text })] }, option.id));
45061
+ }) })), currentQuestion.type === 'rating' && (jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__rating", children: Array.from({ length: (currentQuestion.maxRating || 5) - (currentQuestion.minRating || 1) + 1 }, (_, i) => (currentQuestion.minRating || 1) + i).map((rating) => (jsxRuntimeExports.jsx("button", { type: "button", className: `ai-chat-form-card__rating-btn ${answers[currentQuestion.id] === String(rating) ? 'ai-chat-form-card__rating-btn--selected' : ''}`, onClick: () => handleAnswerChange(currentQuestion.id, String(rating)), style: {
45062
+ borderColor: answers[currentQuestion.id] === String(rating)
45063
+ ? (accentColor || 'var(--ai-chat-accent-color, #3b82f6)')
45064
+ : undefined,
45065
+ backgroundColor: answers[currentQuestion.id] === String(rating)
45066
+ ? (accentColor || 'var(--ai-chat-accent-color, #3b82f6)')
45067
+ : undefined,
45068
+ }, children: rating }, rating))) }))] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-form-card__actions", children: [currentStep > 0 && (jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-form-card__btn ai-chat-form-card__btn--secondary", onClick: handlePrev, children: "Back" })), state.settings.allowSkip && currentStep === 0 && (jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-form-card__btn ai-chat-form-card__btn--ghost", onClick: handleSkip, children: "Skip" })), jsxRuntimeExports.jsx("div", { className: "ai-chat-form-card__actions-spacer" }), currentStep < totalQuestions - 1 ? (jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-form-card__btn ai-chat-form-card__btn--primary", onClick: handleNext, disabled: !isCurrentAnswered(), style: {
45069
+ backgroundColor: accentColor || 'var(--ai-chat-accent-color, #3b82f6)',
45070
+ }, children: "Next" })) : (jsxRuntimeExports.jsx("button", { type: "button", className: "ai-chat-form-card__btn ai-chat-form-card__btn--primary", onClick: handleSubmit, disabled: !canSubmit() || isSubmitting, style: {
45071
+ backgroundColor: accentColor || 'var(--ai-chat-accent-color, #3b82f6)',
45072
+ }, children: isSubmitting ? 'Submitting...' : (state.settings.submitButtonText || 'Submit') }))] })] }));
44203
45073
  }
44204
45074
 
44205
45075
  const pendingResolvers = new Map();
@@ -44212,12 +45082,6 @@
44212
45082
  function getActionRenderer(implementation) {
44213
45083
  return actionRenderers[implementation];
44214
45084
  }
44215
- function getActionPrompt(implementation) {
44216
- if (implementation === "google-calendar-appointment") {
44217
- return "Select a date to continue.";
44218
- }
44219
- return "Action input required.";
44220
- }
44221
45085
  function waitForActionState(toolCallId) {
44222
45086
  return new Promise((resolve) => {
44223
45087
  pendingResolvers.set(toolCallId, resolve);
@@ -44244,26 +45108,272 @@
44244
45108
  resumeCallbacks.delete(toolCallId);
44245
45109
  }
44246
45110
 
44247
- frontendActionHandlers["google-calendar-appointment"] = async (_input, _state, context) => {
44248
- return waitForActionState(context.toolCallId);
44249
- };
45111
+ function registerGoogleCalendarHandler() {
45112
+ frontendActionHandlers["google-calendar-appointment"] = async (_input, _state, context) => {
45113
+ return waitForActionState(context.toolCallId);
45114
+ };
45115
+ }
44250
45116
 
44251
- actionRenderers["google-calendar-appointment"] = (message) => {
44252
- const action = message.action;
44253
- if (!action)
44254
- return null;
44255
- const handleComplete = (toolCallId, newState) => {
44256
- resolveActionState(toolCallId, newState);
45117
+ /**
45118
+ * Register google-calendar-appointment action handler and renderer.
45119
+ * Called by initializeActionHandlers to prevent tree-shaking.
45120
+ */
45121
+ function registerGoogleCalendarAction() {
45122
+ // Register the handler
45123
+ registerGoogleCalendarHandler();
45124
+ // Register the renderer
45125
+ actionRenderers["google-calendar-appointment"] = (message, accentColor) => {
45126
+ const action = message.action;
45127
+ if (!action)
45128
+ return null;
45129
+ const handleComplete = (toolCallId, newState) => {
45130
+ resolveActionState(toolCallId, newState);
45131
+ };
45132
+ return (jsxRuntimeExports.jsx(GoogleCalendarCard, { action: {
45133
+ implementation: action.implementation,
45134
+ toolCallId: action.toolCallId,
45135
+ actionId: action.actionId,
45136
+ input: action.input,
45137
+ state: action.state,
45138
+ done: action.done ?? false,
45139
+ }, onComplete: handleComplete, accentColor: accentColor }));
44257
45140
  };
44258
- return (jsxRuntimeExports.jsx(GoogleCalendarCard, { action: {
44259
- implementation: action.implementation,
44260
- toolCallId: action.toolCallId,
44261
- actionId: action.actionId,
44262
- input: action.input,
44263
- state: action.state,
44264
- done: action.done ?? false,
44265
- }, onComplete: handleComplete }));
44266
- };
45141
+ }
45142
+
45143
+ function registerMicrosoftCalendarHandler() {
45144
+ frontendActionHandlers["microsoft-calendar-appointment"] = async (_input, _state, context) => {
45145
+ return waitForActionState(context.toolCallId);
45146
+ };
45147
+ }
45148
+
45149
+ /**
45150
+ * Register microsoft-calendar-appointment action handler and renderer.
45151
+ * Called by initializeActionHandlers to prevent tree-shaking.
45152
+ */
45153
+ function registerMicrosoftCalendarAction() {
45154
+ // Register the handler
45155
+ registerMicrosoftCalendarHandler();
45156
+ // Register the renderer
45157
+ actionRenderers["microsoft-calendar-appointment"] = (message, accentColor) => {
45158
+ const action = message.action;
45159
+ if (!action)
45160
+ return null;
45161
+ const handleComplete = (toolCallId, newState) => {
45162
+ resolveActionState(toolCallId, newState);
45163
+ };
45164
+ return (jsxRuntimeExports.jsx(MicrosoftCalendarCard, { action: {
45165
+ implementation: action.implementation,
45166
+ toolCallId: action.toolCallId,
45167
+ actionId: action.actionId,
45168
+ input: action.input,
45169
+ state: action.state,
45170
+ done: action.done ?? false,
45171
+ }, onComplete: handleComplete, accentColor: accentColor }));
45172
+ };
45173
+ }
45174
+
45175
+ /**
45176
+ * Register link-preview action handler and renderer.
45177
+ * Called by initializeActionHandlers to prevent tree-shaking.
45178
+ */
45179
+ function registerLinkPreviewAction() {
45180
+ // Handler - auto-completes immediately since no user input is needed
45181
+ frontendActionHandlers["link-preview"] = async (_input, state, _context) => {
45182
+ return { ...state, status: "displaying" };
45183
+ };
45184
+ // Renderer - displays the link preview card
45185
+ actionRenderers["link-preview"] = (message, accentColor) => {
45186
+ const action = message.action;
45187
+ if (!action)
45188
+ return null;
45189
+ const handleComplete = (toolCallId, newState) => {
45190
+ resolveActionState(toolCallId, newState);
45191
+ };
45192
+ // Check if action state indicates it's already complete (displaying or clicked)
45193
+ const state = action.state;
45194
+ const status = state?.status;
45195
+ const isDone = action.done || status === "displaying" || status === "clicked";
45196
+ return (jsxRuntimeExports.jsx(LinkPreviewCard, { action: {
45197
+ implementation: action.implementation,
45198
+ toolCallId: action.toolCallId,
45199
+ actionId: action.actionId,
45200
+ input: action.input,
45201
+ state: action.state,
45202
+ done: isDone,
45203
+ }, onComplete: handleComplete, accentColor: accentColor }));
45204
+ };
45205
+ }
45206
+
45207
+ /**
45208
+ * Register video-player action handler and renderer.
45209
+ * Called by initializeActionHandlers to prevent tree-shaking.
45210
+ */
45211
+ function registerVideoPlayerAction() {
45212
+ // Handler - auto-completes immediately since no user input is needed
45213
+ frontendActionHandlers["video-player"] = async (_input, state, _context) => {
45214
+ return { ...state, status: "displaying" };
45215
+ };
45216
+ // Renderer - displays the embedded video player card
45217
+ actionRenderers["video-player"] = (message, accentColor) => {
45218
+ const action = message.action;
45219
+ if (!action)
45220
+ return null;
45221
+ const handleComplete = (toolCallId, newState) => {
45222
+ resolveActionState(toolCallId, newState);
45223
+ };
45224
+ // Check if action state indicates it's already complete (displaying or played)
45225
+ const state = action.state;
45226
+ const status = state?.status;
45227
+ const isDone = action.done || status === "displaying" || status === "played";
45228
+ return (jsxRuntimeExports.jsx(VideoPlayerCard, { action: {
45229
+ implementation: action.implementation,
45230
+ toolCallId: action.toolCallId,
45231
+ actionId: action.actionId,
45232
+ input: action.input,
45233
+ state: action.state,
45234
+ done: isDone,
45235
+ }, onComplete: handleComplete, accentColor: accentColor }));
45236
+ };
45237
+ }
45238
+
45239
+ /**
45240
+ * Register location-card action handler and renderer.
45241
+ * Called by initializeActionHandlers to prevent tree-shaking.
45242
+ */
45243
+ function registerLocationCardAction() {
45244
+ // Handler - auto-completes immediately since no user input is needed
45245
+ frontendActionHandlers["location-card"] = async (_input, state, _context) => {
45246
+ return { ...state, status: "displaying" };
45247
+ };
45248
+ // Renderer - displays the location card
45249
+ actionRenderers["location-card"] = (message, accentColor, variant) => {
45250
+ const action = message.action;
45251
+ if (!action)
45252
+ return null;
45253
+ const handleComplete = (toolCallId, newState) => {
45254
+ resolveActionState(toolCallId, newState);
45255
+ };
45256
+ // Check if action state indicates it's already complete
45257
+ const state = action.state;
45258
+ const status = state?.status;
45259
+ const isDone = action.done || status === "displaying" || status === "directions_opened";
45260
+ return (jsxRuntimeExports.jsx(LocationCard, { action: {
45261
+ implementation: action.implementation,
45262
+ toolCallId: action.toolCallId,
45263
+ actionId: action.actionId,
45264
+ input: action.input,
45265
+ state: action.state,
45266
+ done: isDone,
45267
+ }, onComplete: handleComplete, accentColor: accentColor, maxColumns: variant === 'fullpage' ? 3 : 1 }));
45268
+ };
45269
+ }
45270
+
45271
+ function registerContactCardAction() {
45272
+ // Handler - auto-completes immediately since no user input is needed
45273
+ frontendActionHandlers['contact-card'] = async (_input, state, _context) => {
45274
+ return { ...state, status: 'displaying' };
45275
+ };
45276
+ // Renderer - displays the contact card
45277
+ actionRenderers['contact-card'] = (message, accentColor, variant) => {
45278
+ const action = message.action;
45279
+ if (!action)
45280
+ return null;
45281
+ const handleComplete = (toolCallId, newState) => {
45282
+ resolveActionState(toolCallId, newState);
45283
+ };
45284
+ // Check if action state indicates it's already complete
45285
+ const state = action.state;
45286
+ const status = state?.status;
45287
+ const isDone = action.done || status === 'displaying' || status === 'contacted';
45288
+ return (jsxRuntimeExports.jsx(ContactCard, { action: {
45289
+ implementation: action.implementation,
45290
+ toolCallId: action.toolCallId,
45291
+ actionId: action.actionId,
45292
+ input: action.input,
45293
+ state: action.state,
45294
+ done: isDone,
45295
+ }, onComplete: handleComplete, accentColor: accentColor, maxColumns: variant === 'fullpage' ? 3 : 1 }));
45296
+ };
45297
+ }
45298
+
45299
+ function registerQueryContactDirectoryAction() {
45300
+ // Handler - auto-completes immediately since no user input is needed
45301
+ frontendActionHandlers['query-contact-directory'] = async (_input, state, _context) => {
45302
+ return { ...state, status: 'displaying' };
45303
+ };
45304
+ // Renderer - displays the contact card with search results
45305
+ actionRenderers['query-contact-directory'] = (message, accentColor, variant) => {
45306
+ const action = message.action;
45307
+ if (!action)
45308
+ return null;
45309
+ // Handle completion - triggers agent to continue with text response
45310
+ const handleComplete = (toolCallId, newState) => {
45311
+ resolveActionState(toolCallId, newState);
45312
+ };
45313
+ // Check if action state indicates it's already complete
45314
+ const state = action.state;
45315
+ const status = state?.status;
45316
+ const isDone = action.done || status === 'displaying' || status === 'contacted';
45317
+ return (jsxRuntimeExports.jsx(ContactCard, { action: {
45318
+ implementation: action.implementation,
45319
+ toolCallId: action.toolCallId,
45320
+ actionId: action.actionId,
45321
+ input: action.input,
45322
+ state: action.state,
45323
+ done: isDone,
45324
+ }, onComplete: handleComplete, accentColor: accentColor, maxColumns: variant === 'fullpage' ? 3 : 1 }));
45325
+ };
45326
+ }
45327
+
45328
+ function registerDisplayFormAction() {
45329
+ // Handler - handles form submission and state updates
45330
+ frontendActionHandlers['display-form'] = async (_input, _state, context) => {
45331
+ return waitForActionState(context.toolCallId);
45332
+ };
45333
+ // Renderer - displays the form card
45334
+ actionRenderers['display-form'] = (message, accentColor, variant) => {
45335
+ const action = message.action;
45336
+ if (!action)
45337
+ return null;
45338
+ const handleComplete = (toolCallId, newState) => {
45339
+ resolveActionState(toolCallId, newState);
45340
+ };
45341
+ // Check if action state indicates it's already complete
45342
+ const state = action.state;
45343
+ const status = state?.status;
45344
+ const isDone = action.done || status === 'completed' || status === 'submitted';
45345
+ return (jsxRuntimeExports.jsx(FormCard, { action: {
45346
+ implementation: action.implementation,
45347
+ toolCallId: action.toolCallId,
45348
+ actionId: action.actionId,
45349
+ input: action.input,
45350
+ state: action.state,
45351
+ done: isDone,
45352
+ }, onComplete: handleComplete, accentColor: accentColor }));
45353
+ };
45354
+ }
45355
+
45356
+ // Track if handlers have been initialized
45357
+ let initialized = false;
45358
+ /**
45359
+ * Initialize all action handlers.
45360
+ * Call this to ensure handlers are registered (prevents tree-shaking in production builds).
45361
+ * Safe to call multiple times - will only register once.
45362
+ */
45363
+ function initializeActionHandlers() {
45364
+ if (initialized)
45365
+ return;
45366
+ initialized = true;
45367
+ // Explicitly call each registration function to prevent tree-shaking
45368
+ registerGoogleCalendarAction();
45369
+ registerMicrosoftCalendarAction();
45370
+ registerLinkPreviewAction();
45371
+ registerVideoPlayerAction();
45372
+ registerLocationCardAction();
45373
+ registerQueryContactDirectoryAction();
45374
+ registerContactCardAction();
45375
+ registerDisplayFormAction();
45376
+ }
44267
45377
 
44268
45378
  /**
44269
45379
  * Local Storage Utilities
@@ -44482,10 +45592,6 @@
44482
45592
  }
44483
45593
  }
44484
45594
 
44485
- /**
44486
- * useChat Hook
44487
- * Main state management for chat functionality
44488
- */
44489
45595
  function hydrateToolNames(messages) {
44490
45596
  const toolCallNameById = new Map();
44491
45597
  for (const entry of messages) {
@@ -44529,81 +45635,77 @@
44529
45635
  };
44530
45636
  });
44531
45637
  }
44532
- function hydrateActionContent(messages) {
44533
- return messages.map((entry) => {
44534
- if (entry.message.role !== "assistant" || !entry.action) {
44535
- return entry;
44536
- }
44537
- const content = typeof entry.message.content === "string" ? entry.message.content : "";
44538
- if (content.trim().length > 0) {
44539
- return entry;
44540
- }
44541
- return {
44542
- ...entry,
44543
- message: { ...entry.message, content: getActionPrompt(entry.action.implementation) },
44544
- };
44545
- });
44546
- }
44547
45638
  function hydrateMessages(messages) {
44548
- return hydrateActionContent(hydrateToolNames(messages));
45639
+ return hydrateToolNames(messages);
44549
45640
  }
44550
- function setupActionResumeCallbacks(messages, client, conversationId, setState, onMessageUpdate) {
44551
- // Find all incomplete actions and register resume callbacks
44552
- for (const message of messages) {
44553
- if (message.action && !message.action.done) {
44554
- const toolCallId = message.action.toolCallId;
44555
- const toolName = message.message.name || message.toolExecuting || "tool";
44556
- registerActionResumeCallback(toolCallId, async (newState) => {
44557
- // When user interacts with the action after reload, continue the stream
44558
- try {
44559
- // Update the action message with the new state
44560
- setState(prev => ({
44561
- ...prev,
44562
- messages: prev.messages.map(m => m.action?.toolCallId === toolCallId
44563
- ? {
44564
- ...m,
44565
- action: m.action ? { ...m.action, state: newState } : undefined,
44566
- }
44567
- : m),
44568
- isTyping: true,
44569
- }));
44570
- const streamState = createStreamState();
44571
- // Continue the agent stream with the new state
44572
- for await (const event of client.continueAgentMessageStream(conversationId, toolCallId, newState)) {
44573
- if (event.type === "done") {
44574
- finalizeToolMessage(streamState, setState, toolCallId, toolName);
44575
- streamState.sources = event.sources;
44576
- streamState.toolCallToActionId = event.tool_call_to_action_id;
44577
- finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id, event.suggestions);
44578
- continue;
44579
- }
44580
- if (event.type === "error") {
44581
- const errorMessage = {
44582
- id: generateMessageId(),
44583
- message: {
44584
- role: "assistant",
44585
- content: "Sorry, an error occurred. Please try again later.",
44586
- },
44587
- timestamp: new Date().toISOString(),
44588
- sources: [],
44589
- isError: true,
44590
- };
44591
- upsertMessage(setState, errorMessage, false);
44592
- setState(prev => ({ ...prev, isTyping: false }));
44593
- return;
44594
- }
44595
- handleStreamEvent(event, streamState, onMessageUpdate, setState);
44596
- }
44597
- setState(prev => ({ ...prev, isTyping: false }));
45641
+
45642
+ function deriveErrorInfo(error) {
45643
+ if (error instanceof ApiError) {
45644
+ const retryAfterSeconds = typeof error.retryAfterMs === 'number'
45645
+ ? Math.max(1, Math.ceil(error.retryAfterMs / 1000))
45646
+ : undefined;
45647
+ const lowerMessage = (error.message || '').toLowerCase();
45648
+ let message;
45649
+ switch (error.status) {
45650
+ case 429: {
45651
+ const isPerUser = lowerMessage.includes('user');
45652
+ const base = isPerUser
45653
+ ? 'You have reached the per-user rate limit.'
45654
+ : 'This widget has received too many requests.';
45655
+ if (retryAfterSeconds) {
45656
+ message = `${base} Please wait ${retryAfterSeconds} second${retryAfterSeconds === 1 ? '' : 's'} before trying again.`;
44598
45657
  }
44599
- catch (error) {
44600
- console.error("[Action Resume] Failed to continue stream:", error);
44601
- setState(prev => ({ ...prev, isTyping: false }));
45658
+ else {
45659
+ message = `${base} Please wait a moment and try again.`;
45660
+ }
45661
+ break;
45662
+ }
45663
+ case 401:
45664
+ message = 'Authentication failed. Please refresh the page or verify your API key.';
45665
+ break;
45666
+ case 403:
45667
+ message = 'Access to this widget is restricted. Please contact the site owner if you believe this is an error.';
45668
+ break;
45669
+ case 404:
45670
+ if (lowerMessage.includes('not active')) {
45671
+ message = 'This widget is currently inactive. Please contact the site owner.';
45672
+ }
45673
+ else {
45674
+ message = 'We could not find this widget. It may have been removed.';
45675
+ }
45676
+ break;
45677
+ default:
45678
+ if (error.status >= 500) {
45679
+ message = 'The server encountered an error. Please try again shortly.';
45680
+ }
45681
+ else if (error.status > 0) {
45682
+ message = error.message || 'Something went wrong. Please try again.';
45683
+ }
45684
+ else {
45685
+ message = error.message || 'Unable to connect to the server. Please check your internet connection.';
44602
45686
  }
44603
- });
44604
45687
  }
45688
+ return { message, retryAfterSeconds, status: error.status };
44605
45689
  }
45690
+ if (error instanceof Error) {
45691
+ const lower = error.message.toLowerCase();
45692
+ if (lower.includes('network')) {
45693
+ return { message: 'Unable to connect to the server. Please check your internet connection.' };
45694
+ }
45695
+ if (lower.includes('timeout')) {
45696
+ return { message: 'The request timed out. Please try again.' };
45697
+ }
45698
+ if (lower.includes('unauthorized') || lower.includes('401')) {
45699
+ return { message: 'Authentication failed. Please refresh the page or verify your API key.' };
45700
+ }
45701
+ if (lower.includes('internal server error') || lower.includes('500')) {
45702
+ return { message: 'The server encountered an error. Please try again shortly.' };
45703
+ }
45704
+ return { message: error.message || 'Something went wrong. Please try again.' };
45705
+ }
45706
+ return { message: 'Something went wrong. Please try again.' };
44606
45707
  }
45708
+
44607
45709
  function createStreamState() {
44608
45710
  return {
44609
45711
  currentContent: "",
@@ -44612,6 +45714,7 @@
44612
45714
  newMessageIds: new Set(),
44613
45715
  sources: [],
44614
45716
  toolCallToActionId: {},
45717
+ requestId: generateMessageId(),
44615
45718
  };
44616
45719
  }
44617
45720
  function upsertMessage(setState, message, isTyping) {
@@ -44647,15 +45750,40 @@
44647
45750
  return msg;
44648
45751
  }
44649
45752
  // Attach suggestions only to the last assistant message
44650
- if (index === lastAssistantIndex && suggestions && suggestions.length > 0) {
44651
- return { ...msg, sources, toolCallToActionId, suggestions };
44652
- }
44653
- return { ...msg, sources, toolCallToActionId };
45753
+ const withSuggestions = index === lastAssistantIndex && suggestions && suggestions.length > 0
45754
+ ? { suggestions }
45755
+ : {};
45756
+ return { ...msg, sources, toolCallToActionId, ...withSuggestions };
44654
45757
  }),
44655
45758
  isTyping: false,
44656
45759
  };
44657
45760
  });
44658
45761
  }
45762
+ function finalizeToolMessage(streamState, setState, toolCallId, toolName) {
45763
+ setState(prev => {
45764
+ const messages = prev.messages.map((entry) => {
45765
+ const matchesToolCall = entry.message.role === "tool" && entry.message.tool_call_id === toolCallId;
45766
+ if (!matchesToolCall) {
45767
+ return entry;
45768
+ }
45769
+ const existingName = entry.message.name || toolName;
45770
+ return {
45771
+ ...entry,
45772
+ message: {
45773
+ role: "tool",
45774
+ content: typeof entry.message.content === "string" ? entry.message.content : "",
45775
+ tool_call_id: toolCallId,
45776
+ name: existingName,
45777
+ },
45778
+ isStreaming: false,
45779
+ toolExecuting: existingName,
45780
+ };
45781
+ });
45782
+ return { ...prev, messages, isTyping: false, isLoading: false };
45783
+ });
45784
+ streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
45785
+ }
45786
+
44659
45787
  function handleContentEvent(event, streamState, onMessageUpdate, setState) {
44660
45788
  streamState.currentContent += event.content;
44661
45789
  const assistantMessage = {
@@ -44702,8 +45830,6 @@
44702
45830
  }
44703
45831
  function handleToolEndEvent(event, streamState, _onMessageUpdate, setState) {
44704
45832
  streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
44705
- // Update state and mark action as done in a single setState call
44706
- // Keep isTyping: true because the agent may continue generating content after tool completion
44707
45833
  setState(prev => {
44708
45834
  const messages = prev.messages.map((msg) => {
44709
45835
  const matchesToolCall = msg.message.role === "tool" && msg.message.tool_call_id === event.tool_call_id;
@@ -44711,7 +45837,26 @@
44711
45837
  return msg;
44712
45838
  }
44713
45839
  const existingName = msg.message.name || event.tool_name;
44714
- return {
45840
+ let action = msg.action;
45841
+ if (event.action_id && event.implementation) {
45842
+ action = {
45843
+ implementation: event.implementation,
45844
+ toolCallId: event.tool_call_id,
45845
+ actionId: event.action_id,
45846
+ input: (event.input || {}),
45847
+ state: (event.state || {}),
45848
+ done: event.done,
45849
+ };
45850
+ }
45851
+ else if (action) {
45852
+ action = {
45853
+ ...action,
45854
+ input: event.input ? event.input : action.input,
45855
+ state: event.state ? event.state : action.state,
45856
+ done: event.done,
45857
+ };
45858
+ }
45859
+ const updatedMsg = {
44715
45860
  ...msg,
44716
45861
  message: {
44717
45862
  role: "tool",
@@ -44721,14 +45866,10 @@
44721
45866
  },
44722
45867
  isStreaming: false,
44723
45868
  toolExecuting: existingName,
44724
- action: msg.action ? {
44725
- ...msg.action,
44726
- state: event.state || msg.action.state,
44727
- done: true, // Mark action as completed
44728
- } : undefined,
45869
+ action,
44729
45870
  };
45871
+ return updatedMsg;
44730
45872
  });
44731
- // Keep typing indicator visible - it will be hidden by done/finalizeStreamMessages
44732
45873
  return { ...prev, messages, isTyping: true, isLoading: false };
44733
45874
  });
44734
45875
  }
@@ -44760,34 +45901,6 @@
44760
45901
  return { ...prev, messages, isTyping: true, isLoading: false };
44761
45902
  });
44762
45903
  }
44763
- function finalizeToolMessage(streamState, setState, toolCallId, toolName) {
44764
- setState(prev => {
44765
- const messages = prev.messages.map((entry) => {
44766
- const matchesToolCall = entry.message.role === "tool" && entry.message.tool_call_id === toolCallId;
44767
- if (!matchesToolCall) {
44768
- return entry;
44769
- }
44770
- const existingName = entry.message.name || toolName;
44771
- return {
44772
- ...entry,
44773
- message: {
44774
- role: "tool",
44775
- content: typeof entry.message.content === "string" ? entry.message.content : "",
44776
- tool_call_id: toolCallId,
44777
- name: existingName,
44778
- },
44779
- isStreaming: false,
44780
- toolExecuting: existingName,
44781
- action: entry.action ? {
44782
- ...entry.action,
44783
- done: true, // Mark action as completed
44784
- } : undefined,
44785
- };
44786
- });
44787
- return { ...prev, messages, isTyping: false, isLoading: false };
44788
- });
44789
- streamState.activeToolCallCount = Math.max(0, streamState.activeToolCallCount - 1);
44790
- }
44791
45904
  function handleDoneEvent(event, streamState, _onMessageUpdate, setState) {
44792
45905
  streamState.sources = event.sources;
44793
45906
  streamState.toolCallToActionId = event.tool_call_to_action_id;
@@ -44846,6 +45959,7 @@
44846
45959
  console.warn('[Chat] Unknown event type:', event.type);
44847
45960
  }
44848
45961
  }
45962
+
44849
45963
  async function handleActionLoop(client, initialEvent, streamState, onMessageUpdate, setState, widgetId, conversationId, getMessages) {
44850
45964
  let pendingEvent = initialEvent;
44851
45965
  while (pendingEvent) {
@@ -44872,7 +45986,7 @@
44872
45986
  actionId: pendingEvent.action_id,
44873
45987
  input: pendingEvent.input,
44874
45988
  state: pendingEvent.state,
44875
- done: false, // Action not yet completed
45989
+ done: pendingEvent.done ?? false,
44876
45990
  },
44877
45991
  };
44878
45992
  if (streamState.activeToolCallCount === 0) {
@@ -44886,7 +46000,7 @@
44886
46000
  id: generateMessageId(),
44887
46001
  message: {
44888
46002
  role: "assistant",
44889
- content: "Sorry, an error occurred. Please try again later.",
46003
+ content: "Sorry, an error occurred.",
44890
46004
  },
44891
46005
  timestamp: new Date().toISOString(),
44892
46006
  sources: [],
@@ -44910,7 +46024,7 @@
44910
46024
  console.error("[Widget] Frontend action failed:", error);
44911
46025
  const errorMessageEntry = {
44912
46026
  id: generateMessageId(),
44913
- message: { role: "assistant", content: "Sorry, an error occurred. Please try again later." },
46027
+ message: { role: "assistant", content: "Sorry, an error occurred." },
44914
46028
  timestamp: new Date().toISOString(),
44915
46029
  sources: [],
44916
46030
  isError: true,
@@ -44922,12 +46036,7 @@
44922
46036
  pendingEvent = null;
44923
46037
  const updatedToolMessage = {
44924
46038
  ...toolMessage,
44925
- action: toolMessage.action
44926
- ? {
44927
- ...toolMessage.action,
44928
- state: nextState,
44929
- }
44930
- : undefined,
46039
+ action: toolMessage.action ? { ...toolMessage.action, state: nextState } : toolMessage.action,
44931
46040
  };
44932
46041
  upsertMessage(setState, updatedToolMessage, true);
44933
46042
  let streamEnded = false;
@@ -44937,22 +46046,20 @@
44937
46046
  break;
44938
46047
  }
44939
46048
  if (event.type === "done") {
44940
- // Don't extract and update state from done event - the state was already
44941
- // updated by tool_end event or by the user's frontend action.
46049
+ // Finalize tool message and stream messages
44942
46050
  finalizeToolMessage(streamState, setState, resumeToolCallId, toolName);
44943
- // Handle the done event but skip the tool finalization part since we already did it
44944
46051
  streamState.sources = event.sources;
44945
46052
  streamState.toolCallToActionId = event.tool_call_to_action_id;
44946
46053
  finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id, event.suggestions);
44947
46054
  streamEnded = true;
44948
- continue; // Skip handleStreamEvent for done events to avoid state conflicts
46055
+ continue;
44949
46056
  }
44950
46057
  if (event.type === "error") {
44951
46058
  const errorMessage = {
44952
46059
  id: generateMessageId(),
44953
46060
  message: {
44954
46061
  role: "assistant",
44955
- content: "Sorry, an error occurred. Please try again later.",
46062
+ content: "Sorry, an error occurred.",
44956
46063
  },
44957
46064
  timestamp: new Date().toISOString(),
44958
46065
  sources: [],
@@ -44963,73 +46070,79 @@
44963
46070
  }
44964
46071
  handleStreamEvent(event, streamState, onMessageUpdate, setState);
44965
46072
  }
44966
- // If stream ended without a done event (e.g., only tool_end was sent), finalize the tool message
46073
+ // If stream ended without a done event, finalize the tool message
44967
46074
  if (!streamEnded && !pendingEvent) {
44968
46075
  finalizeToolMessage(streamState, setState, resumeToolCallId, toolName);
44969
46076
  }
44970
46077
  }
44971
46078
  }
44972
- function deriveErrorInfo(error) {
44973
- if (error instanceof ApiError) {
44974
- const retryAfterSeconds = typeof error.retryAfterMs === 'number'
44975
- ? Math.max(1, Math.ceil(error.retryAfterMs / 1000))
44976
- : undefined;
44977
- const lowerMessage = (error.message || '').toLowerCase();
44978
- let message;
44979
- switch (error.status) {
44980
- case 429: {
44981
- const isPerUser = lowerMessage.includes('user');
44982
- const base = isPerUser
44983
- ? 'You have reached the per-user rate limit.'
44984
- : 'This widget has received too many requests.';
44985
- if (retryAfterSeconds) {
44986
- message = `${base} Please wait ${retryAfterSeconds} second${retryAfterSeconds === 1 ? '' : 's'} before trying again.`;
44987
- }
44988
- else {
44989
- message = `${base} Please wait a moment and try again.`;
44990
- }
44991
- break;
44992
- }
44993
- case 401:
44994
- message = 'Authentication failed. Please refresh the page or verify your API key.';
44995
- break;
44996
- case 403:
44997
- message = 'Access to this widget is restricted. Please contact the site owner if you believe this is an error.';
44998
- break;
44999
- case 404:
45000
- message = 'We could not find this widget. It may have been removed.';
45001
- break;
45002
- default:
45003
- if (error.status >= 500) {
45004
- message = 'The server encountered an error. Please try again shortly.';
45005
- }
45006
- else if (error.status > 0) {
45007
- message = error.message || 'Something went wrong. Please try again.';
46079
+ function setupActionResumeCallbacks(messages, client, conversationId, setState, onMessageUpdate, createStreamState, registerCallback) {
46080
+ // Find all incomplete actions and register resume callbacks
46081
+ for (const message of messages) {
46082
+ if (message.action && !message.action.done) {
46083
+ const toolCallId = message.action.toolCallId;
46084
+ const toolName = message.message.name || message.toolExecuting || "tool";
46085
+ registerCallback(toolCallId, async (newState) => {
46086
+ // When user interacts with the action after reload, continue the stream
46087
+ try {
46088
+ // Update the action message with the new state and check completion
46089
+ setState(prev => ({
46090
+ ...prev,
46091
+ messages: prev.messages.map(m => {
46092
+ if (m.action?.toolCallId !== toolCallId) {
46093
+ return m;
46094
+ }
46095
+ if (!m.action) {
46096
+ return m;
46097
+ }
46098
+ return { ...m, action: { ...m.action, state: newState } };
46099
+ }),
46100
+ isTyping: true,
46101
+ }));
46102
+ const streamState = createStreamState();
46103
+ // Continue the agent stream with the new state
46104
+ for await (const event of client.continueAgentMessageStream(conversationId, toolCallId, newState)) {
46105
+ if (event.type === "done") {
46106
+ finalizeToolMessage(streamState, setState, toolCallId, toolName);
46107
+ streamState.sources = event.sources;
46108
+ streamState.toolCallToActionId = event.tool_call_to_action_id;
46109
+ finalizeStreamMessages(setState, streamState.newMessageIds, event.sources, event.tool_call_to_action_id, event.suggestions);
46110
+ continue;
46111
+ }
46112
+ if (event.type === "error") {
46113
+ const errorMessage = {
46114
+ id: generateMessageId(),
46115
+ message: {
46116
+ role: "assistant",
46117
+ content: "Sorry, an error occurred. Please try again later.",
46118
+ },
46119
+ timestamp: new Date().toISOString(),
46120
+ sources: [],
46121
+ isError: true,
46122
+ };
46123
+ upsertMessage(setState, errorMessage, false);
46124
+ setState(prev => ({ ...prev, isTyping: false }));
46125
+ return;
46126
+ }
46127
+ handleStreamEvent(event, streamState, onMessageUpdate, setState);
46128
+ }
46129
+ setState(prev => ({ ...prev, isTyping: false }));
45008
46130
  }
45009
- else {
45010
- message = error.message || 'Unable to connect to the server. Please check your internet connection.';
46131
+ catch (error) {
46132
+ console.error("[Action Resume] Failed to continue stream:", error);
46133
+ setState(prev => ({ ...prev, isTyping: false }));
45011
46134
  }
46135
+ });
45012
46136
  }
45013
- return { message, retryAfterSeconds, status: error.status };
45014
- }
45015
- if (error instanceof Error) {
45016
- const lower = error.message.toLowerCase();
45017
- if (lower.includes('network')) {
45018
- return { message: 'Unable to connect to the server. Please check your internet connection.' };
45019
- }
45020
- if (lower.includes('timeout')) {
45021
- return { message: 'The request timed out. Please try again.' };
45022
- }
45023
- if (lower.includes('unauthorized') || lower.includes('401')) {
45024
- return { message: 'Authentication failed. Please refresh the page or verify your API key.' };
45025
- }
45026
- if (lower.includes('internal server error') || lower.includes('500')) {
45027
- return { message: 'The server encountered an error. Please try again shortly.' };
45028
- }
45029
- return { message: error.message || 'Something went wrong. Please try again.' };
45030
46137
  }
45031
- return { message: 'Something went wrong. Please try again.' };
45032
46138
  }
46139
+
46140
+ /**
46141
+ * useChat Hook
46142
+ * Main state management for chat functionality
46143
+ */
46144
+ // Initialize action handlers immediately to prevent tree-shaking
46145
+ initializeActionHandlers();
45033
46146
  function useChat(options) {
45034
46147
  const { widgetId, apiUrl, currentRoute, onMessage, onError, skipInitialization = false, } = options;
45035
46148
  const [state, setState] = reactExports.useState({
@@ -45038,23 +46151,24 @@
45038
46151
  isLoading: false,
45039
46152
  isTyping: false,
45040
46153
  error: null,
45041
- conversationId: '', // Will be set after loading conversation
46154
+ conversationId: '',
45042
46155
  config: null,
45043
46156
  });
45044
46157
  const stateRef = reactExports.useRef(state);
45045
46158
  reactExports.useEffect(() => {
45046
46159
  stateRef.current = state;
45047
46160
  }, [state]);
45048
- // Chat history state
45049
46161
  const [conversations, setConversations] = reactExports.useState([]);
46162
+ const abortControllerRef = reactExports.useRef(null);
46163
+ const currentRequestIdRef = reactExports.useRef(null);
46164
+ const lastNewChatTimeRef = reactExports.useRef(0);
46165
+ const NEW_CHAT_COOLDOWN_MS = 5000;
45050
46166
  const apiClient = reactExports.useRef(new WidgetApiClient({ widgetId, apiUrl, currentRoute }));
45051
- // Update API client when currentRoute changes
45052
46167
  reactExports.useEffect(() => {
45053
46168
  apiClient.current = new WidgetApiClient({ widgetId, apiUrl, currentRoute });
45054
46169
  }, [widgetId, apiUrl, currentRoute]);
45055
46170
  // Load configuration on mount and hydrate with existing conversation if available
45056
46171
  reactExports.useEffect(() => {
45057
- // Skip initialization in preview mode
45058
46172
  if (skipInitialization) {
45059
46173
  return;
45060
46174
  }
@@ -45091,7 +46205,7 @@
45091
46205
  }));
45092
46206
  // Setup resume callbacks for incomplete actions
45093
46207
  if (conversationId) {
45094
- setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversationId, setState, onMessage ?? (() => { }));
46208
+ setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversationId, setState, onMessage ?? (() => { }), createStreamState, registerActionResumeCallback);
45095
46209
  }
45096
46210
  }
45097
46211
  catch (error) {
@@ -45108,7 +46222,6 @@
45108
46222
  initialize();
45109
46223
  return () => {
45110
46224
  isMounted = false;
45111
- // Cleanup resume callbacks
45112
46225
  state.messages.forEach(message => {
45113
46226
  if (message.action?.toolCallId) {
45114
46227
  unregisterActionResumeCallback(message.action.toolCallId);
@@ -45131,7 +46244,15 @@
45131
46244
  const hasFiles = !!files && files.length > 0;
45132
46245
  if (!trimmedContent && !hasFiles)
45133
46246
  return;
45134
- // Strip [EXECUTE_ACTION:...] prefix from displayed message (but keep for API)
46247
+ if (stateRef.current.isTyping) {
46248
+ console.warn('[Widget] Cannot send message while streaming is in progress');
46249
+ return;
46250
+ }
46251
+ if (abortControllerRef.current) {
46252
+ abortControllerRef.current.abort();
46253
+ abortControllerRef.current = null;
46254
+ }
46255
+ abortControllerRef.current = new AbortController();
45135
46256
  const displayContent = trimmedContent.replace(/^\[EXECUTE_ACTION:[^\]]+\]\s*/, '');
45136
46257
  const userMessage = {
45137
46258
  id: generateMessageId(),
@@ -45142,12 +46263,11 @@
45142
46263
  timestamp: new Date().toISOString(),
45143
46264
  sources: [],
45144
46265
  };
45145
- // Add user message immediately
45146
46266
  setState(prev => ({
45147
46267
  ...prev,
45148
46268
  messages: [...prev.messages, userMessage],
45149
- isLoading: false, // Don't show loading, will show typing when stream starts
45150
- isTyping: true, // Show typing indicator immediately
46269
+ isLoading: false,
46270
+ isTyping: true,
45151
46271
  error: null,
45152
46272
  }));
45153
46273
  onMessage?.(userMessage);
@@ -45187,16 +46307,29 @@
45187
46307
  }
45188
46308
  catch (uploadError) {
45189
46309
  console.error('Failed to upload file:', uploadError);
45190
- // Continue with other files
45191
46310
  }
45192
46311
  }
45193
46312
  }
45194
- // Stream the response
45195
46313
  let lastStreamedMessage = null;
45196
46314
  const streamState = createStreamState();
45197
- const stream = apiClient.current.sendAgentMessageStream(conversationId, trimmedContent, fileIds);
46315
+ currentRequestIdRef.current = streamState.requestId;
46316
+ const currentAbortController = abortControllerRef.current;
46317
+ const streamConversationId = conversationId;
46318
+ const streamRequestId = streamState.requestId;
46319
+ const stream = apiClient.current.sendAgentMessageStream(conversationId, trimmedContent, fileIds, currentAbortController?.signal);
45198
46320
  for await (const event of stream) {
46321
+ if (currentAbortController?.signal.aborted ||
46322
+ stateRef.current.conversationId !== streamConversationId ||
46323
+ currentRequestIdRef.current !== streamRequestId) {
46324
+ console.log('[Widget] Stream aborted, conversation changed, or superseded by new request');
46325
+ break;
46326
+ }
45199
46327
  if (event.type === "action_request") {
46328
+ if (currentAbortController?.signal.aborted ||
46329
+ stateRef.current.conversationId !== streamConversationId ||
46330
+ currentRequestIdRef.current !== streamRequestId) {
46331
+ break;
46332
+ }
45200
46333
  await handleActionLoop(apiClient.current, event, streamState, (message) => {
45201
46334
  lastStreamedMessage = message;
45202
46335
  }, setState, widgetId, conversationId, () => stateRef.current.messages);
@@ -45206,25 +46339,26 @@
45206
46339
  lastStreamedMessage = message;
45207
46340
  }, setState);
45208
46341
  }
45209
- // Stream completed - finalize state
46342
+ if (currentAbortController?.signal.aborted ||
46343
+ stateRef.current.conversationId !== streamConversationId ||
46344
+ currentRequestIdRef.current !== streamRequestId) {
46345
+ console.log('[Widget] Stream was aborted or superseded, skipping finalization');
46346
+ return;
46347
+ }
45210
46348
  setState(prev => ({
45211
46349
  ...prev,
45212
46350
  isLoading: false,
45213
46351
  isTyping: false,
45214
46352
  }));
45215
- // Notify about final message
45216
46353
  if (lastStreamedMessage) {
45217
46354
  onMessage?.(lastStreamedMessage);
45218
46355
  }
45219
- // Generate follow-up suggestions asynchronously
45220
46356
  const enableFollowUps = state.config?.settings.enableFollowUpSuggestions !== false;
45221
46357
  const actionIds = state.config?.actions || [];
45222
46358
  if (enableFollowUps) {
45223
- // Don't await - let it run in background
45224
46359
  apiClient.current.generateFollowUps(stateRef.current.messages, actionIds)
45225
46360
  .then(suggestions => {
45226
46361
  if (suggestions.length > 0) {
45227
- // Attach suggestions to the last assistant message
45228
46362
  setState(prev => {
45229
46363
  const messages = [...prev.messages];
45230
46364
  for (let i = messages.length - 1; i >= 0; i--) {
@@ -45253,7 +46387,7 @@
45253
46387
  },
45254
46388
  timestamp: new Date().toISOString(),
45255
46389
  sources: [],
45256
- isError: !fallbackMessage, // Only mark as error if using default message
46390
+ isError: !fallbackMessage,
45257
46391
  };
45258
46392
  setState(prev => ({
45259
46393
  ...prev,
@@ -45265,9 +46399,6 @@
45265
46399
  onError?.(err);
45266
46400
  }
45267
46401
  }, [state.conversationId, state.config, state.messages, onMessage, onError]);
45268
- /**
45269
- * Clear all messages
45270
- */
45271
46402
  const clearMessages = reactExports.useCallback(() => {
45272
46403
  setState(prev => ({
45273
46404
  ...prev,
@@ -45280,9 +46411,6 @@
45280
46411
  clearConversation(widgetId);
45281
46412
  }
45282
46413
  }, [widgetId, state.config?.settings.persistConversation]);
45283
- /**
45284
- * Submit feedback for a message
45285
- */
45286
46414
  const submitFeedback = reactExports.useCallback(async (messageId, feedback) => {
45287
46415
  try {
45288
46416
  const message = state.messages.find(msg => msg.id === messageId);
@@ -45292,7 +46420,6 @@
45292
46420
  : undefined;
45293
46421
  console.log('Submitting feedback:', { conversationId: state.conversationId, messageId, feedback });
45294
46422
  await apiClient.current.submitFeedback(state.conversationId, messageId, feedback, meta);
45295
- // Update message with feedback
45296
46423
  setState(prev => ({
45297
46424
  ...prev,
45298
46425
  messages: prev.messages.map(msg => msg.id === messageId
@@ -45307,9 +46434,6 @@
45307
46434
  onError?.(err);
45308
46435
  }
45309
46436
  }, [state.conversationId, onError]);
45310
- /**
45311
- * Load conversation history list from localStorage
45312
- */
45313
46437
  const loadConversations = reactExports.useCallback(() => {
45314
46438
  const persistConversation = state.config?.settings.persistConversation ?? true;
45315
46439
  if (!persistConversation || !isStorageAvailable()) {
@@ -45326,8 +46450,11 @@
45326
46450
  })));
45327
46451
  }, [widgetId, state.config?.settings.persistConversation]);
45328
46452
  const switchConversation = reactExports.useCallback(async (conversationId) => {
46453
+ if (abortControllerRef.current) {
46454
+ abortControllerRef.current.abort();
46455
+ abortControllerRef.current = null;
46456
+ }
45329
46457
  const persistConversation = state.config?.settings.persistConversation ?? true;
45330
- // First try to load from localStorage
45331
46458
  if (persistConversation && isStorageAvailable()) {
45332
46459
  const stored = loadConversationById(widgetId, conversationId);
45333
46460
  if (stored) {
@@ -45335,16 +46462,17 @@
45335
46462
  ...prev,
45336
46463
  conversationId: stored.conversationId,
45337
46464
  messages: hydrateMessages(stored.messages),
46465
+ isTyping: false,
46466
+ isLoading: false,
45338
46467
  }));
45339
46468
  setActiveConversation(widgetId, conversationId);
45340
46469
  return;
45341
46470
  }
45342
46471
  }
45343
- setState(prev => ({ ...prev, isLoading: true, error: null }));
46472
+ setState(prev => ({ ...prev, isLoading: true, isTyping: false, error: null }));
45344
46473
  try {
45345
46474
  const conversation = await apiClient.current.getOrCreateConversation(conversationId);
45346
46475
  const hydratedMessages = hydrateMessages(conversation.messages);
45347
- // Clear old resume callbacks
45348
46476
  state.messages.forEach(message => {
45349
46477
  if (message.action?.toolCallId) {
45350
46478
  unregisterActionResumeCallback(message.action.toolCallId);
@@ -45356,9 +46484,7 @@
45356
46484
  messages: hydratedMessages,
45357
46485
  isLoading: false,
45358
46486
  }));
45359
- // Setup new resume callbacks
45360
- setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversation.id, setState, onMessage ?? (() => { }));
45361
- // Save to local storage
46487
+ setupActionResumeCallbacks(hydratedMessages, apiClient.current, conversation.id, setState, onMessage ?? (() => { }), createStreamState, registerActionResumeCallback);
45362
46488
  if (persistConversation && isStorageAvailable()) {
45363
46489
  saveConversation(widgetId, conversation.id, hydratedMessages);
45364
46490
  }
@@ -45369,11 +46495,23 @@
45369
46495
  }
45370
46496
  }, [widgetId, state.config?.settings.persistConversation]);
45371
46497
  const startNewConversation = reactExports.useCallback(() => {
46498
+ const now = Date.now();
46499
+ if (now - lastNewChatTimeRef.current < NEW_CHAT_COOLDOWN_MS) {
46500
+ console.warn('[Widget] New chat rate limited - please wait');
46501
+ return;
46502
+ }
46503
+ lastNewChatTimeRef.current = now;
46504
+ if (abortControllerRef.current) {
46505
+ abortControllerRef.current.abort();
46506
+ abortControllerRef.current = null;
46507
+ }
45372
46508
  setState(prev => ({
45373
46509
  ...prev,
45374
46510
  messages: [],
45375
46511
  conversationId: '',
45376
46512
  error: null,
46513
+ isTyping: false,
46514
+ isLoading: false,
45377
46515
  }));
45378
46516
  const persistConversation = state.config?.settings.persistConversation ?? true;
45379
46517
  if (persistConversation && isStorageAvailable()) {
@@ -45385,11 +46523,8 @@
45385
46523
  if (!persistConversation || !isStorageAvailable()) {
45386
46524
  return;
45387
46525
  }
45388
- // Delete from storage
45389
46526
  deleteConversation(widgetId, conversationId);
45390
- // Update local state
45391
46527
  setConversations(prev => prev.filter(c => c.id !== conversationId));
45392
- // If we deleted the current conversation, clear it
45393
46528
  if (state.conversationId === conversationId) {
45394
46529
  setState(prev => ({
45395
46530
  ...prev,
@@ -45409,7 +46544,6 @@
45409
46544
  sendMessage,
45410
46545
  clearMessages,
45411
46546
  submitFeedback,
45412
- // Chat history features
45413
46547
  conversations,
45414
46548
  loadConversations,
45415
46549
  switchConversation,
@@ -45418,11 +46552,20 @@
45418
46552
  };
45419
46553
  }
45420
46554
 
46555
+ const ShieldIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }), jsxRuntimeExports.jsx("path", { d: "M9 12l2 2 4-4" })] }));
46556
+ const DataPolicyView = ({ config, widgetName, }) => {
46557
+ const headerTitle = widgetName || config?.appearance?.headerTitle || 'AI Assistant';
46558
+ const hasFileUpload = config?.settings?.enableFileUpload ?? false;
46559
+ const persistsConversation = config?.settings?.persistConversation ?? true;
46560
+ return (jsxRuntimeExports.jsx("div", { className: "ai-chat-data-policy-view", children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-content", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-intro", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-data-policy-icon", children: jsxRuntimeExports.jsx(ShieldIcon, {}) }), jsxRuntimeExports.jsxs("p", { children: ["Dieser Datenschutzhinweis informiert dich gem\u00E4\u00DF Art. 13 DSGVO dar\u00FCber, wie ", jsxRuntimeExports.jsx("strong", { children: headerTitle }), " Daten verarbeitet, wenn du diesen Chat nutzt. Bitte beachte, dass der konkrete Umfang der Verarbeitung vom Betreiber dieser Website/Anwendung (dem Verantwortlichen) sowie von den jeweils aktivierten Funktionen abh\u00E4ngt."] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Verantwortlicher / Kontakt" }), jsxRuntimeExports.jsx("p", { children: "Verantwortlicher im Sinne von Art. 4 Nr. 7 DSGVO ist der Betreiber dieser Website/Anwendung. Die Kontaktdaten (und ggf. die Kontaktdaten eines Datenschutzbeauftragten) findest du in der Datenschutzerkl\u00E4rung bzw. im Impressum der Website, in die dieses Chat-Widget eingebunden ist." })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Verarbeitete Daten (Kategorien)" }), jsxRuntimeExports.jsxs("ul", { children: [jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Chat-Inhalte:" }), " Nachrichten (Text) sowie ggf. Kontextinformationen, die du im Chat angibst. Diese Inhalte werden verarbeitet, um Antworten zu generieren und die Unterhaltung bereitzustellen."] }), hasFileUpload && (jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Hochgeladene Dateien:" }), " Dateien, die du an den Chat \u00FCbermittelst, werden zur Bearbeitung des Anliegens verarbeitet. Die Verarbeitung kann das Extrahieren von Text/Informationen umfassen."] })), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Technische Nutzungsdaten:" }), " z.B. Zeitstempel, Sitzungs-/Request-Informationen sowie technische Metadaten, die f\u00FCr den Betrieb, die Sicherheit (Missbrauchspr\u00E4vention) und Fehleranalyse erforderlich sind."] })] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Zwecke und Rechtsgrundlagen" }), jsxRuntimeExports.jsxs("ul", { children: [jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Bereitstellung des Chats und Beantwortung von Anfragen" }), " (Art. 6 Abs. 1 lit. b DSGVO, soweit Vertrags-/vorvertragliche Ma\u00DFnahmen; andernfalls Art. 6 Abs. 1 lit. f DSGVO \u2013 berechtigtes Interesse an effizienter Kommunikation und Support)."] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Qualit\u00E4tssicherung, Betrieb und Sicherheit" }), " (Art. 6 Abs. 1 lit. f DSGVO), z.B. zur Stabilit\u00E4t, Missbrauchserkennung und Fehlerbehebung."] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Einwilligungsbasierte Verarbeitung" }), " kann erfolgen, sofern der Betreiber dies vorsieht (Art. 6 Abs. 1 lit. a DSGVO)."] })] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Empf\u00E4nger und Auftragsverarbeiter" }), jsxRuntimeExports.jsxs("ul", { children: [jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Hosting/IT-Dienstleister:" }), " Der Betreiber kann Dienstleister f\u00FCr Hosting, Logging, Monitoring und Infrastruktur einsetzen."] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "KI-Dienstleister:" }), " Zur Generierung von Antworten k\u00F6nnen Chat-Inhalte an KI-Modelle bzw. Anbieter von KI-Infrastruktur \u00FCbertragen werden. Soweit erforderlich, erfolgt dies auf Grundlage eines Auftragsverarbeitungsvertrags (Art. 28 DSGVO)."] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Drittlandtransfer:" }), " Falls Empf\u00E4nger au\u00DFerhalb der EU/des EWR sitzen, kann ein Transfer in Drittl\u00E4nder stattfinden. In diesem Fall werden geeignete Garantien (z.B. EU-Standardvertragsklauseln) eingesetzt, soweit erforderlich."] })] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Speicherdauer" }), jsxRuntimeExports.jsxs("ul", { children: [persistsConversation ? (jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Chatverlauf:" }), " Der Chatverlauf kann gespeichert werden, um die Unterhaltung \u00FCber mehrere Sitzungen hinweg fortzusetzen."] })) : (jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Chatverlauf:" }), " Der Chatverlauf wird nicht dauerhaft gespeichert und wird beim Schlie\u00DFen des Chats beendet."] })), hasFileUpload && (jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Dateien:" }), " Hochgeladene Dateien werden nur so lange verarbeitet, wie dies f\u00FCr die Bearbeitung erforderlich ist, und anschlie\u00DFend gel\u00F6scht, sofern keine l\u00E4ngere Speicherung gesetzlich erforderlich ist."] })), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Technische Protokolle:" }), " Technische Logdaten k\u00F6nnen f\u00FCr einen begrenzten Zeitraum gespeichert werden, um den sicheren Betrieb zu gew\u00E4hrleisten."] })] })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Deine Rechte (Betroffenenrechte)" }), jsxRuntimeExports.jsxs("ul", { children: [jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Auskunft" }), " (Art. 15 DSGVO)"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Berichtigung" }), " (Art. 16 DSGVO)"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "L\u00F6schung" }), " (Art. 17 DSGVO) und ", jsxRuntimeExports.jsx("strong", { children: "Einschr\u00E4nkung der Verarbeitung" }), " (Art. 18 DSGVO)"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Daten\u00FCbertragbarkeit" }), " (Art. 20 DSGVO), soweit anwendbar"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Widerspruch" }), " gegen Verarbeitungen auf Grundlage berechtigter Interessen (Art. 21 DSGVO)"] }), jsxRuntimeExports.jsxs("li", { children: [jsxRuntimeExports.jsx("strong", { children: "Beschwerderecht" }), " bei einer Datenschutzaufsichtsbeh\u00F6rde (Art. 77 DSGVO)"] })] }), jsxRuntimeExports.jsx("p", { children: "Hinweis: Ohne eindeutige Identifikationsmerkmale kann der Betreiber einzelne Chatverl\u00E4ufe ggf. nicht einer Person zuordnen. F\u00FCr Anfragen wende dich bitte an den Betreiber dieser Website/Anwendung." })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-data-policy-section", children: [jsxRuntimeExports.jsx("h3", { children: "Wichtiger Hinweis" }), jsxRuntimeExports.jsx("p", { className: "ai-chat-data-policy-warning", children: "Bitte gib keine besonderen Kategorien personenbezogener Daten (z.B. Gesundheitsdaten), Passw\u00F6rter, Kreditkarten-/Bankdaten oder vertrauliche Gesch\u00E4ftsgeheimnisse in den Chat ein. KI-generierte Antworten k\u00F6nnen unzutreffend sein und sollten vor einer Nutzung eigenverantwortlich gepr\u00FCft werden." })] })] }) }));
46561
+ };
46562
+
45421
46563
  const MenuIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "4", y1: "10", x2: "20", y2: "10" }), jsxRuntimeExports.jsx("line", { x1: "10", y1: "14", x2: "20", y2: "14" })] }));
45422
46564
  const PlusIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), jsxRuntimeExports.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })] }));
45423
46565
  const TrashIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M3 6h18" }), jsxRuntimeExports.jsx("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }), jsxRuntimeExports.jsx("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" })] }));
45424
46566
  const CloseIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntimeExports.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
45425
- const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose: _onClose, onFeedback, onActionClick,
46567
+ const BackIcon = () => (jsxRuntimeExports.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M19 12H5" }), jsxRuntimeExports.jsx("path", { d: "M12 19l-7-7 7-7" })] }));
46568
+ const ChatWindow = ({ messages, isLoading, isTyping, config, onSendMessage, onClose: _onClose, onFeedback, onActionClick,
45426
46569
  // Chat history props (only active when persistConversation is true)
45427
46570
  conversations = [], onLoadConversations, onSwitchConversation, onStartNewConversation, onDeleteConversation, currentConversationId,
45428
46571
  // Override props for live preview
@@ -45439,6 +46582,8 @@
45439
46582
  const inputPlaceholder = placeholderOverride ?? appearance?.placeholder ?? 'Ask me anything...';
45440
46583
  // Track if history panel is open
45441
46584
  const [showHistory, setShowHistory] = reactExports.useState(false);
46585
+ // Track if data policy view is open
46586
+ const [showDataPolicy, setShowDataPolicy] = reactExports.useState(false);
45442
46587
  // Scroll button state (managed by MessageList)
45443
46588
  const [showScrollButton, setShowScrollButton] = reactExports.useState(false);
45444
46589
  const [scrollToBottom, setScrollToBottom] = reactExports.useState(null);
@@ -45448,6 +46593,13 @@
45448
46593
  }, []);
45449
46594
  // History exit animation when starting a new chat from overview
45450
46595
  const [isHistoryExiting, setIsHistoryExiting] = reactExports.useState(false);
46596
+ // Handle data policy click
46597
+ const handleDataPolicyClick = reactExports.useCallback(() => {
46598
+ setShowDataPolicy(true);
46599
+ }, []);
46600
+ const handleDataPolicyBack = reactExports.useCallback(() => {
46601
+ setShowDataPolicy(false);
46602
+ }, []);
45451
46603
  // Load conversations when history panel opens
45452
46604
  const handleOpenHistory = () => {
45453
46605
  setShowHistory(true);
@@ -45495,10 +46647,22 @@
45495
46647
  // The backend will detect and trigger the action based on the message
45496
46648
  onSendMessage(question);
45497
46649
  };
45498
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntimeExports.jsx("div", { className: `ai-chat-header ${showHistory ? 'is-history' : ''}`, children: showHistory ? (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: headerTitle }), jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleNewConversation, "aria-label": "New chat", children: jsxRuntimeExports.jsx(PlusIcon, {}) })] })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntimeExports.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: headerTitle })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-actions", children: [canShowHistory && (jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleOpenHistory, "aria-label": "Chat overview", children: jsxRuntimeExports.jsx(MenuIcon, {}) })), jsxRuntimeExports.jsx("button", { className: "ai-chat-close-button header-close-button", onClick: _onClose, "aria-label": "Close chat", children: jsxRuntimeExports.jsx(CloseIcon, {}) })] })] })) }), showHistory ? (jsxRuntimeExports.jsxs("div", { className: "ai-chat-history-panel", children: [conversations.length === 0 ? (jsxRuntimeExports.jsx("div", { className: "ai-chat-history-empty", children: "No previous conversations" })) : (jsxRuntimeExports.jsx("div", { className: `ai-chat-history-list ${isHistoryExiting ? 'exiting' : ''}`, children: conversations.map((conv) => (jsxRuntimeExports.jsx("div", { className: `ai-chat-history-item ${conv.id === currentConversationId ? 'active' : ''}`, onClick: () => handleSelectConversation(conv.id), children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-history-item-content", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-history-item-preview", children: conv.preview }), onDeleteConversation && (jsxRuntimeExports.jsx("button", { className: "ai-chat-history-item-delete", onClick: (e) => {
46650
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntimeExports.jsx("div", { className: `ai-chat-header ${showHistory ? 'is-history' : ''} ${showDataPolicy ? 'is-data-policy' : ''}`, children: showDataPolicy ? (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleDataPolicyBack, "aria-label": "Back to chat", children: jsxRuntimeExports.jsx(BackIcon, {}) }), jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: "Datenschutzhinweis" })] })) : showHistory ? (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: headerTitle }), jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleNewConversation, "aria-label": "New chat", children: jsxRuntimeExports.jsx(PlusIcon, {}) })] })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntimeExports.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: headerTitle })] }), jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-actions", children: [canShowHistory && (jsxRuntimeExports.jsx("button", { className: "ai-chat-header-button", onClick: handleOpenHistory, "aria-label": "Chat overview", children: jsxRuntimeExports.jsx(MenuIcon, {}) })), jsxRuntimeExports.jsx("button", { className: "ai-chat-close-button header-close-button", onClick: _onClose, "aria-label": "Close chat", children: jsxRuntimeExports.jsx(CloseIcon, {}) })] })] })) }), showDataPolicy ? (jsxRuntimeExports.jsx(DataPolicyView, { config: config, onBack: handleDataPolicyBack, widgetName: headerTitle })) : showHistory ? (
46651
+ /* History Panel */
46652
+ jsxRuntimeExports.jsxs("div", { className: "ai-chat-history-panel", children: [conversations.length === 0 ? (jsxRuntimeExports.jsx("div", { className: "ai-chat-history-empty", children: "No previous conversations" })) : (jsxRuntimeExports.jsx("div", { className: `ai-chat-history-list ${isHistoryExiting ? 'exiting' : ''}`, children: conversations.map((conv) => (jsxRuntimeExports.jsx("div", { className: `ai-chat-history-item ${conv.id === currentConversationId ? 'active' : ''}`, onClick: () => handleSelectConversation(conv.id), children: jsxRuntimeExports.jsxs("div", { className: "ai-chat-history-item-content", children: [jsxRuntimeExports.jsx("div", { className: "ai-chat-history-item-preview", children: conv.preview }), onDeleteConversation && (jsxRuntimeExports.jsx("button", { className: "ai-chat-history-item-delete", onClick: (e) => {
45499
46653
  e.stopPropagation();
45500
46654
  onDeleteConversation(conv.id);
45501
- }, "aria-label": "Delete conversation", children: jsxRuntimeExports.jsx(TrashIcon, {}) }))] }) }, conv.id))) })), jsxRuntimeExports.jsx(MessageInput, { onSend: (text) => handleSendFromOverview(text), placeholder: inputPlaceholder, disabled: isLoading, enableFileUpload: settings?.enableFileUpload })] })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [error && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: error })), maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining"] })), isLimitReached && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: "Message limit reached. Please start a new conversation." })), jsxRuntimeExports.jsx(MessageList, { messages: messages, isTyping: isTyping, showTypingIndicator: settings?.showTypingIndicator, showTimestamps: settings?.showTimestamps, enableFeedback: settings?.enableFeedback, showSources: settings?.showSources, sourceDisplayMode: settings?.sourceDisplayMode, welcomeTitle: welcomeTitle || 'Welcome Message', welcomeMessage: welcomeMessage, suggestedQuestions: suggestedQuestionsOverride ?? settings?.suggestedQuestions, accentColor: appearance?.primaryColor, onSuggestedQuestionClick: handleQuestionClick, onActionClick: onActionClick, onFeedback: onFeedback, onScrollStateChange: handleScrollStateChange, getActionRenderer: getActionRenderer }), jsxRuntimeExports.jsx(ScrollButton, { onClick: () => scrollToBottom?.(), visible: showScrollButton }), jsxRuntimeExports.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : inputPlaceholder, disabled: isLoading || isLimitReached, enableFileUpload: settings?.enableFileUpload })] }))] }));
46655
+ }, "aria-label": "Delete conversation", children: jsxRuntimeExports.jsx(TrashIcon, {}) }))] }) }, conv.id))) })), jsxRuntimeExports.jsx(MessageInput, { onSend: (text) => handleSendFromOverview(text), placeholder: inputPlaceholder, disabled: isLoading, enableFileUpload: settings?.enableFileUpload, showDataPolicy: settings?.showDataPolicy ?? true, onDataPolicyClick: handleDataPolicyClick })] })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining"] })), isLimitReached && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: "Message limit reached. Please start a new conversation." })), (() => {
46656
+ console.log('[DEBUG ChatWindow] Rendering MessageList with', messages.length, 'messages');
46657
+ messages.forEach((m, i) => {
46658
+ console.log(`[DEBUG ChatWindow] msg ${i}:`, { role: m.message.role, hasAction: !!m.action, impl: m.action?.implementation });
46659
+ });
46660
+ console.log('[DEBUG ChatWindow] getActionRenderer available:', !!getActionRenderer);
46661
+ if (getActionRenderer) {
46662
+ console.log('[DEBUG ChatWindow] Testing renderer for query-contact-directory:', !!getActionRenderer('query-contact-directory'));
46663
+ }
46664
+ return null;
46665
+ })(), jsxRuntimeExports.jsx(MessageList, { messages: messages, isTyping: isTyping, showTypingIndicator: settings?.showTypingIndicator, showTimestamps: settings?.showTimestamps, showToolCalls: settings?.showToolCalls, enableFeedback: settings?.enableFeedback, welcomeTitle: welcomeTitle || 'Welcome Message', welcomeMessage: welcomeMessage, suggestedQuestions: suggestedQuestionsOverride ?? settings?.suggestedQuestions, accentColor: appearance?.primaryColor, onSuggestedQuestionClick: handleQuestionClick, onActionClick: onActionClick, onFeedback: onFeedback, onScrollStateChange: handleScrollStateChange, getActionRenderer: getActionRenderer }), jsxRuntimeExports.jsx(ScrollButton, { onClick: () => scrollToBottom?.(), visible: showScrollButton }), jsxRuntimeExports.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : (isTyping ? 'Waiting for response...' : inputPlaceholder), disabled: isLoading || isTyping || isLimitReached, enableFileUpload: settings?.enableFileUpload, showDataPolicy: settings?.showDataPolicy ?? true, onDataPolicyClick: handleDataPolicyClick })] }))] }));
45502
46666
  };
45503
46667
 
45504
46668
  /**
@@ -45904,7 +47068,7 @@
45904
47068
  if ( ref === void 0 ) ref = {};
45905
47069
  var insertAt = ref.insertAt;
45906
47070
 
45907
- if (typeof document === 'undefined') { return; }
47071
+ if (!css || typeof document === 'undefined') { return; }
45908
47072
 
45909
47073
  var head = document.head || document.getElementsByTagName('head')[0];
45910
47074
  var style = document.createElement('style');
@@ -45927,7 +47091,10 @@
45927
47091
  }
45928
47092
  }
45929
47093
 
45930
- var css_248z = ".ai-chat-message{animation:ai-chat-message-appear .2s var(--chat-ease-bounce);max-width:85%}.ai-chat-message-content{border-radius:var(--chat-radius-bubble,14px);font-size:var(--chat-text-md,15px);line-height:var(--chat-line-relaxed,1.6);padding:var(--chat-space-sm,8px) var(--chat-space-md,16px)}.ai-chat-message.user .ai-chat-message-content{background:var(--chat-user-bg,#f4f3f0);border-bottom-right-radius:var(--chat-radius-sm,4px);color:var(--chat-user-text,#000)}.ai-chat-message.assistant .ai-chat-message-content{background:var(--chat-assistant-bg,transparent);color:var(--chat-assistant-text,#000)}.ai-chat-message-timestamp{color:var(--chat-text-muted,#71717a);font-size:var(--chat-text-xs,12px);margin-top:var(--chat-space-xs,4px);padding:0 var(--chat-space-xs,4px)}.ai-chat-message.streaming .ai-chat-message-content:after{animation:ai-chat-cursor-blink .8s infinite;content:\"▋\";margin-left:2px;opacity:.7}@keyframes ai-chat-message-appear{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-cursor-blink{0%,50%{opacity:1}51%,to{opacity:0}}.ai-chat-message.fullpage .ai-chat-message-content{font-size:var(--chat-text-lg,18px);padding:var(--chat-space-md,16px) var(--chat-space-lg,24px)}.ai-chat-typing{gap:var(--chat-space-xs,4px);padding:var(--chat-space-sm,8px) var(--chat-space-md,16px)}.ai-chat-typing-dot{background:var(--chat-text-muted,#71717a)}.ai-chat-tool-gear{color:var(--text-primary,#3e3e3e)}.ai-chat-tool-gear.spinning{animation:ai-chat-spin 1.5s linear infinite}.ai-chat-tool-badge{border-radius:8px}.ai-chat-tool-badge.loading{background:#e5e7eb;border:1px solid #d1d5db;color:#1f2937}.ai-chat-tool-badge.error{background:rgba(239,68,68,.1);color:#ef4444}.ai-chat-tool-check{color:#22c55e;flex-shrink:0}.ai-chat-tool-error{color:#ef4444;flex-shrink:0}.ai-chat-tool-badge .tool-name{max-width:150px;overflow:hidden;text-overflow:ellipsis}.ai-chat-widget.dark .ai-chat-tool-gear,.ai-chat-widget[data-theme=dark] .ai-chat-tool-gear,.dark .ai-chat-tool-gear,[data-theme=dark] .ai-chat-tool-gear{color:#fff}.ai-chat-widget.dark .ai-chat-tool-badge,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge,.dark .ai-chat-tool-badge,[data-theme=dark] .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.ai-chat-widget.dark .ai-chat-tool-badge.error,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge.error,.dark .ai-chat-tool-badge.error,[data-theme=dark] .ai-chat-tool-badge.error{background:rgba(239,68,68,.2);color:#f87171}.chakra-ui-dark .ai-chat-tool-gear,html.dark .ai-chat-tool-gear{color:#fff}.chakra-ui-dark .ai-chat-tool-badge,html.dark .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.chakra-ui-dark .ai-chat-tool-badge.error,html.dark .ai-chat-tool-badge.error{background:rgba(239,68,68,.2);color:#f87171}@keyframes ai-chat-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.ai-chat-action-skeleton-item{animation:ai-chat-skeleton-pulse 1.5s ease-in-out infinite;background:var(--bg-secondary,#e5e7eb)}.ai-chat-widget.dark .ai-chat-action-skeleton-item,.chakra-ui-dark .ai-chat-action-skeleton-item,.dark .ai-chat-action-skeleton-item,[data-theme=dark] .ai-chat-action-skeleton-item{background:hsla(0,0%,100%,.1)}.ai-chat-action-skeleton-content{display:flex;flex-direction:column;gap:16px}.ai-chat-action-skeleton-header{align-items:center;display:flex;gap:10px}.ai-chat-action-skeleton-box{background:rgba(0,0,0,.08);border-radius:10px;display:flex;flex-direction:column;gap:8px;padding:14px}.ai-chat-widget.dark .ai-chat-action-skeleton-box,.chakra-ui-dark .ai-chat-action-skeleton-box,.dark .ai-chat-action-skeleton-box,[data-theme=dark] .ai-chat-action-skeleton-box{background:rgba(0,0,0,.25)}.ai-chat-action-card{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f4f4f4);border:none;border-radius:var(--radius-lg,12px);box-sizing:border-box;margin-top:var(--space-sm,8px);max-width:100%;padding:var(--space-md,16px);transition:all var(--duration-normal,.25s) ease;width:100%}.ai-chat-widget.dark .ai-chat-action-card,.chakra-ui-dark .ai-chat-action-card,.dark .ai-chat-action-card,[data-theme=dark] .ai-chat-action-card{background:var(--bg-secondary,#3a3a3a)}.ai-chat-action-booked{background:var(--bg-secondary,#f4f4f4);border:none}.ai-chat-widget.dark .ai-chat-action-booked,.chakra-ui-dark .ai-chat-action-booked,.dark .ai-chat-action-booked,[data-theme=dark] .ai-chat-action-booked{background:var(--bg-secondary,#3a3a3a)}.ai-chat-action-header{align-items:center;color:var(--text-primary,#3e3e3e);display:flex;font-size:var(--text-md,15px);font-weight:var(--font-weight-semibold,600);gap:var(--space-sm,8px);margin-bottom:var(--space-md,16px)}.ai-chat-widget.dark .ai-chat-action-header,.chakra-ui-dark .ai-chat-action-header,.dark .ai-chat-action-header,[data-theme=dark] .ai-chat-action-header{color:var(--text-primary,#fff)}.ai-chat-action-icon{color:var(--action-accent,var(--primary-color,#3b82f6));flex-shrink:0;height:20px;width:20px}.ai-chat-action-success-icon-wrapper{align-items:center;background:var(--action-accent,var(--primary-color,#22c55e));border-radius:50%;color:#fff;display:flex;flex-shrink:0;height:24px;justify-content:center;width:24px}.ai-chat-action-icon-success{color:currentColor;height:14px;width:14px}.ai-chat-action-detail-box{background:var(--bg-primary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-md,8px);display:flex;flex-direction:column;gap:4px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-action-detail-box,.chakra-ui-dark .ai-chat-action-detail-box,.dark .ai-chat-action-detail-box,[data-theme=dark] .ai-chat-action-detail-box{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.05)}.ai-chat-action-label-small{color:var(--text-muted,#71717a);font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}.ai-chat-action-value-large{color:var(--text-primary,#3e3e3e);font-size:15px;font-weight:500}.ai-chat-widget.dark .ai-chat-action-value-large,.chakra-ui-dark .ai-chat-action-value-large,.dark .ai-chat-action-value-large,[data-theme=dark] .ai-chat-action-value-large{color:#fff}.ai-chat-action-link-button{align-items:center;background:var(--action-accent,var(--primary-color,#3b82f6));border:none;border-radius:9999px;box-sizing:border-box;color:#fff;display:flex;font-size:14px;font-weight:600;gap:6px;justify-content:center;margin-top:8px;padding:12px;text-decoration:none;transition:all .2s ease;width:100%}.ai-chat-action-link-button:hover{opacity:.9;transform:translateY(-1px)}.ai-chat-action-body{display:flex;flex-direction:column;gap:var(--space-md,16px)}.ai-chat-action-field{display:flex;flex-direction:column;gap:var(--space-xs,6px)}.ai-chat-action-label{color:var(--text-secondary,#6b7280);font-size:var(--text-sm,13px);font-weight:var(--font-weight-medium,500)}.ai-chat-widget.dark .ai-chat-action-label,.chakra-ui-dark .ai-chat-action-label,.dark .ai-chat-action-label,[data-theme=dark] .ai-chat-action-label{color:var(--text-secondary,#a1a1aa)}.ai-chat-action-input{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);font-size:var(--text-sm,13px);outline:none;padding:10px 12px;transition:border-color .2s ease,box-shadow .2s ease}.ai-chat-action-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.1)}.ai-chat-action-input::placeholder{color:var(--text-muted,#9ca3af)}.ai-chat-widget.dark .ai-chat-action-input,.chakra-ui-dark .ai-chat-action-input,.dark .ai-chat-action-input,[data-theme=dark] .ai-chat-action-input{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-input:focus,.chakra-ui-dark .ai-chat-action-input:focus,.dark .ai-chat-action-input:focus,[data-theme=dark] .ai-chat-action-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.2)}.ai-chat-action-date-grid{display:grid;gap:var(--space-xs,6px);grid-template-columns:repeat(auto-fill,minmax(90px,1fr))}.ai-chat-action-date-btn{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;font-size:var(--text-xs,12px);font-weight:var(--font-weight-medium,500);padding:8px 10px;text-align:center;transition:all .15s ease}.ai-chat-action-date-btn:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-date-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-action-date-btn,.chakra-ui-dark .ai-chat-action-date-btn,.dark .ai-chat-action-date-btn,[data-theme=dark] .ai-chat-action-date-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-date-btn:hover,.chakra-ui-dark .ai-chat-action-date-btn:hover,.dark .ai-chat-action-date-btn:hover,[data-theme=dark] .ai-chat-action-date-btn:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-action-date-btn.active,.chakra-ui-dark .ai-chat-action-date-btn.active,.dark .ai-chat-action-date-btn.active,[data-theme=dark] .ai-chat-action-date-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-action-time-grid{display:grid;gap:var(--space-xs,6px);grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}.ai-chat-action-time-btn{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;font-size:var(--text-xs,12px);font-weight:var(--font-weight-medium,500);padding:8px 10px;text-align:center;transition:all .15s ease}.ai-chat-action-time-btn:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-time-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-action-time-btn,.chakra-ui-dark .ai-chat-action-time-btn,.dark .ai-chat-action-time-btn,[data-theme=dark] .ai-chat-action-time-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-time-btn:hover,.chakra-ui-dark .ai-chat-action-time-btn:hover,.dark .ai-chat-action-time-btn:hover,[data-theme=dark] .ai-chat-action-time-btn:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-action-time-btn.active,.chakra-ui-dark .ai-chat-action-time-btn.active,.dark .ai-chat-action-time-btn.active,[data-theme=dark] .ai-chat-action-time-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-action-button{background:var(--action-accent,var(--primary-color,#3b82f6));border:none;border-radius:9999px;color:#fff;cursor:pointer;font-size:var(--text-sm,13px);font-weight:var(--font-weight-semibold,600);padding:12px 16px;transition:all .2s ease;width:100%}.ai-chat-action-button:hover:not(:disabled){opacity:.9;transform:translateY(-1px)}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-action-error{background:rgba(239,68,68,.1);border-radius:var(--radius-md,8px);color:#dc2626;font-size:var(--text-sm,13px);padding:10px 12px}.ai-chat-widget.dark .ai-chat-action-error,.chakra-ui-dark .ai-chat-action-error,.dark .ai-chat-action-error,[data-theme=dark] .ai-chat-action-error{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-action-hint{color:var(--text-muted,#9ca3af);font-size:var(--text-sm,13px);padding:var(--space-sm,8px);text-align:center}.ai-chat-widget,.chat-ui{--radius-sm:4px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:18px;--radius-pill:9999px;--radius-window-top:22px;--radius-window-bottom:44px;--radius-window-gutter:16px;--radius-chat-bubble:14px;--radius-preset-badge:13px;--radius-history-item:14px;--radius-action-badge:8px;--radius-input:62px;--space-xs:4px;--space-sm:8px;--space-md:16px;--space-lg:24px;--space-xl:32px;--text-xs:12px;--text-sm:14px;--text-md:15px;--text-lg:18px;--text-xl:22px;--text-2xl:28px;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--line-height-tight:1.3;--line-height-normal:1.4;--line-height-relaxed:1.6;--bg-primary:#fff;--bg-secondary:#f4f4f4;--bg-tertiary:#e5e7eb;--bg-hover:#e5e7eb;--text-primary:#3e3e3e;--text-secondary:#000;--text-muted:#71717a;--text-placeholder:#a1a1aa;--border-default:#d3d3d3;--border-subtle:#e5e7eb;--border-muted:#f4f4f5;--user-bg:#f4f3f0;--user-text:#000;--user-bg-hover:#e8e7e4;--agent-bg:transparent;--agent-text:#000;--input-bg:#f4f4f4;--input-border:#d3d3d3;--input-text:#000;--btn-primary-bg:#151515;--btn-primary-text:#f4f4f4;--btn-secondary-bg:transparent;--btn-secondary-text:#71717a;--spring-bounce:cubic-bezier(0.34,1.56,0.64,1);--spring-smooth:cubic-bezier(0.4,0,0.2,1);--spring-snappy:cubic-bezier(0.2,0,0,1);--duration-fast:0.15s;--duration-normal:0.25s;--duration-slow:0.35s;--shadow-sm:0 1px 2px rgba(0,0,0,.05);--shadow-md:0 2px 8px rgba(0,0,0,.1);--shadow-lg:0 4px 16px rgba(0,0,0,.12);--shadow-window:0px 0px 15px 9px rgba(0,0,0,.1);--shadow-button:0px 0px 15px 9px rgba(0,0,0,.03)}.ai-chat-widget.dark,.chat-ui.dark{--bg-primary:#282625;--bg-secondary:#4a4846;--bg-tertiary:#484848;--bg-hover:#484848;--text-primary:#fff;--text-secondary:#fff;--text-muted:#a1a1aa;--text-placeholder:#71717a;--border-default:#5d5b5b;--border-subtle:#5d5b5b;--border-muted:#5d5b5b;--user-bg:#484848;--user-text:#fff;--user-bg-hover:#5a5a5a;--agent-bg:transparent;--agent-text:#fff;--input-bg:#4a4846;--input-border:#5d5b5b;--input-text:#fff;--btn-primary-bg:#fff;--btn-primary-text:#312f2d;--btn-secondary-bg:transparent;--btn-secondary-text:#a1a1aa;--shadow-window:0px 0px 15px 9px rgba(0,0,0,.2);--shadow-button:0px 0px 15px 9px rgba(0,0,0,.03);--shadow-input:0px 0px 10px rgba(0,0,0,.15)}.ai-chat-widget,.chat-ui{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.ai-chat-widget-container{font-size:var(--text-sm);line-height:1.5;position:fixed;z-index:9999}.ai-chat-widget-container.bottom-right{bottom:20px;right:20px}.ai-chat-widget-container.bottom-left{bottom:20px;left:20px}.ai-chat-widget-container.top-right{right:20px;top:20px}.ai-chat-widget-container.top-left{left:20px;top:20px}@keyframes ai-chat-window-open{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes ai-chat-window-close{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}@keyframes ai-chat-message-slide-in{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-welcome-fade-in{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-typing-pulse{0%,60%,to{opacity:.4;transform:translateY(0) scale(1)}30%{opacity:1;transform:translateY(-4px) scale(1.1)}}@keyframes ai-chat-gear-spin{to{transform:rotate(1turn)}}@keyframes ai-chat-tool-active{0%,to{background:var(--bg-secondary);opacity:1}50%{background:var(--bg-tertiary);opacity:1}}@keyframes ai-chat-feedback-morph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes ai-chat-checkmark-pop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes ai-chat-history-exit{to{opacity:0;transform:translateY(-18px)}}@keyframes ai-chat-tool-gradient{0%{background-position:200% 0}to{background-position:-200% 0}}@media (max-width:480px){.ai-chat-widget-container.is-open{height:100vh!important;inset:0!important;width:100vw!important}.ai-chat-widget-container.is-open .ai-chat-window{animation:none!important;border-radius:0!important;height:100%!important;inset:0!important;max-height:100%!important;max-width:100%!important;position:absolute!important;width:100%!important}.ai-chat-widget-container.is-open .ai-chat-button{display:none!important;visibility:hidden!important}.ai-chat-header{padding-top:max(16px,env(safe-area-inset-top))}.ai-chat-input-container{padding-bottom:max(20px,env(safe-area-inset-bottom))}}.ai-chat-window{animation:ai-chat-window-open var(--duration-slow,.35s) var(--spring-bounce);background:var(--bg-primary,#fff);border:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) var(--radius-window-bottom,44px) var(--radius-window-bottom,44px);box-shadow:var(--shadow-window,0 0 15px 5px rgba(0,0,0,.08));display:flex;flex-direction:column;overflow:hidden;position:absolute;transform-origin:bottom right;z-index:2}.ai-chat-widget.dark .ai-chat-window{background:var(--bg-primary,#282625);border-color:var(--border-default,#5d5b5b);border-width:.7px}.ai-chat-window.closing{animation:ai-chat-window-close var(--duration-normal) var(--spring-smooth) forwards}.ai-chat-window.size-small{height:500px;width:380px}.ai-chat-window.size-medium,.ai-chat-window.size-small{max-height:calc(100vh - 100px);max-width:calc(100vw - 40px)}.ai-chat-window.size-medium{height:600px;width:420px}.ai-chat-window.size-large{height:700px;max-height:calc(100vh - 100px);max-width:calc(100vw - 40px);width:480px}.ai-chat-widget-container.bottom-right .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-header{align-items:center;background:var(--bg-primary,#fff);border-bottom:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) 0 0;display:flex;justify-content:space-between;padding:18px var(--space-md,16px);position:relative;z-index:10}.ai-chat-widget.dark .ai-chat-header{background:var(--bg-primary,#282625);border-bottom-color:var(--border-default,#5d5b5b);border-bottom-width:.7px}.ai-chat-header.is-history{padding-left:var(--space-md)}.ai-chat-header.is-history .ai-chat-title{flex:1;min-width:0;overflow:hidden;padding-right:var(--space-lg);text-overflow:ellipsis;white-space:nowrap}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:var(--space-lg)}.ai-chat-header-actions{align-items:center;display:flex;gap:var(--space-sm)}.ai-chat-logo{border-radius:10px;height:36px;object-fit:cover;width:36px}.ai-chat-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-xl,22px);font-weight:var(--font-weight-bold,700);letter-spacing:-.02em}.ai-chat-widget.dark .ai-chat-title{color:var(--text-primary,#fff)}.ai-chat-close-button,.ai-chat-header-button{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-muted);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:32px}.ai-chat-close-button:hover,.ai-chat-header-button:hover{color:var(--text-primary)}.ai-chat-close-button:active,.ai-chat-header-button:active{transform:scale(.95)}.ai-chat-close-button svg,.ai-chat-header-button svg{height:22px;width:22px}.ai-chat-button{align-items:center;background:var(--button-color,var(--btn-primary-bg));border:1px solid var(--border-default,#d3d3d3);border-radius:50%;box-shadow:var(--shadow-button,0 0 15px 9px rgba(0,0,0,.03));color:var(--button-icon-color,var(--btn-primary-text));cursor:pointer;display:flex;height:var(--button-size,56px);justify-content:center;overflow:hidden;position:relative;transition:opacity var(--duration-fast) ease;width:var(--button-size,56px);z-index:1}.ai-chat-button:hover{opacity:.9}.ai-chat-button:active{opacity:.8}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;transition:transform var(--duration-fast) ease;width:50%}.ai-chat-button.is-open .ai-chat-button-svg{transform:rotate(0deg)}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-input-container{background:linear-gradient(to bottom,transparent 0,var(--bg-primary,#fff) 50%,var(--bg-primary,#fff) 100%);bottom:0;left:0;padding-top:30px;position:absolute;right:0;z-index:10}.ai-chat-widget.dark .ai-chat-input-container{background:linear-gradient(to bottom,transparent 0,var(--bg-primary,#282625) 50%,var(--bg-primary,#282625) 100%)}.ai-chat-input-container.separate{padding:0 var(--radius-window-gutter,16px) var(--radius-window-gutter,16px);padding-top:30px}.ai-chat-input-wrapper{align-items:flex-end;background:var(--input-bg,#f4f4f4);border:1px solid var(--input-border,#d3d3d3);border-radius:var(--radius-input,62px);box-sizing:border-box;display:flex;gap:0;height:52px;overflow:hidden;padding:6px 6px 6px 16px;position:relative;transition:all var(--duration-fast,.15s) ease;z-index:5}.ai-chat-input-wrapper.multiline{border-radius:14px!important;min-height:64px;padding:10px 10px 10px 14px}.ai-chat-widget.dark .ai-chat-input-wrapper{background:var(--input-bg,#4a4846);border-color:var(--input-border,#5d5b5b);border-width:.7px;box-shadow:var(--shadow-input,0 0 10px rgba(0,0,0,.15))}.ai-chat-input-wrapper:focus-within{border-color:var(--text-muted,#a1a1aa)}.ai-chat-input{word-wrap:break-word!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;box-sizing:border-box!important;color:var(--input-text,#000)!important;flex:1!important;font-family:inherit!important;font-size:var(--text-md,15px)!important;height:40px!important;line-height:20px!important;margin:0!important;max-height:40px!important;min-height:40px!important;min-width:0!important;outline:none!important;overflow-wrap:anywhere!important;overflow-x:hidden!important;overflow-y:auto!important;padding:10px var(--space-sm,8px)!important;resize:none!important;white-space:pre-wrap!important;width:0!important;word-break:break-word!important}.ai-chat-widget.dark .ai-chat-input{color:var(--input-text,#fff)}.ai-chat-input::placeholder{color:var(--text-placeholder,#a1a1aa)}.ai-chat-widget.dark .ai-chat-input::placeholder{color:var(--text-placeholder,#52525b)}.ai-chat-file-button{align-items:center;align-self:center;background:transparent;border:none;color:var(--text-placeholder);cursor:pointer;display:flex;flex-shrink:0;height:28px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:28px}.ai-chat-file-button:hover{color:var(--text-secondary)}.ai-chat-file-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-send-button{align-items:center;align-self:center;background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#151515))));border:none;border-radius:50%;color:var(--button-icon-color,var(--btn-primary-text,#f4f4f4));cursor:pointer;display:flex;flex-shrink:0;height:40px;justify-content:center;min-height:40px;min-width:40px;padding:0;transition:all var(--duration-fast,.15s) ease;width:40px}.ai-chat-widget.dark .ai-chat-send-button{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#151515))));color:var(--button-icon-color,var(--btn-primary-text,#f4f4f4))}.ai-chat-widget.dark .ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button:hover:not(:disabled){opacity:.8}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.3}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:var(--space-sm);padding:var(--space-sm) var(--space-sm)}.ai-chat-file-item{align-items:center;background:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding:6px 10px}.ai-chat-file-extension{background:var(--btn-primary-bg);border-radius:3px;color:var(--btn-primary-text);display:inline-block;font-size:10px;font-weight:var(--font-weight-semibold);min-width:40px;padding:2px 6px;text-align:center;text-transform:uppercase}.ai-chat-file-info{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.ai-chat-file-name{font-weight:var(--font-weight-medium);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-file-size{color:var(--text-muted);font-size:10px;opacity:.7}.ai-chat-file-remove{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;justify-content:center;opacity:.5;padding:var(--space-xs);transition:opacity var(--duration-fast) ease}.ai-chat-file-remove:hover{opacity:1}.ai-chat-messages{-webkit-overflow-scrolling:touch;-ms-overflow-style:none;align-items:stretch;background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;gap:var(--space-md,16px);justify-content:flex-start;overflow-x:hidden;overflow-y:auto;padding:var(--space-lg,24px) var(--space-md,16px) 100px;position:relative;scroll-behavior:smooth;scrollbar-width:none}.ai-chat-widget.dark .ai-chat-messages{background:var(--bg-primary,#18181b)}.ai-chat-messages::-webkit-scrollbar{display:none}.ai-chat-message{animation:ai-chat-message-slide-in .2s var(--spring-bounce);display:flex;flex-direction:column;max-width:90%}.ai-chat-message.user{align-items:flex-end;align-self:flex-end}.ai-chat-message.assistant{align-items:flex-start;align-self:flex-start;max-width:100%}.ai-chat-message.tool{align-self:flex-start;margin:0 -16px;max-width:100%;padding:0;width:calc(100% + 32px)}.ai-chat-message-content{word-wrap:break-word;border-radius:18px;font-size:var(--text-md,15px);line-height:var(--line-height-relaxed,1.6);overflow-wrap:break-word;padding:8px 14px}.ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#f4f3f0);border-radius:18px;color:var(--user-text,#000)}.ai-chat-widget.dark .ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#484848);color:var(--user-text,#fff)}.ai-chat-message.assistant .ai-chat-message-content{background:var(--agent-bg,transparent);color:var(--agent-text,#000);padding:0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{color:var(--agent-text,#fff)}.ai-chat-message-timestamp{color:var(--text-muted,#71717a);font-size:var(--text-xs,12px);margin-top:var(--space-xs,4px);padding:0 var(--space-xs,4px)}.ai-chat-welcome{animation:ai-chat-welcome-fade-in .3s var(--spring-smooth);display:flex;flex-direction:column;gap:var(--space-md,16px);padding:var(--space-lg,24px) 0}.ai-chat-welcome-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-2xl,28px);font-weight:var(--font-weight-bold,700);line-height:var(--line-height-tight,1.3)}.ai-chat-widget.dark .ai-chat-welcome-title{color:var(--text-primary,#fff)}.ai-chat-welcome-text{color:var(--text-secondary,#000);font-size:var(--text-md,15px);line-height:var(--line-height-relaxed,1.6);max-width:100%}.ai-chat-widget.dark .ai-chat-welcome-text{color:var(--text-secondary,#fff)}.ai-chat-typing{align-items:center;display:flex;gap:var(--space-xs,4px);padding:var(--space-sm,8px) var(--space-md,16px)}.ai-chat-typing-dot{animation:ai-chat-typing-bounce 1.4s ease-in-out infinite both;background:var(--text-muted,#71717a);border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:first-child{animation-delay:-.32s}.ai-chat-typing-dot:nth-child(2){animation-delay:-.16s}.ai-chat-typing-dot:nth-child(3){animation-delay:0s}@keyframes ai-chat-typing-bounce{0%,80%,to{opacity:.4;transform:scale(.6)}40%{opacity:1;transform:scale(1)}}.ai-chat-scroll-button{align-items:center;background:var(--bg-secondary,#f4f4f5);border:1px solid var(--border-subtle,rgba(0,0,0,.1));border-radius:50%;bottom:80px;box-shadow:0 2px 8px rgba(0,0,0,.1);color:var(--text-secondary,#71717a);cursor:pointer;display:flex;height:36px;justify-content:center;left:50%;opacity:0;pointer-events:none;position:absolute;transform:translateX(-50%);transition:background .15s ease,box-shadow .15s ease,opacity .15s ease,visibility .15s ease;visibility:hidden;width:36px;z-index:15}.ai-chat-scroll-button.visible{opacity:1;pointer-events:auto;visibility:visible}.ai-chat-scroll-button:hover{background:var(--bg-tertiary,#e4e4e7);box-shadow:0 4px 12px rgba(0,0,0,.15)}.ai-chat-scroll-button:active{background:var(--bg-tertiary,#d4d4d8)}.ai-chat-widget.dark .ai-chat-scroll-button{background:var(--bg-secondary,#3f3f46);border-color:var(--border-subtle,hsla(0,0%,100%,.1));box-shadow:0 2px 8px rgba(0,0,0,.3);color:var(--text-secondary,#a1a1aa)}.ai-chat-widget.dark .ai-chat-scroll-button:hover{background:var(--bg-tertiary,#52525b);box-shadow:0 4px 12px rgba(0,0,0,.4)}.ai-chat-error{background:var(--bg-secondary);border-radius:var(--radius-chat-bubble);color:var(--text-primary);font-size:var(--text-md);margin:0 auto;padding:10px var(--space-md)}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 var(--space-sm) 0}.ai-chat-message.assistant .ai-chat-message-content p:last-child{margin-bottom:0}.ai-chat-message.assistant .ai-chat-message-content ol,.ai-chat-message.assistant .ai-chat-message-content ul{margin:var(--space-sm) 0;padding-left:var(--space-lg)}.ai-chat-message.assistant .ai-chat-message-content li{margin-bottom:var(--space-xs)}.ai-chat-message.assistant .ai-chat-message-content code{background:rgba(0,0,0,.05);border-radius:var(--radius-sm);font-family:SF Mono,Monaco,Cascadia Code,monospace;font-size:.9em;padding:2px 6px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content code{background:hsla(0,0%,100%,.1)}.ai-chat-message.assistant .ai-chat-message-content pre{background:rgba(0,0,0,.05);border-radius:var(--radius-md);margin:var(--space-sm) 0;overflow-x:auto;padding:var(--space-sm)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content pre{background:hsla(0,0%,100%,.05)}.ai-chat-message.assistant .ai-chat-message-content pre code{background:transparent;padding:0}.ai-chat-message.assistant .ai-chat-message-content a{color:var(--btn-primary-bg);text-decoration:underline}.ai-chat-message.assistant .ai-chat-message-content strong{font-weight:var(--font-weight-semibold)}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--border-default);color:var(--text-muted);margin:var(--space-sm) 0;padding-left:var(--space-md)}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-subtle,rgba(0,0,0,.1));margin:var(--space-lg,24px) 0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content hr{border-top-color:var(--border-subtle,hsla(0,0%,100%,.1))}.ai-chat-message.assistant .ai-chat-message-content table{border-collapse:collapse;font-size:var(--text-sm);margin:var(--space-sm) 0;width:100%}.ai-chat-message.assistant .ai-chat-message-content td,.ai-chat-message.assistant .ai-chat-message-content th{border:1px solid var(--border-subtle);padding:var(--space-sm);text-align:left}.ai-chat-message.assistant .ai-chat-message-content th{font-weight:var(--font-weight-semibold);white-space:nowrap}.ai-chat-message.assistant .ai-chat-message-content tbody tr:nth-child(2n){background:rgba(0,0,0,.02)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content tbody tr:nth-child(2n){background:hsla(0,0%,100%,.03)}.ai-chat-suggested-questions{align-self:flex-end;margin:0;padding:16px 0 0;width:100%}.ai-chat-suggested-questions-list{align-items:center;display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.ai-chat-suggested-question{align-items:center;background:transparent;border:1px solid var(--border-default,#d4d4d8);border-radius:var(--radius-preset-badge,18px);color:var(--text-primary,#18181b);cursor:pointer;display:inline-flex;font-size:14px;font-weight:400;gap:6px;justify-content:center;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:background .15s ease,border-color .15s ease,transform .1s ease;white-space:nowrap}.ai-chat-widget.dark .ai-chat-suggested-question{background:transparent;border-color:var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}.ai-chat-suggested-question-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-suggested-question:hover{background:var(--bg-hover,#f4f4f5);border-color:var(--border-default,#d4d4d8)}.ai-chat-widget.dark .ai-chat-suggested-question:hover{background:var(--bg-hover,#3f3f46);border-color:var(--border-subtle,#52525b)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question.action-type{border:none}.ai-chat-suggested-question.action-type,.ai-chat-widget.dark .ai-chat-suggested-question.action-type{background:var(--primary-color,var(--button-color,#ef4444));color:var(--button-icon-color,#fff)}.ai-chat-suggested-question.action-type:hover{background:var(--primary-color,var(--button-color,#ef4444));opacity:.9}.ai-chat-suggested-question-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.ai-chat-suggested-question:not(.action-type) .ai-chat-suggested-question-icon{display:none}.ai-chat-follow-up-suggestions{box-sizing:border-box;margin:0;padding:8px 16px 0;width:100%}.ai-chat-follow-up-list{align-items:flex-end;display:flex;flex-direction:column;gap:6px}.ai-chat-follow-up-item{align-items:center;border:none;border-radius:var(--radius-preset-badge,18px);cursor:pointer;display:inline-flex;font-size:14px;font-weight:400;gap:6px;justify-content:center;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:opacity .15s ease,transform .1s ease;white-space:nowrap}.ai-chat-follow-up-item,.ai-chat-widget.dark .ai-chat-follow-up-item{background:var(--primary-color,var(--button-color,#07f));color:var(--button-icon-color,#fff)}.ai-chat-follow-up-item:hover{opacity:.9}.ai-chat-follow-up-item:active{transform:scale(.98)}.ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-default,#d4d4d8);color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}.ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#f4f4f5);opacity:1}.ai-chat-widget.dark .ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46);opacity:1}.ai-chat-follow-up-item.action-type{background:var(--primary-color,var(--button-color,#07f));border:none;color:var(--button-icon-color,#fff)}.ai-chat-follow-up-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.ai-chat-follow-up-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-feedback-buttons{align-items:center;display:flex;gap:var(--space-xs)}.ai-chat-feedback{align-items:center;display:inline-flex;gap:0;height:20px}.ai-chat-feedback-button{align-items:center;background:transparent!important;border:none;border-radius:var(--radius-sm);color:var(--text-placeholder);cursor:pointer;display:flex;font-size:var(--text-sm);height:20px;justify-content:center;padding:var(--space-xs);transition:all var(--duration-fast) var(--spring-bounce)}.ai-chat-feedback-button:hover:not(:disabled){background:none!important;color:var(--text-secondary)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.9)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-feedback-button.active{background:none!important;color:var(--text-primary)}.ai-chat-feedback.submitted{align-items:center;animation:ai-chat-feedback-morph .3s var(--spring-bounce);gap:var(--space-xs)}.ai-chat-feedback-message{align-items:center;display:flex;gap:4px;margin-left:var(--space-xxs)}.ai-chat-feedback-checkmark{animation:ai-chat-checkmark-pop .3s var(--spring-bounce);color:#10b981;font-size:var(--text-md);font-weight:700}.ai-chat-feedback-text{color:#10b981;font-size:var(--text-xs);font-weight:var(--font-weight-medium)}.ai-chat-history-panel{background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;overflow:hidden}.ai-chat-widget.dark .ai-chat-history-panel{background:var(--bg-primary,#18181b)}.ai-chat-history-empty,.ai-chat-history-loading{align-items:center;color:var(--text-muted);display:flex;flex:1;font-size:var(--text-sm);justify-content:center;padding:var(--space-lg);text-align:center}.ai-chat-history-list{-ms-overflow-style:none;display:flex;flex:1;flex-direction:column;gap:var(--space-sm);overflow-y:auto;padding:var(--space-md) var(--space-md) 120px;scrollbar-width:none}.ai-chat-history-list::-webkit-scrollbar{display:none}.ai-chat-history-list.exiting{animation:ai-chat-history-exit .22s var(--spring-smooth) forwards}.ai-chat-history-item{align-items:center;background:var(--user-bg,#f4f4f5);border-radius:var(--radius-history-item,15px);display:flex;flex:0 0 auto;flex-direction:row;height:var(--history-item-height,44px);margin:0;overflow:hidden;transition:background var(--duration-fast,.15s) ease;width:100%}.ai-chat-history-item-content{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1;flex-direction:row;height:100%;min-width:0;padding:0 var(--space-xs,16px);text-align:left}.ai-chat-widget.dark .ai-chat-history-item{background:var(--user-bg,#27272a)}.ai-chat-history-item:hover{background:var(--user-bg-hover,#e5e7eb)}.ai-chat-widget.dark .ai-chat-history-item:hover{background:var(--user-bg-hover,#3f3f46)}.ai-chat-history-item.active{background:var(--user-bg-hover,#e5e7eb)}.ai-chat-widget.dark .ai-chat-history-item.active{background:var(--user-bg-hover,#3f3f46)}.ai-chat-history-item-preview{color:var(--text-primary,#18181b);flex:1;font-size:var(--text-sm,14px);font-weight:var(--font-weight-medium,500);line-height:var(--line-height-normal,1.4);margin-bottom:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-widget.dark .ai-chat-history-item-preview{color:var(--text-primary,#fafafa)}.ai-chat-history-item.active .ai-chat-history-item-preview{font-weight:var(--font-weight-medium)}.ai-chat-history-item-meta{display:none}.ai-chat-history-item-delete{align-items:center;background:transparent;border:none;border-radius:var(--radius-sm,8px);color:var(--text-muted,#71717a);cursor:pointer;display:flex;flex-shrink:0;height:32px;justify-content:center;margin-left:auto;margin-right:var(--space-2xs,2px);opacity:0;transition:opacity var(--duration-fast,.15s) ease,background var(--duration-fast,.15s) ease,color var(--duration-fast,.15s) ease;width:32px}.ai-chat-history-item:hover .ai-chat-history-item-delete{opacity:1}.ai-chat-history-item-delete:hover{background:rgba(239,68,68,.1);color:#ef4444}.ai-chat-widget.dark .ai-chat-history-item-delete:hover{background:rgba(239,68,68,.2);color:#f87171}.ai-chat-tool-row{align-items:center;display:flex;gap:10px;margin:2px 0;padding:0 16px}.ai-chat-tool-gear{color:#1f2937;flex-shrink:0;height:20px;width:20px}.ai-chat-tool-gear.spinning{animation:ai-chat-gear-spin 1.5s linear infinite}.ai-chat-tool-badges{align-items:center;display:flex;flex-wrap:wrap;gap:8px}.ai-chat-tool-badge{align-items:center;background:#e5e7eb;border:1px solid #d1d5db;border-radius:var(--radius-action-badge,8px);color:#1f2937;display:inline-flex;font-size:12px;font-weight:500;gap:4px;line-height:1.2;padding:5px 12px;transition:all .2s ease;white-space:nowrap}.ai-chat-tool-badge.loading{animation:ai-chat-tool-gradient 2s linear infinite;background:linear-gradient(90deg,var(--tool-loading-bg-1,#e0e0e0) 0,var(--tool-loading-bg-2,#f0f0f0) 25%,var(--tool-loading-bg-3,#fff) 50%,var(--tool-loading-bg-2,#f0f0f0) 75%,var(--tool-loading-bg-1,#e0e0e0) 100%);background-size:200% 100%;color:var(--tool-loading-text,#1a1a1a);position:relative}.ai-chat-widget:not(.dark) .ai-chat-tool-badge.loading{--tool-loading-bg-1:#2a2a2a;--tool-loading-bg-2:#3a3a3a;--tool-loading-bg-3:#4a4a4a;--tool-loading-text:#fff}.ai-chat-tool-badge.completed{background:#e5e7eb;border:1px solid #d1d5db;color:#1f2937}.ai-chat-widget.dark .ai-chat-tool-badge,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge,.chakra-ui-dark .ai-chat-tool-badge,.dark .ai-chat-tool-badge,[data-theme=dark] .ai-chat-tool-badge,html.dark .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.ai-chat-widget.dark .ai-chat-tool-gear,.ai-chat-widget[data-theme=dark] .ai-chat-tool-gear,.chakra-ui-dark .ai-chat-tool-gear,.dark .ai-chat-tool-gear,[data-theme=dark] .ai-chat-tool-gear,html.dark .ai-chat-tool-gear{color:#fff}.ai-chat-tool-badge.error{background:var(--tool-error-bg,rgba(239,68,68,.15));color:var(--tool-error-text,#ef4444)}.ai-chat-tool-badge .ai-chat-tool-check{color:#22c55e;flex-shrink:0}.ai-chat-tool-badge .ai-chat-tool-error{color:#ef4444;flex-shrink:0}.tool-name{font-weight:500;line-height:1.2;white-space:nowrap}.ai-chat-tool-action{box-sizing:border-box;padding:0 16px;width:100%}.ai-chat-sources{background:rgba(0,0,0,.02);border-radius:6px;font-size:var(--text-xs);margin-top:var(--space-sm);overflow:hidden}.ai-chat-sources-toggle{align-items:center;background:none;border:none;cursor:pointer;display:flex;gap:6px;padding:var(--space-sm) 10px;text-align:left;transition:background var(--duration-fast) ease;width:100%}.ai-chat-sources-toggle:hover{background:rgba(0,0,0,.03)}.ai-chat-sources-icon{color:var(--text-muted);font-size:10px;transition:transform var(--duration-fast) ease}.ai-chat-sources-title{color:var(--text-primary);flex:1;font-size:11px;font-weight:var(--font-weight-semibold);letter-spacing:.5px;text-transform:uppercase}.ai-chat-source-item{border-top:1px solid rgba(0,0,0,.05);color:var(--text-muted);display:flex;gap:var(--space-sm);padding:var(--space-sm) 10px}.ai-chat-source-item:last-child{border-bottom:none}.ai-chat-source-number{color:var(--btn-primary-bg);flex-shrink:0;font-weight:var(--font-weight-semibold)}.ai-chat-source-details{display:flex;flex:1;flex-direction:column;gap:var(--space-xs)}.ai-chat-source-score{color:var(--text-placeholder);font-size:11px}.ai-chat-source-content{color:var(--text-muted);font-size:11px;font-style:italic;line-height:var(--line-height-normal)}.ai-chat-source-metadata{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}.ai-chat-source-meta-item{background:rgba(0,0,0,.05);border-radius:3px;color:var(--text-muted);font-size:10px;padding:2px 6px}";
47094
+ var css_248z$1 = ".ai-chat-message{animation:ai-chat-message-appear .2s var(--chat-ease-bounce);max-width:85%}.ai-chat-message-content{border-radius:var(--chat-radius-bubble,14px);font-size:var(--chat-text-md,15px);line-height:var(--chat-line-relaxed,1.6);padding:var(--chat-space-sm,8px) var(--chat-space-md,16px)}.ai-chat-message.user .ai-chat-message-content{background:var(--chat-user-bg,#f4f3f0);border-bottom-right-radius:var(--chat-radius-sm,4px);color:var(--chat-user-text,#000)}.ai-chat-message.assistant .ai-chat-message-content{background:var(--chat-assistant-bg,transparent);color:var(--chat-assistant-text,#000)}.ai-chat-message-timestamp{color:var(--chat-text-muted,#71717a);font-size:var(--chat-text-xs,12px);margin-top:var(--chat-space-xs,4px);padding:0 var(--chat-space-xs,4px)}.ai-chat-message.streaming .ai-chat-message-content:after{animation:ai-chat-cursor-blink .8s infinite;content:\"▋\";margin-left:2px;opacity:.7}@keyframes ai-chat-message-appear{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-cursor-blink{0%,50%{opacity:1}51%,to{opacity:0}}.ai-chat-message.fullpage .ai-chat-message-content{font-size:var(--chat-text-lg,18px);padding:var(--chat-space-md,16px) var(--chat-space-lg,24px)}.ai-chat-typing{gap:var(--chat-space-xs,4px);padding:var(--chat-space-sm,8px) var(--chat-space-md,16px)}.ai-chat-typing-dot{background:var(--chat-text-muted,#71717a)}.ai-chat-tool-row{padding:0 16px}.ai-chat-tool-gear{color:var(--text-primary,#3e3e3e)}.ai-chat-tool-badge{border-radius:8px}.ai-chat-tool-badge.loading{background:#e5e7eb;border:1px solid #d1d5db;color:#1f2937}.ai-chat-tool-badge.error{background:rgba(239,68,68,.1);color:#ef4444}.ai-chat-tool-check{color:#22c55e;flex-shrink:0}.ai-chat-tool-error{color:#ef4444;flex-shrink:0}.ai-chat-tool-badge .tool-name{max-width:150px;overflow:hidden;text-overflow:ellipsis}.ai-chat-widget.dark .ai-chat-tool-gear,.ai-chat-widget[data-theme=dark] .ai-chat-tool-gear,.dark .ai-chat-tool-gear,[data-theme=dark] .ai-chat-tool-gear{color:#fff}.ai-chat-widget.dark .ai-chat-tool-badge,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge,.dark .ai-chat-tool-badge,[data-theme=dark] .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.ai-chat-widget.dark .ai-chat-tool-badge.error,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge.error,.dark .ai-chat-tool-badge.error,[data-theme=dark] .ai-chat-tool-badge.error{background:rgba(239,68,68,.2);color:#f87171}.chakra-ui-dark .ai-chat-tool-gear,html.dark .ai-chat-tool-gear{color:#fff}.chakra-ui-dark .ai-chat-tool-badge,html.dark .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.chakra-ui-dark .ai-chat-tool-badge.error,html.dark .ai-chat-tool-badge.error{background:rgba(239,68,68,.2);color:#f87171}.ai-chat-pin-input-group{align-items:center;display:flex;flex-wrap:nowrap;gap:8px;justify-content:center;margin:4px 0 8px}.ai-chat-pin-input{align-items:center;appearance:none;background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);box-sizing:border-box;color:var(--text-primary,#3e3e3e);display:inline-flex;flex:0 0 42px;font-family:inherit;font-size:18px;font-weight:600;height:46px;justify-content:center;line-height:1;max-width:42px;min-width:42px;outline:none;padding:0;text-align:center;transition:border-color .2s ease,box-shadow .2s ease;width:42px}.ai-chat-pin-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.1)}.ai-chat-pin-input:disabled{cursor:not-allowed;opacity:.6}.ai-chat-widget.dark .ai-chat-pin-input,.chakra-ui-dark .ai-chat-pin-input,.dark .ai-chat-pin-input,[data-theme=dark] .ai-chat-pin-input{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-pin-input:focus,.chakra-ui-dark .ai-chat-pin-input:focus,.dark .ai-chat-pin-input:focus,[data-theme=dark] .ai-chat-pin-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.2)}.ai-chat-action-button-secondary{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:9999px;color:var(--text-secondary,#6b7280);cursor:pointer;font-size:var(--text-sm,13px);font-weight:var(--font-weight-medium,500);padding:10px 16px;transition:all .2s ease;width:100%}.ai-chat-action-button-secondary:hover:not(:disabled){background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6));color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-button-secondary:disabled{cursor:not-allowed;opacity:.5}.ai-chat-widget.dark .ai-chat-action-button-secondary,.chakra-ui-dark .ai-chat-action-button-secondary,.dark .ai-chat-action-button-secondary,[data-theme=dark] .ai-chat-action-button-secondary{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#e5e7eb}.ai-chat-widget.dark .ai-chat-action-button-secondary:hover:not(:disabled),.chakra-ui-dark .ai-chat-action-button-secondary:hover:not(:disabled),.dark .ai-chat-action-button-secondary:hover:not(:disabled),[data-theme=dark] .ai-chat-action-button-secondary:hover:not(:disabled){background:rgba(59,130,246,.2);border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-action-appointment-list,.ai-chat-action-button-group{display:flex;flex-direction:column;gap:8px}.ai-chat-action-appointment-item{align-items:center;background:var(--bg-primary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-md,8px);display:flex;gap:12px;justify-content:space-between;padding:10px 12px}.ai-chat-widget.dark .ai-chat-action-appointment-item,.chakra-ui-dark .ai-chat-action-appointment-item,.dark .ai-chat-action-appointment-item,[data-theme=dark] .ai-chat-action-appointment-item{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.08)}.ai-chat-action-appointment-info{display:flex;flex-direction:column;gap:2px;min-width:0}.ai-chat-action-appointment-subject{color:var(--text-primary,#3e3e3e);font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-widget.dark .ai-chat-action-appointment-subject,.chakra-ui-dark .ai-chat-action-appointment-subject,.dark .ai-chat-action-appointment-subject,[data-theme=dark] .ai-chat-action-appointment-subject{color:#fff}.ai-chat-action-appointment-time{color:var(--text-muted,#71717a);font-size:12px}.ai-chat-action-appointment-item .ai-chat-action-button-secondary{font-size:12px;padding:6px 12px;width:auto}.ai-chat-action-error-message{background:rgba(239,68,68,.1);border-radius:var(--radius-md,8px);color:#dc2626;font-size:var(--text-sm,13px);padding:12px}.ai-chat-widget.dark .ai-chat-action-error-message,.chakra-ui-dark .ai-chat-action-error-message,.dark .ai-chat-action-error-message,[data-theme=dark] .ai-chat-action-error-message{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-widget,.chat-ui{--radius-sm:4px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:18px;--radius-pill:9999px;--radius-window-top:22px;--radius-window-bottom:44px;--radius-window-gutter:16px;--radius-chat-bubble:14px;--radius-preset-badge:13px;--radius-history-item:14px;--radius-action-badge:8px;--radius-input:62px;--space-xs:4px;--space-sm:8px;--space-md:16px;--space-lg:24px;--space-xl:32px;--text-xs:12px;--text-sm:14px;--text-md:15px;--text-lg:18px;--text-xl:22px;--text-2xl:28px;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--line-height-tight:1.3;--line-height-normal:1.4;--line-height-relaxed:1.6;--bg-primary:#fff;--bg-secondary:#f4f4f4;--bg-tertiary:#e5e7eb;--bg-hover:#e5e7eb;--text-primary:#3e3e3e;--text-secondary:#000;--text-muted:#71717a;--text-placeholder:#a1a1aa;--border-default:#d3d3d3;--border-subtle:#e5e7eb;--border-muted:#f4f4f5;--user-bg:#f4f3f0;--user-text:#000;--user-bg-hover:#e8e7e4;--agent-bg:transparent;--agent-text:#000;--input-bg:#f4f4f4;--input-border:#d3d3d3;--input-text:#000;--btn-primary-bg:#151515;--btn-primary-text:#f4f4f4;--btn-secondary-bg:transparent;--btn-secondary-text:#71717a;--spring-bounce:cubic-bezier(0.34,1.56,0.64,1);--spring-smooth:cubic-bezier(0.4,0,0.2,1);--spring-snappy:cubic-bezier(0.2,0,0,1);--duration-fast:0.15s;--duration-normal:0.25s;--duration-slow:0.35s;--shadow-sm:0 1px 2px rgba(0,0,0,.05);--shadow-md:0 2px 8px rgba(0,0,0,.1);--shadow-lg:0 4px 16px rgba(0,0,0,.12);--shadow-window:0px 0px 15px 9px rgba(0,0,0,.1);--shadow-button:0px 0px 15px 9px rgba(0,0,0,.03)}.ai-chat-widget.dark,.chat-ui.dark{--bg-primary:#282625;--bg-secondary:#4a4846;--bg-tertiary:#484848;--bg-hover:#484848;--text-primary:#fff;--text-secondary:#fff;--text-muted:#a1a1aa;--text-placeholder:#71717a;--border-default:#5d5b5b;--border-subtle:#5d5b5b;--border-muted:#5d5b5b;--user-bg:#484848;--user-text:#fff;--user-bg-hover:#5a5a5a;--agent-bg:transparent;--agent-text:#fff;--input-bg:#4a4846;--input-border:#5d5b5b;--input-text:#fff;--btn-primary-bg:#fff;--btn-primary-text:#312f2d;--btn-secondary-bg:transparent;--btn-secondary-text:#a1a1aa;--shadow-window:0px 0px 15px 9px rgba(0,0,0,.2);--shadow-button:0px 0px 15px 9px rgba(0,0,0,.03);--shadow-input:0px 0px 10px rgba(0,0,0,.15)}.ai-chat-widget,.chat-ui{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.ai-chat-widget-container{font-size:var(--text-sm);line-height:1.5;position:fixed;z-index:var(--widget-z-index,2147483647)}.ai-chat-widget-container.bottom-right{bottom:20px;right:20px}.ai-chat-widget-container.bottom-left{bottom:20px;left:20px}.ai-chat-widget-container.top-right{right:20px;top:20px}.ai-chat-widget-container.top-left{left:20px;top:20px}.ai-chat-widget-container.container-mode{position:absolute}@keyframes ai-chat-window-open{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes ai-chat-window-close{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}@keyframes ai-chat-message-slide-in{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-welcome-fade-in{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes ai-chat-typing-pulse{0%,60%,to{opacity:.4;transform:translateY(0) scale(1)}30%{opacity:1;transform:translateY(-4px) scale(1.1)}}@keyframes ai-chat-gear-spin{to{transform:rotate(1turn)}}@keyframes ai-chat-tool-active{0%,to{background:var(--bg-secondary);opacity:1}50%{background:var(--bg-tertiary);opacity:1}}@keyframes ai-chat-feedback-morph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes ai-chat-checkmark-pop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes ai-chat-history-exit{to{opacity:0;transform:translateY(-18px)}}@keyframes ai-chat-tool-gradient{0%{background-position:200% 0}to{background-position:-200% 0}}.ai-chat-window{animation:ai-chat-window-open var(--duration-slow,.35s) var(--spring-bounce);background:var(--bg-primary,#fff);border:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) var(--radius-window-bottom,44px) var(--radius-window-bottom,44px);box-shadow:var(--shadow-window,0 0 15px 5px rgba(0,0,0,.08));display:flex;flex-direction:column;overflow:hidden;position:absolute;transform-origin:bottom right;z-index:2}.ai-chat-widget.dark .ai-chat-window{background:var(--bg-primary,#282625);border-color:var(--border-default,#5d5b5b);border-width:.7px}.ai-chat-window.closing{animation:ai-chat-window-close var(--duration-normal) var(--spring-smooth) forwards}.ai-chat-window.size-small{height:500px;width:380px}.ai-chat-window.size-medium,.ai-chat-window.size-small{max-height:calc(100vh - 100px);max-width:calc(100vw - 40px)}.ai-chat-window.size-medium{height:600px;width:420px}.ai-chat-window.size-large{height:700px;max-height:calc(100vh - 100px);max-width:calc(100vw - 40px);width:480px}.ai-chat-widget-container.bottom-right .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:calc(var(--button-size, 56px) + 8px);left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:calc(var(--button-size, 56px) + 8px)}.ai-chat-header{align-items:center;background:var(--bg-primary,#fff);border-bottom:1px solid var(--border-default,#d3d3d3);border-radius:var(--radius-window-top,22px) var(--radius-window-top,22px) 0 0;display:flex;justify-content:space-between;padding:12px var(--space-md,16px);position:relative;z-index:10}.ai-chat-widget.dark .ai-chat-header{background:var(--bg-primary,#282625);border-bottom-color:var(--border-default,#5d5b5b);border-bottom-width:.7px}.ai-chat-header.is-history{padding-left:var(--space-md)}.ai-chat-header.is-history .ai-chat-title{flex:1;min-width:0;overflow:hidden;padding-right:var(--space-lg);text-overflow:ellipsis;white-space:nowrap}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:var(--space-lg)}.ai-chat-header-actions{align-items:center;display:flex;gap:var(--space-sm)}.ai-chat-logo{border-radius:10px;height:36px;object-fit:cover;width:36px}.ai-chat-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-xl,22px);font-weight:var(--font-weight-bold,700);letter-spacing:-.02em}.ai-chat-widget.dark .ai-chat-title{color:var(--text-primary,#fff)}.ai-chat-close-button,.ai-chat-header-button{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-muted);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:32px}.ai-chat-close-button:hover,.ai-chat-header-button:hover{color:var(--text-primary)}.ai-chat-close-button:active,.ai-chat-header-button:active{transform:scale(.95)}.ai-chat-close-button svg,.ai-chat-header-button svg{height:22px;width:22px}.ai-chat-button{align-items:center;background:var(--button-color,var(--btn-primary-bg));border:1px solid var(--border-default,#d3d3d3);border-radius:50%;box-shadow:var(--shadow-button,0 0 15px 9px rgba(0,0,0,.03));color:var(--button-icon-color,var(--btn-primary-text));cursor:pointer;display:flex;height:var(--button-size,56px);justify-content:center;overflow:hidden;position:relative;transition:opacity var(--duration-fast) ease;width:var(--button-size,56px);z-index:1}.ai-chat-button:hover{opacity:.9}.ai-chat-button:active{opacity:.8}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;transition:transform var(--duration-fast) ease;width:50%}.ai-chat-button.is-open .ai-chat-button-svg{transform:rotate(0deg)}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-welcome-bubble{animation:ai-chat-bubble-fade-in .3s ease-out;background:var(--button-color,var(--btn-primary-bg,#07f));border:none;border-radius:12px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:var(--button-icon-color,var(--btn-primary-text,#fff));cursor:pointer;font-size:14px;font-weight:500;line-height:1.4;padding:12px 16px;position:absolute;width:200px;z-index:0}.ai-chat-widget-container.bottom-right .ai-chat-welcome-bubble{bottom:68px;right:0;text-align:right}.ai-chat-widget-container.bottom-left .ai-chat-welcome-bubble{bottom:68px;left:0;right:auto;text-align:left}.ai-chat-widget-container.top-right .ai-chat-welcome-bubble{right:0;text-align:right;top:68px}.ai-chat-widget-container.top-left .ai-chat-welcome-bubble{left:0;right:auto;text-align:left;top:68px}.ai-chat-welcome-bubble:hover{filter:brightness(1.1)}@keyframes ai-chat-bubble-fade-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.ai-chat-widget-container.top-left .ai-chat-welcome-bubble,.ai-chat-widget-container.top-right .ai-chat-welcome-bubble{animation-name:ai-chat-bubble-fade-in-down}@keyframes ai-chat-bubble-fade-in-down{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.ai-chat-input-container{background:var(--bg-primary,#fff);bottom:0;left:0;padding:8px 0 16px;position:absolute;right:0;z-index:10}.ai-chat-widget.dark .ai-chat-input-container{background:var(--bg-primary,#282625)}.ai-chat-input-container.separate{padding:0 var(--radius-window-gutter,16px) var(--radius-window-gutter,16px)}.ai-chat-input-wrapper{align-items:flex-end;background:var(--input-bg,#f4f4f4);border:1px solid var(--input-border,#d3d3d3);border-radius:var(--radius-input,62px);box-sizing:border-box;display:flex;gap:0;height:52px;overflow:hidden;padding:6px 6px 6px 16px;position:relative;transition:all var(--duration-fast,.15s) ease;z-index:5}.ai-chat-input-wrapper.multiline{border-radius:14px!important;min-height:64px;padding:10px 10px 10px 14px}.ai-chat-widget.dark .ai-chat-input-wrapper{background:var(--input-bg,#4a4846);border-color:var(--input-border,#5d5b5b);border-width:.7px;box-shadow:var(--shadow-input,0 0 10px rgba(0,0,0,.15))}.ai-chat-input-wrapper:focus-within{border-color:var(--text-muted,#a1a1aa)}.ai-chat-input{word-wrap:break-word!important;background:transparent!important;border:none!important;border-radius:0!important;box-shadow:none!important;box-sizing:border-box!important;color:var(--input-text,#000)!important;flex:1!important;font-family:inherit!important;font-size:var(--text-md,15px)!important;height:40px!important;line-height:20px!important;margin:0!important;max-height:40px!important;min-height:40px!important;min-width:0!important;outline:none!important;overflow-wrap:anywhere!important;overflow-x:hidden!important;overflow-y:auto!important;padding:10px var(--space-sm,8px)!important;resize:none!important;white-space:pre-wrap!important;width:0!important;word-break:break-word!important}.ai-chat-widget.dark .ai-chat-input{color:var(--input-text,#fff)}.ai-chat-input::placeholder{color:var(--text-placeholder,#a1a1aa)}.ai-chat-widget.dark .ai-chat-input::placeholder{color:var(--text-placeholder,#52525b)}.ai-chat-file-button{align-items:center;align-self:center;background:transparent;border:none;color:var(--text-placeholder);cursor:pointer;display:flex;flex-shrink:0;height:28px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:28px}.ai-chat-file-button:hover{color:var(--text-secondary)}.ai-chat-file-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-send-button{align-items:center;align-self:center;background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#151515))));border:none;border-radius:50%;color:var(--button-icon-color,var(--btn-primary-text,#f4f4f4));cursor:pointer;display:flex;flex-shrink:0;height:40px;justify-content:center;min-height:40px;min-width:40px;padding:0;transition:all var(--duration-fast,.15s) ease;width:40px}.ai-chat-widget.dark .ai-chat-send-button{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#151515))));color:var(--button-icon-color,var(--btn-primary-text,#f4f4f4))}.ai-chat-widget.dark .ai-chat-send-button.active{background:var(--send-button-background,var(--primary-color,var(--button-color,var(--btn-primary-bg,#fff))));color:var(--button-icon-color,var(--btn-primary-text,#312f2d))}.ai-chat-send-button:hover:not(:disabled){opacity:.8}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.3}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:var(--space-sm);padding:var(--space-sm) var(--space-sm)}.ai-chat-file-item{align-items:center;background:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding:6px 10px}.ai-chat-file-extension{background:var(--btn-primary-bg);border-radius:3px;color:var(--btn-primary-text);display:inline-block;font-size:10px;font-weight:var(--font-weight-semibold);min-width:40px;padding:2px 6px;text-align:center;text-transform:uppercase}.ai-chat-file-info{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.ai-chat-file-name{font-weight:var(--font-weight-medium);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-file-size{color:var(--text-muted);font-size:10px;opacity:.7}.ai-chat-file-remove{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;justify-content:center;opacity:.5;padding:var(--space-xs);transition:opacity var(--duration-fast) ease}.ai-chat-file-remove:hover{opacity:1}.ai-chat-data-policy{bottom:2px;color:var(--text-muted,#71717a);font-size:9px;left:0;line-height:1.4;opacity:.5;pointer-events:auto;position:absolute;right:0;text-align:center}.ai-chat-widget.dark .ai-chat-data-policy{color:var(--text-muted,#a1a1aa)}.ai-chat-data-policy-link{background:none;border:none;color:var(--text-muted,#71717a);cursor:pointer;font-family:inherit;font-size:inherit;margin:0;padding:0;text-decoration:underline;text-underline-offset:2px;transition:color .15s ease}.ai-chat-data-policy-link:hover{color:var(--text-secondary,#52525b)}.ai-chat-widget.dark .ai-chat-data-policy-link{color:var(--text-muted,#a1a1aa)}.ai-chat-widget.dark .ai-chat-data-policy-link:hover{color:var(--text-secondary,#d4d4d8)}.ai-chat-messages{-webkit-overflow-scrolling:touch;-ms-overflow-style:none;align-items:stretch;background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;gap:var(--space-md,16px);justify-content:flex-start;overflow-x:hidden;overflow-y:auto;padding:0 var(--space-md,16px) 100px;position:relative;scroll-behavior:smooth;scrollbar-width:none}.ai-chat-widget.dark .ai-chat-messages{background:var(--bg-primary,#18181b)}.ai-chat-messages::-webkit-scrollbar{display:none}.ai-chat-message{animation:ai-chat-message-slide-in .2s var(--spring-bounce);display:flex;flex-direction:column;max-width:90%}.ai-chat-message.user{align-items:flex-end;align-self:flex-end}.ai-chat-message.assistant{align-items:flex-start;align-self:flex-start;max-width:100%;width:100%}.ai-chat-message.tool{align-self:stretch;max-width:none;padding:0}.ai-chat-message-content{word-wrap:break-word;border-radius:18px;font-size:var(--text-md,15px);line-height:var(--line-height-relaxed,1.6);overflow-wrap:break-word;padding:8px 14px}.ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#f4f3f0);border-radius:18px;color:var(--user-text,#000)}.ai-chat-widget.dark .ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#484848);color:var(--user-text,#fff)}.ai-chat-message.assistant .ai-chat-message-content{background:var(--agent-bg,transparent);box-sizing:border-box;color:var(--agent-text,#000);padding:0;width:100%}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{color:var(--agent-text,#fff)}.ai-chat-message-timestamp{color:var(--text-muted,#71717a);font-size:var(--text-xs,12px);margin-top:var(--space-xs,4px);padding:0 var(--space-xs,4px)}.ai-chat-welcome{animation:ai-chat-welcome-fade-in .3s var(--spring-smooth);display:flex;flex-direction:column;gap:var(--space-md,16px);padding:var(--space-lg,24px) 0}.ai-chat-welcome-title{color:var(--text-primary,#3e3e3e);font-size:var(--text-2xl,28px);font-weight:var(--font-weight-bold,700);line-height:var(--line-height-tight,1.3)}.ai-chat-widget.dark .ai-chat-welcome-title{color:var(--text-primary,#fff)}.ai-chat-welcome-text{color:var(--text-secondary,#000);font-size:var(--text-md,15px);line-height:var(--line-height-relaxed,1.6);max-width:100%}.ai-chat-widget.dark .ai-chat-welcome-text{color:var(--text-secondary,#fff)}.ai-chat-typing{align-items:center;display:flex;gap:var(--space-xs,4px);padding:var(--space-sm,8px) var(--space-md,16px)}.ai-chat-typing-dot{animation:ai-chat-typing-bounce 1.4s ease-in-out infinite both;background:var(--text-muted,#71717a);border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:first-child{animation-delay:-.32s}.ai-chat-typing-dot:nth-child(2){animation-delay:-.16s}.ai-chat-typing-dot:nth-child(3){animation-delay:0s}@keyframes ai-chat-typing-bounce{0%,80%,to{opacity:.4;transform:scale(.6)}40%{opacity:1;transform:scale(1)}}.ai-chat-scroll-button{align-items:center;background:var(--bg-secondary,#f4f4f5);border:1px solid var(--border-subtle,rgba(0,0,0,.1));border-radius:50%;bottom:80px;box-shadow:0 2px 8px rgba(0,0,0,.1);color:var(--text-secondary,#71717a);cursor:pointer;display:flex;height:36px;justify-content:center;left:50%;opacity:0;pointer-events:none;position:absolute;transform:translateX(-50%);transition:background .15s ease,box-shadow .15s ease,opacity .15s ease,visibility .15s ease;visibility:hidden;width:36px;z-index:15}.ai-chat-scroll-button.visible{opacity:1;pointer-events:auto;visibility:visible}.ai-chat-scroll-button:hover{background:var(--bg-tertiary,#e4e4e7);box-shadow:0 4px 12px rgba(0,0,0,.15)}.ai-chat-scroll-button:active{background:var(--bg-tertiary,#d4d4d8)}.ai-chat-widget.dark .ai-chat-scroll-button{background:var(--bg-secondary,#3f3f46);border-color:var(--border-subtle,hsla(0,0%,100%,.1));box-shadow:0 2px 8px rgba(0,0,0,.3);color:var(--text-secondary,#a1a1aa)}.ai-chat-widget.dark .ai-chat-scroll-button:hover{background:var(--bg-tertiary,#52525b);box-shadow:0 4px 12px rgba(0,0,0,.4)}.ai-chat-error{background:var(--bg-secondary);border-radius:var(--radius-chat-bubble);color:var(--text-primary);font-size:var(--text-md);margin:0 auto;padding:10px var(--space-md)}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 var(--space-sm) 0}.ai-chat-message.assistant .ai-chat-message-content p:last-child{margin-bottom:0}.ai-chat-message.assistant .ai-chat-message-content ol,.ai-chat-message.assistant .ai-chat-message-content ul{margin:var(--space-sm) 0;padding-left:var(--space-lg)}.ai-chat-message.assistant .ai-chat-message-content li{margin-bottom:var(--space-xs)}.ai-chat-message.assistant .ai-chat-message-content code{background:rgba(0,0,0,.05);border-radius:var(--radius-sm);font-family:SF Mono,Monaco,Cascadia Code,monospace;font-size:.9em;padding:2px 6px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content code{background:hsla(0,0%,100%,.1)}.ai-chat-message.assistant .ai-chat-message-content pre{background:rgba(0,0,0,.05);border-radius:var(--radius-md);margin:var(--space-sm) 0;overflow-x:auto;padding:var(--space-sm)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content pre{background:hsla(0,0%,100%,.05)}.ai-chat-message.assistant .ai-chat-message-content pre code{background:transparent;padding:0}.ai-chat-message.assistant .ai-chat-message-content a{color:var(--btn-primary-bg);text-decoration:underline}.ai-chat-message.assistant .ai-chat-message-content strong{font-weight:var(--font-weight-semibold)}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--border-default);color:var(--text-muted);margin:var(--space-sm) 0;padding-left:var(--space-md)}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-subtle,rgba(0,0,0,.1));margin:var(--space-lg,24px) 0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content hr{border-top-color:var(--border-subtle,hsla(0,0%,100%,.1))}.ai-chat-message.assistant .ai-chat-message-content .table-wrapper{border:1px solid var(--border-subtle,rgba(0,0,0,.1));border-radius:var(--radius-md,8px);box-sizing:border-box;display:block;margin:var(--space-sm) var(--space-sm);max-width:100%;overflow:hidden;width:auto}.ai-chat-message.assistant .ai-chat-message-content .table-scroll{max-width:100%;overflow-x:auto;overflow-y:hidden;width:100%}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content .table-wrapper{border-color:var(--border-subtle,hsla(0,0%,100%,.1))}.ai-chat-message.assistant .ai-chat-message-content table{border-collapse:collapse;font-size:var(--text-sm);min-width:100%;width:max-content}.ai-chat-message.assistant .ai-chat-message-content td,.ai-chat-message.assistant .ai-chat-message-content th{border-bottom:1px solid var(--border-subtle,rgba(0,0,0,.1));border-right:1px solid var(--border-subtle,rgba(0,0,0,.1));padding:var(--space-sm);text-align:left}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content td,.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content th{border-color:var(--border-subtle,hsla(0,0%,100%,.1))}.ai-chat-message.assistant .ai-chat-message-content td:last-child,.ai-chat-message.assistant .ai-chat-message-content th:last-child{border-right:none}.ai-chat-message.assistant .ai-chat-message-content tr:last-child td{border-bottom:none}.ai-chat-message.assistant .ai-chat-message-content th{background:rgba(0,0,0,.03);font-weight:var(--font-weight-semibold);white-space:nowrap}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content th{background:hsla(0,0%,100%,.05)}.ai-chat-message.assistant .ai-chat-message-content tbody tr:nth-child(2n){background:rgba(0,0,0,.02)}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content tbody tr:nth-child(2n){background:hsla(0,0%,100%,.03)}.ai-chat-suggested-questions{align-self:flex-end;margin:0;padding:16px 0 0;width:100%}.ai-chat-suggested-questions-list{align-items:center;display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}.ai-chat-suggested-question{align-items:center;background:transparent;border:1px solid var(--border-default,#d4d4d8);border-radius:var(--radius-preset-badge,18px);color:var(--text-primary,#18181b);cursor:pointer;display:inline-flex;font-size:14px;font-weight:400;gap:6px;justify-content:center;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:background .15s ease,border-color .15s ease,transform .1s ease;white-space:nowrap}.ai-chat-widget.dark .ai-chat-suggested-question{background:transparent;border-color:var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}.ai-chat-suggested-question-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-suggested-question:hover{background:var(--bg-hover,#f4f4f5);border-color:var(--border-default,#d4d4d8)}.ai-chat-widget.dark .ai-chat-suggested-question:hover{background:var(--bg-hover,#3f3f46);border-color:var(--border-subtle,#52525b)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question.action-type{border:none}.ai-chat-suggested-question.action-type,.ai-chat-widget.dark .ai-chat-suggested-question.action-type{background:var(--primary-color,var(--button-color,#ef4444));color:var(--button-icon-color,#fff)}.ai-chat-suggested-question.action-type:hover{background:var(--primary-color,var(--button-color,#ef4444));opacity:.9}.ai-chat-suggested-question-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.ai-chat-suggested-question:not(.action-type) .ai-chat-suggested-question-icon{display:none}.ai-chat-follow-up-suggestions{box-sizing:border-box;margin:0;padding:8px 16px 0;width:100%}.ai-chat-follow-up-list{align-items:flex-end;display:flex;flex-direction:column;gap:6px}.ai-chat-follow-up-item{align-items:center;border:none;border-radius:var(--radius-preset-badge,18px);cursor:pointer;display:inline-flex;font-size:14px;font-weight:400;gap:6px;justify-content:center;line-height:1.3;max-width:100%;overflow:hidden;padding:8px 14px;text-overflow:ellipsis;transition:opacity .15s ease,transform .1s ease;white-space:nowrap}.ai-chat-follow-up-item,.ai-chat-widget.dark .ai-chat-follow-up-item{background:var(--primary-color,var(--button-color,#07f));color:var(--button-icon-color,#fff)}.ai-chat-follow-up-item:hover{opacity:.9}.ai-chat-follow-up-item:active{transform:scale(.98)}.ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-default,#d4d4d8);color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-follow-up-item.question-type,.dark .ai-chat-follow-up-item.question-type,[data-color-mode=dark] .ai-chat-follow-up-item.question-type,[data-theme=dark] .ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}@media (prefers-color-scheme:dark){.ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:var(--text-primary,#fafafa)}}.ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#f4f4f5);opacity:1}.ai-chat-widget.dark .ai-chat-follow-up-item.question-type:hover,.dark .ai-chat-follow-up-item.question-type:hover,[data-color-mode=dark] .ai-chat-follow-up-item.question-type:hover,[data-theme=dark] .ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46);opacity:1}@media (prefers-color-scheme:dark){.ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46);opacity:1}}.ai-chat-follow-up-item.action-type{background:var(--primary-color,var(--button-color,#07f));border:none;color:var(--button-icon-color,#fff)}.ai-chat-follow-up-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.ai-chat-follow-up-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-feedback-buttons{align-items:center;display:flex;gap:var(--space-xs)}.ai-chat-feedback{align-items:center;display:inline-flex;gap:0;height:20px}.ai-chat-feedback-button{align-items:center;background:transparent!important;border:none;border-radius:var(--radius-sm);color:var(--text-placeholder);cursor:pointer;display:flex;font-size:var(--text-sm);height:20px;justify-content:center;padding:var(--space-xs);transition:all var(--duration-fast) var(--spring-bounce)}.ai-chat-feedback-button:hover:not(:disabled){background:none!important;color:var(--text-secondary)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.9)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-feedback-button.active{background:none!important;color:var(--text-primary)}.ai-chat-feedback.submitted{align-items:center;animation:ai-chat-feedback-morph .3s var(--spring-bounce);gap:var(--space-xs)}.ai-chat-feedback-message{align-items:center;display:flex;gap:4px;margin-left:var(--space-xxs)}.ai-chat-feedback-checkmark{animation:ai-chat-checkmark-pop .3s var(--spring-bounce);color:#10b981;font-size:var(--text-md);font-weight:700}.ai-chat-feedback-text{color:#10b981;font-size:var(--text-xs);font-weight:var(--font-weight-medium)}.ai-chat-history-panel{background:var(--bg-primary,#fff);display:flex;flex:1;flex-direction:column;overflow:hidden}.ai-chat-widget.dark .ai-chat-history-panel{background:var(--bg-primary,#18181b)}.ai-chat-history-empty,.ai-chat-history-loading{align-items:center;color:var(--text-muted);display:flex;flex:1;font-size:var(--text-sm);justify-content:center;padding:var(--space-lg);text-align:center}.ai-chat-history-list{-ms-overflow-style:none;display:flex;flex:1;flex-direction:column;gap:var(--space-sm);overflow-y:auto;padding:var(--space-xs) var(--space-md) 120px;scrollbar-width:none}.ai-chat-history-list::-webkit-scrollbar{display:none}.ai-chat-history-list.exiting{animation:ai-chat-history-exit .22s var(--spring-smooth) forwards}.ai-chat-history-item{align-items:center;background:var(--user-bg,#f4f4f5);border-radius:var(--radius-history-item,15px);display:flex;flex:0 0 auto;flex-direction:row;height:var(--history-item-height,36px);margin:0;overflow:hidden;transition:background var(--duration-fast,.15s) ease;width:100%}.ai-chat-history-item-content{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1;flex-direction:row;height:100%;min-width:0;padding:0 var(--space-xs,4px) 0 var(--space-md,16px);text-align:left}.ai-chat-widget.dark .ai-chat-history-item{background:var(--user-bg,#27272a)}.ai-chat-history-item:hover{background:var(--user-bg-hover,#e5e7eb)}.ai-chat-widget.dark .ai-chat-history-item:hover{background:var(--user-bg-hover,#3f3f46)}.ai-chat-history-item.active{background:var(--user-bg-hover,#e5e7eb)}.ai-chat-widget.dark .ai-chat-history-item.active{background:var(--user-bg-hover,#3f3f46)}.ai-chat-history-item-preview{color:var(--text-primary,#18181b);flex:1;font-size:var(--text-sm,14px);font-weight:var(--font-weight-medium,500);line-height:var(--line-height-normal,1.4);margin-bottom:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-widget.dark .ai-chat-history-item-preview{color:var(--text-primary,#fafafa)}.ai-chat-history-item.active .ai-chat-history-item-preview{font-weight:var(--font-weight-medium)}.ai-chat-history-item-meta{display:none}.ai-chat-history-item-delete{align-items:center;background:transparent;border:none;border-radius:var(--radius-sm,6px);color:var(--text-muted,#71717a);cursor:pointer;display:flex;flex-shrink:0;height:24px;justify-content:center;margin-left:auto;margin-right:var(--space-xs,4px);opacity:0;transition:opacity var(--duration-fast,.15s) ease,background var(--duration-fast,.15s) ease,color var(--duration-fast,.15s) ease;width:24px}.ai-chat-history-item-delete svg{height:14px;width:14px}.ai-chat-history-item:hover .ai-chat-history-item-delete{opacity:1}.ai-chat-history-item-delete:hover{background:rgba(239,68,68,.1);color:#ef4444}.ai-chat-widget.dark .ai-chat-history-item-delete:hover{background:rgba(239,68,68,.2);color:#f87171}.ai-chat-tool-row{align-items:center;display:flex;gap:10px;margin:2px 0;padding:0}.ai-chat-tool-gear{color:#1f2937;flex-shrink:0;height:20px;width:20px}.ai-chat-tool-gear.spinning{animation:ai-chat-gear-spin 1.5s linear infinite}.ai-chat-tool-badges{align-items:center;display:flex;flex-wrap:wrap;gap:8px}.ai-chat-tool-badge{align-items:center;background:#e5e7eb;border:1px solid #d1d5db;border-radius:var(--radius-action-badge,8px);color:#1f2937;display:inline-flex;font-size:12px;font-weight:500;gap:4px;line-height:1.2;padding:5px 12px;transition:all .2s ease;white-space:nowrap}.ai-chat-tool-badge.loading{animation:ai-chat-tool-gradient 2s linear infinite;background:linear-gradient(90deg,var(--tool-loading-bg-1,#e0e0e0) 0,var(--tool-loading-bg-2,#f0f0f0) 25%,var(--tool-loading-bg-3,#fff) 50%,var(--tool-loading-bg-2,#f0f0f0) 75%,var(--tool-loading-bg-1,#e0e0e0) 100%);background-size:200% 100%;color:var(--tool-loading-text,#1a1a1a);position:relative}.ai-chat-widget:not(.dark) .ai-chat-tool-badge.loading{--tool-loading-bg-1:#2a2a2a;--tool-loading-bg-2:#3a3a3a;--tool-loading-bg-3:#4a4a4a;--tool-loading-text:#fff}.ai-chat-tool-badge.completed{background:#e5e7eb;border:1px solid #d1d5db;color:#1f2937}.ai-chat-widget.dark .ai-chat-tool-badge,.ai-chat-widget[data-theme=dark] .ai-chat-tool-badge,.chakra-ui-dark .ai-chat-tool-badge,.dark .ai-chat-tool-badge,[data-theme=dark] .ai-chat-tool-badge,html.dark .ai-chat-tool-badge{background:hsla(0,0%,100%,.12);border:1px solid hsla(0,0%,100%,.2);color:hsla(0,0%,100%,.9)}.ai-chat-widget.dark .ai-chat-tool-gear,.ai-chat-widget[data-theme=dark] .ai-chat-tool-gear,.chakra-ui-dark .ai-chat-tool-gear,.dark .ai-chat-tool-gear,[data-theme=dark] .ai-chat-tool-gear,html.dark .ai-chat-tool-gear{color:#fff}.ai-chat-tool-badge.error{background:var(--tool-error-bg,rgba(239,68,68,.15));color:var(--tool-error-text,#ef4444)}.ai-chat-tool-badge .ai-chat-tool-check{color:#fff;flex-shrink:0}.ai-chat-tool-badge .ai-chat-tool-error{color:#ef4444;flex-shrink:0}.tool-name{font-weight:500;line-height:1.2;white-space:nowrap}.ai-chat-tool-action{box-sizing:border-box;padding:0;width:100%}@keyframes ai-chat-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.ai-chat-action-skeleton-item{animation:ai-chat-skeleton-pulse 1.5s ease-in-out infinite;background:var(--bg-secondary,#e5e7eb)}.ai-chat-widget.dark .ai-chat-action-skeleton-item,.chakra-ui-dark .ai-chat-action-skeleton-item,.dark .ai-chat-action-skeleton-item,[data-theme=dark] .ai-chat-action-skeleton-item{background:hsla(0,0%,100%,.1)}.ai-chat-action-skeleton-content{display:flex;flex-direction:column;gap:16px}.ai-chat-action-skeleton-header{align-items:center;display:flex;gap:10px}.ai-chat-action-skeleton-box{background:rgba(0,0,0,.08);border-radius:10px;display:flex;flex-direction:column;gap:8px;padding:14px}.ai-chat-widget.dark .ai-chat-action-skeleton-box,.chakra-ui-dark .ai-chat-action-skeleton-box,.dark .ai-chat-action-skeleton-box,[data-theme=dark] .ai-chat-action-skeleton-box{background:rgba(0,0,0,.25)}.ai-chat-action-card{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f9fafb);border:1px solid var(--border-subtle,rgba(0,0,0,.06));border-radius:12px;box-sizing:border-box;margin-top:4px;padding:16px;transition:all .2s ease;width:100%}.ai-chat-widget.dark .ai-chat-action-card,.chakra-ui-dark .ai-chat-action-card,.dark .ai-chat-action-card,[data-theme=dark] .ai-chat-action-card{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1)}.ai-chat-action-booked{background:var(--bg-secondary,#f9fafb);border:1px solid var(--border-subtle,rgba(0,0,0,.06))}.ai-chat-widget.dark .ai-chat-action-booked,.chakra-ui-dark .ai-chat-action-booked,.dark .ai-chat-action-booked,[data-theme=dark] .ai-chat-action-booked{background:var(--bg-secondary,#3a3a3a)}.ai-chat-action-header{align-items:center;color:var(--text-primary,#3e3e3e);display:flex;font-size:var(--text-md,15px);font-weight:var(--font-weight-semibold,600);gap:var(--space-sm,8px);margin-bottom:var(--space-md,16px)}.ai-chat-widget.dark .ai-chat-action-header,.chakra-ui-dark .ai-chat-action-header,.dark .ai-chat-action-header,[data-theme=dark] .ai-chat-action-header{color:var(--text-primary,#fff)}.ai-chat-action-icon{color:var(--action-accent,var(--primary-color,#3b82f6));flex-shrink:0;height:20px;width:20px}.ai-chat-action-success-icon-wrapper{align-items:center;background:var(--action-accent,var(--primary-color,#22c55e));border-radius:50%;color:#fff;display:flex;flex-shrink:0;height:24px;justify-content:center;width:24px}.ai-chat-action-icon-success{color:currentColor;height:14px;width:14px}.ai-chat-action-detail-box{background:var(--bg-primary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-md,8px);display:flex;flex-direction:column;gap:4px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-action-detail-box,.chakra-ui-dark .ai-chat-action-detail-box,.dark .ai-chat-action-detail-box,[data-theme=dark] .ai-chat-action-detail-box{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.05)}.ai-chat-action-label-small{color:var(--text-muted,#71717a);font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}.ai-chat-action-value-large{color:var(--text-primary,#3e3e3e);font-size:15px;font-weight:500}.ai-chat-widget.dark .ai-chat-action-value-large,.chakra-ui-dark .ai-chat-action-value-large,.dark .ai-chat-action-value-large,[data-theme=dark] .ai-chat-action-value-large{color:#fff}.ai-chat-action-body{display:flex;flex-direction:column;gap:var(--space-md,16px)}.ai-chat-action-field{display:flex;flex-direction:column;gap:var(--space-xs,6px)}.ai-chat-action-label{color:var(--text-secondary,#6b7280);font-size:var(--text-sm,13px);font-weight:var(--font-weight-medium,500)}.ai-chat-widget.dark .ai-chat-action-label,.chakra-ui-dark .ai-chat-action-label,.dark .ai-chat-action-label,[data-theme=dark] .ai-chat-action-label{color:var(--text-secondary,#a1a1aa)}.ai-chat-action-input{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);font-size:var(--text-sm,13px);outline:none;padding:10px 12px;transition:border-color .2s ease,box-shadow .2s ease}.ai-chat-action-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.1)}.ai-chat-action-input::placeholder{color:var(--text-muted,#9ca3af)}.ai-chat-widget.dark .ai-chat-action-input,.chakra-ui-dark .ai-chat-action-input,.dark .ai-chat-action-input,[data-theme=dark] .ai-chat-action-input{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-input:focus,.chakra-ui-dark .ai-chat-action-input:focus,.dark .ai-chat-action-input:focus,[data-theme=dark] .ai-chat-action-input:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.2)}.ai-chat-action-button{background:var(--action-accent,var(--primary-color,#3b82f6));border:none;border-radius:9999px;color:#fff;cursor:pointer;font-size:var(--text-sm,13px);font-weight:var(--font-weight-semibold,600);padding:12px 16px;transition:all .2s ease;width:100%}.ai-chat-action-button:hover:not(:disabled){opacity:.9;transform:translateY(-1px)}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-action-link-button{align-items:center;background:var(--action-accent,var(--primary-color,#3b82f6));border:none;border-radius:9999px;box-sizing:border-box;color:#fff;display:flex;font-size:14px;font-weight:600;gap:6px;justify-content:center;margin-top:8px;padding:12px;text-decoration:none;transition:all .2s ease;width:100%}.ai-chat-action-link-button:hover{opacity:.9;transform:translateY(-1px)}.ai-chat-action-error{background:rgba(239,68,68,.1);border-radius:var(--radius-md,8px);color:#dc2626;font-size:var(--text-sm,13px);padding:10px 12px}.ai-chat-widget.dark .ai-chat-action-error,.chakra-ui-dark .ai-chat-action-error,.dark .ai-chat-action-error,[data-theme=dark] .ai-chat-action-error{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-action-hint{color:var(--text-muted,#9ca3af);font-size:var(--text-sm,13px);padding:var(--space-sm,8px);text-align:center}.ai-chat-action-date-grid{display:grid;gap:var(--space-xs,6px);grid-template-columns:repeat(auto-fill,minmax(90px,1fr))}.ai-chat-action-date-btn{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;font-size:var(--text-xs,12px);font-weight:var(--font-weight-medium,500);padding:8px 10px;text-align:center;transition:all .15s ease}.ai-chat-action-date-btn:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-date-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-action-date-btn,.chakra-ui-dark .ai-chat-action-date-btn,.dark .ai-chat-action-date-btn,[data-theme=dark] .ai-chat-action-date-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-date-btn:hover,.chakra-ui-dark .ai-chat-action-date-btn:hover,.dark .ai-chat-action-date-btn:hover,[data-theme=dark] .ai-chat-action-date-btn:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-action-date-btn.active,.chakra-ui-dark .ai-chat-action-date-btn.active,.dark .ai-chat-action-date-btn.active,[data-theme=dark] .ai-chat-action-date-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-action-time-grid{display:grid;gap:var(--space-xs,6px);grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}.ai-chat-action-time-btn{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;font-size:var(--text-xs,12px);font-weight:var(--font-weight-medium,500);padding:8px 10px;text-align:center;transition:all .15s ease}.ai-chat-action-time-btn:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-action-time-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-action-time-btn,.chakra-ui-dark .ai-chat-action-time-btn,.dark .ai-chat-action-time-btn,[data-theme=dark] .ai-chat-action-time-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-action-time-btn:hover,.chakra-ui-dark .ai-chat-action-time-btn:hover,.dark .ai-chat-action-time-btn:hover,[data-theme=dark] .ai-chat-action-time-btn:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-action-time-btn.active,.chakra-ui-dark .ai-chat-action-time-btn.active,.dark .ai-chat-action-time-btn.active,[data-theme=dark] .ai-chat-action-time-btn.active{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-link-preview{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f4f4f4);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:var(--radius-lg,12px);cursor:pointer;display:flex;flex-direction:column;margin-top:4px;overflow:hidden;padding:0!important;position:relative;transition:border-color .2s,box-shadow .2s,transform .2s}.ai-chat-link-preview:hover{border-color:var(--action-accent);box-shadow:0 2px 8px rgba(0,0,0,.1);transform:translateY(-1px)}.ai-chat-link-preview:focus{border-color:var(--action-accent);box-shadow:0 0 0 2px rgba(59,130,246,.2);outline:none}.ai-chat-widget.dark .ai-chat-link-preview,.chakra-ui-dark .ai-chat-link-preview,.dark .ai-chat-link-preview,[data-theme=dark] .ai-chat-link-preview{background:var(--bg-secondary,#3a3a3a);border-color:hsla(0,0%,100%,.08)}.ai-chat-widget.dark .ai-chat-link-preview:hover,.chakra-ui-dark .ai-chat-link-preview:hover,.dark .ai-chat-link-preview:hover,[data-theme=dark] .ai-chat-link-preview:hover{border-color:var(--action-accent);box-shadow:0 2px 12px rgba(0,0,0,.3)}.ai-chat-link-preview__image{aspect-ratio:1.91/1;background:var(--bg-muted,#e5e7eb);overflow:hidden;width:100%}.ai-chat-widget.dark .ai-chat-link-preview__image,.chakra-ui-dark .ai-chat-link-preview__image,.dark .ai-chat-link-preview__image,[data-theme=dark] .ai-chat-link-preview__image{background:hsla(0,0%,100%,.05)}.ai-chat-link-preview__image img{height:100%;object-fit:cover;width:100%}.ai-chat-link-preview__content{flex:1;padding:8px 10px}.ai-chat-link-preview__site{align-items:center;display:flex;gap:6px;margin-bottom:6px}.ai-chat-link-preview__favicon{border-radius:2px;flex-shrink:0;height:16px;width:16px}.ai-chat-link-preview__domain{color:var(--text-muted,#71717a);font-size:12px;letter-spacing:.5px;overflow:hidden;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}.ai-chat-link-preview__title{-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;color:var(--text-primary,#3e3e3e);display:-webkit-box;font-size:15px;font-weight:600;line-height:1.3;margin:0 0 4px;overflow:hidden}.ai-chat-widget.dark .ai-chat-link-preview__title,.chakra-ui-dark .ai-chat-link-preview__title,.dark .ai-chat-link-preview__title,[data-theme=dark] .ai-chat-link-preview__title{color:#fff}.ai-chat-link-preview__description{-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;color:var(--text-muted,#71717a);display:-webkit-box;font-size:13px;line-height:1.4;margin:0;overflow:hidden}.ai-chat-link-preview__context{border-top:1px solid var(--border-subtle,rgba(0,0,0,.08));color:var(--text-muted,#71717a);font-size:12px;font-style:italic;margin:8px 0 0;padding-top:8px}.ai-chat-widget.dark .ai-chat-link-preview__context,.chakra-ui-dark .ai-chat-link-preview__context,.dark .ai-chat-link-preview__context,[data-theme=dark] .ai-chat-link-preview__context{border-color:hsla(0,0%,100%,.08)}.ai-chat-link-preview__arrow{align-items:center;background:var(--bg-primary,#fff);border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.1);color:var(--text-muted,#71717a);display:flex;height:28px;justify-content:center;opacity:0;position:absolute;right:12px;top:12px;transition:opacity .2s,background .2s;width:28px}.ai-chat-link-preview:hover .ai-chat-link-preview__arrow{opacity:1}.ai-chat-widget.dark .ai-chat-link-preview__arrow,.chakra-ui-dark .ai-chat-link-preview__arrow,.dark .ai-chat-link-preview__arrow,[data-theme=dark] .ai-chat-link-preview__arrow{background:hsla(0,0%,100%,.1);color:#fff}.ai-chat-link-preview--error{border-color:rgba(239,68,68,.3)}.ai-chat-link-preview--error:hover{border-color:rgba(239,68,68,.5)}.ai-chat-link-preview__error-text{color:#dc2626;font-size:12px;margin:4px 0 0}.ai-chat-widget.dark .ai-chat-link-preview__error-text,.chakra-ui-dark .ai-chat-link-preview__error-text,.dark .ai-chat-link-preview__error-text,[data-theme=dark] .ai-chat-link-preview__error-text{color:#fca5a5}.ai-chat-video-player{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f4f4f4);border-radius:var(--radius-lg,12px);display:flex;flex-direction:column;gap:0;margin-top:4px;overflow:hidden;padding:0!important}.ai-chat-widget.dark .ai-chat-video-player,.chakra-ui-dark .ai-chat-video-player,.dark .ai-chat-video-player,[data-theme=dark] .ai-chat-video-player{background:var(--bg-secondary,#3a3a3a)}.ai-chat-video-player__header{align-items:center;color:var(--action-accent,var(--primary-color,#3b82f6));display:flex;gap:8px}.ai-chat-video-player__title{color:var(--text-primary,#3e3e3e);font-size:14px;font-weight:600}.ai-chat-widget.dark .ai-chat-video-player__title,.chakra-ui-dark .ai-chat-video-player__title,.dark .ai-chat-video-player__title,[data-theme=dark] .ai-chat-video-player__title{color:#fff}.ai-chat-video-player__container{aspect-ratio:16/9;background:#000;border-radius:8px;overflow:hidden;position:relative;width:100%}.ai-chat-video-player__thumbnail{cursor:pointer;height:100%;position:relative;width:100%}.ai-chat-video-player__thumbnail img{height:100%;object-fit:cover;width:100%}.ai-chat-video-player__placeholder{align-items:center;background:linear-gradient(135deg,#1a1a2e,#16213e);cursor:pointer;display:flex;flex-direction:column;gap:8px;height:100%;justify-content:center;position:relative;width:100%}.ai-chat-video-player__click-text{color:hsla(0,0%,100%,.7);font-size:13px}.ai-chat-video-player__play-btn{align-items:center;background:rgba(0,0,0,.7);border:none;border-radius:50%;color:#fff;cursor:pointer;display:flex;height:64px;justify-content:center;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);transition:background .2s,transform .2s;width:64px}.ai-chat-video-player__placeholder .ai-chat-video-player__play-btn{left:auto;position:relative;top:auto;transform:none}.ai-chat-video-player__play-btn:hover{background:rgba(0,0,0,.9);transform:translate(-50%,-50%) scale(1.05)}.ai-chat-video-player__placeholder .ai-chat-video-player__play-btn:hover{transform:scale(1.05)}.ai-chat-video-player__provider-badge{background:rgba(0,0,0,.8);border-radius:4px;bottom:8px;color:#fff;font-size:11px;font-weight:600;letter-spacing:.5px;padding:4px 8px;position:absolute;right:8px;text-transform:uppercase}.ai-chat-video-player__iframe,.ai-chat-video-player__video{border:none;height:100%;left:0;position:absolute;top:0;width:100%}.ai-chat-video-player__error{align-items:center;background:rgba(239,68,68,.1);color:#dc2626;display:flex;font-size:13px;height:100%;justify-content:center;padding:16px;text-align:center;width:100%}.ai-chat-widget.dark .ai-chat-video-player__error,.chakra-ui-dark .ai-chat-video-player__error,.dark .ai-chat-video-player__error,[data-theme=dark] .ai-chat-video-player__error{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-video-player__context{border-top:1px solid var(--border-subtle,rgba(0,0,0,.08));color:var(--text-muted,#71717a);font-size:12px;font-style:italic;margin-top:4px;padding-top:8px}.ai-chat-widget.dark .ai-chat-video-player__context,.chakra-ui-dark .ai-chat-video-player__context,.dark .ai-chat-video-player__context,[data-theme=dark] .ai-chat-video-player__context{border-color:hsla(0,0%,100%,.08)}.ai-chat-location-card{background:var(--bg-secondary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:12px;overflow:hidden;padding:0}.ai-chat-widget.dark .ai-chat-location-card,.chakra-ui-dark .ai-chat-location-card,.dark .ai-chat-location-card,[data-theme=dark] .ai-chat-location-card{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1)}.ai-chat-location-card--compact{border-radius:10px}.ai-chat-location-card--error{color:var(--text-muted,#71717a);padding:16px;text-align:center}.ai-chat-location-card__map{background:var(--bg-muted,#f4f4f5);position:relative;width:100%}.ai-chat-widget.dark .ai-chat-location-card__map,.chakra-ui-dark .ai-chat-location-card__map,.dark .ai-chat-location-card__map,[data-theme=dark] .ai-chat-location-card__map{background:rgba(0,0,0,.2)}.ai-chat-location-card__map iframe{border:none;display:block;height:100%;width:100%}.ai-chat-location-card__content{padding:12px}.ai-chat-location-card--compact .ai-chat-location-card__content{padding:10px}.ai-chat-location-card__header{align-items:center;display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.ai-chat-location-card__name{color:var(--text-primary,#18181b);flex:1;font-size:16px;font-weight:600;margin:0;min-width:0}.ai-chat-widget.dark .ai-chat-location-card__name,.chakra-ui-dark .ai-chat-location-card__name,.dark .ai-chat-location-card__name,[data-theme=dark] .ai-chat-location-card__name{color:#fff}.ai-chat-location-card--compact .ai-chat-location-card__name{font-size:14px}.ai-chat-location-card__type{background:var(--bg-muted,#f4f4f5);border-radius:10px;color:var(--text-muted,#71717a);font-size:11px;font-weight:500;letter-spacing:.5px;padding:2px 8px;text-transform:uppercase}.ai-chat-widget.dark .ai-chat-location-card__type,.chakra-ui-dark .ai-chat-location-card__type,.dark .ai-chat-location-card__type,[data-theme=dark] .ai-chat-location-card__type{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.7)}.ai-chat-location-card__status{border-radius:12px;font-size:12px;font-weight:500;padding:2px 8px}.ai-chat-location-card__status--open{background:#dcfce7;color:#16a34a}.ai-chat-location-card__status--closed{background:#fef2f2;color:#dc2626}.ai-chat-widget.dark .ai-chat-location-card__status--open,.chakra-ui-dark .ai-chat-location-card__status--open,.dark .ai-chat-location-card__status--open,[data-theme=dark] .ai-chat-location-card__status--open{background:rgba(34,197,94,.2);color:#4ade80}.ai-chat-widget.dark .ai-chat-location-card__status--closed,.chakra-ui-dark .ai-chat-location-card__status--closed,.dark .ai-chat-location-card__status--closed,[data-theme=dark] .ai-chat-location-card__status--closed{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-location-card__address{align-items:flex-start;color:var(--text-muted,#71717a);display:flex;font-size:13px;gap:6px;line-height:1.4;margin:0 0 8px}.ai-chat-location-card__address svg{flex-shrink:0;margin-top:2px}.ai-chat-location-card__description{color:var(--text-muted,#71717a);font-size:13px;line-height:1.4;margin:0 0 8px}.ai-chat-location-card__hours{align-items:flex-start;color:var(--text-muted,#71717a);display:flex;font-size:13px;gap:6px;margin-bottom:8px}.ai-chat-location-card__hours svg{flex-shrink:0;margin-top:2px}.ai-chat-location-card__hours-list{flex:1}.ai-chat-location-card__hours-toggle{align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;font:inherit;gap:4px;padding:0}.ai-chat-location-card__hours-toggle:hover{text-decoration:underline}.ai-chat-location-card__hours-full{list-style:none;margin:8px 0 0;padding:0}.ai-chat-location-card__hours-full li{display:flex;font-size:12px;justify-content:space-between;padding:4px 0}.ai-chat-location-card__hours-today{color:var(--text-primary,#18181b);font-weight:600}.ai-chat-widget.dark .ai-chat-location-card__hours-today,.chakra-ui-dark .ai-chat-location-card__hours-today,.dark .ai-chat-location-card__hours-today,[data-theme=dark] .ai-chat-location-card__hours-today{color:#fff}.ai-chat-location-card__phone{align-items:center;background:none;border:none;color:var(--action-accent,#3b82f6);cursor:pointer;display:flex;font-size:13px;gap:6px;margin-bottom:12px;padding:0}.ai-chat-location-card__phone:hover{text-decoration:underline}.ai-chat-location-card__actions{display:flex;gap:8px;justify-content:flex-start;width:100%}.ai-chat-location-card__button{align-items:center;background:var(--action-accent,#3b82f6);border:none;border-radius:20px;color:#fff;cursor:pointer;display:flex;flex:1;font-size:13px;font-weight:500;gap:6px;justify-content:center;padding:10px 16px;transition:opacity .2s}.ai-chat-location-card__button:hover{opacity:.9}.ai-chat-location-card--compact .ai-chat-location-card__button{font-size:12px;padding:8px 12px}.ai-chat-location-card__link{align-items:center;background:var(--bg-secondary,#fff);border:1px solid var(--border-subtle,rgba(0,0,0,.08));border-radius:20px;color:var(--text-primary,#18181b);display:flex;font-size:13px;gap:6px;padding:10px 16px;text-decoration:none;transition:border-color .2s}.ai-chat-widget.dark .ai-chat-location-card__link,.chakra-ui-dark .ai-chat-location-card__link,.dark .ai-chat-location-card__link,[data-theme=dark] .ai-chat-location-card__link{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-location-card__link:hover{border-color:var(--action-accent,#3b82f6)}.ai-chat-location-card-list{display:flex;flex-direction:column;gap:8px}.ai-chat-location-card-list__header{align-items:center;color:var(--text-muted,#71717a);display:flex;font-size:13px;font-weight:500;gap:6px;margin-bottom:4px;padding:0 4px}.ai-chat-location-card-list__stack{display:grid;gap:12px;grid-template-columns:1fr}.ai-chat-location-card-list__stack--cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.ai-chat-location-card-list__stack--cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}@media (max-width:1000px){.ai-chat-location-card-list__stack--cols-3{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:640px){.ai-chat-location-card-list__stack--cols-2,.ai-chat-location-card-list__stack--cols-3{grid-template-columns:1fr}}.ai-chat-location-card-list__grid{display:grid;gap:8px;grid-template-columns:repeat(2,1fr)}@media (max-width:400px){.ai-chat-location-card-list__grid{grid-template-columns:1fr}}.ai-chat-location-card-list__carousel{-webkit-overflow-scrolling:touch;-ms-overflow-style:none;display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;scroll-snap-type:x mandatory;scrollbar-width:none}.ai-chat-location-card-list__carousel::-webkit-scrollbar{display:none}.ai-chat-location-card-list__carousel>.ai-chat-location-card{flex:0 0 280px;scroll-snap-align:start}.ai-chat-contact-card{background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:16px;overflow:hidden;padding:0;position:relative}.ai-chat-widget.dark .ai-chat-contact-card,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card,.chakra-ui-dark .ai-chat-contact-card,.dark .ai-chat-contact-card,[data-theme=dark] .ai-chat-contact-card,html.dark .ai-chat-contact-card{background:#4a4a4a;border-color:hsla(0,0%,100%,.08)}.ai-chat-contact-card-list{gap:12px;width:100%}.ai-chat-contact-card--compact{border-radius:12px}.ai-chat-contact-card--empty{align-items:center;background:var(--bg-secondary,#f4f4f5);display:flex;flex-direction:column;gap:8px;justify-content:center;padding:24px 16px;text-align:center}.ai-chat-widget.dark .ai-chat-contact-card--empty,.chakra-ui-dark .ai-chat-contact-card--empty,.dark .ai-chat-contact-card--empty,[data-theme=dark] .ai-chat-contact-card--empty{background:#3a3a3a}.ai-chat-contact-card__empty-icon{color:var(--text-muted,#71717a);opacity:.6}.ai-chat-contact-card__empty-text{color:var(--text-muted,#71717a);font-size:14px;margin:0}.ai-chat-contact-card--vertical{display:flex;flex-direction:column}.ai-chat-contact-card--vertical .ai-chat-contact-card__image-section{aspect-ratio:3/2;overflow:hidden;width:100%}.ai-chat-contact-card--vertical .ai-chat-contact-card__image{height:100%;object-fit:cover;width:100%}.ai-chat-contact-card--vertical .ai-chat-contact-card__image-placeholder{align-items:center;background:linear-gradient(135deg,#5a5a5a,#3a3a3a);color:hsla(0,0%,100%,.5);display:flex;height:100%;justify-content:center;width:100%}.ai-chat-contact-card--vertical .ai-chat-contact-card__image-placeholder svg{height:48px;width:48px}.ai-chat-contact-card--vertical .ai-chat-contact-card__info{padding:16px;text-align:center}.ai-chat-contact-card--horizontal{display:flex;flex-direction:row}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image-section{height:160px;min-width:140px;overflow:hidden;width:140px}.ai-chat-contact-card--horizontal.ai-chat-contact-card--compact .ai-chat-contact-card__image-section{height:120px;min-width:100px;width:100px}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image{height:100%;object-fit:cover;width:100%}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image-placeholder{align-items:center;background:linear-gradient(135deg,#5a5a5a,#3a3a3a);color:hsla(0,0%,100%,.5);display:flex;height:100%;justify-content:center;width:100%}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image-placeholder svg{height:36px;width:36px}.ai-chat-contact-card--horizontal .ai-chat-contact-card__info{display:flex;flex:1;flex-direction:column;justify-content:center;padding:16px}.ai-chat-contact-card__name{color:var(--action-accent,#ef4444);font-size:18px;font-weight:600;line-height:1.3;margin:0}.ai-chat-contact-card--compact .ai-chat-contact-card__name{font-size:15px}.ai-chat-contact-card__role{color:rgba(0,0,0,.7);font-size:14px;font-weight:400;margin:2px 0 0}.ai-chat-widget.dark .ai-chat-contact-card__role,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__role,.chakra-ui-dark .ai-chat-contact-card__role,.dark .ai-chat-contact-card__role,[data-theme=dark] .ai-chat-contact-card__role,html.dark .ai-chat-contact-card__role{color:hsla(0,0%,100%,.9)}.ai-chat-contact-card--compact .ai-chat-contact-card__role{font-size:13px}.ai-chat-contact-card__details{display:flex;flex-direction:column;gap:2px;margin-top:12px}.ai-chat-contact-card__detail{color:rgba(0,0,0,.6);display:block;font-size:14px;line-height:1.5;margin:0;text-decoration:none}.ai-chat-contact-card__detail:hover{color:#000;text-decoration:underline}.ai-chat-widget.dark .ai-chat-contact-card__detail,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__detail,.chakra-ui-dark .ai-chat-contact-card__detail,.dark .ai-chat-contact-card__detail,[data-theme=dark] .ai-chat-contact-card__detail,html.dark .ai-chat-contact-card__detail{color:hsla(0,0%,100%,.7)}.ai-chat-widget.dark .ai-chat-contact-card__detail:hover,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__detail:hover,.chakra-ui-dark .ai-chat-contact-card__detail:hover,.dark .ai-chat-contact-card__detail:hover,[data-theme=dark] .ai-chat-contact-card__detail:hover,html.dark .ai-chat-contact-card__detail:hover{color:#fff}.ai-chat-contact-card--compact .ai-chat-contact-card__detail{font-size:13px}.ai-chat-contact-card__responsibilities{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}.ai-chat-contact-card__responsibility-tag{background:rgba(0,0,0,.08);border-radius:10px;color:rgba(0,0,0,.8);font-size:11px;font-weight:500;padding:3px 10px}.ai-chat-widget.dark .ai-chat-contact-card__responsibility-tag,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__responsibility-tag,.chakra-ui-dark .ai-chat-contact-card__responsibility-tag,.dark .ai-chat-contact-card__responsibility-tag,[data-theme=dark] .ai-chat-contact-card__responsibility-tag,html.dark .ai-chat-contact-card__responsibility-tag{background:hsla(0,0%,100%,.15);color:hsla(0,0%,100%,.9)}.ai-chat-contact-card__responsibility-more{color:rgba(0,0,0,.5);font-size:11px;padding:3px 4px}.ai-chat-widget.dark .ai-chat-contact-card__responsibility-more,.ai-chat-widget[data-theme=dark] .ai-chat-contact-card__responsibility-more,.chakra-ui-dark .ai-chat-contact-card__responsibility-more,.dark .ai-chat-contact-card__responsibility-more,[data-theme=dark] .ai-chat-contact-card__responsibility-more,html.dark .ai-chat-contact-card__responsibility-more{color:hsla(0,0%,100%,.5)}.ai-chat-contact-card__actions{display:flex;gap:8px;padding:0 12px 12px}.ai-chat-contact-card--compact .ai-chat-contact-card__actions{gap:6px;padding:0 10px 10px}.ai-chat-contact-card__button{align-items:center;border:none;border-radius:9999px;cursor:pointer;display:flex;font-size:14px;font-weight:600;gap:8px;justify-content:center;padding:12px 20px;transition:all .15s ease;white-space:nowrap}.ai-chat-contact-card--compact .ai-chat-contact-card__button{font-size:13px;padding:10px 16px}.ai-chat-contact-card__button:hover{box-shadow:0 4px 12px rgba(0,0,0,.15);transform:translateY(-1px)}.ai-chat-contact-card__button:active{transform:translateY(0)}.ai-chat-contact-card__button--primary{background:var(--action-accent,#3b82f6);color:#fff;flex:1}.ai-chat-contact-card__button--primary:hover{background:color-mix(in srgb,var(--action-accent,#3b82f6) 90%,#000)}.ai-chat-contact-card__button--secondary{background:var(--bg-muted,#f4f4f5);border:1px solid var(--border-subtle,rgba(0,0,0,.08));color:var(--text-primary,#18181b);flex:1}.ai-chat-contact-card__button--secondary:hover{background:var(--bg-hover,#e4e4e7)}.ai-chat-widget.dark .ai-chat-contact-card__button--secondary,.chakra-ui-dark .ai-chat-contact-card__button--secondary,.dark .ai-chat-contact-card__button--secondary,[data-theme=dark] .ai-chat-contact-card__button--secondary{background:hsla(0,0%,100%,.1);border-color:hsla(0,0%,100%,.15);color:#fff}.ai-chat-widget.dark .ai-chat-contact-card__button--secondary:hover,.chakra-ui-dark .ai-chat-contact-card__button--secondary:hover,.dark .ai-chat-contact-card__button--secondary:hover,[data-theme=dark] .ai-chat-contact-card__button--secondary:hover{background:hsla(0,0%,100%,.15)}.ai-chat-contact-card-list{display:flex;flex-direction:column;gap:8px}.ai-chat-contact-card-list__header{align-items:center;color:var(--text-muted,#71717a);display:flex;font-size:13px;font-weight:500;gap:6px;margin-bottom:2px;margin-top:8px;padding:0 4px}.ai-chat-contact-card-list__stack{display:grid;gap:12px;grid-template-columns:repeat(3,minmax(0,1fr))}@media (max-width:900px){.ai-chat-contact-card-list__stack{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:600px){.ai-chat-contact-card-list__stack{grid-template-columns:1fr}}.ai-chat-contact-card-list__stack--widget{grid-template-columns:1fr}@container (min-width: 380px){.ai-chat-contact-card-list__stack--widget{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:520px){.ai-chat-contact-card-list__stack{grid-template-columns:1fr!important}.ai-chat-contact-card--horizontal{flex-direction:column}.ai-chat-contact-card--horizontal .ai-chat-contact-card__image-section{aspect-ratio:3/2;height:auto;min-width:100%;width:100%}}.ai-chat-contact-card__initials{align-items:center;display:flex;font-size:48px;font-weight:600;height:100%;justify-content:center;letter-spacing:.05em;text-transform:uppercase;width:100%}.ai-chat-contact-card--compact .ai-chat-contact-card__initials{font-size:32px}.ai-chat-contact-card--horizontal .ai-chat-contact-card__initials{font-size:28px}.ai-chat-contact-card--horizontal.ai-chat-contact-card--compact .ai-chat-contact-card__initials{font-size:22px}.ai-chat-form-card{--action-accent:var(--primary-color,#3b82f6);background:var(--bg-secondary,#f9fafb);border:1px solid var(--border-subtle,rgba(0,0,0,.06));border-radius:12px;box-sizing:border-box;margin:6px 0;overflow:hidden;padding:16px;width:100%}.ai-chat-widget.dark .ai-chat-form-card,.chakra-ui-dark .ai-chat-form-card,.dark .ai-chat-form-card,[data-theme=dark] .ai-chat-form-card{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1)}.ai-chat-form-card--empty,.ai-chat-form-card--error,.ai-chat-form-card--skipped,.ai-chat-form-card--submitted{padding:12px 16px}.ai-chat-form-card__header{align-items:center;display:flex;gap:8px;margin-bottom:12px}.ai-chat-form-card__icon{font-size:18px}.ai-chat-form-card__title{color:var(--text-primary,#3e3e3e);font-size:15px;font-weight:600}.ai-chat-widget.dark .ai-chat-form-card__title,.chakra-ui-dark .ai-chat-form-card__title,.dark .ai-chat-form-card__title,[data-theme=dark] .ai-chat-form-card__title{color:#fff}.ai-chat-form-card__description{color:var(--text-muted,#71717a);font-size:13px;line-height:1.4;margin:0 0 12px}.ai-chat-form-card__context{color:var(--text-muted,#71717a);font-size:12px;font-style:italic;margin:0 0 12px}.ai-chat-form-card__error{color:#dc2626;font-size:13px;margin:0}.ai-chat-widget.dark .ai-chat-form-card__error,.chakra-ui-dark .ai-chat-form-card__error,.dark .ai-chat-form-card__error,[data-theme=dark] .ai-chat-form-card__error{color:#fca5a5}.ai-chat-form-card__success{color:#16a34a;font-size:13px;margin:0}.ai-chat-widget.dark .ai-chat-form-card__success,.chakra-ui-dark .ai-chat-form-card__success,.dark .ai-chat-form-card__success,[data-theme=dark] .ai-chat-form-card__success{color:#4ade80}.ai-chat-form-card__empty-text,.ai-chat-form-card__skipped-text{color:var(--text-muted,#71717a);font-size:13px;margin:0}.ai-chat-form-card__progress{align-items:center;display:flex;gap:12px;margin-bottom:16px}.ai-chat-form-card__progress-bar{background:var(--action-accent,var(--primary-color,#3b82f6));border-radius:2px;flex:1;height:4px;transition:width .3s ease}.ai-chat-form-card__progress-text{color:var(--text-muted,#71717a);font-size:12px;white-space:nowrap}.ai-chat-form-card__question{margin-bottom:16px}.ai-chat-form-card__question-text{color:var(--text-primary,#3e3e3e);font-size:14px;font-weight:500;line-height:1.4;margin:0 0 12px}.ai-chat-widget.dark .ai-chat-form-card__question-text,.chakra-ui-dark .ai-chat-form-card__question-text,.dark .ai-chat-form-card__question-text,[data-theme=dark] .ai-chat-form-card__question-text{color:#fff}.ai-chat-form-card__required{color:#dc2626;margin-left:2px}.ai-chat-form-card__answer{margin-top:8px}.ai-chat-form-card__textarea{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);box-sizing:border-box;color:var(--text-primary,#3e3e3e);font-family:inherit;font-size:14px;min-height:80px;outline:none;padding:10px 12px;resize:vertical;transition:border-color .2s ease,box-shadow .2s ease;width:100%}.ai-chat-form-card__textarea:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.1)}.ai-chat-form-card__textarea::placeholder{color:var(--text-muted,#9ca3af)}.ai-chat-widget.dark .ai-chat-form-card__textarea,.chakra-ui-dark .ai-chat-form-card__textarea,.dark .ai-chat-form-card__textarea,[data-theme=dark] .ai-chat-form-card__textarea{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-form-card__textarea:focus,.chakra-ui-dark .ai-chat-form-card__textarea:focus,.dark .ai-chat-form-card__textarea:focus,[data-theme=dark] .ai-chat-form-card__textarea:focus{border-color:var(--action-accent,var(--primary-color,#3b82f6));box-shadow:0 0 0 3px rgba(59,130,246,.2)}.ai-chat-form-card__options{display:flex;flex-direction:column;gap:8px}.ai-chat-form-card__option{align-items:center;background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);cursor:pointer;display:flex;gap:10px;padding:10px 12px;transition:border-color .15s,background .15s}.ai-chat-form-card__option:hover{background:rgba(59,130,246,.05);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-form-card__option,.chakra-ui-dark .ai-chat-form-card__option,.dark .ai-chat-form-card__option,[data-theme=dark] .ai-chat-form-card__option{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1)}.ai-chat-widget.dark .ai-chat-form-card__option:hover,.chakra-ui-dark .ai-chat-form-card__option:hover,.dark .ai-chat-form-card__option:hover,[data-theme=dark] .ai-chat-form-card__option:hover{background:rgba(59,130,246,.15);border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-form-card__option input{accent-color:var(--action-accent,var(--primary-color,#3b82f6));margin:0}.ai-chat-form-card__option-text{color:var(--text-primary,#3e3e3e);font-size:14px}.ai-chat-widget.dark .ai-chat-form-card__option-text,.chakra-ui-dark .ai-chat-form-card__option-text,.dark .ai-chat-form-card__option-text,[data-theme=dark] .ai-chat-form-card__option-text{color:#fff}.ai-chat-form-card__rating{display:flex;flex-wrap:wrap;gap:8px}.ai-chat-form-card__rating-btn{align-items:center;background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);border-radius:var(--radius-md,8px);color:var(--text-primary,#3e3e3e);cursor:pointer;display:flex;font-size:14px;font-weight:500;height:40px;justify-content:center;transition:all .15s ease;width:40px}.ai-chat-form-card__rating-btn--selected,.ai-chat-form-card__rating-btn:hover{border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-form-card__rating-btn--selected{background:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-widget.dark .ai-chat-form-card__rating-btn,.chakra-ui-dark .ai-chat-form-card__rating-btn,.dark .ai-chat-form-card__rating-btn,[data-theme=dark] .ai-chat-form-card__rating-btn{background:rgba(0,0,0,.2);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-widget.dark .ai-chat-form-card__rating-btn:hover,.chakra-ui-dark .ai-chat-form-card__rating-btn:hover,.dark .ai-chat-form-card__rating-btn:hover,[data-theme=dark] .ai-chat-form-card__rating-btn:hover{border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-form-card__rating-btn--selected,.chakra-ui-dark .ai-chat-form-card__rating-btn--selected,.dark .ai-chat-form-card__rating-btn--selected,[data-theme=dark] .ai-chat-form-card__rating-btn--selected{background:var(--action-accent,var(--primary-color,#3b82f6));border-color:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-form-card__actions{align-items:center;border-top:1px solid var(--border-subtle,rgba(0,0,0,.08));display:flex;gap:8px;margin-top:16px;padding-top:16px}.ai-chat-widget.dark .ai-chat-form-card__actions,.chakra-ui-dark .ai-chat-form-card__actions,.dark .ai-chat-form-card__actions,[data-theme=dark] .ai-chat-form-card__actions{border-color:hsla(0,0%,100%,.08)}.ai-chat-form-card__actions-spacer{flex:1}.ai-chat-form-card__btn{border:none;border-radius:9999px;cursor:pointer;font-family:inherit;font-size:13px;font-weight:500;padding:8px 16px;transition:all .2s ease}.ai-chat-form-card__btn:disabled{cursor:not-allowed;opacity:.5}.ai-chat-form-card__btn--primary{background:var(--action-accent,var(--primary-color,#3b82f6));color:#fff}.ai-chat-form-card__btn--primary:hover:not(:disabled){opacity:.9;transform:translateY(-1px)}.ai-chat-form-card__btn--secondary{background:var(--bg-primary,#fff);border:1px solid var(--border-default,#e5e7eb);color:var(--text-primary,#3e3e3e)}.ai-chat-form-card__btn--secondary:hover:not(:disabled){border-color:var(--action-accent,var(--primary-color,#3b82f6))}.ai-chat-widget.dark .ai-chat-form-card__btn--secondary,.chakra-ui-dark .ai-chat-form-card__btn--secondary,.dark .ai-chat-form-card__btn--secondary,[data-theme=dark] .ai-chat-form-card__btn--secondary{background:hsla(0,0%,100%,.05);border-color:hsla(0,0%,100%,.1);color:#fff}.ai-chat-form-card__btn--ghost{background:transparent;color:var(--text-muted,#71717a)}.ai-chat-form-card__btn--ghost:hover:not(:disabled){background:rgba(0,0,0,.05);color:var(--text-primary,#3e3e3e)}.ai-chat-widget.dark .ai-chat-form-card__btn--ghost:hover:not(:disabled),.chakra-ui-dark .ai-chat-form-card__btn--ghost:hover:not(:disabled),.dark .ai-chat-form-card__btn--ghost:hover:not(:disabled),[data-theme=dark] .ai-chat-form-card__btn--ghost:hover:not(:disabled){background:hsla(0,0%,100%,.05);color:#fff}.chat-fullpage{--fp-max-width:800px;--fp-padding-x:16px;--fp-padding-top-mobile:64px;--fp-padding-top-desktop:16px;--fp-padding-bottom:200px;--fp-input-bottom:0}.chat-fullpage .ai-chat-messages{background:transparent;height:100%;margin:0 auto;max-width:var(--fp-max-width);padding:var(--fp-padding-top-desktop) var(--fp-padding-x) var(--fp-padding-bottom)}@media (max-width:768px){.chat-fullpage .ai-chat-messages{padding-top:var(--fp-padding-top-mobile)}}.chat-fullpage .ai-chat-message{animation:none}.chat-fullpage .ai-chat-message.user{max-width:85%}.chat-fullpage .ai-chat-message.user .ai-chat-message-content{background:var(--bg-muted,#f4f4f5);border-radius:24px;color:#000;padding:8px 16px}.chat-fullpage.dark .ai-chat-message.user .ai-chat-message-content{background:var(--bg-muted,#27272a);color:#fff}.chat-fullpage .ai-chat-message.assistant{width:100%}.chat-fullpage .ai-chat-message.assistant .ai-chat-message-content{color:#000;padding:8px 16px}.chat-fullpage.dark .ai-chat-message.assistant .ai-chat-message-content{color:#fff}.chat-fullpage .ai-chat-message.tool{margin:0;padding:0;width:100%}.chat-fullpage .ai-chat-welcome{align-items:center;display:flex;flex-direction:column;gap:24px;justify-content:center;min-height:60vh;padding:24px;text-align:center}.chat-fullpage .ai-chat-welcome-title{font-size:32px;font-weight:600}.chat-fullpage .ai-chat-welcome-text{color:var(--text-muted,#71717a);font-size:18px;max-width:400px}.chat-fullpage .ai-chat-input-container{background:transparent;bottom:0;left:0;padding:16px 16px calc(16px + env(safe-area-inset-bottom));position:fixed;right:0;z-index:20}.chat-fullpage .ai-chat-input-container:after{background:var(--bg-primary,#fff);bottom:0;content:\"\";height:calc(40% + 16px);left:0;pointer-events:none;position:absolute;right:0;z-index:-1}.chat-fullpage.dark .ai-chat-input-container:after{background:var(--bg-primary,#18181b)}@media (min-width:769px){.chat-fullpage .ai-chat-input-container{background:transparent;bottom:var(--fp-input-bottom);left:50%;max-width:var(--fp-max-width);padding:0;position:absolute;right:auto;transform:translateX(-50%);width:100%}}.chat-fullpage .ai-chat-input-wrapper{background:var(--bg-muted,#f4f4f5);border:1px solid var(--border-muted,#e4e4e7);border-radius:24px;box-shadow:0 1px 8px rgba(0,0,0,.06);margin:0 auto;max-width:var(--fp-max-width)}.chat-fullpage.dark .ai-chat-input-wrapper{background:var(--bg-muted,#27272a);border-color:var(--border-muted,#3f3f46);box-shadow:0 1px 12px rgba(0,0,0,.25)}.chat-fullpage .ai-chat-scroll-button{bottom:100px}@media (min-width:769px){.chat-fullpage .ai-chat-scroll-button{bottom:90px}}.chat-fullpage .ai-chat-suggested-questions{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;max-width:600px}.chat-fullpage .ai-chat-suggested-question{border-radius:9999px;font-size:14px;padding:8px 16px}.chat-fullpage .ai-chat-follow-up-suggestions{margin-top:12px}.chat-fullpage .ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-default,#d4d4d8);color:#000}.chat-fullpage .ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#f4f4f5)}.chat-fullpage.dark .ai-chat-follow-up-item.question-type{background:transparent;border:1px solid var(--border-subtle,#52525b);color:#fff}.chat-fullpage.dark .ai-chat-follow-up-item.question-type:hover{background:var(--bg-hover,#3f3f46)}.chat-fullpage .ai-chat-typing{padding:8px 16px}@media (max-width:480px){body.ai-chat-widget-open{height:100%!important;overflow:hidden!important;position:fixed!important;touch-action:none!important;width:100%!important}.ai-chat-widget-container.is-open{height:100vh!important;height:100dvh!important;width:100vw!important;z-index:var(--widget-z-index,2147483647)!important}.ai-chat-widget-container.is-open,.ai-chat-widget-container.is-open .ai-chat-window{bottom:0!important;left:0!important;position:fixed!important;right:0!important;top:0!important}.ai-chat-widget-container.is-open .ai-chat-window{animation:none!important;border:none!important;border-radius:0!important;box-shadow:none!important;height:100%!important;max-height:100%!important;max-width:100%!important;outline:none!important;transform:none!important;width:100%!important}.ai-chat-widget-container.is-open .ai-chat-button{display:none!important;pointer-events:none!important;visibility:hidden!important}.ai-chat-widget-container.is-open .ai-chat-header{border-radius:0!important;flex-shrink:0;padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right));padding-top:max(12px,env(safe-area-inset-top));position:relative;z-index:100}.ai-chat-widget-container.is-open .ai-chat-messages{-webkit-overflow-scrolling:touch;flex:1;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;padding-bottom:120px;padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right));touch-action:pan-y}.ai-chat-widget-container.is-open .ai-chat-input-container{background:var(--bg-primary,#fff);bottom:0!important;left:0!important;padding:8px max(12px,env(safe-area-inset-right)) max(16px,calc(env(safe-area-inset-bottom) + 8px)) max(12px,env(safe-area-inset-left));position:fixed!important;right:0!important;z-index:100}.ai-chat-widget.dark .ai-chat-widget-container.is-open .ai-chat-input-container{background:var(--bg-primary,#282625)}.ai-chat-widget-container.is-open .ai-chat-input-container:after{display:none}.ai-chat-widget-container.is-open .ai-chat-input-wrapper{margin:0;max-width:100%}.ai-chat-widget-container.is-open .ai-chat-scroll-button{bottom:calc(80px + env(safe-area-inset-bottom))}.ai-chat-widget-container.is-open .ai-chat-welcome{padding:16px 0}.ai-chat-widget-container.is-open .ai-chat-welcome-title{font-size:24px}.ai-chat-widget-container.is-open .ai-chat-suggested-questions{align-items:stretch;flex-direction:column}.ai-chat-widget-container.is-open .ai-chat-suggested-question{text-align:center;width:100%}}@media (min-width:481px) and (max-width:768px){.ai-chat-widget-container.is-open .ai-chat-window{border-radius:22px 22px 44px 44px;max-height:calc(100vh - 100px);max-width:calc(100vw - 32px)}}";
47095
+ styleInject(css_248z$1);
47096
+
47097
+ var css_248z = ".ai-chat-data-policy-view{display:flex;flex:1;flex-direction:column;min-height:0;overflow:hidden}.ai-chat-data-policy-content{-webkit-overflow-scrolling:touch;flex:1;overflow-y:auto;padding:20px 16px 40px}.ai-chat-data-policy-intro{align-items:center;background:var(--bg-subtle,rgba(0,0,0,.02));border-radius:12px;display:flex;flex-direction:column;margin-bottom:20px;padding:16px;text-align:center}.ai-chat-widget.dark .ai-chat-data-policy-intro{background:var(--bg-subtle,hsla(0,0%,100%,.04))}.ai-chat-data-policy-icon{align-items:center;background:var(--primary-color,#07f);border-radius:12px;color:#fff;display:flex;height:48px;justify-content:center;margin-bottom:12px;width:48px}.ai-chat-data-policy-intro p{color:var(--text-secondary,#52525b);font-size:13px;line-height:1.5;margin:0}.ai-chat-widget.dark .ai-chat-data-policy-intro p{color:var(--text-secondary,#a1a1aa)}.ai-chat-data-policy-intro strong{color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-data-policy-intro strong{color:var(--text-primary,#fafafa)}.ai-chat-data-policy-section{margin-bottom:20px}.ai-chat-data-policy-section h3{color:var(--text-primary,#18181b);font-size:13px;font-weight:600;letter-spacing:.02em;margin:0 0 8px;text-transform:uppercase}.ai-chat-widget.dark .ai-chat-data-policy-section h3{color:var(--text-primary,#fafafa)}.ai-chat-data-policy-section ul{list-style:none;margin:0;padding:0}.ai-chat-data-policy-section li{color:var(--text-secondary,#52525b);font-size:12px;line-height:1.5;padding:8px 0 8px 16px;position:relative}.ai-chat-widget.dark .ai-chat-data-policy-section li{color:var(--text-secondary,#a1a1aa)}.ai-chat-data-policy-section li:before{background:var(--text-muted,#a1a1aa);border-radius:50%;content:\"\";height:4px;left:0;position:absolute;top:14px;width:4px}.ai-chat-data-policy-section li strong{color:var(--text-primary,#18181b)}.ai-chat-widget.dark .ai-chat-data-policy-section li strong{color:var(--text-primary,#fafafa)}.ai-chat-data-policy-section p{color:var(--text-secondary,#52525b);font-size:12px;line-height:1.5;margin:0}.ai-chat-widget.dark .ai-chat-data-policy-section p{color:var(--text-secondary,#a1a1aa)}.ai-chat-data-policy-warning{background:rgba(234,179,8,.1);border:1px solid rgba(234,179,8,.3);border-radius:8px;color:#92400e!important;padding:12px}.ai-chat-widget.dark .ai-chat-data-policy-warning{background:rgba(234,179,8,.15);border-color:rgba(234,179,8,.25);color:#fbbf24!important}";
45931
47098
  styleInject(css_248z);
45932
47099
 
45933
47100
  // Icon components mapping
@@ -45935,9 +47102,10 @@
45935
47102
  FiMessageCircle: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("path", { d: "M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" }) })),
45936
47103
  FiChevronDown: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polyline", { points: "6 9 12 15 18 9" }) })),
45937
47104
  };
45938
- const ChatWidget = ({ widgetId, apiUrl = window.location.origin, previewMode = false, previewConfig, position = 'bottom-right', primaryColor, size, headerTitle, welcomeTitle, welcomeMessage, placeholder, theme, suggestedQuestions, customStyles, currentRoute, defaultOpen = false, zIndex, onOpen, onClose, onMessage, onError, mode = 'bubble', }) => {
47105
+ const ChatWidget = ({ widgetId, apiUrl = window.location.origin, previewMode = false, previewConfig, position = 'bottom-right', primaryColor, size, headerTitle, welcomeTitle, welcomeMessage, placeholder, welcomeBubbleText, theme, suggestedQuestions, customStyles, currentRoute, defaultOpen = false, zIndex, containerMode = false, onOpen, onClose, onMessage, onError, mode = 'bubble', }) => {
45939
47106
  const [isOpen, setIsOpen] = reactExports.useState(defaultOpen);
45940
47107
  const [autoDetectedTheme, setAutoDetectedTheme] = reactExports.useState('light');
47108
+ const [showWelcomeBubble, setShowWelcomeBubble] = reactExports.useState(false);
45941
47109
  const widgetRef = reactExports.useRef(null);
45942
47110
  const containerRef = reactExports.useRef(null);
45943
47111
  // Determine mode
@@ -45959,10 +47127,9 @@
45959
47127
  showChatHistory: true,
45960
47128
  showTimestamps: true,
45961
47129
  showTypingIndicator: true,
47130
+ showToolCalls: false,
45962
47131
  enableFileUpload: false,
45963
47132
  enableFeedback: true,
45964
- showSources: false,
45965
- sourceDisplayMode: 'none',
45966
47133
  },
45967
47134
  behavior: {
45968
47135
  agentic: false,
@@ -45999,7 +47166,6 @@
45999
47166
  const messages = previewMode ? [] : chatHook.messages;
46000
47167
  const isLoading = previewMode ? false : chatHook.isLoading;
46001
47168
  const isTyping = previewMode ? false : chatHook.isTyping;
46002
- const error = previewMode ? null : chatHook.error;
46003
47169
  const config = previewMode ? mergedPreviewConfig : chatHook.config;
46004
47170
  const sendMessage = previewMode ? (() => Promise.resolve()) : chatHook.sendMessage;
46005
47171
  const submitFeedback = previewMode ? (() => Promise.resolve()) : chatHook.submitFeedback;
@@ -46034,8 +47200,13 @@
46034
47200
  mediaQuery.removeEventListener('change', handleMediaChange);
46035
47201
  };
46036
47202
  }, [config]);
46037
- // Handle auto-open (only for bubble mode)
47203
+ // Check if device is mobile
47204
+ const isMobile = typeof window !== 'undefined' && window.innerWidth <= 480;
47205
+ // Handle auto-open (only for bubble mode, disabled on mobile)
46038
47206
  reactExports.useEffect(() => {
47207
+ // Never auto-open on mobile devices
47208
+ if (isMobile)
47209
+ return undefined;
46039
47210
  if (!isEmbedded && config?.settings.autoOpen) {
46040
47211
  const delay = config.settings.autoOpenDelay || 0;
46041
47212
  const timer = setTimeout(() => {
@@ -46045,7 +47216,7 @@
46045
47216
  return () => clearTimeout(timer);
46046
47217
  }
46047
47218
  return undefined;
46048
- }, [config, onOpen, isEmbedded]);
47219
+ }, [config, onOpen, isEmbedded, isMobile]);
46049
47220
  // Handle close on Escape key (only for bubble mode)
46050
47221
  reactExports.useEffect(() => {
46051
47222
  if (!isOpen || isEmbedded)
@@ -46059,6 +47230,37 @@
46059
47230
  document.addEventListener('keydown', handleEscapeKey);
46060
47231
  return () => document.removeEventListener('keydown', handleEscapeKey);
46061
47232
  }, [isOpen, onClose, isEmbedded]);
47233
+ // Handle body scroll lock on mobile when widget is open
47234
+ reactExports.useEffect(() => {
47235
+ if (!isOpen || isEmbedded)
47236
+ return;
47237
+ // Only apply scroll lock on mobile
47238
+ const checkMobile = window.innerWidth <= 480;
47239
+ if (!checkMobile)
47240
+ return;
47241
+ // Add class to body to lock scrolling
47242
+ document.body.classList.add('ai-chat-widget-open');
47243
+ return () => {
47244
+ document.body.classList.remove('ai-chat-widget-open');
47245
+ };
47246
+ }, [isOpen, isEmbedded]);
47247
+ // Handle welcome bubble visibility per session
47248
+ // Shows on each new session if welcomeBubbleText is configured
47249
+ reactExports.useEffect(() => {
47250
+ if (isEmbedded || previewMode)
47251
+ return;
47252
+ const bubbleText = welcomeBubbleText ?? config?.appearance?.welcomeBubbleText;
47253
+ if (!bubbleText) {
47254
+ setShowWelcomeBubble(false);
47255
+ return;
47256
+ }
47257
+ // Check if bubble was already dismissed this session
47258
+ const storageKey = `ai-chat-bubble-dismissed-${widgetId || 'default'}`;
47259
+ const wasDismissed = sessionStorage.getItem(storageKey) === 'true';
47260
+ if (!wasDismissed && !isOpen) {
47261
+ setShowWelcomeBubble(true);
47262
+ }
47263
+ }, [widgetId, welcomeBubbleText, config, isOpen, isEmbedded, previewMode]);
46062
47264
  // Determine theme - use prop override if provided, otherwise auto-detect
46063
47265
  const appearanceConfig = config?.appearance;
46064
47266
  const effectiveTheme = theme ?? autoDetectedTheme;
@@ -46072,6 +47274,7 @@
46072
47274
  const effectiveWelcomeTitle = welcomeTitle ?? appearanceConfig?.welcomeTitle ?? '';
46073
47275
  const effectiveWelcomeMessage = welcomeMessage ?? appearanceConfig?.welcomeMessage ?? '';
46074
47276
  const effectivePlaceholder = placeholder ?? appearanceConfig?.placeholder ?? '';
47277
+ const effectiveWelcomeBubbleText = welcomeBubbleText ?? appearanceConfig?.welcomeBubbleText ?? '';
46075
47278
  // Generate styles using simplified theme system
46076
47279
  const simpleAppearance = {
46077
47280
  accentColor};
@@ -46093,6 +47296,18 @@
46093
47296
  return;
46094
47297
  const newState = !isOpen;
46095
47298
  setIsOpen(newState);
47299
+ // Dismiss welcome bubble when chat is opened
47300
+ if (newState && showWelcomeBubble) {
47301
+ setShowWelcomeBubble(false);
47302
+ // Store in sessionStorage so it doesn't show again this session
47303
+ const storageKey = `ai-chat-bubble-dismissed-${widgetId || 'default'}`;
47304
+ try {
47305
+ sessionStorage.setItem(storageKey, 'true');
47306
+ }
47307
+ catch {
47308
+ // Ignore storage errors
47309
+ }
47310
+ }
46096
47311
  if (newState) {
46097
47312
  onOpen?.();
46098
47313
  }
@@ -46123,13 +47338,13 @@
46123
47338
  const IconComponent = isOpen ? iconComponents.FiChevronDown : iconComponents.FiMessageCircle;
46124
47339
  // Embedded mode renders directly without wrapper positioning
46125
47340
  if (isEmbedded) {
46126
- return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ai-chat-widget-embedded ${effectiveTheme}`, style: { ...mergedStyles, width: '100%', height: '100%' }, children: jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: () => { }, onFeedback: handleFeedback, onActionClick: handleActionClick, conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, onDeleteConversation: deleteConversation, currentConversationId: conversationId, headerTitleOverride: effectiveHeaderTitle, welcomeTitleOverride: effectiveWelcomeTitle, welcomeMessageOverride: effectiveWelcomeMessage, placeholderOverride: effectivePlaceholder, suggestedQuestionsOverride: suggestedQuestions }) }));
47341
+ return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ai-chat-widget-embedded ${effectiveTheme}`, style: { ...mergedStyles, width: '100%', height: '100%' }, children: jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, config: config, onSendMessage: sendMessage, onClose: () => { }, onFeedback: handleFeedback, onActionClick: handleActionClick, conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, onDeleteConversation: deleteConversation, currentConversationId: conversationId, headerTitleOverride: effectiveHeaderTitle, welcomeTitleOverride: effectiveWelcomeTitle, welcomeMessageOverride: effectiveWelcomeMessage, placeholderOverride: effectivePlaceholder, suggestedQuestionsOverride: suggestedQuestions }) }));
46127
47342
  }
46128
- return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style: mergedStyles, children: jsxRuntimeExports.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition} ${isOpen ? 'is-open' : ''}`, children: [isOpen && (jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback, onActionClick: handleActionClick,
47343
+ return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style: mergedStyles, children: jsxRuntimeExports.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition} ${isOpen ? 'is-open' : ''} ${containerMode ? 'container-mode' : ''}`, children: [isOpen && (jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback, onActionClick: handleActionClick,
46129
47344
  // Chat history props (only active when persistConversation is true)
46130
47345
  conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, onDeleteConversation: deleteConversation, currentConversationId: conversationId,
46131
47346
  // Override props for live preview
46132
- headerTitleOverride: effectiveHeaderTitle, welcomeTitleOverride: effectiveWelcomeTitle, welcomeMessageOverride: effectiveWelcomeMessage, placeholderOverride: effectivePlaceholder, suggestedQuestionsOverride: suggestedQuestions })), jsxRuntimeExports.jsx("button", { className: `ai-chat-button ${isOpen ? 'is-open' : ''}`, onClick: handleToggle, "aria-label": isOpen ? "Minimize chat" : "Open chat", children: jsxRuntimeExports.jsx("div", { className: "ai-chat-button-svg", children: jsxRuntimeExports.jsx(IconComponent, {}) }) })] }) }));
47347
+ headerTitleOverride: effectiveHeaderTitle, welcomeTitleOverride: effectiveWelcomeTitle, welcomeMessageOverride: effectiveWelcomeMessage, placeholderOverride: effectivePlaceholder, suggestedQuestionsOverride: suggestedQuestions })), !isOpen && effectiveWelcomeBubbleText && (previewMode || showWelcomeBubble) && (jsxRuntimeExports.jsx("div", { className: "ai-chat-welcome-bubble", onClick: handleToggle, children: jsxRuntimeExports.jsx("span", { children: effectiveWelcomeBubbleText }) })), jsxRuntimeExports.jsx("button", { className: `ai-chat-button ${isOpen ? 'is-open' : ''}`, onClick: handleToggle, "aria-label": isOpen ? "Minimize chat" : "Open chat", children: jsxRuntimeExports.jsx("div", { className: "ai-chat-button-svg", children: jsxRuntimeExports.jsx(IconComponent, {}) }) })] }) }));
46133
47348
  };
46134
47349
 
46135
47350
  /**