@ihoomanai/chat-widget 3.0.21 → 4.0.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.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @ihoomanai/chat-widget v3.0.21
3
- * Universal chat support widget for any website - secure Widget ID based initialization
2
+ * @ihoomanai/chat-widget v4.0.0
3
+ * Professional AI chat widget for any website - dark theme, modern design, secure Widget ID based initialization
4
4
  *
5
5
  * @license MIT
6
6
  * @copyright Ihooman AI
@@ -10,20 +10,20 @@
10
10
  * Enhanced with professional features
11
11
  * @version 3.0.0
12
12
  */
13
- const VERSION = '3.0.21';
13
+ const VERSION = '4.0.0';
14
14
  const STORAGE_PREFIX = 'ihooman_chat_';
15
15
  const DEFAULT_SERVER_URL = 'https://api.ihooman.ai';
16
16
  const defaultConfig = {
17
17
  serverUrl: DEFAULT_SERVER_URL,
18
- theme: 'light',
18
+ theme: 'dark',
19
19
  position: 'bottom-right',
20
- title: 'Chat Support',
21
- subtitle: 'We typically reply within minutes',
22
- welcomeMessage: 'Hi there! 👋 How can we help you today?',
23
- placeholder: 'Type a message...',
24
- primaryColor: '#00aeff',
25
- gradientFrom: '#00aeff',
26
- gradientTo: '#0066ff',
20
+ title: 'AI Assistant',
21
+ subtitle: 'Always here to help',
22
+ welcomeMessage: 'Hello! How can I help you today?',
23
+ placeholder: 'Send a message...',
24
+ primaryColor: '#ededed',
25
+ gradientFrom: '#171717',
26
+ gradientTo: '#171717',
27
27
  showTimestamps: true,
28
28
  showTypingIndicator: true,
29
29
  enableSounds: true,
@@ -31,11 +31,11 @@ const defaultConfig = {
31
31
  startOpen: false,
32
32
  persistSession: true,
33
33
  zIndex: 9999,
34
- width: 380,
35
- height: 560,
36
- buttonSize: 60,
34
+ width: 400,
35
+ height: 620,
36
+ buttonSize: 52,
37
37
  borderRadius: 16,
38
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
38
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, sans-serif',
39
39
  avatarUrl: '',
40
40
  poweredBy: true,
41
41
  presetQuestions: [],
@@ -45,18 +45,18 @@ const defaultConfig = {
45
45
  allowLocalhost: true,
46
46
  };
47
47
  const icons = {
48
- chat: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>`,
49
- close: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`,
50
- send: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>`,
51
- attach: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><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"></path></svg>`,
52
- minimize: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="5" y1="12" x2="19" y2="12"></line></svg>`,
53
- bot: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="10" rx="2"></rect><circle cx="12" cy="5" r="2"></circle><path d="M12 7v4"></path></svg>`,
54
- agent: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>`,
55
- ticket: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline></svg>`,
56
- history: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`,
57
- plus: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>`,
58
- star: `<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path></svg>`,
59
- starEmpty: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path></svg>`};
48
+ chat: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>`,
49
+ close: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`,
50
+ send: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg>`,
51
+ attach: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m21.44 11.05-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"></path></svg>`,
52
+ minimize: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"></path></svg>`,
53
+ sparkle: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path></svg>`,
54
+ agent: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="5"></circle><path d="M20 21a8 8 0 0 0-16 0"></path></svg>`,
55
+ ticket: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"></path><path d="M14 2v4a2 2 0 0 0 2 2h4"></path><path d="M10 18v-1"></path><path d="M14 18v-1"></path><path d="M10 14v-1"></path><path d="M14 14v-1"></path></svg>`,
56
+ history: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"></path><path d="M3 3v5h5"></path><path d="M12 7v5l4 2"></path></svg>`,
57
+ plus: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5v14"></path></svg>`,
58
+ star: `<svg viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>`,
59
+ starEmpty: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>`};
60
60
  let config = { widgetId: '', ...defaultConfig };
61
61
  let state = {
62
62
  isOpen: false,
@@ -202,21 +202,32 @@ function matchUrlPattern(pattern) {
202
202
  // STYLES
203
203
  // ============================================================================
204
204
  function generateStyles() {
205
- const { primaryColor, gradientFrom, gradientTo, fontFamily, borderRadius, zIndex, width, height, buttonSize } = config;
206
- const isDark = config.theme === 'dark';
207
- const bgColor = isDark ? '#1a1a2e' : '#ffffff';
208
- const textColor = isDark ? '#e4e4e7' : '#1f2937';
209
- const mutedColor = isDark ? '#71717a' : '#6b7280';
210
- const borderColor = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.08)';
211
- const inputBg = isDark ? '#16162a' : '#f9fafb';
212
- const messageBgUser = `linear-gradient(135deg, ${gradientFrom}, ${gradientTo})`;
213
- const messageBgBot = isDark ? '#252542' : '#f1f5f9';
205
+ const { fontFamily, borderRadius, zIndex, width, height, buttonSize } = config;
206
+ const isDark = config.theme === 'dark' || config.theme === 'auto';
207
+ // Professional dark/light color tokens Vercel-inspired
208
+ const bgColor = isDark ? '#0a0a0a' : '#ffffff';
209
+ const bgElevated = isDark ? '#141414' : '#fafafa';
210
+ const bgSurface = isDark ? '#1a1a1a' : '#f4f4f5';
211
+ const textColor = isDark ? '#ededed' : '#09090b';
212
+ const textSecondary = isDark ? '#a1a1aa' : '#71717a';
213
+ const mutedColor = isDark ? '#52525b' : '#a1a1aa';
214
+ const borderColor = isDark ? '#27272a' : '#e4e4e7';
215
+ const borderSubtle = isDark ? '#1f1f23' : '#f4f4f5';
216
+ const inputBg = isDark ? '#141414' : '#fafafa';
217
+ const hoverBg = isDark ? '#1c1c1c' : '#f4f4f5';
218
+ const accentColor = isDark ? '#ededed' : '#18181b';
219
+ const accentBg = isDark ? '#ededed' : '#18181b';
220
+ const accentText = isDark ? '#09090b' : '#fafafa';
221
+ const userMsgBg = isDark ? '#27272a' : '#18181b';
222
+ const userMsgText = isDark ? '#ededed' : '#fafafa';
223
+ const botMsgBg = 'transparent';
214
224
  const positionRight = config.position?.includes('right') ?? true;
215
225
  const positionBottom = config.position?.includes('bottom') ?? true;
226
+ const shadowLg = isDark ? '0 24px 48px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.05)' : '0 24px 48px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.05)';
216
227
  return `
217
228
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
218
229
  :host { all: initial; }
219
- .ihooman-widget { font-family: ${fontFamily}; font-size: 14px; line-height: 1.5; color: ${textColor}; -webkit-font-smoothing: antialiased; }
230
+ .ihooman-widget { font-family: ${fontFamily}; font-size: 14px; line-height: 1.6; color: ${textColor}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
220
231
  button {
221
232
  font-family: inherit;
222
233
  font-size: 100%;
@@ -229,144 +240,188 @@ function generateStyles() {
229
240
  cursor: pointer;
230
241
  outline: none;
231
242
  }
232
- .ihooman-toggle { position: fixed !important; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 20px' : 'top: 20px'}; width: ${buttonSize}px !important; height: ${buttonSize}px !important; border-radius: 50% !important; background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}) !important; border: none !important; cursor: pointer; z-index: ${zIndex}; display: flex !important; align-items: center; justify-content: center; box-shadow: 0 4px 20px rgba(0, 174, 255, 0.35); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow: hidden; }
233
- .ihooman-toggle:hover { transform: scale(1.08); box-shadow: 0 6px 28px rgba(0, 174, 255, 0.45); }
234
- .ihooman-toggle:active { transform: scale(0.95); }
235
- .ihooman-toggle::before { content: ''; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(255,255,255,0.2), transparent); border-radius: 50%; }
236
- .ihooman-toggle svg { width: 26px; height: 26px; color: white; transition: transform 0.3s ease, opacity 0.2s ease; position: relative; z-index: 1; }
237
- .ihooman-toggle .chat-icon { display: flex; align-items: center; justify-content: center; transition: transform 0.3s ease, opacity 0.2s ease; }
238
- .ihooman-toggle .close-icon { position: absolute; display: flex; align-items: center; justify-content: center; transform: rotate(-90deg) scale(0); opacity: 0; transition: transform 0.3s ease, opacity 0.2s ease; }
243
+ button:focus-visible { outline: 2px solid ${accentColor}; outline-offset: 2px; }
244
+
245
+ /* ── Toggle Button ── */
246
+ .ihooman-toggle { position: fixed !important; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 20px' : 'top: 20px'}; width: ${buttonSize}px !important; height: ${buttonSize}px !important; border-radius: 50% !important; background: ${accentBg} !important; border: 1px solid ${borderColor} !important; cursor: pointer; z-index: ${zIndex}; display: flex !important; align-items: center; justify-content: center; box-shadow: ${shadowLg}; transition: all 0.2s ease-out; overflow: hidden; }
247
+ .ihooman-toggle:hover { transform: scale(1.05); box-shadow: ${shadowLg}; }
248
+ .ihooman-toggle:active { transform: scale(0.96); }
249
+ .ihooman-toggle svg { width: 22px; height: 22px; color: ${accentText}; transition: transform 0.25s ease-out, opacity 0.15s ease; position: relative; z-index: 1; }
250
+ .ihooman-toggle .chat-icon { display: flex; align-items: center; justify-content: center; transition: transform 0.25s ease-out, opacity 0.15s ease; }
251
+ .ihooman-toggle .close-icon { position: absolute; display: flex; align-items: center; justify-content: center; transform: rotate(-90deg) scale(0); opacity: 0; transition: transform 0.25s ease-out, opacity 0.15s ease; }
239
252
  .ihooman-toggle.open .chat-icon { transform: rotate(90deg) scale(0); opacity: 0; }
240
253
  .ihooman-toggle.open .close-icon { transform: rotate(0) scale(1); opacity: 1; }
241
- .ihooman-pulse { position: absolute; inset: 0; border-radius: 50%; background: ${primaryColor}; animation: ihooman-pulse 2s ease-out infinite; }
242
- @keyframes ihooman-pulse { 0% { transform: scale(1); opacity: 0.5; } 100% { transform: scale(1.6); opacity: 0; } }
243
- .ihooman-toggle.open .ihooman-pulse { display: none; }
244
- .ihooman-badge { position: absolute; top: -4px; right: -4px; min-width: 20px; height: 20px; padding: 0 6px; background: #ef4444; color: white; font-size: 11px; font-weight: 600; border-radius: 10px; display: flex; align-items: center; justify-content: center; z-index: 2; }
254
+ .ihooman-pulse { display: none; }
255
+ .ihooman-badge { position: absolute; top: -3px; right: -3px; min-width: 18px; height: 18px; padding: 0 5px; background: #dc2626; color: white; font-size: 10px; font-weight: 600; border-radius: 9px; display: flex; align-items: center; justify-content: center; z-index: 2; border: 2px solid ${bgColor}; }
245
256
  .ihooman-badge:empty { display: none; }
246
- .ihooman-window { position: fixed; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 90px' : 'top: 90px'}; width: ${width}px; height: ${height}px; min-height: ${height}px; max-height: ${height}px; z-index: ${(zIndex ?? 9999) - 1}; display: flex; flex-direction: column; opacity: 0; visibility: hidden; transform: translateY(20px) scale(0.95); transition: opacity 0.3s, visibility 0.3s, transform 0.3s; overscroll-behavior: contain; }
257
+
258
+ /* ── Window ── */
259
+ .ihooman-window { position: fixed; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 84px' : 'top: 84px'}; width: ${width}px; height: ${height}px; min-height: ${height}px; max-height: ${height}px; z-index: ${(zIndex ?? 9999) - 1}; display: flex; flex-direction: column; opacity: 0; visibility: hidden; transform: translateY(12px) scale(0.97); transition: opacity 0.2s ease-out, visibility 0.2s ease-out, transform 0.2s ease-out; overscroll-behavior: contain; }
247
260
  .ihooman-window.open { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
248
- .ihooman-container { position: relative; width: 100%; height: 100%; display: flex; flex-direction: column; border-radius: ${borderRadius}px; overflow: hidden; flex-shrink: 0; }
249
- .ihooman-container::before { content: ''; position: absolute; inset: 0; background: ${bgColor}; opacity: 0.97; backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-radius: ${borderRadius}px; border: 1px solid ${borderColor}; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); }
250
- .ihooman-container > * { position: relative; z-index: 1; }
251
- .ihooman-header { padding: 16px 20px; background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
252
- .ihooman-header-avatar { width: 42px; height: 42px; border-radius: 50%; background: rgba(255,255,255,0.2); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
253
- .ihooman-header-avatar img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
254
- .ihooman-header-avatar svg { width: 22px; height: 22px; }
261
+
262
+ /* ── Container ── */
263
+ .ihooman-container { position: relative; width: 100%; height: 100%; display: flex; flex-direction: column; border-radius: ${borderRadius}px; overflow: hidden; flex-shrink: 0; background: ${bgColor}; border: 1px solid ${borderColor}; box-shadow: ${shadowLg}; }
264
+
265
+ /* ── Header ── */
266
+ .ihooman-header { padding: 14px 16px; background: ${bgElevated}; color: ${textColor}; display: flex; align-items: center; gap: 12px; flex-shrink: 0; border-bottom: 1px solid ${borderColor}; }
267
+ .ihooman-header-avatar { width: 36px; height: 36px; border-radius: 10px; background: ${bgSurface}; display: flex; align-items: center; justify-content: center; flex-shrink: 0; border: 1px solid ${borderColor}; }
268
+ .ihooman-header-avatar img { width: 100%; height: 100%; border-radius: 10px; object-fit: cover; }
269
+ .ihooman-header-avatar svg { width: 18px; height: 18px; color: ${textSecondary}; }
255
270
  .ihooman-header-info { flex: 1; min-width: 0; }
256
- .ihooman-header-title { font-size: 16px; font-weight: 600; margin-bottom: 2px; }
257
- .ihooman-header-status { display: flex; align-items: center; gap: 6px; font-size: 12px; opacity: 0.9; }
258
- .ihooman-status-dot { width: 8px; height: 8px; border-radius: 50%; background: #22c55e; }
259
- .ihooman-status-dot.offline { background: #f59e0b; }
260
- .ihooman-header-actions { display: flex; gap: 8px; }
261
- .ihooman-header-btn { width: 28px; height: 28px; border-radius: 6px; background: rgba(255,255,255,0.15); border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; color: white; transition: background 0.2s; }
262
- .ihooman-header-btn:hover { background: rgba(255,255,255,0.25); }
263
- .ihooman-header-btn svg { width: 14px; height: 14px; }
264
- .ihooman-messages { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 16px; display: flex; flex-direction: column; gap: 12px; background: ${bgColor}; overscroll-behavior: contain; min-height: 0; }
265
- .ihooman-messages::-webkit-scrollbar { width: 6px; }
271
+ .ihooman-header-title { font-size: 14px; font-weight: 600; margin-bottom: 1px; letter-spacing: -0.01em; color: ${textColor}; }
272
+ .ihooman-header-status { display: flex; align-items: center; gap: 5px; font-size: 12px; color: ${textSecondary}; }
273
+ .ihooman-status-dot { width: 6px; height: 6px; border-radius: 50%; background: #22c55e; flex-shrink: 0; }
274
+ .ihooman-status-dot.offline { background: #a1a1aa; }
275
+ .ihooman-header-actions { display: flex; gap: 4px; }
276
+ .ihooman-header-btn { width: 30px; height: 30px; border-radius: 8px; background: transparent; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; color: ${textSecondary}; transition: background 0.15s ease, color 0.15s ease; }
277
+ .ihooman-header-btn:hover { background: ${hoverBg}; color: ${textColor}; }
278
+ .ihooman-header-btn svg { width: 15px; height: 15px; }
279
+
280
+ /* ── Messages ── */
281
+ .ihooman-messages { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 20px 16px; display: flex; flex-direction: column; gap: 6px; background: ${bgColor}; overscroll-behavior: contain; min-height: 0; }
282
+ .ihooman-messages::-webkit-scrollbar { width: 4px; }
266
283
  .ihooman-messages::-webkit-scrollbar-track { background: transparent; }
267
- .ihooman-messages::-webkit-scrollbar-thumb { background: ${borderColor}; border-radius: 3px; }
268
- .ihooman-message { display: flex; flex-direction: column; max-width: 85%; animation: ihooman-fadeIn 0.3s ease; }
269
- @keyframes ihooman-fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
284
+ .ihooman-messages::-webkit-scrollbar-thumb { background: ${isDark ? '#27272a' : '#d4d4d8'}; border-radius: 2px; }
285
+ .ihooman-message { display: flex; flex-direction: column; max-width: 88%; animation: ihooman-fadeIn 0.25s ease-out; }
286
+ @keyframes ihooman-fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
270
287
  .ihooman-message.user { align-self: flex-end; align-items: flex-end; }
271
- .ihooman-message.bot { align-self: flex-start; align-items: flex-start; }
272
- .ihooman-message-content { padding: 12px 16px; border-radius: 16px; word-wrap: break-word; }
273
- .ihooman-message.user .ihooman-message-content { background: ${messageBgUser}; color: white; border-bottom-right-radius: 4px; }
274
- .ihooman-message.bot .ihooman-message-content { background: ${messageBgBot}; color: ${textColor}; border-bottom-left-radius: 4px; }
275
- .ihooman-message-content code { background: rgba(0,0,0,0.1); padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 13px; }
276
- .ihooman-message-time { font-size: 11px; color: ${mutedColor}; margin-top: 4px; padding: 0 4px; }
277
- .ihooman-typing { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: ${messageBgBot}; border-radius: 16px; border-bottom-left-radius: 4px; max-width: 80px; align-self: flex-start; }
278
- .ihooman-typing-dots { display: flex; gap: 4px; }
279
- .ihooman-typing-dot { width: 8px; height: 8px; background: ${mutedColor}; border-radius: 50%; animation: ihooman-typing 1.4s infinite; }
280
- .ihooman-typing-dot:nth-child(2) { animation-delay: 0.2s; }
281
- .ihooman-typing-dot:nth-child(3) { animation-delay: 0.4s; }
282
- @keyframes ihooman-typing { 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; } 30% { transform: translateY(-4px); opacity: 1; } }
288
+ .ihooman-message.bot { align-self: flex-start; align-items: flex-start; max-width: 100%; }
289
+ .ihooman-message-content { padding: 10px 14px; border-radius: 14px; word-wrap: break-word; overflow-wrap: break-word; font-size: 14px; line-height: 1.6; }
290
+ .ihooman-message.user .ihooman-message-content { background: ${userMsgBg}; color: ${userMsgText}; border-bottom-right-radius: 4px; }
291
+ .ihooman-message.bot .ihooman-message-content { background: ${botMsgBg}; color: ${textColor}; padding: 6px 2px; }
292
+ .ihooman-message-content a { color: ${isDark ? '#60a5fa' : '#2563eb'}; text-decoration: underline; text-underline-offset: 2px; }
293
+ .ihooman-message-content a:hover { opacity: 0.8; }
294
+ .ihooman-message-content code { background: ${isDark ? '#27272a' : '#f4f4f5'}; padding: 2px 6px; border-radius: 4px; font-family: 'SF Mono', 'Fira Code', 'Fira Mono', Menlo, Consolas, monospace; font-size: 12.5px; border: 1px solid ${borderSubtle}; }
295
+ .ihooman-message-content strong { font-weight: 600; }
296
+ .ihooman-message-time { font-size: 11px; color: ${mutedColor}; margin-top: 3px; padding: 0 4px; }
297
+
298
+ /* ── Typing Indicator — Shimmer ── */
299
+ .ihooman-typing { display: flex; align-items: center; gap: 10px; padding: 10px 2px; max-width: 180px; align-self: flex-start; animation: ihooman-fadeIn 0.2s ease-out; }
300
+ .ihooman-typing-shimmer { font-size: 13px; color: ${mutedColor}; background: linear-gradient(90deg, ${mutedColor} 25%, ${textSecondary} 50%, ${mutedColor} 75%); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; animation: ihooman-shimmer 1.5s ease-in-out infinite; }
301
+ @keyframes ihooman-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
302
+ .ihooman-typing-dots { display: flex; gap: 3px; align-items: center; }
303
+ .ihooman-typing-dot { width: 5px; height: 5px; background: ${mutedColor}; border-radius: 50%; animation: ihooman-typing 1.2s ease-in-out infinite; }
304
+ .ihooman-typing-dot:nth-child(2) { animation-delay: 0.15s; }
305
+ .ihooman-typing-dot:nth-child(3) { animation-delay: 0.3s; }
306
+ @keyframes ihooman-typing { 0%, 60%, 100% { opacity: 0.3; transform: scale(0.8); } 30% { opacity: 1; transform: scale(1); } }
307
+
308
+ /* ── Input Area ── */
283
309
  .ihooman-input-area { padding: 12px 16px; background: ${bgColor}; border-top: 1px solid ${borderColor}; flex-shrink: 0; }
284
- .ihooman-input-wrapper { display: flex; align-items: flex-end; gap: 8px; background: ${inputBg}; border: 1px solid ${borderColor}; border-radius: 12px; padding: 8px 12px; transition: border-color 0.2s, box-shadow 0.2s; }
285
- .ihooman-input-wrapper:focus-within { border-color: ${primaryColor}; box-shadow: 0 0 0 3px rgba(0, 174, 255, 0.1); }
286
- .ihooman-input { flex: 1; border: none; background: transparent; font-family: inherit; font-size: 14px; color: ${textColor}; resize: none; max-height: 100px; outline: none; line-height: 1.4; }
310
+ .ihooman-input-wrapper { display: flex; align-items: flex-end; gap: 8px; background: ${inputBg}; border: 1px solid ${borderColor}; border-radius: 12px; padding: 8px 12px; transition: border-color 0.15s ease, box-shadow 0.15s ease; }
311
+ .ihooman-input-wrapper:focus-within { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
312
+ .ihooman-input { flex: 1; border: none; background: transparent; font-family: inherit; font-size: 14px; color: ${textColor}; resize: none; max-height: 100px; outline: none; line-height: 1.5; }
287
313
  .ihooman-input::placeholder { color: ${mutedColor}; }
288
- .ihooman-input-btn { width: 32px; height: 32px; border-radius: 8px; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; background: transparent; color: ${mutedColor}; }
289
- .ihooman-input-btn:hover { background: ${borderColor}; color: ${textColor}; }
290
- .ihooman-input-btn.send { background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; }
291
- .ihooman-input-btn.send:hover { opacity: 0.9; }
292
- .ihooman-input-btn.send:disabled { opacity: 0.5; cursor: not-allowed; }
314
+ .ihooman-input-btn { width: 30px; height: 30px; border-radius: 8px; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.15s ease; background: transparent; color: ${mutedColor}; flex-shrink: 0; }
315
+ .ihooman-input-btn:hover { color: ${textColor}; background: ${hoverBg}; }
316
+ .ihooman-input-btn.send { background: ${accentBg}; color: ${accentText}; }
317
+ .ihooman-input-btn.send:hover { opacity: 0.85; }
318
+ .ihooman-input-btn.send:disabled { opacity: 0.3; cursor: not-allowed; }
293
319
  .ihooman-input-btn svg { width: 16px; height: 16px; }
294
- .ihooman-input:disabled { opacity: 0.6; cursor: not-allowed; }
295
- .ihooman-input-btn.attach:disabled { opacity: 0.4; cursor: not-allowed; }
320
+ .ihooman-input:disabled { opacity: 0.5; cursor: not-allowed; }
321
+ .ihooman-input-btn.attach:disabled { opacity: 0.3; cursor: not-allowed; }
296
322
  .ihooman-file-input { display: none; }
297
- .ihooman-powered { text-align: center; padding: 8px; font-size: 11px; color: ${mutedColor}; background: ${bgColor}; }
298
- .ihooman-powered a { color: ${primaryColor}; text-decoration: none; }
323
+
324
+ /* ── Powered By ── */
325
+ .ihooman-powered { text-align: center; padding: 8px; font-size: 11px; color: ${mutedColor}; background: ${bgColor}; border-top: 1px solid ${borderSubtle}; }
326
+ .ihooman-powered a { color: ${textSecondary}; text-decoration: none; font-weight: 500; }
327
+ .ihooman-powered a:hover { color: ${textColor}; }
328
+
329
+ /* ── Escalation ── */
299
330
  .ihooman-escalation-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
300
331
  .ihooman-escalation-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
301
- .ihooman-status-bar { padding: 10px 16px; text-align: center; font-size: 13px; display: none; }
332
+
333
+ /* ── Status Bar ── */
334
+ .ihooman-status-bar { padding: 8px 16px; text-align: center; font-size: 12px; display: none; font-weight: 500; }
302
335
  .ihooman-status-bar.show { display: block; }
303
- .ihooman-status-bar.waiting { background: #fef3c7; color: #92400e; }
304
- .ihooman-status-bar.connected { background: #dcfce7; color: #166534; }
336
+ .ihooman-status-bar.waiting { background: ${isDark ? '#1c1917' : '#fef9c3'}; color: ${isDark ? '#fbbf24' : '#92400e'}; border-bottom: 1px solid ${isDark ? '#292524' : '#fef08a'}; }
337
+ .ihooman-status-bar.connected { background: ${isDark ? '#052e16' : '#dcfce7'}; color: ${isDark ? '#4ade80' : '#166534'}; border-bottom: 1px solid ${isDark ? '#14532d' : '#bbf7d0'}; }
338
+
339
+ /* ── Chat View ── */
305
340
  .ihooman-chat-view { display: flex; flex-direction: column; flex: 1; overflow: hidden; min-height: 0; }
306
341
  .ihooman-chat-view.hidden { display: none; }
307
- .ihooman-ticket-view { display: none; flex-direction: column; padding: 20px; gap: 16px; background: ${bgColor}; flex: 1; overflow-y: auto; min-height: 0; }
342
+
343
+ /* ── Ticket View ── */
344
+ .ihooman-ticket-view { display: none; flex-direction: column; padding: 20px; gap: 14px; background: ${bgColor}; flex: 1; overflow-y: auto; min-height: 0; }
308
345
  .ihooman-ticket-view.show { display: flex; }
309
- .ihooman-ticket-title { font-size: 18px; font-weight: 600; color: ${textColor}; margin: 0; }
310
- .ihooman-ticket-subtitle { font-size: 13px; color: ${mutedColor}; margin: 0; }
311
- .ihooman-ticket-input { padding: 12px 14px; border: 1px solid ${borderColor}; border-radius: 10px; font-size: 14px; font-family: inherit; background: ${inputBg}; color: ${textColor}; outline: none; transition: border-color 0.2s; }
312
- .ihooman-ticket-input:focus { border-color: ${primaryColor}; }
346
+ .ihooman-ticket-title { font-size: 16px; font-weight: 600; color: ${textColor}; margin: 0; letter-spacing: -0.01em; }
347
+ .ihooman-ticket-subtitle { font-size: 13px; color: ${textSecondary}; margin: 0; }
348
+ .ihooman-ticket-input { padding: 10px 14px; border: 1px solid ${borderColor}; border-radius: 10px; font-size: 14px; font-family: inherit; background: ${inputBg}; color: ${textColor}; outline: none; transition: border-color 0.15s ease; }
349
+ .ihooman-ticket-input:focus { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
313
350
  .ihooman-ticket-input::placeholder { color: ${mutedColor}; }
314
351
  .ihooman-ticket-textarea { min-height: 100px; resize: vertical; }
315
- .ihooman-ticket-submit { display: flex; align-items: center; justify-content: center; padding: 12px; background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; border: none; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; line-height: 1.4; }
316
- .ihooman-ticket-submit:hover { opacity: 0.9; }
317
- .ihooman-ticket-submit:disabled { opacity: 0.5; cursor: not-allowed; }
318
- .ihooman-ticket-back { display: flex; align-items: center; justify-content: center; padding: 10px; background: transparent; color: ${mutedColor}; border: 1px solid ${borderColor}; border-radius: 8px; font-size: 13px; cursor: pointer; transition: all 0.2s; line-height: 1.4; }
319
- .ihooman-ticket-back:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)'}; }
352
+ .ihooman-ticket-submit { display: flex; align-items: center; justify-content: center; padding: 10px; background: ${accentBg}; color: ${accentText}; border: none; border-radius: 10px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.15s ease; line-height: 1.4; }
353
+ .ihooman-ticket-submit:hover { opacity: 0.85; }
354
+ .ihooman-ticket-submit:disabled { opacity: 0.4; cursor: not-allowed; }
355
+ .ihooman-ticket-back { display: flex; align-items: center; justify-content: center; padding: 10px; background: transparent; color: ${textSecondary}; border: 1px solid ${borderColor}; border-radius: 10px; font-size: 13px; cursor: pointer; transition: all 0.15s ease; line-height: 1.4; }
356
+ .ihooman-ticket-back:hover { background: ${hoverBg}; color: ${textColor}; }
357
+
358
+ /* ── History View ── */
320
359
  .ihooman-history-view { display: none; flex-direction: column; flex: 1; overflow: hidden; background: ${bgColor}; }
321
360
  .ihooman-history-view.show { display: flex; }
322
361
  .ihooman-history-header { padding: 12px 16px; border-bottom: 1px solid ${borderColor}; display: flex; justify-content: space-between; align-items: center; }
323
- .ihooman-history-title { font-size: 14px; font-weight: 600; color: ${textColor}; margin: 0; }
324
- .ihooman-history-new { display: inline-flex; align-items: center; justify-content: center; gap: 4px; background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; border: none; padding: 6px 12px; border-radius: 6px; font-size: 12px; font-weight: 500; cursor: pointer; transition: all 0.2s; line-height: 1.4; }
325
- .ihooman-history-new:hover { opacity: 0.9; }
362
+ .ihooman-history-title { font-size: 13px; font-weight: 600; color: ${textColor}; margin: 0; }
363
+ .ihooman-history-new { display: inline-flex; align-items: center; justify-content: center; gap: 4px; background: ${accentBg}; color: ${accentText}; border: none; padding: 6px 12px; border-radius: 8px; font-size: 12px; font-weight: 500; cursor: pointer; transition: all 0.15s ease; line-height: 1.4; }
364
+ .ihooman-history-new:hover { opacity: 0.85; }
326
365
  .ihooman-history-new svg { width: 12px; height: 12px; flex-shrink: 0; }
327
366
  .ihooman-history-list { flex: 1; overflow-y: auto; padding: 8px; overscroll-behavior: contain; }
328
- .ihooman-history-item { padding: 12px; border: 1px solid ${borderColor}; border-radius: 8px; margin-bottom: 6px; cursor: pointer; transition: all 0.2s; background: ${bgColor}; }
329
- .ihooman-history-item:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : '#f8fafc'}; }
330
- .ihooman-history-item.active { background: ${isDark ? 'rgba(0, 174, 255, 0.1)' : '#eff6ff'}; border-color: ${primaryColor}; }
367
+ .ihooman-history-item { padding: 12px; border: 1px solid ${borderColor}; border-radius: 10px; margin-bottom: 6px; cursor: pointer; transition: all 0.15s ease; background: ${bgColor}; }
368
+ .ihooman-history-item:hover { background: ${hoverBg}; }
369
+ .ihooman-history-item.active { background: ${hoverBg}; border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
331
370
  .ihooman-history-preview { font-size: 13px; color: ${textColor}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
332
371
  .ihooman-history-meta { font-size: 11px; color: ${mutedColor}; margin-top: 4px; display: flex; justify-content: space-between; }
333
- .ihooman-history-empty { padding: 40px; text-align: center; color: ${mutedColor}; font-size: 14px; }
334
- .ihooman-preset-questions { padding: 10px 16px; display: flex; flex-wrap: wrap; gap: 6px; background: ${bgColor}; border-top: 1px solid ${borderColor}; }
372
+ .ihooman-history-empty { padding: 40px; text-align: center; color: ${mutedColor}; font-size: 13px; }
373
+
374
+ /* ── Preset Questions ── */
375
+ .ihooman-preset-questions { padding: 10px 16px; display: flex; flex-wrap: wrap; gap: 6px; background: ${bgColor}; border-top: 1px solid ${borderSubtle}; }
335
376
  .ihooman-preset-questions:empty { display: none; }
336
377
  .ihooman-preset-questions.hidden { display: none; }
337
- .ihooman-proactive-toast { position: fixed; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 90px' : 'top: 90px'}; max-width: 300px; padding: 16px; background: ${bgColor}; border-radius: 12px; box-shadow: 0 10px 40px rgba(0,0,0,0.15); z-index: ${(zIndex ?? 9999) - 2}; opacity: 0; visibility: hidden; transform: translateY(10px); transition: all 0.3s ease; border: 1px solid ${borderColor}; }
378
+
379
+ /* ── Proactive Toast ── */
380
+ .ihooman-proactive-toast { position: fixed; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 84px' : 'top: 84px'}; max-width: 320px; padding: 16px; background: ${bgElevated}; border-radius: 14px; box-shadow: ${shadowLg}; z-index: ${(zIndex ?? 9999) - 2}; opacity: 0; visibility: hidden; transform: translateY(8px); transition: all 0.2s ease-out; border: 1px solid ${borderColor}; }
338
381
  .ihooman-proactive-toast.show { opacity: 1; visibility: visible; transform: translateY(0); }
339
- .ihooman-proactive-toast-content { font-size: 14px; color: ${textColor}; margin-bottom: 12px; }
382
+ .ihooman-proactive-toast-content { font-size: 14px; color: ${textColor}; margin-bottom: 12px; line-height: 1.5; }
340
383
  .ihooman-proactive-toast-actions { display: flex; gap: 8px; }
341
- .ihooman-proactive-toast-btn { display: inline-flex; align-items: center; justify-content: center; padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s; line-height: 1.4; }
342
- .ihooman-proactive-toast-btn.primary { background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; border: none; }
343
- .ihooman-proactive-toast-btn.primary:hover { opacity: 0.9; }
344
- .ihooman-proactive-toast-btn.secondary { background: transparent; color: ${mutedColor}; border: 1px solid ${borderColor}; }
345
- .ihooman-proactive-toast-btn.secondary:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)'}; }
346
- .ihooman-survey-view { display: none; flex-direction: column; padding: 20px; gap: 16px; background: ${bgColor}; flex: 1; align-items: center; justify-content: center; }
384
+ .ihooman-proactive-toast-btn { display: inline-flex; align-items: center; justify-content: center; padding: 8px 16px; border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.15s ease; line-height: 1.4; }
385
+ .ihooman-proactive-toast-btn.primary { background: ${accentBg}; color: ${accentText}; border: none; }
386
+ .ihooman-proactive-toast-btn.primary:hover { opacity: 0.85; }
387
+ .ihooman-proactive-toast-btn.secondary { background: transparent; color: ${textSecondary}; border: 1px solid ${borderColor}; }
388
+ .ihooman-proactive-toast-btn.secondary:hover { background: ${hoverBg}; }
389
+
390
+ /* ── Survey View ── */
391
+ .ihooman-survey-view { display: none; flex-direction: column; padding: 24px; gap: 16px; background: ${bgColor}; flex: 1; align-items: center; justify-content: center; }
347
392
  .ihooman-survey-view.show { display: flex; }
348
- .ihooman-survey-question { font-size: 16px; font-weight: 600; color: ${textColor}; text-align: center; }
393
+ .ihooman-survey-question { font-size: 16px; font-weight: 600; color: ${textColor}; text-align: center; letter-spacing: -0.01em; }
349
394
  .ihooman-survey-stars { display: flex; gap: 8px; }
350
- .ihooman-survey-star { width: 40px; height: 40px; cursor: pointer; color: ${mutedColor}; transition: all 0.2s; }
395
+ .ihooman-survey-star { width: 36px; height: 36px; cursor: pointer; color: ${mutedColor}; transition: all 0.15s ease; }
351
396
  .ihooman-survey-star:hover, .ihooman-survey-star.active { color: #fbbf24; transform: scale(1.1); }
352
397
  .ihooman-survey-star svg { width: 100%; height: 100%; }
353
- .ihooman-survey-comment { width: 100%; padding: 12px; border: 1px solid ${borderColor}; border-radius: 8px; font-size: 14px; resize: none; min-height: 80px; background: ${inputBg}; color: ${textColor}; }
354
- .ihooman-survey-submit { display: inline-flex; align-items: center; justify-content: center; padding: 10px 20px; background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; border: none; border-radius: 6px; font-size: 13px; font-weight: 500; cursor: pointer; line-height: 1.4; }
355
- .ihooman-survey-submit:hover { opacity: 0.9; }
398
+ .ihooman-survey-comment { width: 100%; padding: 12px; border: 1px solid ${borderColor}; border-radius: 10px; font-size: 14px; font-family: inherit; resize: none; min-height: 80px; background: ${inputBg}; color: ${textColor}; outline: none; }
399
+ .ihooman-survey-comment:focus { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
400
+ .ihooman-survey-submit { display: inline-flex; align-items: center; justify-content: center; padding: 10px 20px; background: ${accentBg}; color: ${accentText}; border: none; border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer; line-height: 1.4; transition: all 0.15s ease; }
401
+ .ihooman-survey-submit:hover { opacity: 0.85; }
356
402
  .ihooman-survey-skip { display: inline-flex; align-items: center; justify-content: center; padding: 8px 16px; background: transparent; color: ${mutedColor}; border: none; font-size: 12px; cursor: pointer; line-height: 1.4; }
357
403
  .ihooman-survey-skip:hover { color: ${textColor}; }
358
- .ihooman-feedback-btns { display: flex; gap: 6px; margin-top: 6px; }
404
+
405
+ /* ── Feedback ── */
406
+ .ihooman-feedback-btns { display: flex; gap: 4px; margin-top: 4px; }
359
407
  .ihooman-feedback-btn svg { width: 12px; height: 12px; }
360
- .ihooman-carousel { display: flex; gap: 12px; overflow-x: auto; padding: 8px 0; scroll-snap-type: x mandatory; }
361
- .ihooman-carousel::-webkit-scrollbar { height: 4px; }
362
- .ihooman-carousel-card { min-width: 200px; max-width: 250px; border: 1px solid ${borderColor}; border-radius: 12px; overflow: hidden; scroll-snap-align: start; background: ${bgColor}; }
408
+
409
+ /* ── Carousel ── */
410
+ .ihooman-carousel { display: flex; gap: 10px; overflow-x: auto; padding: 8px 0; scroll-snap-type: x mandatory; }
411
+ .ihooman-carousel::-webkit-scrollbar { height: 3px; }
412
+ .ihooman-carousel::-webkit-scrollbar-thumb { background: ${isDark ? '#27272a' : '#d4d4d8'}; border-radius: 2px; }
413
+ .ihooman-carousel-card { min-width: 200px; max-width: 250px; border: 1px solid ${borderColor}; border-radius: 12px; overflow: hidden; scroll-snap-align: start; background: ${bgElevated}; }
363
414
  .ihooman-carousel-card img { width: 100%; height: 120px; object-fit: cover; }
364
415
  .ihooman-carousel-card-content { padding: 12px; }
365
- .ihooman-carousel-card-title { font-size: 14px; font-weight: 600; color: ${textColor}; margin-bottom: 4px; }
366
- .ihooman-carousel-card-desc { font-size: 12px; color: ${mutedColor}; margin-bottom: 8px; }
416
+ .ihooman-carousel-card-title { font-size: 13px; font-weight: 600; color: ${textColor}; margin-bottom: 4px; }
417
+ .ihooman-carousel-card-desc { font-size: 12px; color: ${textSecondary}; margin-bottom: 8px; }
367
418
  .ihooman-carousel-card-btns { display: flex; flex-direction: column; gap: 6px; }
419
+
420
+ /* ── Quick Replies ── */
368
421
  .ihooman-quick-replies { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
369
- @media (max-width: 480px) { .ihooman-window { width: calc(100vw - 20px); height: calc(100vh - 100px); min-height: 400px; max-height: calc(100vh - 100px); left: 10px; right: 10px; bottom: 80px; } .ihooman-toggle { ${positionRight ? 'right: 16px' : 'left: 16px'}; bottom: 16px; } .ihooman-proactive-toast { left: 10px; right: 10px; max-width: none; } }
422
+
423
+ /* ── Responsive ── */
424
+ @media (max-width: 480px) { .ihooman-window { width: calc(100vw - 16px); height: calc(100vh - 100px); min-height: 400px; max-height: calc(100vh - 100px); left: 8px; right: 8px; bottom: 80px; } .ihooman-toggle { ${positionRight ? 'right: 16px' : 'left: 16px'}; bottom: 16px; } .ihooman-proactive-toast { left: 8px; right: 8px; max-width: none; } }
370
425
  `;
371
426
  }
372
427
  // ============================================================================
@@ -406,9 +461,9 @@ function createWidget() {
406
461
  <div class="ihooman-window" role="dialog" aria-label="Chat window">
407
462
  <div class="ihooman-container">
408
463
  <div class="ihooman-header">
409
- <div class="ihooman-header-avatar">${config.avatarUrl ? `<img src="${escapeHtml(config.avatarUrl)}" alt="Support">` : icons.bot}</div>
464
+ <div class="ihooman-header-avatar">${config.avatarUrl ? `<img src="${escapeHtml(config.avatarUrl)}" alt="Assistant">` : icons.sparkle}</div>
410
465
  <div class="ihooman-header-info">
411
- <div class="ihooman-header-title">${escapeHtml(config.title || 'Chat Support')}</div>
466
+ <div class="ihooman-header-title">${escapeHtml(config.title || 'AI Assistant')}</div>
412
467
  <div class="ihooman-header-status"><span class="ihooman-status-dot"></span><span class="ihooman-status-text">Online</span></div>
413
468
  </div>
414
469
  <div class="ihooman-header-actions">
@@ -430,7 +485,7 @@ function createWidget() {
430
485
  </div>
431
486
  </div>
432
487
  <div class="ihooman-ticket-view">
433
- <h4 class="ihooman-ticket-title">📝 Submit a Ticket</h4>
488
+ <h4 class="ihooman-ticket-title">Submit a Ticket</h4>
434
489
  <p class="ihooman-ticket-subtitle">We'll get back to you via email</p>
435
490
  <input class="ihooman-ticket-input" id="ihooman-ticket-name" placeholder="Your name" required>
436
491
  <input class="ihooman-ticket-input" id="ihooman-ticket-email" type="email" placeholder="Your email" required>
@@ -889,6 +944,7 @@ async function handleRequestLiveAgent() {
889
944
  function startLiveAgentPolling() {
890
945
  if (liveAgentPollInterval)
891
946
  return;
947
+ let agentConnected = false;
892
948
  liveAgentPollInterval = setInterval(async () => {
893
949
  if (!state.sessionId || !isLiveAgentMode) {
894
950
  stopLiveAgentPolling();
@@ -902,6 +958,12 @@ function startLiveAgentPolling() {
902
958
  // Check both ticket_status and conversation_status for agent handling
903
959
  if (data.ticket_status === 'in_progress' || data.conversation_status === 'active') {
904
960
  updateStatusBar('connected', '🟢 Connected to live agent');
961
+ // Agent is connected — stop polling, WebSocket handles real-time updates.
962
+ // Status changes (close/resolve) will come through WebSocket messages.
963
+ if (!agentConnected) {
964
+ agentConnected = true;
965
+ stopLiveAgentPolling();
966
+ }
905
967
  }
906
968
  else if (data.ticket_status === 'open') {
907
969
  updateStatusBar('waiting', data.position_in_queue > 1
@@ -919,7 +981,7 @@ function startLiveAgentPolling() {
919
981
  }
920
982
  }
921
983
  catch { /* ignore */ }
922
- }, 3000);
984
+ }, 15000);
923
985
  }
924
986
  function stopLiveAgentPolling() {
925
987
  if (liveAgentPollInterval) {
@@ -1014,7 +1076,7 @@ function showTyping() {
1014
1076
  return;
1015
1077
  const typing = document.createElement('div');
1016
1078
  typing.className = 'ihooman-typing';
1017
- typing.innerHTML = `<div class="ihooman-typing-dots"><span class="ihooman-typing-dot"></span><span class="ihooman-typing-dot"></span><span class="ihooman-typing-dot"></span></div>`;
1079
+ typing.innerHTML = `<span class="ihooman-typing-shimmer">Thinking...</span><div class="ihooman-typing-dots"><span class="ihooman-typing-dot"></span><span class="ihooman-typing-dot"></span><span class="ihooman-typing-dot"></span></div>`;
1018
1080
  elements.messages.appendChild(typing);
1019
1081
  elements.messages.scrollTop = elements.messages.scrollHeight;
1020
1082
  }
@@ -1036,7 +1098,7 @@ function disableInput() {
1036
1098
  function enableInput() {
1037
1099
  if (elements.input) {
1038
1100
  elements.input.disabled = false;
1039
- elements.input.placeholder = config.placeholder || 'Type a message...';
1101
+ elements.input.placeholder = config.placeholder || 'Send a message...';
1040
1102
  }
1041
1103
  if (elements.sendBtn)
1042
1104
  elements.sendBtn.disabled = !elements.input?.value.trim();
@@ -1326,7 +1388,7 @@ function connectWebSocket(chatEndpoint) {
1326
1388
  emit('connected');
1327
1389
  startHeartbeat();
1328
1390
  };
1329
- ws.onclose = (_event) => {
1391
+ ws.onclose = (event) => {
1330
1392
  state.isConnected = false;
1331
1393
  state.connectionStatus = 'disconnected';
1332
1394
  updateStatus(false);
@@ -1336,6 +1398,9 @@ function connectWebSocket(chatEndpoint) {
1336
1398
  intentionalDisconnect = false;
1337
1399
  return;
1338
1400
  }
1401
+ // Code 4002 means this connection was replaced by a newer one — don't reconnect
1402
+ if (event.code === 4002)
1403
+ return;
1339
1404
  if (!state.isOpen)
1340
1405
  return;
1341
1406
  if (reconnectAttempts < maxReconnectAttempts) {
@@ -1657,11 +1722,10 @@ function getFontWeightValue(weight) {
1657
1722
  default: return 500;
1658
1723
  }
1659
1724
  }
1660
- // Default button styles - MUST match client-dashboard/src/components/widget/ButtonStylingEditor.tsx
1661
1725
  const DEFAULT_BUTTON_STYLES = {
1662
1726
  primary: {
1663
- backgroundColor: '#00aeff',
1664
- textColor: '#ffffff',
1727
+ backgroundColor: '#ededed',
1728
+ textColor: '#09090b',
1665
1729
  borderColor: 'transparent',
1666
1730
  borderWidth: 0,
1667
1731
  borderRadius: 8,
@@ -1672,8 +1736,8 @@ const DEFAULT_BUTTON_STYLES = {
1672
1736
  },
1673
1737
  secondary: {
1674
1738
  backgroundColor: 'transparent',
1675
- textColor: '#6b7280',
1676
- borderColor: '#e5e7eb',
1739
+ textColor: '#a1a1aa',
1740
+ borderColor: '#27272a',
1677
1741
  borderWidth: 1,
1678
1742
  borderRadius: 8,
1679
1743
  paddingVertical: 8,
@@ -1682,9 +1746,9 @@ const DEFAULT_BUTTON_STYLES = {
1682
1746
  fontWeight: 'medium',
1683
1747
  },
1684
1748
  presetQuestions: {
1685
- backgroundColor: 'rgba(0, 174, 255, 0.1)',
1686
- textColor: '#00aeff',
1687
- borderColor: 'rgba(0, 174, 255, 0.2)',
1749
+ backgroundColor: 'transparent',
1750
+ textColor: '#a1a1aa',
1751
+ borderColor: '#27272a',
1688
1752
  borderWidth: 1,
1689
1753
  borderRadius: 20,
1690
1754
  paddingVertical: 6,
@@ -1693,9 +1757,9 @@ const DEFAULT_BUTTON_STYLES = {
1693
1757
  fontWeight: 'medium',
1694
1758
  },
1695
1759
  quickReplies: {
1696
- backgroundColor: '#f3f4f6',
1697
- textColor: '#374151',
1698
- borderColor: '#e5e7eb',
1760
+ backgroundColor: '#1a1a1a',
1761
+ textColor: '#a1a1aa',
1762
+ borderColor: '#27272a',
1699
1763
  borderWidth: 1,
1700
1764
  borderRadius: 16,
1701
1765
  paddingVertical: 5,
@@ -1705,8 +1769,8 @@ const DEFAULT_BUTTON_STYLES = {
1705
1769
  },
1706
1770
  feedback: {
1707
1771
  backgroundColor: 'transparent',
1708
- textColor: '#9ca3af',
1709
- borderColor: '#e5e7eb',
1772
+ textColor: '#52525b',
1773
+ borderColor: '#27272a',
1710
1774
  borderWidth: 1,
1711
1775
  borderRadius: 6,
1712
1776
  paddingVertical: 4,
@@ -1715,19 +1779,19 @@ const DEFAULT_BUTTON_STYLES = {
1715
1779
  fontWeight: 'medium',
1716
1780
  },
1717
1781
  headerActions: {
1718
- backgroundColor: 'rgba(255, 255, 255, 0.1)',
1719
- textColor: '#ffffff',
1782
+ backgroundColor: 'transparent',
1783
+ textColor: '#a1a1aa',
1720
1784
  borderColor: 'transparent',
1721
1785
  borderWidth: 0,
1722
- borderRadius: 6,
1786
+ borderRadius: 8,
1723
1787
  paddingVertical: 6,
1724
1788
  paddingHorizontal: 6,
1725
1789
  fontSize: 14,
1726
1790
  fontWeight: 'medium',
1727
1791
  },
1728
1792
  escalation: {
1729
- backgroundColor: '#00aeff',
1730
- textColor: '#ffffff',
1793
+ backgroundColor: '#ededed',
1794
+ textColor: '#09090b',
1731
1795
  borderColor: 'transparent',
1732
1796
  borderWidth: 0,
1733
1797
  borderRadius: 8,
@@ -1737,21 +1801,21 @@ const DEFAULT_BUTTON_STYLES = {
1737
1801
  fontWeight: 'medium',
1738
1802
  },
1739
1803
  cardActions: {
1740
- backgroundColor: '#00aeff',
1741
- textColor: '#ffffff',
1804
+ backgroundColor: '#ededed',
1805
+ textColor: '#09090b',
1742
1806
  borderColor: 'transparent',
1743
1807
  borderWidth: 0,
1744
- borderRadius: 6,
1808
+ borderRadius: 8,
1745
1809
  paddingVertical: 6,
1746
1810
  paddingHorizontal: 12,
1747
1811
  fontSize: 12,
1748
1812
  fontWeight: 'medium',
1749
1813
  },
1750
1814
  toggleButton: {
1751
- backgroundColor: '#00aeff',
1752
- textColor: '#ffffff',
1753
- borderColor: 'transparent',
1754
- borderWidth: 0,
1815
+ backgroundColor: '#ededed',
1816
+ textColor: '#09090b',
1817
+ borderColor: '#27272a',
1818
+ borderWidth: 1,
1755
1819
  borderRadius: 30,
1756
1820
  paddingVertical: 0,
1757
1821
  paddingHorizontal: 0,
@@ -1760,7 +1824,7 @@ const DEFAULT_BUTTON_STYLES = {
1760
1824
  },
1761
1825
  attachButton: {
1762
1826
  backgroundColor: 'transparent',
1763
- textColor: '#6b7280',
1827
+ textColor: '#52525b',
1764
1828
  borderColor: 'transparent',
1765
1829
  borderWidth: 0,
1766
1830
  borderRadius: 8,