@chatwidgetai/chat-widget 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -195,6 +195,124 @@ class WidgetApiClient {
195
195
  throw error;
196
196
  }
197
197
  }
198
+ /**
199
+ * Stream chat message responses
200
+ */
201
+ async *sendMessageStream(conversationId, message, fileIds) {
202
+ const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/chat`, {
203
+ method: 'POST',
204
+ headers: {
205
+ 'Content-Type': 'application/json',
206
+ },
207
+ body: JSON.stringify({
208
+ conversationId: conversationId,
209
+ message,
210
+ fileIds,
211
+ timeZone: this.getTimeZone(),
212
+ }),
213
+ });
214
+ if (!response.ok) {
215
+ throw await buildApiError(response, 'Failed to send message');
216
+ }
217
+ if (!response.body) {
218
+ throw new Error('Response body is null');
219
+ }
220
+ const reader = response.body.getReader();
221
+ const decoder = new TextDecoder();
222
+ let buffer = '';
223
+ try {
224
+ while (true) {
225
+ const { done, value } = await reader.read();
226
+ if (done)
227
+ break;
228
+ buffer += decoder.decode(value, { stream: true });
229
+ const lines = buffer.split('\n');
230
+ buffer = lines.pop() || '';
231
+ for (const line of lines) {
232
+ if (line.startsWith('data: ')) {
233
+ try {
234
+ const data = JSON.parse(line.slice(6));
235
+ // Handle error events
236
+ if (data.type === 'error') {
237
+ throw new Error(data.error || 'Stream error');
238
+ }
239
+ // Yield ConversationMessage objects
240
+ if (data.id) {
241
+ yield data;
242
+ }
243
+ }
244
+ catch (e) {
245
+ console.error('[Widget API Client] Failed to parse SSE data:', line, e);
246
+ throw e;
247
+ }
248
+ }
249
+ }
250
+ }
251
+ }
252
+ finally {
253
+ reader.releaseLock();
254
+ }
255
+ }
256
+ /**
257
+ * Stream agent message responses with tool execution
258
+ * Handles streaming events from backend and yields ConversationMessage updates
259
+ */
260
+ async *sendAgentMessageStream(conversationId, message, fileIds) {
261
+ const response = await fetch(`${this.config.apiUrl}/api/widget/${this.config.widgetId}/agent`, {
262
+ method: 'POST',
263
+ headers: {
264
+ 'Content-Type': 'application/json',
265
+ },
266
+ body: JSON.stringify({
267
+ conversationId: conversationId,
268
+ message,
269
+ fileIds,
270
+ timeZone: this.getTimeZone(),
271
+ }),
272
+ });
273
+ if (!response.ok) {
274
+ throw await buildApiError(response, 'Failed to send agent message');
275
+ }
276
+ if (!response.body) {
277
+ throw new Error('Response body is null');
278
+ }
279
+ const reader = response.body.getReader();
280
+ const decoder = new TextDecoder();
281
+ let buffer = '';
282
+ try {
283
+ while (true) {
284
+ const { done, value } = await reader.read();
285
+ if (done)
286
+ break;
287
+ buffer += decoder.decode(value, { stream: true });
288
+ const lines = buffer.split('\n');
289
+ buffer = lines.pop() || '';
290
+ for (const line of lines) {
291
+ if (line.startsWith('data: ')) {
292
+ try {
293
+ const data = JSON.parse(line.slice(6));
294
+ // Handle error events
295
+ if (data.type === 'error') {
296
+ throw new Error(data.error || 'Stream error');
297
+ }
298
+ // Yield ConversationMessage objects that come from the backend
299
+ // The backend yields full ConversationMessage objects during streaming
300
+ if (data.id) {
301
+ yield data;
302
+ }
303
+ }
304
+ catch (e) {
305
+ console.error('[Widget API Client] Failed to parse SSE data:', line, e);
306
+ throw e;
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
312
+ finally {
313
+ reader.releaseLock();
314
+ }
315
+ }
198
316
  /**
199
317
  * Submit feedback for a message
200
318
  */
@@ -542,7 +660,7 @@ function useChat(options) {
542
660
  console.log('[useChat] Config fetched successfully:', {
543
661
  hasAppearance: !!config.appearance,
544
662
  });
545
- const persistConversation = config.behavior.persistConversation ?? true;
663
+ const persistConversation = config.settings.persistConversation ?? true;
546
664
  let conversationId = '';
547
665
  let messages = [];
548
666
  if (persistConversation && isStorageAvailable()) {
@@ -590,14 +708,14 @@ function useChat(options) {
590
708
  }, [widgetId, apiUrl, onError]);
591
709
  // Save conversation when messages change
592
710
  react.useEffect(() => {
593
- const persistConversation = state.config?.behavior.persistConversation ?? true;
711
+ const persistConversation = state.config?.settings.persistConversation ?? true;
594
712
  if (persistConversation &&
595
713
  isStorageAvailable() &&
596
714
  state.messages.length > 0 &&
597
715
  state.conversationId) {
598
716
  saveConversation(widgetId, state.conversationId, state.messages);
599
717
  }
600
- }, [widgetId, state.messages, state.conversationId, state.config?.behavior.persistConversation]);
718
+ }, [widgetId, state.messages, state.conversationId, state.config?.settings.persistConversation]);
601
719
  /**
602
720
  * Send a message
603
721
  */
@@ -619,8 +737,8 @@ function useChat(options) {
619
737
  setState(prev => ({
620
738
  ...prev,
621
739
  messages: [...prev.messages, userMessage],
622
- isLoading: true,
623
- isTyping: true,
740
+ isLoading: false, // Don't show loading, will show typing when stream starts
741
+ isTyping: true, // Show typing indicator immediately
624
742
  error: null,
625
743
  }));
626
744
  onMessage?.(userMessage);
@@ -666,71 +784,56 @@ function useChat(options) {
666
784
  }
667
785
  // Determine if widget has actions (use agent endpoint)
668
786
  const useAgent = state.config?.behavior.agentic || (state.config?.actions && state.config.actions.length > 0);
669
- let response;
670
- if (useAgent) {
671
- // Use agent endpoint - returns ConversationMessage[]
672
- response = await apiClient.current.sendAgentMessage(conversationId, trimmedContent, fileIds);
673
- }
674
- else {
675
- // Use standard chat endpoint
676
- response = await apiClient.current.sendMessage(conversationId, trimmedContent, fileIds);
677
- }
678
- // Both endpoints now return ConversationMessage[] array (FULL conversation)
679
- if (Array.isArray(response)) {
680
- // Response is already ConversationMessage[]
681
- const allMessages = response;
682
- // Find new messages (those not in current state)
683
- const existingIds = new Set(state.messages.map(m => m.id));
684
- const newMessages = allMessages.filter(msg => !existingIds.has(msg.id));
685
- setState(prev => ({
686
- ...prev,
687
- messages: allMessages, // Replace with full conversation
688
- isLoading: false,
689
- isTyping: false,
690
- }));
691
- // Only notify about new messages
692
- newMessages.forEach(msg => onMessage?.(msg));
693
- }
694
- else if (response.type === 'error') {
695
- // Error response from agent
696
- const errorContent = response.message || response.error || 'An error occurred';
697
- const errorMessage = {
698
- id: response.message_id || generateMessageId(),
699
- message: {
700
- type: 'ai',
701
- content: `⚠️ ${errorContent}`,
702
- },
703
- timestamp: response.timestamp || new Date().toISOString(),
704
- sources: [],
705
- };
706
- setState(prev => ({
707
- ...prev,
708
- messages: [...prev.messages, errorMessage],
709
- isLoading: false,
710
- isTyping: false,
711
- error: errorContent,
712
- }));
713
- onMessage?.(errorMessage);
787
+ // Stream the response
788
+ let lastStreamedMessage = null;
789
+ const stream = useAgent
790
+ ? apiClient.current.sendAgentMessageStream(conversationId, trimmedContent, fileIds)
791
+ : apiClient.current.sendMessageStream(conversationId, trimmedContent, fileIds);
792
+ for await (const message of stream) {
793
+ lastStreamedMessage = message;
794
+ // Update state with streamed message
795
+ setState(prev => {
796
+ const existingIndex = prev.messages.findIndex(m => m.id === message.id);
797
+ if (existingIndex >= 0) {
798
+ // Update existing streaming message
799
+ const newMessages = [...prev.messages];
800
+ newMessages[existingIndex] = message;
801
+ // Show typing indicator if:
802
+ // 1. Message is streaming AND has no content (waiting for first token or after tool call)
803
+ // 2. Message is a tool execution (shows loading spinner on the tool)
804
+ const isAIMessage = message.message.type === 'ai';
805
+ const hasContent = isAIMessage && message.message.content.trim().length > 0;
806
+ const isToolExecuting = message.toolExecuting !== undefined;
807
+ return {
808
+ ...prev,
809
+ messages: newMessages,
810
+ isTyping: (message.isStreaming && !hasContent && isAIMessage) || isToolExecuting,
811
+ isLoading: false,
812
+ };
813
+ }
814
+ else {
815
+ // Add new streaming message
816
+ const isAIMessage = message.message.type === 'ai';
817
+ const hasContent = isAIMessage && message.message.content.trim().length > 0;
818
+ const isToolExecuting = message.toolExecuting !== undefined;
819
+ return {
820
+ ...prev,
821
+ messages: [...prev.messages, message],
822
+ isTyping: (message.isStreaming && !hasContent && isAIMessage) || isToolExecuting,
823
+ isLoading: false,
824
+ };
825
+ }
826
+ });
714
827
  }
715
- else {
716
- // Standard message response (type: 'message' or undefined)
717
- const messageContent = response.content || response.message || '';
718
- const assistantMessage = {
719
- id: response.message_id || response.messageId || generateMessageId(),
720
- message: {
721
- type: 'ai',
722
- content: messageContent,
723
- },
724
- timestamp: response.timestamp || new Date().toISOString(),
725
- sources: response.sources || [],
726
- };
727
- setState(prev => ({
728
- ...prev,
729
- messages: [...prev.messages, assistantMessage],
730
- isLoading: false,
731
- isTyping: false,
732
- }));
733
- onMessage?.(assistantMessage);
828
+ // Stream completed - finalize state
829
+ setState(prev => ({
830
+ ...prev,
831
+ isLoading: false,
832
+ isTyping: false,
833
+ }));
834
+ // Notify about final message
835
+ if (lastStreamedMessage) {
836
+ onMessage?.(lastStreamedMessage);
734
837
  }
735
838
  }
736
839
  catch (error) {
@@ -788,11 +891,11 @@ function useChat(options) {
788
891
  conversationId: '',
789
892
  error: null,
790
893
  }));
791
- const persistConversation = state.config?.behavior.persistConversation ?? true;
894
+ const persistConversation = state.config?.settings.persistConversation ?? true;
792
895
  if (persistConversation && isStorageAvailable()) {
793
896
  clearConversation(widgetId);
794
897
  }
795
- }, [widgetId, state.config?.behavior.persistConversation]);
898
+ }, [widgetId, state.config?.settings.persistConversation]);
796
899
  /**
797
900
  * Submit feedback for a message
798
901
  */
@@ -819,7 +922,7 @@ function useChat(options) {
819
922
  * Load conversation history list from localStorage
820
923
  */
821
924
  const loadConversations = react.useCallback(() => {
822
- const persistConversation = state.config?.behavior.persistConversation ?? true;
925
+ const persistConversation = state.config?.settings.persistConversation ?? true;
823
926
  if (!persistConversation || !isStorageAvailable()) {
824
927
  setConversations([]);
825
928
  return;
@@ -832,12 +935,12 @@ function useChat(options) {
832
935
  messageCount: entry.messageCount,
833
936
  startedAt: entry.lastUpdated,
834
937
  })));
835
- }, [widgetId, state.config?.behavior.persistConversation]);
938
+ }, [widgetId, state.config?.settings.persistConversation]);
836
939
  /**
837
940
  * Switch to a different conversation (from localStorage first, then fetch from server if needed)
838
941
  */
839
942
  const switchConversation = react.useCallback(async (conversationId) => {
840
- const persistConversation = state.config?.behavior.persistConversation ?? true;
943
+ const persistConversation = state.config?.settings.persistConversation ?? true;
841
944
  // First try to load from localStorage
842
945
  if (persistConversation && isStorageAvailable()) {
843
946
  const stored = loadConversationById(widgetId, conversationId);
@@ -870,7 +973,7 @@ function useChat(options) {
870
973
  const errorInfo = deriveErrorInfo(error);
871
974
  setState(prev => ({ ...prev, isLoading: false, error: errorInfo.message }));
872
975
  }
873
- }, [widgetId, state.config?.behavior.persistConversation]);
976
+ }, [widgetId, state.config?.settings.persistConversation]);
874
977
  /**
875
978
  * Start a new conversation (keeps history)
876
979
  */
@@ -882,11 +985,11 @@ function useChat(options) {
882
985
  error: null,
883
986
  }));
884
987
  // Clear active conversation but keep history
885
- const persistConversation = state.config?.behavior.persistConversation ?? true;
988
+ const persistConversation = state.config?.settings.persistConversation ?? true;
886
989
  if (persistConversation && isStorageAvailable()) {
887
990
  clearConversation(widgetId);
888
991
  }
889
- }, [widgetId, state.config?.behavior.persistConversation]);
992
+ }, [widgetId, state.config?.settings.persistConversation]);
890
993
  return {
891
994
  messages: state.messages,
892
995
  isLoading: state.isLoading,
@@ -21594,7 +21697,7 @@ const Sources = ({ sources, displayMode = 'with-score' }) => {
21594
21697
  return (jsxRuntime.jsxs("div", { className: "ai-chat-sources", children: [jsxRuntime.jsxs("button", { className: "ai-chat-sources-toggle", onClick: () => setIsExpanded(!isExpanded), "aria-expanded": isExpanded, children: [jsxRuntime.jsx("span", { className: "ai-chat-sources-icon", children: isExpanded ? '▼' : '▶' }), jsxRuntime.jsxs("span", { className: "ai-chat-sources-title", children: [sources.length, " source", sources.length > 1 ? 's' : ''] })] }), isExpanded && displayMode !== 'minimal' && (jsxRuntime.jsx("div", { className: "ai-chat-sources-list", children: sources.map((source, index) => (jsxRuntime.jsxs("div", { className: "ai-chat-source-item", children: [jsxRuntime.jsxs("div", { className: "ai-chat-source-number", children: [index + 1, "."] }), jsxRuntime.jsxs("div", { className: "ai-chat-source-details", children: [displayMode === 'with-score' && source.score && (jsxRuntime.jsxs("div", { className: "ai-chat-source-score", children: ["Score: ", (source.score * 100).toFixed(0), "%"] })), (displayMode === 'with-content' || displayMode === 'full') && source.doc.pageContent && (jsxRuntime.jsxs("div", { className: "ai-chat-source-content", children: [source.doc.pageContent.substring(0, 100), source.doc.pageContent.length > 100 ? '...' : ''] })), displayMode === 'full' && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [source.score && (jsxRuntime.jsxs("div", { className: "ai-chat-source-score", children: ["Score: ", (source.score * 100).toFixed(0), "%"] })), source.doc.metadata && Object.keys(source.doc.metadata).length > 0 && (jsxRuntime.jsx("div", { className: "ai-chat-source-metadata", children: Object.entries(source.doc.metadata).map(([key, value]) => (jsxRuntime.jsxs("span", { className: "ai-chat-source-meta-item", children: [key, ": ", String(value)] }, key))) }))] }))] })] }, `${source.kbId}-${source.doc.id}-${index}`))) }))] }));
21595
21698
  };
21596
21699
 
21597
- const Message = ({ message, showTimestamp = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', onFeedback, toolCallNameById, }) => {
21700
+ const Message = ({ message, showTimestamp = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', onFeedback, }) => {
21598
21701
  const formatTime = (timestamp) => {
21599
21702
  const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
21600
21703
  return date.toLocaleTimeString('en-US', {
@@ -21603,72 +21706,84 @@ const Message = ({ message, showTimestamp = true, enableFeedback = true, showSou
21603
21706
  hour12: true,
21604
21707
  });
21605
21708
  };
21606
- // Map message type to CSS class
21607
- const messageClass = message.message.type === 'human' ? 'user' :
21608
- message.message.type === 'ai' ? 'assistant' :
21609
- message.message.type === 'system' ? 'system' : 'tool';
21610
- const isAssistant = message.message.type === 'ai';
21611
- const isSystem = message.message.type === 'system';
21612
- const isTool = message.message.type === 'tool';
21613
- const isHuman = message.message.type === 'human';
21614
- const userMessage = isHuman ? message.message.content.split('--- File Content ---')[0] : '';
21615
- const aiContent = isAssistant ? (message.message.content || '') : '';
21616
- const aiHasContent = isAssistant ? aiContent.trim().length > 0 : false;
21617
- const renderAssistant = () => {
21618
- // Only render assistant bubble if there's textual content
21619
- return jsxRuntime.jsx(Markdown, { children: aiContent });
21620
- };
21621
21709
  const formatToolName = (name) => {
21622
- // Remove common prefixes like "action_" or "tool_"
21623
- let formatted = name.replace(/^(action_|tool_)/, '');
21624
- // Convert snake_case to Title Case
21625
- formatted = formatted
21710
+ return name
21711
+ .replace(/^(action_|tool_)/, '')
21626
21712
  .split('_')
21627
21713
  .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
21628
21714
  .join(' ');
21629
- return formatted;
21630
- };
21631
- const renderTool = () => {
21632
- const tool = message.message;
21633
- const rawToolName = (toolCallNameById && toolCallNameById[tool.tool_call_id]) || 'Tool';
21634
- const displayName = formatToolName(rawToolName);
21635
- return (jsxRuntime.jsxs("div", { className: "ai-chat-tool-message", title: rawToolName, children: [jsxRuntime.jsx("span", { className: "tool-finished", children: jsxRuntime.jsx("span", { className: "tool-check", children: "\u2713" }) }), jsxRuntime.jsx("span", { className: "tool-name", children: displayName })] }));
21636
21715
  };
21637
- // If assistant message has no content (e.g., only started a tool), render nothing at all
21638
- if (isAssistant && !aiHasContent) {
21639
- return null;
21716
+ const SpinnerIcon = () => (jsxRuntime.jsx("svg", { className: "ai-chat-tool-spinner", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
21717
+ const CheckIcon = () => (jsxRuntime.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: jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
21718
+ const ErrorIcon = () => (jsxRuntime.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: jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }));
21719
+ const msgType = message.message.type;
21720
+ const isError = message.isError || false;
21721
+ const isTool = msgType === 'tool';
21722
+ const isAssistant = msgType === 'ai';
21723
+ const isSystem = msgType === 'system';
21724
+ const isHuman = msgType === 'human';
21725
+ // Tool message rendering - show as a minimal pill
21726
+ if (isTool) {
21727
+ // Get tool name from toolExecuting (during execution) or message.name (persisted)
21728
+ const toolName = message.toolExecuting || message.message.name || 'Tool';
21729
+ const hasError = isError;
21730
+ return (jsxRuntime.jsx("div", { className: "ai-chat-message tool", children: jsxRuntime.jsxs("div", { className: `ai-chat-tool-message ${hasError ? 'error' : ''}`, title: toolName, children: [message.isStreaming ? (jsxRuntime.jsx(SpinnerIcon, {})) : hasError ? (jsxRuntime.jsx(ErrorIcon, {})) : (jsxRuntime.jsx(CheckIcon, {})), jsxRuntime.jsx("span", { className: "tool-name", children: formatToolName(toolName) })] }) }));
21731
+ }
21732
+ // AI message rendering
21733
+ if (isAssistant) {
21734
+ const aiContent = message.message.content || '';
21735
+ const hasContent = aiContent.trim().length > 0;
21736
+ if (!hasContent)
21737
+ return null;
21738
+ return (jsxRuntime.jsxs("div", { className: `ai-chat-message assistant ${isError ? 'error' : ''}`, children: [jsxRuntime.jsxs("div", { className: "ai-chat-message-content", children: [isError && (jsxRuntime.jsxs("div", { className: "ai-chat-error-indicator", children: [jsxRuntime.jsx("span", { className: "error-icon", children: "\u26A0\uFE0F" }), jsxRuntime.jsx("span", { className: "error-text", children: "Error" })] })), jsxRuntime.jsx(Markdown, { children: aiContent })] }), showTimestamp && (jsxRuntime.jsxs("div", { className: "ai-chat-message-meta", children: [jsxRuntime.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }), enableFeedback && onFeedback && (jsxRuntime.jsx(FeedbackButtons, { messageId: message.id, currentFeedback: message.feedback, onFeedback: onFeedback }))] })), showSources && message.sources?.length > 0 && (jsxRuntime.jsx(Sources, { sources: message.sources, displayMode: sourceDisplayMode }))] }));
21739
+ }
21740
+ // System message rendering
21741
+ if (isSystem) {
21742
+ return (jsxRuntime.jsxs("div", { className: "ai-chat-message system", children: [jsxRuntime.jsx("div", { className: "ai-chat-message-content", children: jsxRuntime.jsxs("div", { className: "ai-chat-system-message", children: [jsxRuntime.jsx("span", { className: "system-icon", children: "\u2139\uFE0F" }), message.message.content] }) }), showTimestamp && (jsxRuntime.jsx("div", { className: "ai-chat-message-meta", children: jsxRuntime.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }) }))] }));
21640
21743
  }
21641
- const showTimestampForThis = showTimestamp && !isTool && !(isAssistant && !aiHasContent);
21642
- return (jsxRuntime.jsxs("div", { className: `ai-chat-message ${messageClass}`, children: [isTool ? (
21643
- // Render tool call completion as a standalone, non-bubble event
21644
- renderTool()) : (jsxRuntime.jsx("div", { className: "ai-chat-message-content", children: isAssistant ? (renderAssistant()) : isSystem ? (jsxRuntime.jsxs("div", { className: "ai-chat-system-message", children: [jsxRuntime.jsx("span", { className: "system-icon", children: "\u2139\uFE0F" }), message.message.content] })) : (userMessage) })), showTimestampForThis && (jsxRuntime.jsxs("div", { className: "ai-chat-message-meta", children: [jsxRuntime.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }), isAssistant && aiHasContent && enableFeedback && onFeedback && (jsxRuntime.jsx(FeedbackButtons, { messageId: message.id, currentFeedback: message.feedback, onFeedback: onFeedback }))] })), isAssistant && aiHasContent && showSources && message.sources && message.sources.length > 0 && (jsxRuntime.jsx(Sources, { sources: message.sources, displayMode: sourceDisplayMode }))] }));
21744
+ // Human message rendering
21745
+ if (isHuman) {
21746
+ const userContent = message.message.content.split('--- File Content ---')[0];
21747
+ return (jsxRuntime.jsxs("div", { className: "ai-chat-message user", children: [jsxRuntime.jsx("div", { className: "ai-chat-message-content", children: userContent }), showTimestamp && (jsxRuntime.jsx("div", { className: "ai-chat-message-meta", children: jsxRuntime.jsx("span", { className: "ai-chat-message-timestamp", children: formatTime(message.timestamp) }) }))] }));
21748
+ }
21749
+ return null;
21645
21750
  };
21646
21751
 
21647
21752
  const TypingIndicator = () => {
21648
21753
  return (jsxRuntime.jsx("div", { className: "ai-chat-message assistant", children: jsxRuntime.jsxs("div", { className: "ai-chat-typing", children: [jsxRuntime.jsx("span", { className: "ai-chat-typing-dot" }), jsxRuntime.jsx("span", { className: "ai-chat-typing-dot" }), jsxRuntime.jsx("span", { className: "ai-chat-typing-dot" })] }) }));
21649
21754
  };
21650
21755
 
21651
- const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeTitle, welcomeMessage, onFeedback, }) => {
21756
+ const SuggestedQuestions = ({ questions, onQuestionClick, }) => {
21757
+ if (!questions || questions.length === 0) {
21758
+ return null;
21759
+ }
21760
+ // Filter out empty questions
21761
+ const validQuestions = questions.filter(q => q && q.trim());
21762
+ if (validQuestions.length === 0) {
21763
+ return null;
21764
+ }
21765
+ return (jsxRuntime.jsx("div", { className: "ai-chat-suggested-questions", children: jsxRuntime.jsx("div", { className: "ai-chat-suggested-questions-list", children: validQuestions.slice(0, 5).map((question, index) => (jsxRuntime.jsx("button", { className: "ai-chat-suggested-question", onClick: () => onQuestionClick(question), type: "button", children: jsxRuntime.jsx("span", { className: "ai-chat-suggested-question-text", children: question }) }, index))) }) }));
21766
+ };
21767
+
21768
+ const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeTitle, welcomeMessage, suggestedQuestions, onSuggestedQuestionClick, onFeedback, }) => {
21769
+ const containerRef = react.useRef(null);
21652
21770
  const messagesEndRef = react.useRef(null);
21653
- // Auto-scroll to bottom when new messages arrive
21771
+ // Auto-scroll to bottom only on initial mount/load
21654
21772
  react.useEffect(() => {
21655
- messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
21656
- }, [messages, isTyping]);
21657
- // Build a map from tool_call_id -> tool name from AI messages
21658
- const toolCallNameById = react.useMemo(() => {
21659
- const map = {};
21660
- for (const m of messages) {
21661
- if (m.message.type === 'ai' && Array.isArray(m.message.tool_calls)) {
21662
- for (const tc of m.message.tool_calls) {
21663
- if (tc?.id && tc?.name) {
21664
- map[tc.id] = tc.name;
21665
- }
21666
- }
21667
- }
21773
+ const container = containerRef.current;
21774
+ if (!container)
21775
+ return;
21776
+ // Only scroll if content actually overflows AND the user is near the bottom.
21777
+ // This prevents the "first message" case from being pushed to the very bottom
21778
+ // (which looks like a huge empty gap above the first user message).
21779
+ const overflow = container.scrollHeight - container.clientHeight;
21780
+ const isOverflowing = overflow > 20;
21781
+ const nearBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 80;
21782
+ if (isOverflowing && nearBottom) {
21783
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
21668
21784
  }
21669
- return map;
21670
- }, [messages]);
21671
- return (jsxRuntime.jsxs("div", { className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [messages.length === 0 && (welcomeTitle || welcomeMessage) && (jsxRuntime.jsxs("div", { className: "ai-chat-welcome", children: [welcomeTitle && (jsxRuntime.jsx("div", { className: "ai-chat-welcome-title", children: welcomeTitle })), welcomeMessage && (jsxRuntime.jsx("div", { className: "ai-chat-welcome-text", children: welcomeMessage }))] })), messages.map((message) => (jsxRuntime.jsx(Message, { message: message, showTimestamp: showTimestamps, enableFeedback: enableFeedback, showSources: showSources, sourceDisplayMode: sourceDisplayMode, toolCallNameById: toolCallNameById, onFeedback: onFeedback }, message.id))), isTyping && showTypingIndicator && jsxRuntime.jsx(TypingIndicator, {}), jsxRuntime.jsx("div", { ref: messagesEndRef })] }));
21785
+ }, [messages, isTyping]);
21786
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [(welcomeTitle || welcomeMessage) && (jsxRuntime.jsxs("div", { className: "ai-chat-welcome", children: [welcomeTitle && (jsxRuntime.jsx("div", { className: "ai-chat-welcome-title", children: welcomeTitle })), welcomeMessage && (jsxRuntime.jsx("div", { className: "ai-chat-welcome-text", children: welcomeMessage })), messages.length === 0 && onSuggestedQuestionClick && suggestedQuestions && suggestedQuestions.length > 0 && (jsxRuntime.jsx(SuggestedQuestions, { questions: suggestedQuestions, onQuestionClick: onSuggestedQuestionClick }))] })), messages.map((message) => (jsxRuntime.jsx(Message, { message: message, showTimestamp: showTimestamps, enableFeedback: enableFeedback, showSources: showSources, sourceDisplayMode: sourceDisplayMode, onFeedback: onFeedback }, message.id))), isTyping && showTypingIndicator && jsxRuntime.jsx(TypingIndicator, {}), jsxRuntime.jsx("div", { ref: messagesEndRef })] }));
21672
21787
  };
21673
21788
 
21674
21789
  // Allowed file types
@@ -21756,49 +21871,38 @@ const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled =
21756
21871
  return (jsxRuntime.jsxs("div", { className: `ai-chat-input-container ${separateFromChat ? 'separate' : 'integrated'}`, children: [selectedFiles.length > 0 && (jsxRuntime.jsx("div", { className: "ai-chat-file-list", children: selectedFiles.map((file, index) => {
21757
21872
  const ext = getFileExtension(file.name);
21758
21873
  return (jsxRuntime.jsxs("div", { className: "ai-chat-file-item", children: [jsxRuntime.jsx("span", { className: "ai-chat-file-extension", children: ext }), jsxRuntime.jsxs("div", { className: "ai-chat-file-info", children: [jsxRuntime.jsx("span", { className: "ai-chat-file-name", children: file.name }), jsxRuntime.jsx("span", { className: "ai-chat-file-size", children: formatFileSize(file.size) })] }), jsxRuntime.jsx("button", { className: "ai-chat-file-remove", onClick: () => handleRemoveFile(index), "aria-label": "Remove file", children: jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }, index));
21759
- }) })), jsxRuntime.jsxs("div", { className: "ai-chat-input-wrapper", children: [enableFileUpload && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("input", { ref: fileInputRef, type: "file", onChange: handleFileSelect, style: { display: 'none' }, multiple: true, accept: ALLOWED_EXTENSIONS.join(','), "aria-label": "File input" }), jsxRuntime.jsx("button", { className: "ai-chat-file-button", onClick: () => fileInputRef.current?.click(), disabled: disabled, "aria-label": "Attach file", children: jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.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" }) }) })] })), jsxRuntime.jsx("textarea", { ref: textareaRef, className: "ai-chat-input", value: value, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, "aria-label": "Message input" }), jsxRuntime.jsx("button", { className: `ai-chat-send-button ${canSend ? 'active' : ''}`, onClick: handleSend, disabled: disabled || !canSend, "aria-label": "Send message", children: jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M22 2L11 13" }), jsxRuntime.jsx("path", { d: "M22 2L15 22L11 13L2 9L22 2Z" })] }) })] })] }));
21760
- };
21761
-
21762
- const ArrowIcon = () => (jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M5 12h14M12 5l7 7-7 7" }) }));
21763
- const SuggestedQuestions = ({ questions, onQuestionClick, }) => {
21764
- if (!questions || questions.length === 0) {
21765
- return null;
21766
- }
21767
- // Filter out empty questions
21768
- const validQuestions = questions.filter(q => q && q.trim());
21769
- if (validQuestions.length === 0) {
21770
- return null;
21771
- }
21772
- return (jsxRuntime.jsx("div", { className: "ai-chat-suggested-questions", children: jsxRuntime.jsx("div", { className: "ai-chat-suggested-questions-list", children: validQuestions.slice(0, 3).map((question, index) => (jsxRuntime.jsxs("button", { className: "ai-chat-suggested-question", onClick: () => onQuestionClick(question), type: "button", children: [jsxRuntime.jsx("span", { className: "ai-chat-suggested-question-text", children: question }), jsxRuntime.jsx("span", { className: "ai-chat-suggested-question-icon", children: jsxRuntime.jsx(ArrowIcon, {}) })] }, index))) }) }));
21874
+ }) })), jsxRuntime.jsxs("div", { className: "ai-chat-input-wrapper", children: [enableFileUpload && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("input", { ref: fileInputRef, type: "file", onChange: handleFileSelect, style: { display: 'none' }, multiple: true, accept: ALLOWED_EXTENSIONS.join(','), "aria-label": "File input" }), jsxRuntime.jsx("button", { className: "ai-chat-file-button", onClick: () => fileInputRef.current?.click(), disabled: disabled, "aria-label": "Attach file", children: jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.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" }) }) })] })), jsxRuntime.jsx("textarea", { ref: textareaRef, className: "ai-chat-input", value: value, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, "aria-label": "Message input" }), jsxRuntime.jsx("button", { className: `ai-chat-send-button ${canSend ? 'active' : ''}`, onClick: handleSend, disabled: disabled || !canSend, "aria-label": "Send message", children: jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M12 19V5" }), jsxRuntime.jsx("path", { d: "M5 12l7-7 7 7" })] }) })] })] }));
21773
21875
  };
21774
21876
 
21775
- const MinimizeIcon = () => (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M5 12h14" }) }));
21776
- const HistoryIcon = () => (jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }), jsxRuntime.jsx("polyline", { points: "12 6 12 12 16 14" })] }));
21777
- const NewChatIcon = () => (jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M12 5v14M5 12h14" }) }));
21778
- const BackIcon = () => (jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M19 12H5M12 19l-7-7 7-7" }) }));
21779
- const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose, onFeedback,
21877
+ const MenuIcon = () => (jsxRuntime.jsxs("svg", { width: "26", height: "26", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M4 10h16" }), jsxRuntime.jsx("path", { d: "M10 14h10" })] }));
21878
+ const PlusIcon = () => (jsxRuntime.jsxs("svg", { width: "26", height: "26", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M12 5v14" }), jsxRuntime.jsx("path", { d: "M5 12h14" })] }));
21879
+ const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose: _onClose, onFeedback,
21780
21880
  // Chat history props (only active when persistConversation is true)
21781
- conversations = [], onLoadConversations, onSwitchConversation, onStartNewConversation, currentConversationId, }) => {
21881
+ conversations = [], onLoadConversations, onSwitchConversation, onStartNewConversation, currentConversationId,
21882
+ // Override props for live preview
21883
+ headerTitleOverride, welcomeTitleOverride, welcomeMessageOverride, placeholderOverride, suggestedQuestionsOverride, }) => {
21782
21884
  console.log('[ChatWindow] Rendering ChatWindow component');
21783
21885
  const appearance = config?.appearance;
21784
- const behavior = config?.behavior;
21785
- // Use simplified appearance fields
21886
+ const settings = config?.settings;
21887
+ // Check if chat history should be shown (requires both persistConversation AND showChatHistory)
21888
+ const canShowHistory = (settings?.persistConversation ?? true) && (settings?.showChatHistory ?? true);
21889
+ // Apply overrides for live preview (overrides take priority over saved config)
21786
21890
  const size = appearance?.size || 'medium';
21787
- const headerTitle = appearance?.headerTitle || 'AI Assistant';
21788
- const welcomeMessage = appearance?.welcomeMessage || '👋 Hi there! How can I assist you today?';
21789
- const inputPlaceholder = appearance?.placeholder || 'Ask me anything...';
21891
+ const headerTitle = headerTitleOverride ?? appearance?.headerTitle ?? 'AI Assistant';
21892
+ const welcomeTitle = welcomeTitleOverride ?? appearance?.welcomeTitle ?? '';
21893
+ const welcomeMessage = welcomeMessageOverride ?? appearance?.welcomeMessage ?? '';
21894
+ const inputPlaceholder = placeholderOverride ?? appearance?.placeholder ?? 'Ask me anything...';
21790
21895
  console.log('[ChatWindow] Appearance values:', {
21791
21896
  size,
21792
21897
  headerTitle,
21898
+ welcomeTitle,
21793
21899
  welcomeMessage,
21794
21900
  inputPlaceholder,
21795
21901
  });
21796
- // Track if suggested questions should be shown
21797
- const [showSuggestedQuestions, setShowSuggestedQuestions] = react.useState(true);
21798
21902
  // Track if history panel is open
21799
21903
  const [showHistory, setShowHistory] = react.useState(false);
21800
- // Check if chat history feature is enabled (only when persistConversation is true)
21801
- const isHistoryEnabled = behavior?.persistConversation !== false && !!onLoadConversations;
21904
+ // History exit animation when starting a new chat from overview
21905
+ const [isHistoryExiting, setIsHistoryExiting] = react.useState(false);
21802
21906
  // Load conversations when history panel opens
21803
21907
  const handleOpenHistory = () => {
21804
21908
  setShowHistory(true);
@@ -21813,30 +21917,37 @@ conversations = [], onLoadConversations, onSwitchConversation, onStartNewConvers
21813
21917
  setShowHistory(false);
21814
21918
  }
21815
21919
  };
21816
- // Handle new conversation
21817
21920
  const handleNewConversation = () => {
21818
- if (onStartNewConversation) {
21819
- onStartNewConversation();
21921
+ if (!onStartNewConversation)
21922
+ return;
21923
+ onStartNewConversation();
21924
+ setShowHistory(false);
21925
+ };
21926
+ const handleSendFromOverview = (content) => {
21927
+ const trimmed = content.trim();
21928
+ if (!trimmed)
21929
+ return;
21930
+ if (!onStartNewConversation) {
21931
+ // Fallback: just go back to chat and send
21820
21932
  setShowHistory(false);
21933
+ onSendMessage(trimmed);
21934
+ return;
21821
21935
  }
21936
+ setIsHistoryExiting(true);
21937
+ window.setTimeout(() => {
21938
+ onStartNewConversation();
21939
+ setShowHistory(false);
21940
+ setIsHistoryExiting(false);
21941
+ onSendMessage(trimmed);
21942
+ }, 240);
21822
21943
  };
21823
- // Hide suggested questions after first user message
21824
- react.useEffect(() => {
21825
- const userMessages = messages.filter(m => m.message.type === 'human');
21826
- if (userMessages.length > 0) {
21827
- setShowSuggestedQuestions(false);
21828
- }
21829
- }, [messages]);
21830
21944
  // Check if message limit is reached
21831
- const maxMessages = behavior?.maxMessagesPerSession;
21945
+ const maxMessages = settings?.maxMessagesPerSession;
21832
21946
  const userMessageCount = messages.filter(m => m.message.type === 'human').length;
21833
21947
  const isLimitReached = maxMessages ? userMessageCount >= maxMessages : false;
21834
- // Handle suggested question click
21835
21948
  const handleQuestionClick = (question) => {
21836
- setShowSuggestedQuestions(false);
21837
21949
  onSendMessage(question);
21838
21950
  };
21839
- const hasMessages = messages.length > 0;
21840
21951
  // Format date for conversation list
21841
21952
  const formatDate = (dateString) => {
21842
21953
  const date = new Date(dateString);
@@ -21851,7 +21962,7 @@ conversations = [], onLoadConversations, onSwitchConversation, onStartNewConvers
21851
21962
  return `${diffDays} days ago`;
21852
21963
  return date.toLocaleDateString();
21853
21964
  };
21854
- return (jsxRuntime.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntime.jsx("div", { className: "ai-chat-header", children: showHistory ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { className: "ai-chat-header-button", onClick: () => setShowHistory(false), "aria-label": "Back to chat", children: jsxRuntime.jsx(BackIcon, {}) }), jsxRuntime.jsx("div", { className: "ai-chat-title", children: "Chat History" }), jsxRuntime.jsx("button", { className: "ai-chat-header-button", onClick: handleNewConversation, "aria-label": "New conversation", children: jsxRuntime.jsx(NewChatIcon, {}) })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntime.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntime.jsx("div", { className: "ai-chat-title", children: headerTitle })] }), jsxRuntime.jsxs("div", { className: "ai-chat-header-actions", children: [isHistoryEnabled && (jsxRuntime.jsx("button", { className: "ai-chat-header-button", onClick: handleOpenHistory, "aria-label": "Chat history", children: jsxRuntime.jsx(HistoryIcon, {}) })), jsxRuntime.jsx("button", { className: "ai-chat-close-button", onClick: onClose, "aria-label": "Minimize chat", children: jsxRuntime.jsx(MinimizeIcon, {}) })] })] })) }), showHistory ? (jsxRuntime.jsx("div", { className: "ai-chat-history-panel", children: conversations.length === 0 ? (jsxRuntime.jsx("div", { className: "ai-chat-history-empty", children: "No previous conversations" })) : (jsxRuntime.jsx("div", { className: "ai-chat-history-list", children: conversations.map((conv) => (jsxRuntime.jsxs("button", { className: `ai-chat-history-item ${conv.id === currentConversationId ? 'active' : ''}`, onClick: () => handleSelectConversation(conv.id), children: [jsxRuntime.jsx("div", { className: "ai-chat-history-item-preview", children: conv.preview }), jsxRuntime.jsxs("div", { className: "ai-chat-history-item-meta", children: [jsxRuntime.jsx("span", { children: formatDate(conv.lastMessageAt) }), jsxRuntime.jsxs("span", { children: [conv.messageCount, " messages"] })] })] }, conv.id))) })) })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [error && (jsxRuntime.jsx("div", { className: "ai-chat-error", role: "alert", children: error })), maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxRuntime.jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining"] })), isLimitReached && (jsxRuntime.jsx("div", { className: "ai-chat-error", role: "alert", children: "Message limit reached. Please start a new conversation." })), jsxRuntime.jsx(MessageList, { messages: messages, isTyping: isTyping, showTypingIndicator: behavior?.showTypingIndicator, showTimestamps: behavior?.showTimestamps, enableFeedback: behavior?.enableFeedback, showSources: behavior?.showSources, sourceDisplayMode: behavior?.sourceDisplayMode, welcomeMessage: welcomeMessage, onFeedback: onFeedback }), showSuggestedQuestions && !hasMessages && behavior?.suggestedQuestions && behavior.suggestedQuestions.length > 0 && (jsxRuntime.jsx(SuggestedQuestions, { questions: behavior.suggestedQuestions, onQuestionClick: handleQuestionClick })), jsxRuntime.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : inputPlaceholder, disabled: isLoading || isLimitReached, enableFileUpload: behavior?.enableFileUpload })] }))] }));
21965
+ return (jsxRuntime.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntime.jsx("div", { className: `ai-chat-header ${showHistory ? 'is-history' : ''}`, children: showHistory ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "ai-chat-title", children: headerTitle }), jsxRuntime.jsx("button", { className: "ai-chat-header-button", onClick: handleNewConversation, "aria-label": "New chat", children: jsxRuntime.jsx(PlusIcon, {}) })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntime.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntime.jsx("div", { className: "ai-chat-title", children: headerTitle })] }), canShowHistory && (jsxRuntime.jsx("div", { className: "ai-chat-header-actions", children: jsxRuntime.jsx("button", { className: "ai-chat-close-button", onClick: handleOpenHistory, "aria-label": "Chat overview", children: jsxRuntime.jsx(MenuIcon, {}) }) }))] })) }), showHistory ? (jsxRuntime.jsxs("div", { className: "ai-chat-history-panel", children: [conversations.length === 0 ? (jsxRuntime.jsx("div", { className: "ai-chat-history-empty", children: "No previous conversations" })) : (jsxRuntime.jsx("div", { className: `ai-chat-history-list ${isHistoryExiting ? 'exiting' : ''}`, children: conversations.map((conv) => (jsxRuntime.jsxs("button", { className: `ai-chat-history-item ${conv.id === currentConversationId ? 'active' : ''}`, onClick: () => handleSelectConversation(conv.id), children: [jsxRuntime.jsx("div", { className: "ai-chat-history-item-preview", children: conv.preview }), jsxRuntime.jsxs("div", { className: "ai-chat-history-item-meta", children: [jsxRuntime.jsx("span", { children: formatDate(conv.lastMessageAt) }), jsxRuntime.jsxs("span", { children: [conv.messageCount, " messages"] })] })] }, conv.id))) })), jsxRuntime.jsx(MessageInput, { onSend: (text) => handleSendFromOverview(text), placeholder: inputPlaceholder, disabled: isLoading, enableFileUpload: settings?.enableFileUpload })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [error && (jsxRuntime.jsx("div", { className: "ai-chat-error", role: "alert", children: error })), maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxRuntime.jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining"] })), isLimitReached && (jsxRuntime.jsx("div", { className: "ai-chat-error", role: "alert", children: "Message limit reached. Please start a new conversation." })), jsxRuntime.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, onSuggestedQuestionClick: handleQuestionClick, onFeedback: onFeedback }), jsxRuntime.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : inputPlaceholder, disabled: isLoading || isLimitReached, enableFileUpload: settings?.enableFileUpload })] }))] }));
21855
21966
  };
21856
21967
 
21857
21968
  /**
@@ -22034,22 +22145,18 @@ function generateDarkPalette(accentColor) {
22034
22145
  * Generate all CSS custom properties for the widget
22035
22146
  */
22036
22147
  function generateThemeStyles(appearance, theme) {
22037
- const palette = theme === 'dark'
22038
- ? generateDarkPalette(appearance.accentColor)
22039
- : generateLightPalette(appearance.accentColor);
22148
+ const hasAccentColor = appearance.accentColor && appearance.accentColor.trim() !== '';
22040
22149
  // Liquid glass design - frosted glass with transparency
22041
22150
  const isLight = theme === 'light';
22042
- return {
22151
+ // Base styles that don't depend on accent color
22152
+ const styles = {
22043
22153
  // ========================================================================
22044
- // BUTTON (FAB) - Liquid Glass Style
22154
+ // BUTTON (FAB) - Base styles
22045
22155
  // ========================================================================
22046
- '--button-color': palette.accent,
22047
22156
  '--button-opacity': '1',
22048
22157
  '--button-size': '56px',
22049
- '--button-icon-color': palette.userBubbleText,
22050
22158
  '--button-border-radius': '50%',
22051
22159
  '--button-border-width': '0px',
22052
- '--button-border-color': palette.accent,
22053
22160
  '--button-border-opacity': '1',
22054
22161
  '--button-backdrop-blur': '20px',
22055
22162
  '--button-shadow': `0 4px 24px rgba(0, 0, 0, 0.15), 0 2px 8px rgba(0, 0, 0, 0.1)`,
@@ -22072,7 +22179,6 @@ function generateThemeStyles(appearance, theme) {
22072
22179
  // ========================================================================
22073
22180
  '--header-background': 'transparent',
22074
22181
  '--header-opacity': '1',
22075
- '--header-text-color': palette.accent,
22076
22182
  '--header-border-bottom-width': '0px',
22077
22183
  '--header-border-bottom-color': 'transparent',
22078
22184
  '--header-border-bottom-opacity': '0',
@@ -22082,17 +22188,13 @@ function generateThemeStyles(appearance, theme) {
22082
22188
  // ========================================================================
22083
22189
  '--chat-background': 'transparent',
22084
22190
  '--chat-opacity': '1',
22085
- '--welcome-color': palette.text,
22086
- '--message-text-color': palette.text,
22087
22191
  // ========================================================================
22088
22192
  // MESSAGE BUBBLES - Glass style
22089
22193
  // ========================================================================
22090
- '--bubble-user-color': palette.userBubble,
22091
22194
  '--bubble-user-opacity': '1',
22092
- '--user-message-text': palette.userBubbleText,
22093
22195
  '--bubble-assistant-color': isLight ? 'rgba(255, 255, 255, 0.8)' : 'rgba(255, 255, 255, 0.1)',
22094
22196
  '--bubble-assistant-opacity': '1',
22095
- '--assistant-message-text': isLight ? palette.text : '#f0f0f0',
22197
+ '--assistant-message-text': isLight ? '#000000' : '#f0f0f0',
22096
22198
  '--bubble-border-radius': '20px',
22097
22199
  '--bubble-border-width': isLight ? '1px' : '1px',
22098
22200
  '--bubble-border-color': isLight ? 'rgba(0, 0, 0, 0.05)' : 'rgba(255, 255, 255, 0.08)',
@@ -22114,38 +22216,48 @@ function generateThemeStyles(appearance, theme) {
22114
22216
  '--input-border-color': isLight ? 'rgba(0, 0, 0, 0.08)' : 'rgba(255, 255, 255, 0.1)',
22115
22217
  '--input-border-opacity': '1',
22116
22218
  '--input-shadow': `inset 0 1px 3px rgba(0, 0, 0, 0.04), 0 2px 8px rgba(0, 0, 0, 0.04)`,
22117
- '--send-button-background': palette.accent,
22118
22219
  '--send-button-opacity': '1',
22119
22220
  '--send-button-border-radius': '50%',
22120
22221
  '--send-button-border-width': '0px',
22121
- '--send-button-border-color': palette.accent,
22122
22222
  '--send-button-border-opacity': '1',
22123
22223
  // ========================================================================
22124
22224
  // HOVER STATES
22125
22225
  // ========================================================================
22126
22226
  '--hover-button-scale': '1.08',
22127
22227
  '--hover-button-opacity': '1',
22128
- '--hover-input-border-color': palette.accent,
22129
22228
  '--hover-send-button-opacity': '1',
22130
22229
  '--hover-close-button-opacity': '1',
22131
22230
  // ========================================================================
22132
- // ACTIVE STATES
22133
- // ========================================================================
22134
- '--active-input-border-color': palette.accent,
22135
- '--active-input-shadow': `0 0 0 4px ${withAlpha(palette.accent, 0.15)}`,
22136
- // ========================================================================
22137
- // GENERAL
22138
- // ========================================================================
22139
- '--primary-color': palette.accent,
22140
- '--background-color': palette.background,
22141
- '--text-color': palette.text,
22142
- '--border-color': palette.border,
22143
- // ========================================================================
22144
22231
  // GLASS EFFECTS
22145
22232
  // ========================================================================
22146
22233
  '--glass-blur': '20px',
22147
22234
  '--glass-saturation': '180%',
22148
22235
  };
22236
+ // Only add accent-color-based styles if an accent color is provided
22237
+ if (hasAccentColor) {
22238
+ const palette = theme === 'dark'
22239
+ ? generateDarkPalette(appearance.accentColor)
22240
+ : generateLightPalette(appearance.accentColor);
22241
+ // Add accent color styles
22242
+ styles['--button-color'] = palette.accent;
22243
+ styles['--button-icon-color'] = palette.userBubbleText;
22244
+ styles['--button-border-color'] = palette.accent;
22245
+ styles['--header-text-color'] = palette.accent;
22246
+ styles['--welcome-color'] = palette.text;
22247
+ styles['--message-text-color'] = palette.text;
22248
+ styles['--bubble-user-color'] = palette.userBubble;
22249
+ styles['--user-message-text'] = palette.userBubbleText;
22250
+ styles['--send-button-background'] = palette.accent;
22251
+ styles['--send-button-border-color'] = palette.accent;
22252
+ styles['--hover-input-border-color'] = palette.accent;
22253
+ styles['--active-input-border-color'] = palette.accent;
22254
+ styles['--active-input-shadow'] = `0 0 0 4px ${withAlpha(palette.accent, 0.15)}`;
22255
+ styles['--primary-color'] = palette.accent;
22256
+ styles['--background-color'] = palette.background;
22257
+ styles['--text-color'] = palette.text;
22258
+ styles['--border-color'] = palette.border;
22259
+ }
22260
+ return styles;
22149
22261
  }
22150
22262
 
22151
22263
  /**
@@ -22256,7 +22368,7 @@ function styleInject(css, ref) {
22256
22368
  if ( ref === void 0 ) ref = {};
22257
22369
  var insertAt = ref.insertAt;
22258
22370
 
22259
- if (!css || typeof document === 'undefined') { return; }
22371
+ if (typeof document === 'undefined') { return; }
22260
22372
 
22261
22373
  var head = document.head || document.getElementsByTagName('head')[0];
22262
22374
  var style = document.createElement('style');
@@ -22279,10 +22391,7 @@ function styleInject(css, ref) {
22279
22391
  }
22280
22392
  }
22281
22393
 
22282
- var css_248z$1 = ".ai-chat-widget{--primary-color:#07f;--background-color:#fff;--text-color:#1f2937;--border-color:#e5e7eb;--user-message-bg:var(--primary-color);--user-message-text:#fff;--assistant-message-bg:#f3f4f6;--assistant-message-text:#374151;--input-bg:#fff;--input-border:#d1d5db;--shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);--shadow-lg:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);--button-color:#07f;--button-size:56px;--button-border-radius:28px;--button-border-width:0px;--button-border-color:#07f;--button-opacity:1;--button-backdrop-blur:0px;--button-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);--card-background:#fff;--card-border-radius:16px;--card-border-width:0px;--card-border-color:#e5e7eb;--card-opacity:1;--card-backdrop-blur:0px;--card-shadow:0 25px 50px -12px rgba(0,0,0,.25);--header-background:#07f;--header-text-color:#fff;--header-font-size:18px;--header-border-bottom-width:0px;--header-border-bottom-color:#e5e7eb;--header-opacity:1;--header-backdrop-blur:0px;--chat-background:#fff;--chat-opacity:1;--chat-backdrop-blur:0px;--welcome-font-size:16px;--welcome-color:#1f2937;--welcome-opacity:1;--bubble-user-color:#07f;--bubble-assistant-color:#f3f4f6;--bubble-border-radius:16px;--bubble-border-width:0px;--bubble-border-color:#e5e7eb;--bubble-opacity:1;--typing-animation-color:#f3f4f6;--typing-animation-opacity:1;--typing-animation-border-width:0px;--typing-animation-border-color:#e5e7eb;--typing-animation-border-radius:16px;--footer-background:#fff;--footer-border-top-width:1px;--footer-border-top-color:#e5e7eb;--footer-opacity:1;--footer-backdrop-blur:0px;--input-background:#fff;--input-border-radius:24px;--input-border-width:1.5px;--input-border-color:#d1d5db;--input-opacity:1;--input-shadow:0 1px 2px 0 rgba(0,0,0,.05);--send-button-background:#07f;--send-button-border-radius:20px;--send-button-border-width:0px;--send-button-border-color:#07f;--send-button-opacity:1;--hover-button-scale:1.05;--hover-button-opacity:0.9;--hover-input-border-color:#9ca3af;--hover-send-button-opacity:0.85;--hover-close-button-opacity:1;--active-input-border-color:#07f;--active-input-shadow:0 0 0 3px rgba(0,119,255,.1);-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.dark{--background-color:#001d3d;--text-color:#f9fafb;--border-color:#374151;--assistant-message-bg:#036;--assistant-message-text:#e5e7eb;--input-bg:#002855;--input-border:#374151}.ai-chat-widget.dark .ai-chat-message.system .ai-chat-message-content{background-color:#78350f;color:#fef3c7}.ai-chat-widget.dark .ai-chat-message.tool .ai-chat-message-content{background-color:#1e3a8a;color:#dbeafe}.ai-chat-widget-container{font-size:14px;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}.ai-chat-button{align-items:center;backdrop-filter:blur(var(--button-backdrop-blur));-webkit-backdrop-filter:blur(var(--button-backdrop-blur));background-color:var(--button-color);border:var(--button-border-width) solid var(--button-border-color);border-radius:var(--button-border-radius);box-shadow:var(--button-shadow);color:#fff;cursor:pointer;display:flex;height:var(--button-size);justify-content:center;opacity:var(--button-opacity);transition:all .3s cubic-bezier(.4,0,.2,1);width:var(--button-size)}.ai-chat-button:hover{opacity:.9}.ai-chat-button:active{opacity:.8}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;width:50%}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-window{border-radius:var(--card-border-radius);box-shadow:0 0 0 var(--card-border-width) var(--card-border-color-rgba,var(--card-border-color)),var(--card-shadow);display:flex;flex-direction:column;overflow:hidden;position:absolute}.ai-chat-window>*{position:relative;z-index:1}.ai-chat-window:before{backdrop-filter:blur(var(--card-backdrop-blur));-webkit-backdrop-filter:blur(var(--card-backdrop-blur));background-color:var(--card-background);border-radius:var(--card-border-radius);content:\"\";inset:0;opacity:var(--card-opacity);pointer-events:none;position:absolute;z-index:0}.ai-chat-widget-container.bottom-right .ai-chat-window{bottom:calc(var(--button-size, 60px) + 16px);right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:calc(var(--button-size, 60px) + 16px);left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:calc(var(--button-size, 60px) + 16px)}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:calc(var(--button-size, 60px) + 16px)}.ai-chat-button{z-index:1}.ai-chat-window{z-index:2}.ai-chat-window.size-small{height:500px;width:380px}.ai-chat-window.size-medium{height:650px;width:440px}.ai-chat-window.size-large{height:750px;width:520px}.ai-chat-logo{border-radius:50%;height:32px;object-fit:cover;width:32px}.ai-chat-messages::-webkit-scrollbar{width:6px}.ai-chat-messages::-webkit-scrollbar-track{background:transparent}.ai-chat-messages::-webkit-scrollbar-thumb{background:var(--border-color);border-radius:3px}.ai-chat-messages::-webkit-scrollbar-thumb:hover{background:var(--input-border)}.ai-chat-message{display:flex;flex-direction:column;gap:4px}.ai-chat-message.user{align-items:flex-end}.ai-chat-message.assistant{align-items:flex-start}.ai-chat-message.system{align-items:center}.ai-chat-message.tool{align-items:flex-start}.ai-chat-message-content{word-wrap:break-word;border:var(--bubble-border-width) solid var(--bubble-border-color);border-radius:var(--bubble-border-radius);font-size:15px;line-height:1.6;max-width:80%;opacity:var(--bubble-opacity);padding:12px 16px}.ai-chat-message.user .ai-chat-message-content{background-color:var(--bubble-user-color);border-bottom-right-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.1);color:var(--user-message-text)}.ai-chat-message.assistant .ai-chat-message-content{background-color:var(--bubble-assistant-color,#f3f4f6);border:1px solid var(--bubble-border-color,rgba(0,0,0,.08));border-radius:var(--bubble-border-radius,16px);border-bottom-left-radius:4px;box-shadow:none;color:var(--assistant-message-text);max-width:85%;padding:12px 16px}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 12px}.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:8px 0 12px;padding-left:24px}.ai-chat-message.assistant .ai-chat-message-content li{line-height:1.5;margin:6px 0}.ai-chat-message.assistant .ai-chat-message-content li::marker{color:var(--primary-color,#07f)}.ai-chat-message.assistant .ai-chat-message-content ol li::marker{font-weight:600}.ai-chat-message.assistant .ai-chat-message-content strong{font-weight:600}.ai-chat-message.assistant .ai-chat-message-content em{font-style:italic}.ai-chat-message.assistant .ai-chat-message-content code{background-color:rgba(0,0,0,.06);border-radius:4px;font-family:SF Mono,Consolas,Monaco,monospace;font-size:.9em;padding:2px 6px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content code{background-color:hsla(0,0%,100%,.1)}.ai-chat-message.assistant .ai-chat-message-content pre{background-color:rgba(0,0,0,.06);border-radius:8px;margin:8px 0 12px;overflow-x:auto;padding:12px}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content pre{background-color:hsla(0,0%,100%,.08)}.ai-chat-message.assistant .ai-chat-message-content pre code{background-color:transparent;border-radius:0;padding:0}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--primary-color,#07f);color:var(--text-muted,#6b7280);margin:8px 0 12px;padding:4px 0 4px 12px}.ai-chat-message.assistant .ai-chat-message-content a{color:var(--primary-color,#07f);text-decoration:underline}.ai-chat-message.assistant .ai-chat-message-content a:hover{opacity:.8}.ai-chat-message.assistant .ai-chat-message-content h1,.ai-chat-message.assistant .ai-chat-message-content h2,.ai-chat-message.assistant .ai-chat-message-content h3,.ai-chat-message.assistant .ai-chat-message-content h4,.ai-chat-message.assistant .ai-chat-message-content h5,.ai-chat-message.assistant .ai-chat-message-content h6{font-weight:600;line-height:1.3;margin:16px 0 8px}.ai-chat-message.assistant .ai-chat-message-content h1:first-child,.ai-chat-message.assistant .ai-chat-message-content h2:first-child,.ai-chat-message.assistant .ai-chat-message-content h3:first-child{margin-top:0}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-color,#e5e7eb);margin:12px 0}.ai-chat-message.system .ai-chat-message-content{background-color:#fef3c7;border-radius:8px;color:#92400e;font-size:12px;font-style:italic;max-width:90%;text-align:center}.ai-chat-message.tool .ai-chat-message-content{background-color:#dbeafe;border-bottom-left-radius:4px;color:#1e40af;font-family:Courier New,monospace;font-size:13px}.ai-chat-tool-indicators{display:flex;gap:6px;margin-top:6px}.tool-indicator{align-items:center;background:#dbeafe;border-radius:50%;color:#1e40af;display:inline-flex;height:18px;justify-content:center;overflow:hidden;position:relative;width:18px}.tool-indicator .icon{font-size:12px;line-height:1;z-index:1}.tool-indicator.started:after{animation:ai-spin 1s linear infinite;border:2px solid rgba(30,64,175,.25);border-radius:50%;border-top-color:#1e40af;content:\"\";inset:0;position:absolute}@keyframes ai-spin{to{transform:rotate(1turn)}}.ai-chat-tool-message{align-items:center;background:rgba(16,185,129,.1);border:1px solid rgba(16,185,129,.2);border-radius:20px;color:#059669;display:inline-flex;gap:8px;padding:8px 14px}.ai-chat-widget.dark .ai-chat-tool-message{background:rgba(16,185,129,.15);border-color:rgba(16,185,129,.25);color:#34d399}.tool-finished{align-items:center;display:inline-flex;font-size:14px;justify-content:center}.tool-finished .tool-icon{display:none}.tool-finished .tool-check{font-size:14px;font-weight:700}.tool-name{font-size:13px;font-weight:500}.ai-chat-message-timestamp{color:rgba(0,0,0,.6);filter:invert(1) grayscale(1) contrast(1.2);mix-blend-mode:difference;padding:0 4px}.ai-chat-welcome{align-items:center;color:var(--welcome-color);display:flex;flex-direction:column;justify-content:center;min-height:200px;opacity:var(--welcome-opacity);padding:60px 32px 40px;text-align:center}.ai-chat-welcome-title{color:var(--primary-color);font-size:28px;font-weight:700;letter-spacing:-.03em;margin-bottom:12px}.ai-chat-welcome-text{color:var(--assistant-message-text);font-size:16px;line-height:1.6;max-width:280px;opacity:.7}.ai-chat-typing{align-items:center;background-color:var(--assistant-message-bg);border-radius:12px;border-bottom-left-radius:4px;display:flex;gap:4px;max-width:80px;padding:10px 14px}.ai-chat-typing-dot{animation:typingBounce 1.4s infinite;background-color:#9ca3af;border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:nth-child(2){animation-delay:.2s}.ai-chat-typing-dot:nth-child(3){animation-delay:.4s}@keyframes typingBounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-8px)}}.ai-chat-file-button{align-items:center;background:none;border:none;border-radius:6px;color:var(--text-color);cursor:pointer;display:flex;justify-content:center;padding:8px;transition:background-color .2s}.ai-chat-file-button:hover:not(:disabled){background-color:rgba(0,0,0,.05)}.ai-chat-file-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:8px;padding:8px 12px}.ai-chat-file-item{align-items:center;background-color:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:12px;gap:8px;padding:6px 10px}.ai-chat-file-extension{background-color:var(--primary-color);border-radius:3px;color:#fff;display:inline-block;font-size:10px;font-weight:600;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:500;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:4px;transition:opacity .15s ease}.ai-chat-file-remove:hover{opacity:1}.ai-chat-message-attachments{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.ai-chat-message-attachment{align-items:center;background-color:rgba(0,0,0,.08);border-radius:4px;display:inline-flex;font-size:11px;gap:4px;padding:3px 8px}.ai-chat-attachment-icon{font-size:12px}.ai-chat-attachment-ext{background-color:var(--primary-color);border-radius:2px;color:#fff;display:inline-block;font-size:9px;font-weight:600;padding:1px 4px;text-transform:uppercase}.ai-chat-attachment-name{max-width:120px;opacity:.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-sources{background-color:rgba(0,0,0,.02);border-radius:6px;font-size:12px;margin-top:8px;overflow:hidden}.ai-chat-sources-toggle{align-items:center;background:none;border:none;cursor:pointer;display:flex;gap:6px;padding:8px 10px;text-align:left;transition:background-color .2s;width:100%}.ai-chat-sources-toggle:hover{background-color:rgba(0,0,0,.03)}.ai-chat-sources-icon{color:var(--text-muted);font-size:10px;transition:transform .2s}.ai-chat-sources-title{color:var(--text-color);flex:1;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}.ai-chat-source-item{border-top:1px solid rgba(0,0,0,.05);color:#6b7280;display:flex;gap:8px;padding:8px 10px}.ai-chat-source-item:last-child{border-bottom:none}.ai-chat-source-number{color:var(--primary-color);flex-shrink:0;font-weight:600}.ai-chat-source-details{display:flex;flex:1;flex-direction:column;gap:4px}.ai-chat-source-score{color:#9ca3af;font-size:11px}.ai-chat-source-content{color:#6b7280;font-size:11px;font-style:italic;line-height:1.4}.ai-chat-source-metadata{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}.ai-chat-source-meta-item{background-color:rgba(0,0,0,.05);border-radius:3px;color:#6b7280;font-size:10px;padding:2px 6px}.ai-chat-message-meta{align-items:center;display:inline-flex;gap:6px;height:20px}.ai-chat-message-timestamp{color:#71717a;font-size:11px;line-height:1}.ai-chat-feedback{gap:0}.ai-chat-feedback,.ai-chat-feedback-button{align-items:center;display:inline-flex;height:20px}.ai-chat-feedback-button{background:none!important;border:none;border-radius:0;color:#71717a;cursor:pointer;justify-content:center;padding:0 4px;transition:color .15s ease}.ai-chat-feedback-button:hover:not(:disabled){background:none!important;color:#52525b}.ai-chat-feedback-button:active:not(:disabled){opacity:.7}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-feedback-button.active{background:none!important;color:var(--primary-color,#07f)}.ai-chat-feedback-submitted{align-items:center;animation:feedbackMorph .3s cubic-bezier(.34,1.56,.64,1);display:flex;gap:6px}.ai-chat-feedback-checkmark{animation:checkmarkPop .3s cubic-bezier(.34,1.56,.64,1);color:#10b981;font-size:16px;font-weight:700}.ai-chat-feedback-text{animation:textSlideIn .3s ease;color:#10b981;font-size:13px;font-weight:500}@keyframes feedbackMorph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes checkmarkPop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes textSlideIn{0%{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}.ai-chat-error{align-items:flex-start;background-color:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:12px;color:#ef4444;display:flex;font-size:14px;font-weight:500;gap:10px;line-height:1.5;margin:8px 16px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-error{background-color:rgba(239,68,68,.15);border-color:rgba(239,68,68,.25);color:#fca5a5}.ai-chat-error:before{align-items:center;background:rgba(239,68,68,.2);border-radius:50%;content:\"⚠\";display:flex;flex-shrink:0;font-size:14px;font-weight:700;height:20px;justify-content:center;width:20px}.ai-chat-widget.dark .ai-chat-error:before{background:rgba(239,68,68,.25)}.ai-chat-warning{background-color:rgba(245,158,11,.1);border:1px solid rgba(245,158,11,.2);border-radius:12px;color:#d97706;font-size:13px;margin:8px 16px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-warning{background-color:rgba(245,158,11,.15);border-color:rgba(245,158,11,.25);color:#fbbf24}.ai-chat-suggested-questions{bottom:80px;left:0;padding:0 20px 16px;position:absolute;right:0;z-index:5}.ai-chat-suggested-questions-list{display:flex;flex-direction:column;gap:8px}.ai-chat-suggested-question{align-items:center;background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:14px;box-shadow:0 1px 3px rgba(0,0,0,.04);color:#374151;cursor:pointer;display:flex;font-size:14px;font-weight:500;gap:12px;justify-content:space-between;padding:14px 16px;text-align:left;transition:all .15s ease;width:100%}.ai-chat-suggested-question:hover{background:#f9fafb;border-color:rgba(0,0,0,.12);box-shadow:0 2px 8px rgba(0,0,0,.06)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question-text{flex:1;line-height:1.4}.ai-chat-suggested-question-icon{color:var(--primary-color,#07f);flex-shrink:0;opacity:.7;transition:transform .15s ease,opacity .15s ease}.ai-chat-suggested-question:hover .ai-chat-suggested-question-icon{opacity:1;transform:translateX(3px)}@media (max-width:480px){.ai-chat-window{border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}.ai-chat-widget-container{bottom:20px!important;right:20px!important}.ai-chat-suggested-question{font-size:13px;padding:9px 10px}}.ai-chat-action-approval{background:linear-gradient(135deg,#07f,#001d3d);border-radius:16px;box-shadow:0 4px 12px rgba(0,119,255,.3);color:#fff;margin:16px;padding:16px}.ai-chat-action-approval-content{align-items:flex-start;display:flex;gap:12px;margin-bottom:16px}.ai-chat-action-approval-icon{align-items:center;background:hsla(0,0%,100%,.2);border-radius:8px;display:flex;flex-shrink:0;height:40px;justify-content:center;width:40px}.ai-chat-action-approval-text{flex:1}.ai-chat-action-approval-title{font-size:15px;font-weight:600;margin-bottom:4px}.ai-chat-action-approval-description{font-size:13px;line-height:1.4;opacity:.95}.ai-chat-action-approval-buttons{display:flex;gap:8px;justify-content:flex-end}.ai-chat-action-button{align-items:center;border:none;border-radius:8px;cursor:pointer;display:flex;font-family:inherit;font-size:14px;font-weight:500;gap:6px;padding:8px 16px;transition:all .2s ease}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.6}.ai-chat-action-button-reject{background:hsla(0,0%,100%,.2);color:#fff}.ai-chat-action-button-reject:hover:not(:disabled){background:hsla(0,0%,100%,.3)}.ai-chat-action-button-approve{background:#fff;color:#07f}.ai-chat-action-button-approve:hover:not(:disabled){background:#f0f0f0;box-shadow:0 2px 8px rgba(0,0,0,.15);transform:translateY(-1px)}.ai-chat-action-spinner{animation:ai-chat-spin .6s linear infinite;border:2px solid rgba(0,119,255,.3);border-radius:50%;border-top-color:#07f;display:inline-block;height:14px;width:14px}@keyframes ai-chat-spin{to{transform:rotate(1turn)}}.ai-chat-header-actions{align-items:center;display:flex;gap:4px}.ai-chat-header-button{align-items:center;background:transparent;border:none;border-radius:8px;color:var(--header-text-color,#fff);cursor:pointer;display:flex;height:32px;justify-content:center;opacity:.8;transition:background-color .15s ease;width:32px}.ai-chat-header-button:hover{background:hsla(0,0%,100%,.15);opacity:1}.ai-chat-header-button svg{height:18px;width:18px}.ai-chat-history-panel{background:var(--chat-background,#fff);display:flex;flex:1;flex-direction:column;overflow:hidden}.ai-chat-history-empty,.ai-chat-history-loading{align-items:center;color:var(--text-color,#6b7280);display:flex;flex:1;font-size:14px;justify-content:center;padding:24px;text-align:center}.ai-chat-history-list{flex:1;overflow-y:auto;padding:8px}.ai-chat-history-item{align-items:stretch;background:transparent;border:none;border-bottom:1px solid var(--border-color,rgba(0,0,0,.06));border-radius:0;cursor:pointer;display:flex;flex-direction:column;padding:12px 16px;text-align:left;transition:background-color .12s ease;width:100%}.ai-chat-history-item:last-child{border-bottom:none}.ai-chat-history-item:hover{background:rgba(0,0,0,.03)}.ai-chat-widget.dark .ai-chat-history-item:hover{background:hsla(0,0%,100%,.05)}.ai-chat-history-item.active{background:rgba(0,0,0,.05)}.ai-chat-widget.dark .ai-chat-history-item.active{background:hsla(0,0%,100%,.08)}.ai-chat-history-item.active .ai-chat-history-item-meta{opacity:.8}.ai-chat-history-item-preview{color:var(--text-color,#1f2937);font-size:14px;font-weight:400;line-height:1.4;margin-bottom:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-history-item.active .ai-chat-history-item-preview{font-weight:500}.ai-chat-history-item-meta{color:var(--text-color,#9ca3af);display:flex;font-size:11px;gap:8px;opacity:.8}.ai-chat-history-list::-webkit-scrollbar{width:6px}.ai-chat-history-list::-webkit-scrollbar-track{background:transparent}.ai-chat-history-list::-webkit-scrollbar-thumb{background:var(--border-color,#e5e7eb);border-radius:3px}.ai-chat-history-list::-webkit-scrollbar-thumb:hover{background:var(--input-border,#d1d5db)}";
22283
- styleInject(css_248z$1);
22284
-
22285
- var css_248z = ".ai-chat-widget{--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.2s;--duration-normal:0.35s;--duration-slow:0.5s}.ai-chat-button{align-items:center;background:var(--button-color,var(--primary-color,#07f));border:none;border-radius:50%;box-shadow:0 2px 8px rgba(0,0,0,.15);cursor:pointer;display:flex;height:48px;justify-content:center;overflow:hidden;position:relative;transition:opacity .15s ease;width:48px}.ai-chat-button:hover{opacity:.9}.ai-chat-button:active{opacity:.8}.ai-chat-button-svg{height:20px;transition:transform .15s ease;width:20px}.ai-chat-button.is-open .ai-chat-button-svg{transform:rotate(0deg)}.ai-chat-window{animation:windowOpen var(--duration-slow) var(--spring-bounce);background:#fff;border:1px solid #e5e7eb;border-radius:16px;box-shadow:0 4px 24px rgba(0,0,0,.12),0 1px 3px rgba(0,0,0,.08);display:flex;flex-direction:column;overflow:hidden;position:absolute;transform-origin:bottom right}.ai-chat-widget.dark .ai-chat-window{background:#18181b;border-color:#27272a}@keyframes windowOpen{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}.ai-chat-window.closing{animation:windowClose var(--duration-normal) var(--spring-smooth) forwards}@keyframes windowClose{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}.ai-chat-header{align-items:center;background:#fff;border-bottom:1px solid #e5e7eb;display:flex;justify-content:space-between;padding:16px 20px;position:relative;z-index:10}.ai-chat-widget.dark .ai-chat-header{background:#18181b;border-bottom-color:#27272a}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:12px}.ai-chat-logo{border-radius:10px;height:36px;object-fit:cover;width:36px}.ai-chat-title{color:#18181b;font-size:15px;font-weight:600;letter-spacing:-.01em}.ai-chat-widget.dark .ai-chat-title{color:#fafafa}.ai-chat-close-button{align-items:center;background:transparent;border:none;border-radius:8px;color:#a1a1aa;cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all .15s ease;width:32px}.ai-chat-widget.dark .ai-chat-close-button{color:#71717a}.ai-chat-close-button:hover{background:#f4f4f5;color:#52525b}.ai-chat-widget.dark .ai-chat-close-button:hover{background:#27272a;color:#a1a1aa}.ai-chat-close-button:active{transform:scale(.95)}.ai-chat-messages{-webkit-overflow-scrolling:touch;background:#f4f4f5;display:flex;flex:1;flex-direction:column;gap:12px;overflow-x:hidden;overflow-y:auto;padding:16px 16px 90px;position:relative;scroll-behavior:smooth}.ai-chat-widget.dark .ai-chat-messages{background:#18181b}.ai-chat-messages::-webkit-scrollbar{width:4px}.ai-chat-messages::-webkit-scrollbar-track{background:transparent}.ai-chat-messages::-webkit-scrollbar-thumb{background:rgba(0,0,0,.15);border-radius:4px}.ai-chat-messages::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.25)}.ai-chat-message{animation:messageSlideIn var(--duration-normal) var(--spring-bounce);display:flex;flex-direction:column;gap:6px}@keyframes messageSlideIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.ai-chat-message-content{word-wrap:break-word;border-radius:12px;font-size:14px;line-height:1.5;max-width:85%;padding:8px 14px}.ai-chat-message.user .ai-chat-message-content{background:var(--bubble-user-color,var(--primary-color,#07f));border-bottom-right-radius:4px;color:#fff;margin-left:auto}.ai-chat-message.assistant .ai-chat-message-content{background:#fff;border:1px solid #e5e7eb;border-bottom-left-radius:4px;color:#374151}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{background:#18181b;border-color:#27272a;color:#e4e4e7}.ai-chat-typing{align-items:center;animation:messageSlideIn var(--duration-normal) var(--spring-bounce);background:#fff;border:1px solid #e5e7eb;border-radius:12px;border-bottom-left-radius:4px;display:flex;gap:4px;max-width:64px;padding:12px 16px}.ai-chat-widget.dark .ai-chat-typing{background:#18181b;border-color:#27272a}.ai-chat-typing-dot{animation:typingPulse 1.4s ease-in-out infinite;background:linear-gradient(135deg,var(--primary-color) 0,color-mix(in srgb,var(--primary-color) 70%,#000) 100%);border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:nth-child(2){animation-delay:.15s}.ai-chat-typing-dot:nth-child(3){animation-delay:.3s}@keyframes typingPulse{0%,60%,to{opacity:.4;transform:translateY(0) scale(1)}30%{opacity:1;transform:translateY(-6px) scale(1.1)}}.ai-chat-input-container{background:transparent;bottom:0;left:0;padding:0 16px 16px;position:absolute;right:0;z-index:10}.ai-chat-input-container:before{background:linear-gradient(0deg,#f4f4f5 80%,transparent);bottom:0;content:\"\";height:48px;left:0;pointer-events:none;position:absolute;right:0;z-index:-1}.ai-chat-widget.dark .ai-chat-input-container:before{background:linear-gradient(0deg,#18181b 80%,transparent)}.ai-chat-input-wrapper{align-items:center;background:#f4f4f5;border:1px solid #e5e7eb;border-radius:9999px;display:flex;gap:0;padding:4px 4px 4px 16px;position:relative;transition:all .15s ease;z-index:5}.ai-chat-widget.dark .ai-chat-input-wrapper{background:#27272a;border-color:#3f3f46}.ai-chat-input-wrapper:focus-within{border-color:var(--primary-color);box-shadow:0 0 0 2px rgba(var(--primary-color-rgb,0,119,255),.15)}.ai-chat-input{background:transparent;border:none;color:var(--text-color);flex:1;font-family:inherit;font-size:14px;line-height:1.4;max-height:100px;min-height:20px;outline:none;padding:8px 0;resize:none}.ai-chat-input::placeholder{color:rgba(0,0,0,.35)}.ai-chat-widget.dark .ai-chat-input::placeholder{color:hsla(0,0%,100%,.35)}.ai-chat-send-button{align-items:center;background:transparent;border:none;border-radius:8px;color:#a1a1aa;cursor:pointer;display:flex;flex-shrink:0;height:36px;justify-content:center;padding:0;transition:all .15s ease;width:36px}.ai-chat-widget.dark .ai-chat-send-button{color:#71717a}.ai-chat-send-button.active{background:var(--primary-color,#07f);color:#fff}.ai-chat-send-button.active:hover:not(:disabled){opacity:.9}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.4}.ai-chat-tool-message{align-items:center;animation:toolPulse 2s ease-in-out infinite;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background:linear-gradient(135deg,rgba(16,185,129,.15),rgba(16,185,129,.08));border:1px solid rgba(16,185,129,.2);border-radius:16px;display:inline-flex;gap:10px;padding:10px 16px}@keyframes toolPulse{0%,to{box-shadow:0 0 0 0 rgba(16,185,129,.2)}50%{box-shadow:0 0 0 8px rgba(16,185,129,0)}}.tool-finished{align-items:center;animation:toolComplete .5s var(--spring-bounce);background:linear-gradient(135deg,#10b981,#059669);border-radius:50%;color:#fff;display:inline-flex;height:28px;justify-content:center;position:relative;width:28px}@keyframes toolComplete{0%{transform:scale(0) rotate(-180deg)}to{transform:scale(1) rotate(0deg)}}.tool-indicator{align-items:center;background:linear-gradient(135deg,rgba(59,130,246,.2),rgba(59,130,246,.1));border-radius:50%;color:#3b82f6;display:inline-flex;height:24px;justify-content:center;position:relative;width:24px}.tool-indicator.started:after{animation:toolSpin .8s linear infinite;border:2px solid transparent;border-radius:50%;border-top-color:#3b82f6;content:\"\";inset:-2px;position:absolute}@keyframes toolSpin{to{transform:rotate(1turn)}}.ai-chat-welcome{align-items:center;animation:welcomeFadeIn var(--duration-slow) var(--spring-smooth);display:flex;flex-direction:column;justify-content:center;min-height:200px;padding:60px 32px 40px;text-align:center}@keyframes welcomeFadeIn{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}.ai-chat-welcome-title{color:var(--primary-color);font-size:28px;font-weight:700;letter-spacing:-.03em;margin-bottom:12px}.ai-chat-welcome-text{color:var(--text-color);font-size:16px;line-height:1.6;max-width:280px;opacity:.6}.ai-chat-suggested-questions{bottom:76px;left:0;padding:0 16px 12px;position:absolute;right:0;z-index:5}.ai-chat-suggested-questions-list{display:flex;flex-direction:column;gap:6px}.ai-chat-suggested-question{align-items:center;background:#fff;border:1px solid #e5e7eb;border-radius:10px;color:#374151;cursor:pointer;display:flex;font-size:13px;font-weight:500;gap:10px;justify-content:space-between;padding:10px 14px;text-align:left;transition:all .15s ease;width:100%}.ai-chat-widget.dark .ai-chat-suggested-question{background:#18181b;border-color:#27272a;color:#e4e4e7}.ai-chat-suggested-question:hover{background:#f4f4f5;border-color:#d4d4d8}.ai-chat-widget.dark .ai-chat-suggested-question:hover{background:#27272a;border-color:#3f3f46}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question-text{flex:1;line-height:1.4}.ai-chat-suggested-question-icon{color:var(--primary-color,#07f);flex-shrink:0;opacity:.7;transition:transform .15s ease,opacity .15s ease}.ai-chat-suggested-question:hover .ai-chat-suggested-question-icon{opacity:1;transform:translateX(3px)}.ai-chat-feedback-button{align-items:center;background:rgba(0,0,0,.04);border:none;border-radius:8px;cursor:pointer;display:flex;font-size:16px;gap:4px;padding:6px 10px;transition:all var(--duration-fast) var(--spring-bounce)}.ai-chat-feedback-button:hover:not(:disabled){background:rgba(0,0,0,.08);transform:scale(1.15)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.9)}.ai-chat-feedback-button.active{background:rgba(var(--primary-color-rgb,0,119,255),.15)}@media (max-width:480px){.ai-chat-window{animation:mobileSlideUp var(--duration-normal) var(--spring-smooth);border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}@keyframes mobileSlideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.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))}}";
22394
+ var css_248z = ".ai-chat-widget{--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:14px;--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{--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{-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 windowOpen{0%{opacity:0;transform:scale(.9) translateY(20px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes windowClose{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.9) translateY(20px)}}@keyframes messageSlideIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes welcomeFadeIn{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}@keyframes typingPulse{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 feedbackMorph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes checkmarkPop{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)}}@media (max-width:480px){.ai-chat-window{animation:mobileSlideUp var(--duration-normal) var(--spring-smooth);border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}@keyframes mobileSlideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.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-button{align-items:center;background:var(--button-color,var(--btn-primary-bg));border:1px solid var(--button-border-color,var(--button-color,var(--btn-primary-bg)));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:filter var(--duration-fast) ease,transform var(--duration-fast) ease;width:var(--button-size,56px);z-index:1}.ai-chat-button:hover{transform:scale(1.02)}.ai-chat-button:active{transform:scale(.98)}.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-window{animation:windowOpen var(--duration-slow,.35s) var(--spring-bounce,cubic-bezier(.34,1.56,.64,1));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:windowClose var(--duration-normal) var(--spring-smooth) forwards}.ai-chat-window.size-small{height:580px;width:380px}.ai-chat-window.size-medium{height:720px;width:440px}.ai-chat-window.size-large{height:820px;width:520px}.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{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text-primary);cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:color var(--duration-fast) ease;width:32px}.ai-chat-close-button:hover{color:var(--text-muted)}.ai-chat-close-button:active{transform:scale(.95)}.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:all var(--duration-fast) ease;width:32px}.ai-chat-header-button:hover{background:var(--bg-secondary);color:var(--text-secondary)}.ai-chat-header-button svg{height:18px;width:18px}.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:messageSlideIn var(--duration-normal) var(--spring-bounce);display:flex;flex-direction:column;gap:6px}.ai-chat-message-content{word-wrap:break-word;font-size:var(--text-md);line-height:var(--line-height-relaxed);max-width:85%}.ai-chat-message.user{align-items:flex-end}.ai-chat-message.user .ai-chat-message-content{background:var(--user-bg,#f4f3f0);border:none;border-radius:var(--radius-chat-bubble,15px);box-shadow:none;color:var(--user-text,#000);padding:var(--space-sm,8px) var(--space-md,16px)}.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.user .ai-chat-message-meta{justify-content:flex-end;padding-right:var(--space-xs)}.ai-chat-message.assistant{align-items:flex-start}.ai-chat-message.assistant .ai-chat-message-content{background:var(--agent-bg,transparent);border:none;color:var(--agent-text,#18181b);padding:0}.ai-chat-widget.dark .ai-chat-message.assistant .ai-chat-message-content{color:var(--agent-text,#fafafa)}.ai-chat-message.system{align-items:center}.ai-chat-message.system .ai-chat-message-content{background:hsla(48,96%,89%,.8);border-radius:var(--radius-md);color:#92400e;font-size:var(--text-xs);font-style:italic;max-width:90%;padding:var(--space-sm) var(--space-md);text-align:center}.ai-chat-widget.dark .ai-chat-message.system .ai-chat-message-content{background:rgba(120,53,15,.5);color:#fef3c7}.ai-chat-message.tool{align-items:flex-start}.ai-chat-message.tool .ai-chat-message-content{background:rgba(219,234,254,.8);border-radius:var(--radius-chat-bubble);border-bottom-left-radius:var(--radius-xs);color:#1e40af;font-family:Courier New,monospace;font-size:var(--text-sm);padding:var(--space-sm) var(--space-md)}.ai-chat-widget.dark .ai-chat-message.tool .ai-chat-message-content{background:rgba(30,58,138,.5);color:#dbeafe}.ai-chat-message-meta{align-items:center;color:var(--text-muted);display:flex;font-size:var(--text-xs);gap:var(--space-sm);padding-left:var(--space-xs)}.ai-chat-message-timestamp{font-size:var(--text-xs);line-height:1}.ai-chat-typing{align-items:center;animation:messageSlideIn var(--duration-normal) var(--spring-bounce);background:transparent;display:flex;gap:5px;padding:0}.ai-chat-typing-dot{animation:typingPulse 1.4s ease-in-out infinite;background:var(--text-muted);border-radius:50%;height:6px;width:6px}.ai-chat-typing-dot:nth-child(2){animation-delay:.15s}.ai-chat-typing-dot:nth-child(3){animation-delay:.3s}.ai-chat-welcome{align-items:stretch;animation:welcomeFadeIn var(--duration-slow) var(--spring-smooth);display:flex;flex-direction:column;justify-content:flex-start;padding:0;text-align:left}.ai-chat-welcome-text,.ai-chat-welcome-title{align-self:flex-start}.ai-chat-welcome-title{color:var(--text-primary);font-size:var(--text-2xl);font-weight:var(--font-weight-semibold);letter-spacing:-.02em;margin-bottom:var(--space-md)}.ai-chat-welcome-text{color:var(--text-secondary);font-size:var(--text-md);line-height:var(--line-height-relaxed);max-width:100%}.ai-chat-error{align-items:flex-start;align-self:center;background:var(--bg-secondary);border:none;border-radius:var(--radius-chat-bubble);color:var(--text-primary);display:flex;font-size:var(--text-md);font-weight:var(--font-weight-normal);gap:10px;line-height:1.5;margin:0 auto;max-width:90%;padding:10px var(--space-md)}.ai-chat-error:before{align-items:center;background:rgba(239,68,68,.15);border-radius:50%;color:#ef4444;content:\"⚠\";display:flex;flex-shrink:0;font-size:var(--text-xs);font-weight:700;height:18px;justify-content:center;margin-top:2px;width:18px}.ai-chat-widget.dark .ai-chat-error:before{background:rgba(239,68,68,.2);color:#fca5a5}.ai-chat-message.assistant .ai-chat-message-content p{margin:0 0 12px}.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:8px 0 12px;padding-left:24px}.ai-chat-message.assistant .ai-chat-message-content li{line-height:1.5;margin:6px 0}.ai-chat-message.assistant .ai-chat-message-content strong{font-weight:var(--font-weight-semibold)}.ai-chat-message.assistant .ai-chat-message-content em{font-style:italic}.ai-chat-message.assistant .ai-chat-message-content code{background:rgba(0,0,0,.06);border-radius:var(--radius-sm);font-family:SF Mono,Consolas,Monaco,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,.06);border-radius:var(--radius-md);margin:8px 0 12px;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%,.08)}.ai-chat-message.assistant .ai-chat-message-content pre code{background:transparent;border-radius:0;padding:0}.ai-chat-message.assistant .ai-chat-message-content blockquote{border-left:3px solid var(--btn-primary-bg);color:var(--text-muted);margin:8px 0 12px;padding:4px 0 4px 12px}.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 a:hover{opacity:.8}.ai-chat-message.assistant .ai-chat-message-content h1,.ai-chat-message.assistant .ai-chat-message-content h2,.ai-chat-message.assistant .ai-chat-message-content h3,.ai-chat-message.assistant .ai-chat-message-content h4,.ai-chat-message.assistant .ai-chat-message-content h5,.ai-chat-message.assistant .ai-chat-message-content h6{font-weight:var(--font-weight-semibold);line-height:var(--line-height-tight);margin:16px 0 8px}.ai-chat-message.assistant .ai-chat-message-content h1:first-child,.ai-chat-message.assistant .ai-chat-message-content h2:first-child,.ai-chat-message.assistant .ai-chat-message-content h3:first-child{margin-top:0}.ai-chat-message.assistant .ai-chat-message-content hr{border:none;border-top:1px solid var(--border-subtle);margin:12px 0}.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:center;background:var(--input-bg,#f4f4f4);border:1px solid var(--input-border,#d3d3d3);border-radius:var(--radius-input,62px);display:flex;gap:0;height:52px;padding:6px 6px 6px 12px;position:relative;transition:all var(--duration-fast,.15s) ease;z-index:5}.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{background:transparent;border:none;color:var(--input-text,#000);flex:1;font-family:inherit;font-size:var(--text-md,15px);height:20px;line-height:var(--line-height-normal,1.4);max-height:20px;min-height:20px;outline:none;overflow:hidden;padding:0 var(--space-sm,8px);resize:none}.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;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;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;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-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{background:var(--primary-color,var(--button-color,var(--user-bg,#f4f3f0)));border:none;border-radius:var(--radius-preset-badge,13px);color:var(--button-icon-color,var(--user-text,#000));cursor:pointer;font-size:14px;font-weight:400;line-height:1.3;padding:8px 14px;transition:background .15s ease,opacity .15s ease;white-space:nowrap}.ai-chat-widget.dark .ai-chat-suggested-question{background:var(--primary-color,var(--button-color,var(--user-bg,#484848)));color:var(--button-icon-color,var(--user-text,#fff))}.ai-chat-suggested-question-text{white-space:nowrap}.ai-chat-suggested-question:hover{filter:brightness(.9)}.ai-chat-widget.dark .ai-chat-suggested-question:hover{filter:brightness(1.15)}.ai-chat-suggested-question:active{transform:scale(.98)}.ai-chat-suggested-question-icon{display:none}.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:feedbackMorph .3s var(--spring-bounce);display:flex;gap:6px}.ai-chat-feedback-checkmark{animation:checkmarkPop .3s var(--spring-bounce);color:#10b981;font-size:var(--text-md);font-weight:700}.ai-chat-feedback-text{color:#10b981;font-size:var(--text-sm);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:stretch;background:var(--user-bg,#f4f4f5);border:none;border-radius:var(--radius-history-item,15px);cursor:pointer;display:flex;flex-direction:column;margin:0;padding:var(--space-sm,8px) var(--space-md,16px);text-align:left;transition:background var(--duration-fast,.15s) ease;width:100%}.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);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-tool-row{align-items:center;display:flex;gap:10px;margin:var(--space-sm) 0 6px}.ai-chat-tool-gear{align-items:center;color:var(--text-primary);display:inline-flex;height:26px;justify-content:center;width:26px}.ai-chat-tool-gear.spinning{animation:ai-chat-gear-spin .9s linear infinite}.ai-chat-tool-pills{display:flex;flex-wrap:wrap;gap:var(--space-sm)}.ai-chat-tool-pill{align-items:center;border-radius:var(--radius-pill);color:var(--button-icon-color,var(--btn-primary-text,var(--text-primary)));display:inline-flex;font-size:var(--text-sm);font-weight:var(--font-weight-medium);justify-content:center;line-height:1;padding:var(--space-sm) 14px}.ai-chat-tool-pill,.ai-chat-tool-pill.active{background:var(--primary-color,var(--button-color,var(--btn-primary-bg,var(--bg-secondary))))}.ai-chat-tool-pill.active{animation:ai-chat-tool-active 1.1s ease-in-out infinite;overflow:hidden;position:relative}.ai-chat-tool-pill.done{background:var(--primary-color,var(--button-color,var(--btn-primary-bg)));color:var(--button-icon-color,var(--btn-primary-text))}.ai-chat-tool-indicators{display:flex;gap:6px;margin-top:6px}.tool-indicator{align-items:center;background:linear-gradient(135deg,rgba(59,130,246,.2),rgba(59,130,246,.1));border-radius:50%;color:#3b82f6;display:inline-flex;height:24px;justify-content:center;position:relative;width:24px}.tool-indicator .icon{font-size:var(--text-xs);line-height:1;z-index:1}.tool-indicator.started:after{animation:ai-chat-gear-spin .8s linear infinite;border:2px solid transparent;border-radius:50%;border-top-color:#3b82f6;content:\"\";inset:-2px;position:absolute}.ai-chat-tool-message{align-items:center;background:hsla(0,0%,50%,.1);border:none;border-radius:var(--radius-pill);color:hsla(0,0%,50%,.8);display:inline-flex;font-size:12px;gap:5px;padding:4px 10px}.ai-chat-tool-message .ai-chat-tool-spinner{animation:ai-chat-tool-spin 1s linear infinite;flex-shrink:0;opacity:.6}.ai-chat-tool-message .ai-chat-tool-check{flex-shrink:0;opacity:.7}.ai-chat-tool-message .ai-chat-tool-error{color:#ef4444;flex-shrink:0;opacity:.7}.ai-chat-tool-message.error{background:rgba(239,68,68,.1);color:rgba(239,68,68,.9)}.tool-name{font-size:12px;font-weight:var(--font-weight-regular);line-height:1.2;white-space:nowrap}@keyframes ai-chat-tool-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes ai-chat-tool-check-appear{0%{opacity:0;transform:scale(.5)}to{opacity:.7;transform:scale(1)}}.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}";
22286
22395
  styleInject(css_248z);
22287
22396
 
22288
22397
  // Icon components mapping
@@ -22290,19 +22399,76 @@ const iconComponents = {
22290
22399
  FiMessageCircle: () => (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.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" }) })),
22291
22400
  FiChevronDown: () => (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" }) })),
22292
22401
  };
22293
- const ChatWidget = ({ widgetId, apiUrl = window.location.origin, position = 'bottom-right', primaryColor, onOpen, onClose, onMessage, onError, }) => {
22402
+ const ChatWidget = ({ widgetId, apiUrl = window.location.origin, previewMode = false, previewConfig, position = 'bottom-right', primaryColor, size, headerTitle, welcomeTitle, welcomeMessage, placeholder, theme, suggestedQuestions, customStyles, onOpen, onClose, onMessage, onError, }) => {
22294
22403
  const [isOpen, setIsOpen] = react.useState(false);
22295
22404
  const [autoDetectedTheme, setAutoDetectedTheme] = react.useState('light');
22296
22405
  const widgetRef = react.useRef(null);
22297
22406
  const containerRef = react.useRef(null);
22298
- const { messages, isLoading, isTyping, error, config, sendMessage, submitFeedback,
22299
- // Chat history (only active when persistConversation is true)
22300
- conversations, loadConversations, switchConversation, startNewConversation, conversationId, } = useChat({
22301
- widgetId,
22407
+ // Default config for preview mode
22408
+ const defaultPreviewConfig = {
22409
+ appearance: {
22410
+ primaryColor: primaryColor || '#0077FF',
22411
+ position: position || 'bottom-right',
22412
+ size: size || 'small',
22413
+ headerTitle: headerTitle || 'AI Assistant',
22414
+ welcomeTitle: welcomeTitle || 'Welcome!',
22415
+ welcomeMessage: welcomeMessage || 'Hi there! How can I help you today?',
22416
+ placeholder: placeholder || 'Ask me anything...',
22417
+ },
22418
+ settings: {
22419
+ autoOpen: false,
22420
+ persistConversation: true,
22421
+ showChatHistory: true,
22422
+ showTimestamps: true,
22423
+ showTypingIndicator: true,
22424
+ enableFileUpload: false,
22425
+ enableFeedback: true,
22426
+ showSources: false,
22427
+ sourceDisplayMode: 'none',
22428
+ },
22429
+ behavior: {
22430
+ agentic: false,
22431
+ },
22432
+ knowledgeBases: [],
22433
+ };
22434
+ // Merge preview config with defaults
22435
+ const mergedPreviewConfig = {
22436
+ ...defaultPreviewConfig,
22437
+ ...previewConfig,
22438
+ appearance: {
22439
+ ...defaultPreviewConfig.appearance,
22440
+ ...previewConfig?.appearance,
22441
+ },
22442
+ settings: {
22443
+ ...defaultPreviewConfig.settings,
22444
+ ...previewConfig?.settings,
22445
+ },
22446
+ behavior: {
22447
+ ...defaultPreviewConfig.behavior,
22448
+ ...previewConfig?.behavior,
22449
+ },
22450
+ };
22451
+ // Always call useChat hook (React rules), but use a dummy widgetId in preview mode
22452
+ // The hook will fail to load config, but we don't use its results in preview mode anyway
22453
+ const chatHook = useChat({
22454
+ widgetId: previewMode ? '__preview__' : (widgetId || '__preview__'),
22302
22455
  apiUrl,
22303
- onMessage,
22304
- onError,
22456
+ onMessage: previewMode ? undefined : onMessage,
22457
+ onError: previewMode ? undefined : onError,
22305
22458
  });
22459
+ // Extract values from hook or use preview defaults
22460
+ const messages = previewMode ? [] : chatHook.messages;
22461
+ const isLoading = previewMode ? false : chatHook.isLoading;
22462
+ const isTyping = previewMode ? false : chatHook.isTyping;
22463
+ const error = previewMode ? null : chatHook.error;
22464
+ const config = previewMode ? mergedPreviewConfig : chatHook.config;
22465
+ const sendMessage = previewMode ? (() => Promise.resolve()) : chatHook.sendMessage;
22466
+ const submitFeedback = previewMode ? (() => Promise.resolve()) : chatHook.submitFeedback;
22467
+ const conversations = previewMode ? [] : chatHook.conversations;
22468
+ const loadConversations = previewMode ? (() => { }) : chatHook.loadConversations;
22469
+ const switchConversation = previewMode ? (() => Promise.resolve()) : chatHook.switchConversation;
22470
+ const startNewConversation = previewMode ? (() => { }) : chatHook.startNewConversation;
22471
+ const conversationId = previewMode ? '' : chatHook.conversationId;
22306
22472
  // Auto-detect theme from background
22307
22473
  react.useEffect(() => {
22308
22474
  if (!containerRef.current)
@@ -22340,8 +22506,8 @@ const ChatWidget = ({ widgetId, apiUrl = window.location.origin, position = 'bot
22340
22506
  }, [config, autoDetectedTheme]);
22341
22507
  // Handle auto-open
22342
22508
  react.useEffect(() => {
22343
- if (config?.behavior.autoOpen) {
22344
- const delay = config.behavior.autoOpenDelay || 0;
22509
+ if (config?.settings.autoOpen) {
22510
+ const delay = config.settings.autoOpenDelay || 0;
22345
22511
  const timer = setTimeout(() => {
22346
22512
  setIsOpen(true);
22347
22513
  onOpen?.();
@@ -22363,31 +22529,33 @@ const ChatWidget = ({ widgetId, apiUrl = window.location.origin, position = 'bot
22363
22529
  document.addEventListener('keydown', handleEscapeKey);
22364
22530
  return () => document.removeEventListener('keydown', handleEscapeKey);
22365
22531
  }, [isOpen, onClose]);
22366
- // Determine theme - always auto-detect from background
22532
+ // Determine theme - use prop override if provided, otherwise auto-detect
22367
22533
  const appearanceConfig = config?.appearance;
22368
- const effectiveTheme = autoDetectedTheme;
22369
- // Determine position (config takes priority over prop)
22370
- const effectivePosition = config?.appearance.position || position;
22371
- // Get accent color from config or prop
22372
- const accentColor = primaryColor || appearanceConfig?.primaryColor || '#0077FF';
22534
+ const effectiveTheme = theme ?? autoDetectedTheme;
22535
+ // Determine position (prop override takes priority for live preview)
22536
+ const effectivePosition = position || config?.appearance.position || 'bottom-right';
22537
+ // Get accent color from prop or config (empty string means no accent color / vanilla mode)
22538
+ const accentColor = primaryColor ?? appearanceConfig?.primaryColor ?? '';
22539
+ // Apply prop overrides for live preview (props take priority over config)
22540
+ size || appearanceConfig?.size || 'small';
22541
+ const effectiveHeaderTitle = headerTitle ?? appearanceConfig?.headerTitle ?? '';
22542
+ const effectiveWelcomeTitle = welcomeTitle ?? appearanceConfig?.welcomeTitle ?? '';
22543
+ const effectiveWelcomeMessage = welcomeMessage ?? appearanceConfig?.welcomeMessage ?? '';
22544
+ const effectivePlaceholder = placeholder ?? appearanceConfig?.placeholder ?? '';
22373
22545
  // Generate styles using simplified theme system
22374
22546
  const simpleAppearance = {
22375
- accentColor,
22376
- size: appearanceConfig?.size || 'small',
22377
- welcomeMessage: appearanceConfig?.welcomeMessage || '',
22378
- placeholder: appearanceConfig?.placeholder || '',
22379
- headerTitle: appearanceConfig?.headerTitle || '',
22380
- };
22547
+ accentColor};
22381
22548
  // Generate theme styles from accent color
22382
22549
  const generatedStyles = generateThemeStyles(simpleAppearance, effectiveTheme);
22383
22550
  // Also apply legacy styles for backward compatibility
22384
22551
  const legacyStyles = appearanceConfig
22385
22552
  ? applyAppearanceStyles(appearanceConfig)
22386
22553
  : {};
22387
- // Merge styles (generated takes priority for new simplified system)
22388
- const customStyles = {
22554
+ // Merge styles (generated takes priority for new simplified system, then custom overrides)
22555
+ const mergedStyles = {
22389
22556
  ...legacyStyles,
22390
22557
  ...generatedStyles,
22558
+ ...customStyles,
22391
22559
  };
22392
22560
  // Debug logging for theme and styles
22393
22561
  react.useEffect(() => {
@@ -22412,16 +22580,19 @@ const ChatWidget = ({ widgetId, apiUrl = window.location.origin, position = 'bot
22412
22580
  await submitFeedback(messageId, feedback);
22413
22581
  };
22414
22582
  // Don't render until config is loaded to avoid flash of unstyled content
22415
- if (!config) {
22583
+ // In preview mode, config is always available
22584
+ if (!config && !previewMode) {
22416
22585
  console.log('[ChatWidget] Not rendering - config not loaded yet');
22417
22586
  return null;
22418
22587
  }
22419
22588
  console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
22420
22589
  // Get button icon based on state
22421
22590
  const IconComponent = isOpen ? iconComponents.FiChevronDown : iconComponents.FiMessageCircle;
22422
- return (jsxRuntime.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style: customStyles, children: jsxRuntime.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition}`, children: [isOpen && (jsxRuntime.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback,
22591
+ return (jsxRuntime.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style: mergedStyles, children: jsxRuntime.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition}`, children: [isOpen && (jsxRuntime.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback,
22423
22592
  // Chat history props (only active when persistConversation is true)
22424
- conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, currentConversationId: conversationId })), jsxRuntime.jsx("button", { className: `ai-chat-button ${isOpen ? 'is-open' : ''}`, onClick: handleToggle, "aria-label": isOpen ? "Minimize chat" : "Open chat", children: jsxRuntime.jsx("div", { className: "ai-chat-button-svg", children: jsxRuntime.jsx(IconComponent, {}) }) })] }) }));
22593
+ conversations: conversations, onLoadConversations: loadConversations, onSwitchConversation: switchConversation, onStartNewConversation: startNewConversation, currentConversationId: conversationId,
22594
+ // Override props for live preview
22595
+ headerTitleOverride: effectiveHeaderTitle, welcomeTitleOverride: effectiveWelcomeTitle, welcomeMessageOverride: effectiveWelcomeMessage, placeholderOverride: effectivePlaceholder, suggestedQuestionsOverride: suggestedQuestions })), jsxRuntime.jsx("button", { className: `ai-chat-button ${isOpen ? 'is-open' : ''}`, onClick: handleToggle, "aria-label": isOpen ? "Minimize chat" : "Open chat", children: jsxRuntime.jsx("div", { className: "ai-chat-button-svg", children: jsxRuntime.jsx(IconComponent, {}) }) })] }) }));
22425
22596
  };
22426
22597
 
22427
22598
  exports.ApiError = ApiError;