@chatwidgetai/chat-widget 0.1.2 → 0.1.3

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
@@ -418,9 +418,16 @@ function useChat(options) {
418
418
  // Load configuration on mount and hydrate with existing conversation if available
419
419
  react.useEffect(() => {
420
420
  let isMounted = true;
421
+ console.log('[useChat] Effect running, mounting component');
421
422
  const initialize = async () => {
422
423
  try {
424
+ console.log('[useChat] Fetching config...');
423
425
  const config = await apiClient.current.getConfig();
426
+ console.log('[useChat] Config fetched successfully:', {
427
+ hasAppearance: !!config.appearance,
428
+ hasLightMode: !!config.appearance?.lightMode,
429
+ hasDarkMode: !!config.appearance?.darkMode,
430
+ });
424
431
  const persistConversation = config.behavior.persistConversation ?? true;
425
432
  let conversationId = '';
426
433
  let messages = [];
@@ -439,8 +446,10 @@ function useChat(options) {
439
446
  }
440
447
  }
441
448
  if (!isMounted) {
449
+ console.log('[useChat] Component unmounted, skipping state update');
442
450
  return;
443
451
  }
452
+ console.log('[useChat] Setting config in state');
444
453
  setState(prev => ({
445
454
  ...prev,
446
455
  config,
@@ -449,6 +458,7 @@ function useChat(options) {
449
458
  }));
450
459
  }
451
460
  catch (error) {
461
+ console.error('[useChat] Error fetching config:', error);
452
462
  if (!isMounted) {
453
463
  return;
454
464
  }
@@ -460,6 +470,7 @@ function useChat(options) {
460
470
  };
461
471
  initialize();
462
472
  return () => {
473
+ console.log('[useChat] Effect cleanup, unmounting component');
463
474
  isMounted = false;
464
475
  };
465
476
  }, [widgetId, apiKey, apiUrl, onError]);
@@ -21433,7 +21444,7 @@ const TypingIndicator = () => {
21433
21444
  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" })] }) }));
21434
21445
  };
21435
21446
 
21436
- const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeMessage, onFeedback, }) => {
21447
+ const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeTitle, welcomeMessage, onFeedback, }) => {
21437
21448
  const messagesEndRef = react.useRef(null);
21438
21449
  // Auto-scroll to bottom when new messages arrive
21439
21450
  react.useEffect(() => {
@@ -21453,7 +21464,7 @@ const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, s
21453
21464
  }
21454
21465
  return map;
21455
21466
  }, [messages]);
21456
- return (jsxRuntime.jsxs("div", { className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [messages.length === 0 && welcomeMessage && (jsxRuntime.jsxs("div", { className: "ai-chat-welcome", children: [jsxRuntime.jsx("div", { className: "ai-chat-welcome-title", children: "Welcome!" }), 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 })] }));
21467
+ 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 })] }));
21457
21468
  };
21458
21469
 
21459
21470
  // Allowed file types
@@ -21479,7 +21490,7 @@ const formatFileSize = (bytes) => {
21479
21490
  return (bytes / 1024).toFixed(1) + ' KB';
21480
21491
  return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
21481
21492
  };
21482
- const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, }) => {
21493
+ const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, separateFromChat = true, }) => {
21483
21494
  const [value, setValue] = react.useState('');
21484
21495
  const [selectedFiles, setSelectedFiles] = react.useState([]);
21485
21496
  const textareaRef = react.useRef(null);
@@ -21537,7 +21548,8 @@ const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled =
21537
21548
  textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
21538
21549
  }
21539
21550
  };
21540
- return (jsxRuntime.jsxs("div", { className: "ai-chat-input-container", children: [selectedFiles.length > 0 && (jsxRuntime.jsx("div", { className: "ai-chat-file-list", children: selectedFiles.map((file, index) => {
21551
+ console.log('[MessageInput] separateFromChat:', separateFromChat, 'class:', separateFromChat ? 'separate' : 'integrated');
21552
+ 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) => {
21541
21553
  const ext = getFileExtension(file.name);
21542
21554
  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: "\u00D7" })] }, index));
21543
21555
  }) })), 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: "20", height: "20", 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", onClick: handleSend, disabled: disabled || (!value.trim() && selectedFiles.length === 0), "aria-label": "Send message", children: jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }), jsxRuntime.jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })] }) })] })] }));
@@ -21556,9 +21568,23 @@ const SuggestedQuestions = ({ questions, onQuestionClick, }) => {
21556
21568
  };
21557
21569
 
21558
21570
  const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose, onFeedback, }) => {
21571
+ console.log('[ChatWindow] Rendering ChatWindow component');
21559
21572
  const appearance = config?.appearance;
21560
21573
  const behavior = config?.behavior;
21561
21574
  const size = appearance?.size || 'medium';
21575
+ console.log('[ChatWindow] Size:', size, 'Appearance:', !!appearance);
21576
+ // Determine current theme config
21577
+ const themePreference = appearance?.theme ?? 'light';
21578
+ const canUseDarkMode = appearance?.darkModeEnabled !== false;
21579
+ const prefersDark = typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches;
21580
+ const isDarkMode = themePreference === 'auto'
21581
+ ? (canUseDarkMode && prefersDark)
21582
+ : themePreference === 'dark' && canUseDarkMode;
21583
+ const themeConfig = (isDarkMode ? appearance?.darkMode : appearance?.lightMode) ?? (appearance?.lightMode || appearance?.darkMode);
21584
+ const headerTitle = themeConfig?.header?.title ?? appearance?.header?.title ?? appearance?.companyName ?? 'AI Assistant';
21585
+ const welcomeTitle = themeConfig?.chat?.welcomeTitle ?? 'Welcome!';
21586
+ const welcomeMessage = themeConfig?.chat?.welcomeMessage ?? appearance?.welcomeMessage ?? '👋 Hi there! How can I assist you today?';
21587
+ const inputPlaceholder = themeConfig?.footer?.inputPlaceholder ?? appearance?.placeholder ?? 'Ask me anything...';
21562
21588
  // Track if suggested questions should be shown
21563
21589
  const [showSuggestedQuestions, setShowSuggestedQuestions] = react.useState(true);
21564
21590
  // Hide suggested questions after first user message
@@ -21577,9 +21603,240 @@ const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessag
21577
21603
  setShowSuggestedQuestions(false);
21578
21604
  onSendMessage(question);
21579
21605
  };
21580
- return (jsxRuntime.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntime.jsxs("div", { className: "ai-chat-header", 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: appearance?.companyName || 'AI Assistant' })] }), jsxRuntime.jsx("button", { className: "ai-chat-close-button", onClick: onClose, "aria-label": "Close chat", children: jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), 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 in this session"] })), isLimitReached && (jsxRuntime.jsxs("div", { className: "ai-chat-error", role: "alert", children: ["Message limit reached (", maxMessages, " messages per session). 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: appearance?.welcomeMessage, onFeedback: onFeedback }), showSuggestedQuestions && behavior?.suggestedQuestions && behavior.suggestedQuestions.length > 0 && (jsxRuntime.jsx(SuggestedQuestions, { questions: behavior.suggestedQuestions, onQuestionClick: handleQuestionClick })), jsxRuntime.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : appearance?.placeholder, disabled: isLoading || isLimitReached, enableFileUpload: behavior?.enableFileUpload })] }));
21606
+ return (jsxRuntime.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntime.jsxs("div", { className: "ai-chat-header", 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.jsx("button", { className: "ai-chat-close-button", onClick: onClose, "aria-label": "Close chat", children: jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), 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 in this session"] })), isLimitReached && (jsxRuntime.jsxs("div", { className: "ai-chat-error", role: "alert", children: ["Message limit reached (", maxMessages, " messages per session). 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, welcomeTitle: welcomeTitle, welcomeMessage: welcomeMessage, onFeedback: onFeedback }), showSuggestedQuestions && 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, separateFromChat: themeConfig?.footer?.separateFromChat })] }));
21581
21607
  };
21582
21608
 
21609
+ /**
21610
+ * Convert shadow size to CSS box-shadow value
21611
+ */
21612
+ function getShadowValue(size) {
21613
+ const shadows = {
21614
+ 'none': 'none',
21615
+ 'sm': '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
21616
+ 'md': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
21617
+ 'lg': '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
21618
+ 'xl': '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
21619
+ '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
21620
+ };
21621
+ return shadows[size] || shadows.none;
21622
+ }
21623
+ /**
21624
+ * Apply appearance configuration as CSS custom properties
21625
+ * This allows the widget to be fully customizable via the appearance config
21626
+ *
21627
+ * @param appearance - Widget appearance configuration
21628
+ * @param theme - Current theme ('light' or 'dark')
21629
+ */
21630
+ function applyAppearanceStyles(appearance, theme = 'light') {
21631
+ const styles = {};
21632
+ // Global font family
21633
+ if (appearance.fontFamily) {
21634
+ styles.fontFamily = appearance.fontFamily;
21635
+ }
21636
+ // Select the correct theme configuration
21637
+ const themeConfig = theme === 'dark' ? appearance.darkMode : appearance.lightMode;
21638
+ // If theme config exists and has required properties, use it
21639
+ if (themeConfig && themeConfig.button) {
21640
+ // ========================================================================
21641
+ // BUTTON APPEARANCE
21642
+ // ========================================================================
21643
+ const btn = themeConfig.button;
21644
+ if (btn.color)
21645
+ styles['--button-color'] = btn.color;
21646
+ if (btn.opacity !== undefined)
21647
+ styles['--button-opacity'] = btn.opacity.toString();
21648
+ if (btn.size)
21649
+ styles['--button-size'] = `${btn.size}px`;
21650
+ if (btn.borderRadius !== undefined)
21651
+ styles['--button-border-radius'] = `${btn.borderRadius}px`;
21652
+ if (btn.borderWidth !== undefined)
21653
+ styles['--button-border-width'] = `${btn.borderWidth}px`;
21654
+ if (btn.borderColor)
21655
+ styles['--button-border-color'] = btn.borderColor;
21656
+ if (btn.borderOpacity !== undefined)
21657
+ styles['--button-border-opacity'] = btn.borderOpacity.toString();
21658
+ if (btn.backdropBlur !== undefined)
21659
+ styles['--button-backdrop-blur'] = `${btn.backdropBlur}px`;
21660
+ if (btn.shadow)
21661
+ styles['--button-shadow'] = getShadowValue(btn.shadow);
21662
+ // ========================================================================
21663
+ // CARD/WINDOW APPEARANCE
21664
+ // ========================================================================
21665
+ const card = themeConfig.card;
21666
+ if (card.backgroundColor)
21667
+ styles['--card-background'] = card.backgroundColor;
21668
+ if (card.opacity !== undefined)
21669
+ styles['--card-opacity'] = card.opacity.toString();
21670
+ if (card.borderRadius !== undefined)
21671
+ styles['--card-border-radius'] = `${card.borderRadius}px`;
21672
+ if (card.borderWidth !== undefined)
21673
+ styles['--card-border-width'] = `${card.borderWidth}px`;
21674
+ if (card.borderColor) {
21675
+ styles['--card-border-color'] = card.borderColor;
21676
+ // Create rgba border color with opacity for box-shadow
21677
+ if (card.borderOpacity !== undefined) {
21678
+ const opacity = card.borderOpacity;
21679
+ // Convert hex to rgba
21680
+ const hex = card.borderColor.replace('#', '');
21681
+ const r = parseInt(hex.substring(0, 2), 16);
21682
+ const g = parseInt(hex.substring(2, 4), 16);
21683
+ const b = parseInt(hex.substring(4, 6), 16);
21684
+ styles['--card-border-color-rgba'] = `rgba(${r}, ${g}, ${b}, ${opacity})`;
21685
+ }
21686
+ }
21687
+ if (card.borderOpacity !== undefined)
21688
+ styles['--card-border-opacity'] = card.borderOpacity.toString();
21689
+ if (card.backdropBlur !== undefined)
21690
+ styles['--card-backdrop-blur'] = `${card.backdropBlur}px`;
21691
+ if (card.shadow)
21692
+ styles['--card-shadow'] = getShadowValue(card.shadow);
21693
+ // ========================================================================
21694
+ // HEADER APPEARANCE
21695
+ // ========================================================================
21696
+ const header = themeConfig.header;
21697
+ if (header.backgroundColor)
21698
+ styles['--header-background'] = header.backgroundColor;
21699
+ if (header.opacity !== undefined)
21700
+ styles['--header-opacity'] = header.opacity.toString();
21701
+ if (header.textColor)
21702
+ styles['--header-text-color'] = header.textColor;
21703
+ if (header.borderBottomWidth !== undefined)
21704
+ styles['--header-border-bottom-width'] = `${header.borderBottomWidth}px`;
21705
+ if (header.borderBottomColor)
21706
+ styles['--header-border-bottom-color'] = header.borderBottomColor;
21707
+ if (header.borderBottomOpacity !== undefined)
21708
+ styles['--header-border-bottom-opacity'] = header.borderBottomOpacity.toString();
21709
+ // ========================================================================
21710
+ // CHAT APPEARANCE
21711
+ // ========================================================================
21712
+ const chat = themeConfig.chat;
21713
+ if (chat.backgroundColor)
21714
+ styles['--chat-background'] = chat.backgroundColor;
21715
+ if (chat.opacity !== undefined)
21716
+ styles['--chat-opacity'] = chat.opacity.toString();
21717
+ // Welcome message
21718
+ if (chat.welcomeColor)
21719
+ styles['--welcome-color'] = chat.welcomeColor;
21720
+ // Message bubbles
21721
+ if (chat.enableBubbles) {
21722
+ if (chat.bubbleUserColor)
21723
+ styles['--bubble-user-color'] = chat.bubbleUserColor;
21724
+ if (chat.bubbleUserOpacity !== undefined)
21725
+ styles['--bubble-user-opacity'] = chat.bubbleUserOpacity.toString();
21726
+ if (chat.bubbleAssistantColor)
21727
+ styles['--bubble-assistant-color'] = chat.bubbleAssistantColor;
21728
+ if (chat.bubbleAssistantOpacity !== undefined)
21729
+ styles['--bubble-assistant-opacity'] = chat.bubbleAssistantOpacity.toString();
21730
+ if (chat.bubbleBorderWidth !== undefined)
21731
+ styles['--bubble-border-width'] = `${chat.bubbleBorderWidth}px`;
21732
+ if (chat.bubbleBorderColor)
21733
+ styles['--bubble-border-color'] = chat.bubbleBorderColor;
21734
+ if (chat.bubbleBorderOpacity !== undefined)
21735
+ styles['--bubble-border-opacity'] = chat.bubbleBorderOpacity.toString();
21736
+ }
21737
+ else {
21738
+ // Plain text mode
21739
+ if (chat.textColor)
21740
+ styles['--message-text-color'] = chat.textColor;
21741
+ }
21742
+ // ========================================================================
21743
+ // FOOTER APPEARANCE
21744
+ // ========================================================================
21745
+ const footer = themeConfig.footer;
21746
+ // Only if separate from chat
21747
+ if (footer.separateFromChat) {
21748
+ if (footer.backgroundColor)
21749
+ styles['--footer-background'] = footer.backgroundColor;
21750
+ if (footer.opacity !== undefined)
21751
+ styles['--footer-opacity'] = footer.opacity.toString();
21752
+ if (footer.borderTopWidth !== undefined)
21753
+ styles['--footer-border-top-width'] = `${footer.borderTopWidth}px`;
21754
+ if (footer.borderTopColor)
21755
+ styles['--footer-border-top-color'] = footer.borderTopColor;
21756
+ if (footer.borderTopOpacity !== undefined)
21757
+ styles['--footer-border-top-opacity'] = footer.borderTopOpacity.toString();
21758
+ }
21759
+ // Backdrop blur (only when floating)
21760
+ if (!footer.separateFromChat && footer.backdropBlur !== undefined) {
21761
+ styles['--footer-backdrop-blur'] = `${footer.backdropBlur}px`;
21762
+ }
21763
+ // Input field
21764
+ if (footer.inputBackgroundColor)
21765
+ styles['--input-background'] = footer.inputBackgroundColor;
21766
+ if (footer.inputBackgroundOpacity !== undefined)
21767
+ styles['--input-background-opacity'] = footer.inputBackgroundOpacity.toString();
21768
+ if (footer.inputBorderRadius !== undefined)
21769
+ styles['--input-border-radius'] = `${footer.inputBorderRadius}px`;
21770
+ if (footer.inputBorderWidth !== undefined)
21771
+ styles['--input-border-width'] = `${footer.inputBorderWidth}px`;
21772
+ if (footer.inputBorderColor)
21773
+ styles['--input-border-color'] = footer.inputBorderColor;
21774
+ if (footer.inputBorderOpacity !== undefined)
21775
+ styles['--input-border-opacity'] = footer.inputBorderOpacity.toString();
21776
+ if (footer.inputShadow)
21777
+ styles['--input-shadow'] = getShadowValue(footer.inputShadow);
21778
+ // Send button
21779
+ if (footer.buttonBackgroundColor)
21780
+ styles['--send-button-background'] = footer.buttonBackgroundColor;
21781
+ if (footer.buttonOpacity !== undefined)
21782
+ styles['--send-button-opacity'] = footer.buttonOpacity.toString();
21783
+ if (footer.buttonBorderRadius !== undefined)
21784
+ styles['--send-button-border-radius'] = `${footer.buttonBorderRadius}px`;
21785
+ if (footer.buttonBorderWidth !== undefined)
21786
+ styles['--send-button-border-width'] = `${footer.buttonBorderWidth}px`;
21787
+ if (footer.buttonBorderColor)
21788
+ styles['--send-button-border-color'] = footer.buttonBorderColor;
21789
+ if (footer.buttonBorderOpacity !== undefined)
21790
+ styles['--send-button-border-opacity'] = footer.buttonBorderOpacity.toString();
21791
+ // ========================================================================
21792
+ // HOVER STATES
21793
+ // ========================================================================
21794
+ const hover = themeConfig.hover;
21795
+ if (hover.buttonScale !== undefined)
21796
+ styles['--hover-button-scale'] = hover.buttonScale.toString();
21797
+ if (hover.buttonOpacity !== undefined)
21798
+ styles['--hover-button-opacity'] = hover.buttonOpacity.toString();
21799
+ if (hover.inputBorderColor)
21800
+ styles['--hover-input-border-color'] = hover.inputBorderColor;
21801
+ if (hover.sendButtonOpacity !== undefined)
21802
+ styles['--hover-send-button-opacity'] = hover.sendButtonOpacity.toString();
21803
+ if (hover.closeButtonOpacity !== undefined)
21804
+ styles['--hover-close-button-opacity'] = hover.closeButtonOpacity.toString();
21805
+ // ========================================================================
21806
+ // ACTIVE STATES
21807
+ // ========================================================================
21808
+ const active = themeConfig.active;
21809
+ if (active.inputBorderColor)
21810
+ styles['--active-input-border-color'] = active.inputBorderColor;
21811
+ if (active.inputShadow)
21812
+ styles['--active-input-shadow'] = active.inputShadow;
21813
+ }
21814
+ else {
21815
+ // Fallback to legacy fields if no theme config
21816
+ if (appearance.primaryColor)
21817
+ styles['--primary-color'] = appearance.primaryColor;
21818
+ if (appearance.borderRadius !== undefined)
21819
+ styles['--border-radius'] = `${appearance.borderRadius}px`;
21820
+ // Legacy button
21821
+ if (appearance.button) {
21822
+ const btn = appearance.button;
21823
+ if (btn.color)
21824
+ styles['--button-color'] = btn.color;
21825
+ if (btn.size)
21826
+ styles['--button-size'] = `${btn.size}px`;
21827
+ if (btn.borderRadius !== undefined)
21828
+ styles['--button-border-radius'] = `${btn.borderRadius}px`;
21829
+ if (btn.borderWidth !== undefined)
21830
+ styles['--button-border-width'] = `${btn.borderWidth}px`;
21831
+ if (btn.borderColor)
21832
+ styles['--button-border-color'] = btn.borderColor;
21833
+ if (btn.opacity !== undefined)
21834
+ styles['--button-opacity'] = btn.opacity.toString();
21835
+ }
21836
+ }
21837
+ return styles;
21838
+ }
21839
+
21583
21840
  function styleInject(css, ref) {
21584
21841
  if ( ref === void 0 ) ref = {};
21585
21842
  var insertAt = ref.insertAt;
@@ -21607,11 +21864,12 @@ function styleInject(css, ref) {
21607
21864
  }
21608
21865
  }
21609
21866
 
21610
- var css_248z = ".ai-chat-widget{--primary-color:#7c3aed;--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:#1f2937;--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);-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:#1f2937;--text-color:#f9fafb;--border-color:#374151;--assistant-message-bg:#374151;--assistant-message-text:#f9fafb;--input-bg:#374151;--input-border:#4b5563}.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;background-color:var(--primary-color);border:none;border-radius:50%;box-shadow:var(--shadow-lg);color:#fff;cursor:pointer;display:flex;font-size:24px;height:60px;justify-content:center;transition:transform .2s,box-shadow .2s;width:60px}.ai-chat-button:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);transform:scale(1.05)}.ai-chat-button:active{transform:scale(.95)}.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{background-color:var(--background-color);border-radius:12px;box-shadow:var(--shadow-lg);display:flex;flex-direction:column;overflow:hidden;transition:opacity .2s,transform .2s}.ai-chat-window.size-small{height:400px;width:300px}.ai-chat-window.size-medium{height:600px;width:400px}.ai-chat-window.size-large{height:700px;width:500px}.ai-chat-header{align-items:center;background-color:var(--primary-color);color:#fff;display:flex;justify-content:space-between;padding:16px}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:12px}.ai-chat-logo{border-radius:50%;height:32px;object-fit:cover;width:32px}.ai-chat-title{font-size:16px;font-weight:600}.ai-chat-close-button{align-items:center;background:none;border:none;border-radius:4px;color:#fff;cursor:pointer;display:flex;justify-content:center;padding:4px;transition:background-color .2s}.ai-chat-close-button:hover{background-color:hsla(0,0%,100%,.1)}.ai-chat-messages{background-color:var(--background-color);display:flex;flex:1;flex-direction:column;gap:12px;overflow-y:auto;padding:16px}.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{animation:slideIn .2s ease-out;display:flex;flex-direction:column;gap:4px}@keyframes slideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.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-radius:12px;line-height:1.5;max-width:80%;padding:10px 14px}.ai-chat-message.user .ai-chat-message-content{background-color:var(--user-message-bg);border-bottom-right-radius:4px;color:var(--user-message-text)}.ai-chat-message.assistant .ai-chat-message-content{background-color:var(--assistant-message-bg);border-bottom-left-radius:4px;color:var(--assistant-message-text)}.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{background:linear-gradient(135deg,#ecfdf5,#d1fae5);border:1px solid #a7f3d0;border-radius:9999px;box-shadow:0 1px 2px rgba(0,0,0,.04),0 1px 8px rgba(16,185,129,.08);color:#065f46;gap:10px;padding:6px 12px}.ai-chat-tool-message,.tool-finished{align-items:center;display:inline-flex}.tool-finished{background:rgba(16,185,129,.12);border-radius:50%;color:#059669;height:22px;justify-content:center;position:relative;width:22px}.tool-finished .tool-icon{font-size:14px}.tool-finished .tool-check{align-items:center;background:#10b981;border-radius:50%;bottom:-3px;box-shadow:0 1px 2px rgba(0,0,0,.12);color:#fff;display:inline-flex;font-size:10px;height:14px;justify-content:center;position:absolute;right:-3px;width:14px}.tool-name{font-size:12px;font-weight:600}.ai-chat-message-timestamp{color:#9ca3af;font-size:11px;padding:0 4px}.ai-chat-welcome{color:var(--text-color);padding:32px 16px;text-align:center}.ai-chat-welcome-title{font-size:18px;font-weight:600;margin-bottom:8px}.ai-chat-welcome-text{color:#6b7280;font-size:14px}.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-input-container{background-color:var(--background-color);border-top:1px solid var(--border-color);padding:16px}.ai-chat-input-wrapper{align-items:flex-end;display:flex;gap:8px}.ai-chat-input{background-color:var(--input-bg);border:1px solid var(--input-border);border-radius:8px;color:var(--text-color);flex:1;font-family:inherit;font-size:14px;max-height:120px;min-height:40px;outline:none;padding:10px 12px;resize:none;transition:border-color .2s}.ai-chat-input:focus{border-color:var(--primary-color)}.ai-chat-input::placeholder{color:#9ca3af}.ai-chat-send-button{align-items:center;background-color:var(--primary-color);border:none;border-radius:8px;color:#fff;cursor:pointer;display:flex;font-weight:500;height:40px;justify-content:center;min-width:40px;padding:10px 16px;transition:opacity .2s,transform .1s}.ai-chat-send-button:hover:not(:disabled){opacity:.9}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.5}.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{background:none;border:none;cursor:pointer;font-size:18px;line-height:1;opacity:.6;padding:0 4px;transition:opacity .2s}.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-feedback{align-items:center;display:flex;gap:8px;margin-top:8px;min-height:32px}.ai-chat-feedback-button{align-items:center;background:none;border:none;border-radius:6px;cursor:pointer;display:flex;font-size:16px;gap:4px;overflow:hidden;padding:6px 10px;position:relative;transition:all .2s ease}.ai-chat-feedback-button:hover:not(:disabled){background-color:rgba(0,0,0,.05);transform:scale(1.2)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.95)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-feedback-button.active{background-color:rgba(124,58,237,.1)}.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:#fee2e2;border-left:4px solid #dc2626;border-radius:8px;color:#991b1b;display:flex;font-size:14px;font-weight:500;gap:8px;line-height:1.5;margin:8px 16px;padding:12px 16px}.ai-chat-error:before{content:\"⚠️\";flex-shrink:0;font-size:16px}.ai-chat-warning{background-color:#fef3c7;border-radius:8px;color:#92400e;font-size:13px;margin:8px 16px;padding:12px}.ai-chat-suggested-questions{margin-bottom:8px;padding:12px 16px}.ai-chat-suggested-questions-label{color:#6b7280;font-size:12px;font-weight:500;margin-bottom:8px}.ai-chat-suggested-questions-list{display:flex;flex-direction:column;gap:8px}.ai-chat-suggested-question{align-items:center;background-color:#f9fafb;border:1px solid #e5e7eb;border-radius:8px;color:#374151;cursor:pointer;display:flex;font-size:14px;gap:8px;padding:10px 12px;text-align:left;transition:all .2s ease;width:100%}.ai-chat-suggested-question:hover{background-color:#f3f4f6;border-color:var(--ai-chat-primary-color,#6366f1);box-shadow:0 2px 4px rgba(0,0,0,.05);transform:translateY(-1px)}.ai-chat-suggested-question:active{transform:translateY(0)}.ai-chat-suggested-question-icon{flex-shrink:0;font-size:16px}.ai-chat-suggested-question-text{flex:1;line-height:1.4}@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,#667eea,#764ba2);border-radius:12px;box-shadow:0 4px 12px rgba(102,126,234,.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:#667eea}.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(102,126,234,.3);border-radius:50%;border-top-color:#667eea;display:inline-block;height:14px;width:14px}@keyframes ai-chat-spin{to{transform:rotate(1turn)}}";
21867
+ var css_248z = ".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{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);opacity:var(--hover-button-opacity);transform:scale(var(--hover-button-scale))}.ai-chat-button:active{transform:scale(.95)}.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:0;right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:0;left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:0}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:0}.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-header{align-items:center;border-bottom:var(--header-border-bottom-width) solid var(--header-border-bottom-color);box-shadow:0 2px 8px rgba(0,0,0,.1);color:var(--header-text-color);display:flex;justify-content:space-between;padding:20px;position:relative}.ai-chat-header:before{backdrop-filter:blur(var(--header-backdrop-blur));-webkit-backdrop-filter:blur(var(--header-backdrop-blur));background-color:var(--header-background);content:\"\";inset:0;opacity:var(--header-opacity);pointer-events:none;position:absolute;z-index:0}.ai-chat-header>*{position:relative;z-index:1}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:12px}.ai-chat-logo{border-radius:50%;height:32px;object-fit:cover;width:32px}.ai-chat-title{color:var(--header-text-color);font-size:var(--header-font-size);font-weight:600;letter-spacing:-.01em}.ai-chat-close-button{align-items:center;background:none;border:none;border-radius:8px;color:var(--header-text-color);cursor:pointer;display:flex;justify-content:center;opacity:.9;padding:8px;transition:all .2s ease}.ai-chat-close-button:hover{background-color:hsla(0,0%,100%,.15);opacity:var(--hover-close-button-opacity);transform:scale(1.05)}.ai-chat-messages{background-color:var(--chat-background);display:flex;flex:1;flex-direction:column;gap:16px;overflow-x:hidden;overflow-y:auto;padding:20px;position:relative}.ai-chat-window:has(.ai-chat-input-container.integrated) .ai-chat-messages{padding-bottom:100px}.ai-chat-messages:before{backdrop-filter:blur(var(--chat-backdrop-blur));-webkit-backdrop-filter:blur(var(--chat-backdrop-blur));background-color:var(--chat-background);bottom:0;content:\"\";left:0;opacity:var(--chat-opacity);pointer-events:none;position:absolute;right:0;top:0;z-index:0}.ai-chat-messages>*{position:relative;z-index:1}.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{animation:slideIn .2s ease-out;display:flex;flex-direction:column;gap:4px}@keyframes slideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.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);border-bottom-left-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.05);color:var(--assistant-message-text)}.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{background:linear-gradient(135deg,#ecfdf5,#d1fae5);border:1px solid #a7f3d0;border-radius:9999px;box-shadow:0 1px 2px rgba(0,0,0,.04),0 1px 8px rgba(16,185,129,.08);color:#065f46;gap:10px;padding:6px 12px}.ai-chat-tool-message,.tool-finished{align-items:center;display:inline-flex}.tool-finished{background:rgba(16,185,129,.12);border-radius:50%;color:#059669;height:22px;justify-content:center;position:relative;width:22px}.tool-finished .tool-icon{font-size:14px}.tool-finished .tool-check{align-items:center;background:#10b981;border-radius:50%;bottom:-3px;box-shadow:0 1px 2px rgba(0,0,0,.12);color:#fff;display:inline-flex;font-size:10px;height:14px;justify-content:center;position:absolute;right:-3px;width:14px}.tool-name{font-size:12px;font-weight:600}.ai-chat-message-timestamp{color:rgba(0,0,0,.6);filter:invert(1) grayscale(1) contrast(1.2);font-size:11px;mix-blend-mode:difference;padding:0 4px}.ai-chat-welcome{color:var(--welcome-color);opacity:var(--welcome-opacity);padding:48px 24px;text-align:center}.ai-chat-welcome-title{color:var(--welcome-color);font-size:calc(var(--welcome-font-size)*1.5);font-weight:700;letter-spacing:-.02em;margin-bottom:12px}.ai-chat-welcome-text{color:var(--welcome-color);font-size:var(--welcome-font-size);line-height:1.6}.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-input-container{padding:20px;position:relative}.ai-chat-input-container.separate{border-top:var(--footer-border-top-width) solid var(--footer-border-top-color)}.ai-chat-input-container.integrated{bottom:0;left:0;padding-bottom:calc(20px + var(--card-border-width));position:absolute;right:0;z-index:10}.ai-chat-input-container.separate:before{backdrop-filter:blur(var(--footer-backdrop-blur));-webkit-backdrop-filter:blur(var(--footer-backdrop-blur));background-color:var(--footer-background);content:\"\";inset:0;opacity:var(--footer-opacity);pointer-events:none;position:absolute;z-index:0}.ai-chat-input-container>*{position:relative;z-index:1}.ai-chat-input-wrapper{align-items:center;background-color:var(--input-background);border:var(--input-border-width) solid var(--input-border-color);border-radius:var(--input-border-radius);display:flex;gap:0;opacity:var(--input-opacity);padding:6px 6px 6px 16px;transition:all .2s ease}.ai-chat-input-wrapper:hover{border-color:var(--hover-input-border-color)}.ai-chat-input-wrapper:focus-within{border-color:var(--active-input-border-color);box-shadow:var(--active-input-shadow)}.ai-chat-input{background-color:transparent;border:none;border-radius:0;color:var(--text-color);flex:1;font-family:inherit;font-size:15px;max-height:120px;min-height:40px;outline:none;padding:10px 0;resize:none}.ai-chat-input::placeholder{color:#9ca3af}.ai-chat-send-button{align-items:center;background-color:var(--send-button-background);border:var(--send-button-border-width) solid var(--send-button-border-color);border-radius:var(--send-button-border-radius);color:#fff;cursor:pointer;display:flex;flex-shrink:0;font-weight:500;height:40px;justify-content:center;min-width:40px;opacity:var(--send-button-opacity);padding:0;transition:all .2s ease;width:40px}.ai-chat-send-button:hover:not(:disabled){opacity:var(--hover-send-button-opacity);transform:scale(1.05)}.ai-chat-send-button:active:not(:disabled){transform:scale(.98)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.5}.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{background:none;border:none;cursor:pointer;font-size:18px;line-height:1;opacity:.6;padding:0 4px;transition:opacity .2s}.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-feedback{align-items:center;display:flex;gap:8px;margin-top:8px;min-height:32px}.ai-chat-feedback-button{align-items:center;background:none;border:none;border-radius:6px;cursor:pointer;display:flex;filter:drop-shadow(0 1px 2px rgba(0,0,0,.3));font-size:16px;gap:4px;overflow:hidden;padding:6px 10px;position:relative;transition:all .2s ease}.ai-chat-feedback-button:hover:not(:disabled){background-color:rgba(0,0,0,.05);transform:scale(1.2)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.95)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-feedback-button.active{background-color:rgba(0,119,255,.1)}.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:#fee2e2;border-left:4px solid #dc2626;border-radius:8px;color:#991b1b;display:flex;font-size:14px;font-weight:500;gap:8px;line-height:1.5;margin:8px 16px;padding:12px 16px}.ai-chat-error:before{content:\"⚠️\";flex-shrink:0;font-size:16px}.ai-chat-warning{background-color:#fef3c7;border-radius:8px;color:#92400e;font-size:13px;margin:8px 16px;padding:12px}.ai-chat-suggested-questions{margin-bottom:8px;padding:12px 16px}.ai-chat-suggested-questions-label{color:#6b7280;font-size:12px;font-weight:500;margin-bottom:8px}.ai-chat-suggested-questions-list{display:flex;flex-direction:column;gap:8px}.ai-chat-suggested-question{align-items:center;background-color:#f9fafb;border:1px solid #e5e7eb;border-radius:8px;color:#374151;cursor:pointer;display:flex;font-size:14px;gap:8px;padding:10px 12px;text-align:left;transition:all .2s ease;width:100%}.ai-chat-suggested-question:hover{background-color:#f3f4f6;border-color:var(--ai-chat-primary-color,#6366f1);box-shadow:0 2px 4px rgba(0,0,0,.05);transform:translateY(-1px)}.ai-chat-suggested-question:active{transform:translateY(0)}.ai-chat-suggested-question-icon{flex-shrink:0;font-size:16px}.ai-chat-suggested-question-text{flex:1;line-height:1.4}@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)}}";
21611
21868
  styleInject(css_248z);
21612
21869
 
21613
21870
  const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, position = 'bottom-right', theme: themeOverride, primaryColor, onOpen, onClose, onMessage, onError, }) => {
21614
21871
  const [isOpen, setIsOpen] = react.useState(false);
21872
+ const widgetRef = react.useRef(null);
21615
21873
  const { messages, isLoading, isTyping, error, config, sendMessage, submitFeedback, } = useChat({
21616
21874
  widgetId,
21617
21875
  apiKey,
@@ -21619,6 +21877,21 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
21619
21877
  onMessage,
21620
21878
  onError,
21621
21879
  });
21880
+ // Debug logging
21881
+ react.useEffect(() => {
21882
+ console.log('[ChatWidget] Config loaded:', config ? 'YES' : 'NO');
21883
+ if (config) {
21884
+ console.log('[ChatWidget] Config details:', {
21885
+ theme: config.appearance?.theme,
21886
+ darkModeEnabled: config.appearance?.darkModeEnabled,
21887
+ hasLightMode: !!config.appearance?.lightMode,
21888
+ hasDarkMode: !!config.appearance?.darkMode,
21889
+ });
21890
+ }
21891
+ }, [config]);
21892
+ react.useEffect(() => {
21893
+ console.log('[ChatWidget] isOpen changed:', isOpen);
21894
+ }, [isOpen]);
21622
21895
  // Handle auto-open
21623
21896
  react.useEffect(() => {
21624
21897
  if (config?.behavior.autoOpen) {
@@ -21631,26 +21904,84 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
21631
21904
  }
21632
21905
  return undefined;
21633
21906
  }, [config, onOpen]);
21907
+ // Handle close on outside click
21908
+ react.useEffect(() => {
21909
+ if (!isOpen || !config?.appearance.closeOnOutsideClick)
21910
+ return;
21911
+ const handleClickOutside = (event) => {
21912
+ if (widgetRef.current && !widgetRef.current.contains(event.target)) {
21913
+ console.log('[ChatWidget] Closing due to outside click');
21914
+ setIsOpen(false);
21915
+ onClose?.();
21916
+ }
21917
+ };
21918
+ // Add slight delay to avoid immediate close on open
21919
+ const timer = setTimeout(() => {
21920
+ document.addEventListener('mousedown', handleClickOutside);
21921
+ }, 100);
21922
+ return () => {
21923
+ clearTimeout(timer);
21924
+ document.removeEventListener('mousedown', handleClickOutside);
21925
+ };
21926
+ }, [isOpen, config, onClose]);
21927
+ // Handle close on Escape key
21928
+ react.useEffect(() => {
21929
+ if (!isOpen || !config?.appearance.closeOnEscape)
21930
+ return;
21931
+ const handleEscapeKey = (event) => {
21932
+ if (event.key === 'Escape') {
21933
+ setIsOpen(false);
21934
+ onClose?.();
21935
+ }
21936
+ };
21937
+ document.addEventListener('keydown', handleEscapeKey);
21938
+ return () => document.removeEventListener('keydown', handleEscapeKey);
21939
+ }, [isOpen, config, onClose]);
21634
21940
  // Determine theme
21635
- const theme = themeOverride || config?.appearance.theme || 'light';
21636
- const effectiveTheme = theme === 'auto'
21637
- ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
21638
- : theme;
21941
+ const appearanceConfig = config?.appearance;
21942
+ const themeSetting = themeOverride || appearanceConfig?.theme || 'light';
21943
+ const canUseDarkMode = appearanceConfig?.darkModeEnabled !== false;
21944
+ // Only check system preference if dark mode is enabled
21945
+ const systemPrefersDark = canUseDarkMode && typeof window !== "undefined"
21946
+ ? window.matchMedia('(prefers-color-scheme: dark)').matches
21947
+ : false;
21948
+ const effectiveTheme = !canUseDarkMode
21949
+ ? 'light' // Force light mode if dark mode is disabled
21950
+ : themeSetting === 'auto'
21951
+ ? (systemPrefersDark ? 'dark' : 'light')
21952
+ : themeSetting === 'dark'
21953
+ ? 'dark'
21954
+ : 'light';
21639
21955
  // Determine position (config takes priority over prop)
21640
21956
  const effectivePosition = config?.appearance.position || position;
21641
- // Apply custom styles
21642
- const customStyles = {};
21643
- if (primaryColor || config?.appearance.primaryColor) {
21644
- customStyles['--primary-color'] = primaryColor || config?.appearance.primaryColor || '';
21645
- }
21646
- if (config?.appearance.fontFamily) {
21647
- customStyles.fontFamily = config.appearance.fontFamily;
21648
- }
21649
- if (config?.appearance.borderRadius !== undefined) {
21650
- customStyles['--border-radius'] = `${config.appearance.borderRadius}px`;
21651
- }
21957
+ // Apply custom styles from appearance configuration
21958
+ // Use the correct theme configuration (lightMode or darkMode)
21959
+ const customStyles = appearanceConfig
21960
+ ? applyAppearanceStyles(appearanceConfig, effectiveTheme)
21961
+ : {};
21962
+ // Override with prop values if provided
21963
+ if (primaryColor) {
21964
+ customStyles['--primary-color'] = primaryColor;
21965
+ }
21966
+ // Debug logging for theme and styles
21967
+ react.useEffect(() => {
21968
+ console.log('[ChatWidget] Theme info:', {
21969
+ effectiveTheme,
21970
+ canUseDarkMode,
21971
+ themeSetting,
21972
+ systemPrefersDark,
21973
+ hasCustomStyles: Object.keys(customStyles).length > 0,
21974
+ buttonColor: customStyles['--button-color'],
21975
+ buttonSize: customStyles['--button-size'],
21976
+ cardBackground: customStyles['--card-background'],
21977
+ cardOpacity: customStyles['--card-opacity'],
21978
+ cardBorderRadius: customStyles['--card-border-radius'],
21979
+ });
21980
+ console.log('[ChatWidget] All CSS variables:', customStyles);
21981
+ }, [effectiveTheme, customStyles]);
21652
21982
  const handleToggle = () => {
21653
21983
  const newState = !isOpen;
21984
+ console.log('[ChatWidget] handleToggle called, setting isOpen to:', newState);
21654
21985
  setIsOpen(newState);
21655
21986
  if (newState) {
21656
21987
  onOpen?.();
@@ -21662,10 +21993,13 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
21662
21993
  const handleFeedback = async (messageId, feedback) => {
21663
21994
  await submitFeedback(messageId, feedback);
21664
21995
  };
21665
- return (jsxRuntime.jsx("div", { className: `ai-chat-widget ${effectiveTheme}`, style: customStyles, children: jsxRuntime.jsx("div", { 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 })) : (jsxRuntime.jsx("button", { className: "ai-chat-button", onClick: handleToggle, "aria-label": "Open chat", style: {
21666
- width: config?.appearance.buttonSize || 60,
21667
- height: config?.appearance.buttonSize || 60,
21668
- }, children: config?.appearance.buttonIcon ? (jsxRuntime.jsx("span", { className: "ai-chat-button-icon", children: config.appearance.buttonIcon })) : (jsxRuntime.jsx("svg", { className: "ai-chat-button-svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })) })) }) }));
21996
+ // Don't render until config is loaded to avoid flash of unstyled content
21997
+ if (!config) {
21998
+ console.log('[ChatWidget] Not rendering - config not loaded yet');
21999
+ return null;
22000
+ }
22001
+ console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
22002
+ return (jsxRuntime.jsx("div", { 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 })), !isOpen && (jsxRuntime.jsx("button", { className: "ai-chat-button", onClick: handleToggle, "aria-label": "Open chat", children: config?.appearance.buttonIcon ? (jsxRuntime.jsx("span", { className: "ai-chat-button-icon", children: config.appearance.buttonIcon })) : (jsxRuntime.jsx("svg", { className: "ai-chat-button-svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })) }))] }) }));
21669
22003
  };
21670
22004
 
21671
22005
  exports.ApiError = ApiError;