@ihoomanai/chat-widget 3.0.22 → 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/src/widget.ts CHANGED
@@ -17,21 +17,21 @@ import type {
17
17
  WidgetView,
18
18
  } from './types';
19
19
 
20
- const VERSION = '3.0.21';
20
+ const VERSION = '4.0.0';
21
21
  const STORAGE_PREFIX = 'ihooman_chat_';
22
22
  const DEFAULT_SERVER_URL = 'https://api.ihooman.ai';
23
23
 
24
24
  const defaultConfig: Partial<WidgetConfig> = {
25
25
  serverUrl: DEFAULT_SERVER_URL,
26
- theme: 'light',
26
+ theme: 'dark',
27
27
  position: 'bottom-right',
28
- title: 'Chat Support',
29
- subtitle: 'We typically reply within minutes',
30
- welcomeMessage: 'Hi there! 👋 How can we help you today?',
31
- placeholder: 'Type a message...',
32
- primaryColor: '#00aeff',
33
- gradientFrom: '#00aeff',
34
- gradientTo: '#0066ff',
28
+ title: 'AI Assistant',
29
+ subtitle: 'Always here to help',
30
+ welcomeMessage: 'Hello! How can I help you today?',
31
+ placeholder: 'Send a message...',
32
+ primaryColor: '#ededed',
33
+ gradientFrom: '#171717',
34
+ gradientTo: '#171717',
35
35
  showTimestamps: true,
36
36
  showTypingIndicator: true,
37
37
  enableSounds: true,
@@ -39,11 +39,11 @@ const defaultConfig: Partial<WidgetConfig> = {
39
39
  startOpen: false,
40
40
  persistSession: true,
41
41
  zIndex: 9999,
42
- width: 380,
43
- height: 560,
44
- buttonSize: 60,
42
+ width: 400,
43
+ height: 620,
44
+ buttonSize: 52,
45
45
  borderRadius: 16,
46
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
46
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, sans-serif',
47
47
  avatarUrl: '',
48
48
  poweredBy: true,
49
49
  presetQuestions: [],
@@ -54,22 +54,23 @@ const defaultConfig: Partial<WidgetConfig> = {
54
54
  };
55
55
 
56
56
  const icons = {
57
- 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>`,
58
- 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>`,
59
- 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>`,
60
- 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>`,
61
- 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>`,
62
- 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>`,
63
- 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>`,
64
- 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>`,
65
- 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>`,
66
- 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>`,
67
- 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>`,
68
- 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>`,
69
- thumbUp: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"></path></svg>`,
70
- thumbDown: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"></path></svg>`,
71
- chevronLeft: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"></polyline></svg>`,
72
- chevronRight: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"></polyline></svg>`,
57
+ 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>`,
58
+ 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>`,
59
+ 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>`,
60
+ 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>`,
61
+ 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>`,
62
+ 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>`,
63
+ bot: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8V4H8"></path><rect width="16" height="12" x="4" y="8" rx="2"></rect><path d="M2 14h2"></path><path d="M20 14h2"></path><path d="M15 13v2"></path><path d="M9 13v2"></path></svg>`,
64
+ 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>`,
65
+ 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>`,
66
+ 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>`,
67
+ 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>`,
68
+ 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>`,
69
+ 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>`,
70
+ thumbUp: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M7 10v12"></path><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"></path></svg>`,
71
+ thumbDown: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M17 14V2"></path><path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z"></path></svg>`,
72
+ chevronLeft: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"></path></svg>`,
73
+ chevronRight: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"></path></svg>`,
73
74
  };
74
75
 
75
76
  let config: WidgetConfig = { widgetId: '', ...defaultConfig };
@@ -245,22 +246,34 @@ function matchUrlPattern(pattern: string): boolean {
245
246
  // ============================================================================
246
247
 
247
248
  function generateStyles(): string {
248
- const { primaryColor, gradientFrom, gradientTo, fontFamily, borderRadius, zIndex, width, height, buttonSize } = config;
249
- const isDark = config.theme === 'dark';
250
- const bgColor = isDark ? '#1a1a2e' : '#ffffff';
251
- const textColor = isDark ? '#e4e4e7' : '#1f2937';
252
- const mutedColor = isDark ? '#71717a' : '#6b7280';
253
- const borderColor = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.08)';
254
- const inputBg = isDark ? '#16162a' : '#f9fafb';
255
- const messageBgUser = `linear-gradient(135deg, ${gradientFrom}, ${gradientTo})`;
256
- const messageBgBot = isDark ? '#252542' : '#f1f5f9';
249
+ const { fontFamily, borderRadius, zIndex, width, height, buttonSize } = config;
250
+ const isDark = config.theme === 'dark' || config.theme === 'auto';
251
+
252
+ // Professional dark/light color tokens Vercel-inspired
253
+ const bgColor = isDark ? '#0a0a0a' : '#ffffff';
254
+ const bgElevated = isDark ? '#141414' : '#fafafa';
255
+ const bgSurface = isDark ? '#1a1a1a' : '#f4f4f5';
256
+ const textColor = isDark ? '#ededed' : '#09090b';
257
+ const textSecondary = isDark ? '#a1a1aa' : '#71717a';
258
+ const mutedColor = isDark ? '#52525b' : '#a1a1aa';
259
+ const borderColor = isDark ? '#27272a' : '#e4e4e7';
260
+ const borderSubtle = isDark ? '#1f1f23' : '#f4f4f5';
261
+ const inputBg = isDark ? '#141414' : '#fafafa';
262
+ const hoverBg = isDark ? '#1c1c1c' : '#f4f4f5';
263
+ const accentColor = isDark ? '#ededed' : '#18181b';
264
+ const accentBg = isDark ? '#ededed' : '#18181b';
265
+ const accentText = isDark ? '#09090b' : '#fafafa';
266
+ const userMsgBg = isDark ? '#27272a' : '#18181b';
267
+ const userMsgText = isDark ? '#ededed' : '#fafafa';
268
+ const botMsgBg = 'transparent';
257
269
  const positionRight = config.position?.includes('right') ?? true;
258
270
  const positionBottom = config.position?.includes('bottom') ?? true;
271
+ 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)';
259
272
 
260
273
  return `
261
274
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
262
275
  :host { all: initial; }
263
- .ihooman-widget { font-family: ${fontFamily}; font-size: 14px; line-height: 1.5; color: ${textColor}; -webkit-font-smoothing: antialiased; }
276
+ .ihooman-widget { font-family: ${fontFamily}; font-size: 14px; line-height: 1.6; color: ${textColor}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
264
277
  button {
265
278
  font-family: inherit;
266
279
  font-size: 100%;
@@ -273,144 +286,188 @@ function generateStyles(): string {
273
286
  cursor: pointer;
274
287
  outline: none;
275
288
  }
276
- .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; }
277
- .ihooman-toggle:hover { transform: scale(1.08); box-shadow: 0 6px 28px rgba(0, 174, 255, 0.45); }
278
- .ihooman-toggle:active { transform: scale(0.95); }
279
- .ihooman-toggle::before { content: ''; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(255,255,255,0.2), transparent); border-radius: 50%; }
280
- .ihooman-toggle svg { width: 26px; height: 26px; color: white; transition: transform 0.3s ease, opacity 0.2s ease; position: relative; z-index: 1; }
281
- .ihooman-toggle .chat-icon { display: flex; align-items: center; justify-content: center; transition: transform 0.3s ease, opacity 0.2s ease; }
282
- .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; }
289
+ button:focus-visible { outline: 2px solid ${accentColor}; outline-offset: 2px; }
290
+
291
+ /* ── Toggle Button ── */
292
+ .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; }
293
+ .ihooman-toggle:hover { transform: scale(1.05); box-shadow: ${shadowLg}; }
294
+ .ihooman-toggle:active { transform: scale(0.96); }
295
+ .ihooman-toggle svg { width: 22px; height: 22px; color: ${accentText}; transition: transform 0.25s ease-out, opacity 0.15s ease; position: relative; z-index: 1; }
296
+ .ihooman-toggle .chat-icon { display: flex; align-items: center; justify-content: center; transition: transform 0.25s ease-out, opacity 0.15s ease; }
297
+ .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; }
283
298
  .ihooman-toggle.open .chat-icon { transform: rotate(90deg) scale(0); opacity: 0; }
284
299
  .ihooman-toggle.open .close-icon { transform: rotate(0) scale(1); opacity: 1; }
285
- .ihooman-pulse { position: absolute; inset: 0; border-radius: 50%; background: ${primaryColor}; animation: ihooman-pulse 2s ease-out infinite; }
286
- @keyframes ihooman-pulse { 0% { transform: scale(1); opacity: 0.5; } 100% { transform: scale(1.6); opacity: 0; } }
287
- .ihooman-toggle.open .ihooman-pulse { display: none; }
288
- .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; }
300
+ .ihooman-pulse { display: none; }
301
+ .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}; }
289
302
  .ihooman-badge:empty { display: none; }
290
- .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; }
303
+
304
+ /* ── Window ── */
305
+ .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; }
291
306
  .ihooman-window.open { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
292
- .ihooman-container { position: relative; width: 100%; height: 100%; display: flex; flex-direction: column; border-radius: ${borderRadius}px; overflow: hidden; flex-shrink: 0; }
293
- .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); }
294
- .ihooman-container > * { position: relative; z-index: 1; }
295
- .ihooman-header { padding: 16px 20px; background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
296
- .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; }
297
- .ihooman-header-avatar img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
298
- .ihooman-header-avatar svg { width: 22px; height: 22px; }
307
+
308
+ /* ── Container ── */
309
+ .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}; }
310
+
311
+ /* ── Header ── */
312
+ .ihooman-header { padding: 14px 16px; background: ${bgElevated}; color: ${textColor}; display: flex; align-items: center; gap: 12px; flex-shrink: 0; border-bottom: 1px solid ${borderColor}; }
313
+ .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}; }
314
+ .ihooman-header-avatar img { width: 100%; height: 100%; border-radius: 10px; object-fit: cover; }
315
+ .ihooman-header-avatar svg { width: 18px; height: 18px; color: ${textSecondary}; }
299
316
  .ihooman-header-info { flex: 1; min-width: 0; }
300
- .ihooman-header-title { font-size: 16px; font-weight: 600; margin-bottom: 2px; }
301
- .ihooman-header-status { display: flex; align-items: center; gap: 6px; font-size: 12px; opacity: 0.9; }
302
- .ihooman-status-dot { width: 8px; height: 8px; border-radius: 50%; background: #22c55e; }
303
- .ihooman-status-dot.offline { background: #f59e0b; }
304
- .ihooman-header-actions { display: flex; gap: 8px; }
305
- .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; }
306
- .ihooman-header-btn:hover { background: rgba(255,255,255,0.25); }
307
- .ihooman-header-btn svg { width: 14px; height: 14px; }
308
- .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; }
309
- .ihooman-messages::-webkit-scrollbar { width: 6px; }
317
+ .ihooman-header-title { font-size: 14px; font-weight: 600; margin-bottom: 1px; letter-spacing: -0.01em; color: ${textColor}; }
318
+ .ihooman-header-status { display: flex; align-items: center; gap: 5px; font-size: 12px; color: ${textSecondary}; }
319
+ .ihooman-status-dot { width: 6px; height: 6px; border-radius: 50%; background: #22c55e; flex-shrink: 0; }
320
+ .ihooman-status-dot.offline { background: #a1a1aa; }
321
+ .ihooman-header-actions { display: flex; gap: 4px; }
322
+ .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; }
323
+ .ihooman-header-btn:hover { background: ${hoverBg}; color: ${textColor}; }
324
+ .ihooman-header-btn svg { width: 15px; height: 15px; }
325
+
326
+ /* ── Messages ── */
327
+ .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; }
328
+ .ihooman-messages::-webkit-scrollbar { width: 4px; }
310
329
  .ihooman-messages::-webkit-scrollbar-track { background: transparent; }
311
- .ihooman-messages::-webkit-scrollbar-thumb { background: ${borderColor}; border-radius: 3px; }
312
- .ihooman-message { display: flex; flex-direction: column; max-width: 85%; animation: ihooman-fadeIn 0.3s ease; }
313
- @keyframes ihooman-fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
330
+ .ihooman-messages::-webkit-scrollbar-thumb { background: ${isDark ? '#27272a' : '#d4d4d8'}; border-radius: 2px; }
331
+ .ihooman-message { display: flex; flex-direction: column; max-width: 88%; animation: ihooman-fadeIn 0.25s ease-out; }
332
+ @keyframes ihooman-fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
314
333
  .ihooman-message.user { align-self: flex-end; align-items: flex-end; }
315
- .ihooman-message.bot { align-self: flex-start; align-items: flex-start; }
316
- .ihooman-message-content { padding: 12px 16px; border-radius: 16px; word-wrap: break-word; }
317
- .ihooman-message.user .ihooman-message-content { background: ${messageBgUser}; color: white; border-bottom-right-radius: 4px; }
318
- .ihooman-message.bot .ihooman-message-content { background: ${messageBgBot}; color: ${textColor}; border-bottom-left-radius: 4px; }
319
- .ihooman-message-content code { background: rgba(0,0,0,0.1); padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 13px; }
320
- .ihooman-message-time { font-size: 11px; color: ${mutedColor}; margin-top: 4px; padding: 0 4px; }
321
- .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; }
322
- .ihooman-typing-dots { display: flex; gap: 4px; }
323
- .ihooman-typing-dot { width: 8px; height: 8px; background: ${mutedColor}; border-radius: 50%; animation: ihooman-typing 1.4s infinite; }
324
- .ihooman-typing-dot:nth-child(2) { animation-delay: 0.2s; }
325
- .ihooman-typing-dot:nth-child(3) { animation-delay: 0.4s; }
326
- @keyframes ihooman-typing { 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; } 30% { transform: translateY(-4px); opacity: 1; } }
334
+ .ihooman-message.bot { align-self: flex-start; align-items: flex-start; max-width: 100%; }
335
+ .ihooman-message-content { padding: 10px 14px; border-radius: 14px; word-wrap: break-word; overflow-wrap: break-word; font-size: 14px; line-height: 1.6; }
336
+ .ihooman-message.user .ihooman-message-content { background: ${userMsgBg}; color: ${userMsgText}; border-bottom-right-radius: 4px; }
337
+ .ihooman-message.bot .ihooman-message-content { background: ${botMsgBg}; color: ${textColor}; padding: 6px 2px; }
338
+ .ihooman-message-content a { color: ${isDark ? '#60a5fa' : '#2563eb'}; text-decoration: underline; text-underline-offset: 2px; }
339
+ .ihooman-message-content a:hover { opacity: 0.8; }
340
+ .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}; }
341
+ .ihooman-message-content strong { font-weight: 600; }
342
+ .ihooman-message-time { font-size: 11px; color: ${mutedColor}; margin-top: 3px; padding: 0 4px; }
343
+
344
+ /* ── Typing Indicator — Shimmer ── */
345
+ .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; }
346
+ .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; }
347
+ @keyframes ihooman-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
348
+ .ihooman-typing-dots { display: flex; gap: 3px; align-items: center; }
349
+ .ihooman-typing-dot { width: 5px; height: 5px; background: ${mutedColor}; border-radius: 50%; animation: ihooman-typing 1.2s ease-in-out infinite; }
350
+ .ihooman-typing-dot:nth-child(2) { animation-delay: 0.15s; }
351
+ .ihooman-typing-dot:nth-child(3) { animation-delay: 0.3s; }
352
+ @keyframes ihooman-typing { 0%, 60%, 100% { opacity: 0.3; transform: scale(0.8); } 30% { opacity: 1; transform: scale(1); } }
353
+
354
+ /* ── Input Area ── */
327
355
  .ihooman-input-area { padding: 12px 16px; background: ${bgColor}; border-top: 1px solid ${borderColor}; flex-shrink: 0; }
328
- .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; }
329
- .ihooman-input-wrapper:focus-within { border-color: ${primaryColor}; box-shadow: 0 0 0 3px rgba(0, 174, 255, 0.1); }
330
- .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; }
356
+ .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; }
357
+ .ihooman-input-wrapper:focus-within { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
358
+ .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; }
331
359
  .ihooman-input::placeholder { color: ${mutedColor}; }
332
- .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}; }
333
- .ihooman-input-btn:hover { background: ${borderColor}; color: ${textColor}; }
334
- .ihooman-input-btn.send { background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; }
335
- .ihooman-input-btn.send:hover { opacity: 0.9; }
336
- .ihooman-input-btn.send:disabled { opacity: 0.5; cursor: not-allowed; }
360
+ .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; }
361
+ .ihooman-input-btn:hover { color: ${textColor}; background: ${hoverBg}; }
362
+ .ihooman-input-btn.send { background: ${accentBg}; color: ${accentText}; }
363
+ .ihooman-input-btn.send:hover { opacity: 0.85; }
364
+ .ihooman-input-btn.send:disabled { opacity: 0.3; cursor: not-allowed; }
337
365
  .ihooman-input-btn svg { width: 16px; height: 16px; }
338
- .ihooman-input:disabled { opacity: 0.6; cursor: not-allowed; }
339
- .ihooman-input-btn.attach:disabled { opacity: 0.4; cursor: not-allowed; }
366
+ .ihooman-input:disabled { opacity: 0.5; cursor: not-allowed; }
367
+ .ihooman-input-btn.attach:disabled { opacity: 0.3; cursor: not-allowed; }
340
368
  .ihooman-file-input { display: none; }
341
- .ihooman-powered { text-align: center; padding: 8px; font-size: 11px; color: ${mutedColor}; background: ${bgColor}; }
342
- .ihooman-powered a { color: ${primaryColor}; text-decoration: none; }
369
+
370
+ /* ── Powered By ── */
371
+ .ihooman-powered { text-align: center; padding: 8px; font-size: 11px; color: ${mutedColor}; background: ${bgColor}; border-top: 1px solid ${borderSubtle}; }
372
+ .ihooman-powered a { color: ${textSecondary}; text-decoration: none; font-weight: 500; }
373
+ .ihooman-powered a:hover { color: ${textColor}; }
374
+
375
+ /* ── Escalation ── */
343
376
  .ihooman-escalation-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
344
377
  .ihooman-escalation-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
345
- .ihooman-status-bar { padding: 10px 16px; text-align: center; font-size: 13px; display: none; }
378
+
379
+ /* ── Status Bar ── */
380
+ .ihooman-status-bar { padding: 8px 16px; text-align: center; font-size: 12px; display: none; font-weight: 500; }
346
381
  .ihooman-status-bar.show { display: block; }
347
- .ihooman-status-bar.waiting { background: #fef3c7; color: #92400e; }
348
- .ihooman-status-bar.connected { background: #dcfce7; color: #166534; }
382
+ .ihooman-status-bar.waiting { background: ${isDark ? '#1c1917' : '#fef9c3'}; color: ${isDark ? '#fbbf24' : '#92400e'}; border-bottom: 1px solid ${isDark ? '#292524' : '#fef08a'}; }
383
+ .ihooman-status-bar.connected { background: ${isDark ? '#052e16' : '#dcfce7'}; color: ${isDark ? '#4ade80' : '#166534'}; border-bottom: 1px solid ${isDark ? '#14532d' : '#bbf7d0'}; }
384
+
385
+ /* ── Chat View ── */
349
386
  .ihooman-chat-view { display: flex; flex-direction: column; flex: 1; overflow: hidden; min-height: 0; }
350
387
  .ihooman-chat-view.hidden { display: none; }
351
- .ihooman-ticket-view { display: none; flex-direction: column; padding: 20px; gap: 16px; background: ${bgColor}; flex: 1; overflow-y: auto; min-height: 0; }
388
+
389
+ /* ── Ticket View ── */
390
+ .ihooman-ticket-view { display: none; flex-direction: column; padding: 20px; gap: 14px; background: ${bgColor}; flex: 1; overflow-y: auto; min-height: 0; }
352
391
  .ihooman-ticket-view.show { display: flex; }
353
- .ihooman-ticket-title { font-size: 18px; font-weight: 600; color: ${textColor}; margin: 0; }
354
- .ihooman-ticket-subtitle { font-size: 13px; color: ${mutedColor}; margin: 0; }
355
- .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; }
356
- .ihooman-ticket-input:focus { border-color: ${primaryColor}; }
392
+ .ihooman-ticket-title { font-size: 16px; font-weight: 600; color: ${textColor}; margin: 0; letter-spacing: -0.01em; }
393
+ .ihooman-ticket-subtitle { font-size: 13px; color: ${textSecondary}; margin: 0; }
394
+ .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; }
395
+ .ihooman-ticket-input:focus { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
357
396
  .ihooman-ticket-input::placeholder { color: ${mutedColor}; }
358
397
  .ihooman-ticket-textarea { min-height: 100px; resize: vertical; }
359
- .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; }
360
- .ihooman-ticket-submit:hover { opacity: 0.9; }
361
- .ihooman-ticket-submit:disabled { opacity: 0.5; cursor: not-allowed; }
362
- .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; }
363
- .ihooman-ticket-back:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)'}; }
398
+ .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; }
399
+ .ihooman-ticket-submit:hover { opacity: 0.85; }
400
+ .ihooman-ticket-submit:disabled { opacity: 0.4; cursor: not-allowed; }
401
+ .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; }
402
+ .ihooman-ticket-back:hover { background: ${hoverBg}; color: ${textColor}; }
403
+
404
+ /* ── History View ── */
364
405
  .ihooman-history-view { display: none; flex-direction: column; flex: 1; overflow: hidden; background: ${bgColor}; }
365
406
  .ihooman-history-view.show { display: flex; }
366
407
  .ihooman-history-header { padding: 12px 16px; border-bottom: 1px solid ${borderColor}; display: flex; justify-content: space-between; align-items: center; }
367
- .ihooman-history-title { font-size: 14px; font-weight: 600; color: ${textColor}; margin: 0; }
368
- .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; }
369
- .ihooman-history-new:hover { opacity: 0.9; }
408
+ .ihooman-history-title { font-size: 13px; font-weight: 600; color: ${textColor}; margin: 0; }
409
+ .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; }
410
+ .ihooman-history-new:hover { opacity: 0.85; }
370
411
  .ihooman-history-new svg { width: 12px; height: 12px; flex-shrink: 0; }
371
412
  .ihooman-history-list { flex: 1; overflow-y: auto; padding: 8px; overscroll-behavior: contain; }
372
- .ihooman-history-item { padding: 12px; border: 1px solid ${borderColor}; border-radius: 8px; margin-bottom: 6px; cursor: pointer; transition: all 0.2s; background: ${bgColor}; }
373
- .ihooman-history-item:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : '#f8fafc'}; }
374
- .ihooman-history-item.active { background: ${isDark ? 'rgba(0, 174, 255, 0.1)' : '#eff6ff'}; border-color: ${primaryColor}; }
413
+ .ihooman-history-item { padding: 12px; border: 1px solid ${borderColor}; border-radius: 10px; margin-bottom: 6px; cursor: pointer; transition: all 0.15s ease; background: ${bgColor}; }
414
+ .ihooman-history-item:hover { background: ${hoverBg}; }
415
+ .ihooman-history-item.active { background: ${hoverBg}; border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
375
416
  .ihooman-history-preview { font-size: 13px; color: ${textColor}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
376
417
  .ihooman-history-meta { font-size: 11px; color: ${mutedColor}; margin-top: 4px; display: flex; justify-content: space-between; }
377
- .ihooman-history-empty { padding: 40px; text-align: center; color: ${mutedColor}; font-size: 14px; }
378
- .ihooman-preset-questions { padding: 10px 16px; display: flex; flex-wrap: wrap; gap: 6px; background: ${bgColor}; border-top: 1px solid ${borderColor}; }
418
+ .ihooman-history-empty { padding: 40px; text-align: center; color: ${mutedColor}; font-size: 13px; }
419
+
420
+ /* ── Preset Questions ── */
421
+ .ihooman-preset-questions { padding: 10px 16px; display: flex; flex-wrap: wrap; gap: 6px; background: ${bgColor}; border-top: 1px solid ${borderSubtle}; }
379
422
  .ihooman-preset-questions:empty { display: none; }
380
423
  .ihooman-preset-questions.hidden { display: none; }
381
- .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}; }
424
+
425
+ /* ── Proactive Toast ── */
426
+ .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}; }
382
427
  .ihooman-proactive-toast.show { opacity: 1; visibility: visible; transform: translateY(0); }
383
- .ihooman-proactive-toast-content { font-size: 14px; color: ${textColor}; margin-bottom: 12px; }
428
+ .ihooman-proactive-toast-content { font-size: 14px; color: ${textColor}; margin-bottom: 12px; line-height: 1.5; }
384
429
  .ihooman-proactive-toast-actions { display: flex; gap: 8px; }
385
- .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; }
386
- .ihooman-proactive-toast-btn.primary { background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; border: none; }
387
- .ihooman-proactive-toast-btn.primary:hover { opacity: 0.9; }
388
- .ihooman-proactive-toast-btn.secondary { background: transparent; color: ${mutedColor}; border: 1px solid ${borderColor}; }
389
- .ihooman-proactive-toast-btn.secondary:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)'}; }
390
- .ihooman-survey-view { display: none; flex-direction: column; padding: 20px; gap: 16px; background: ${bgColor}; flex: 1; align-items: center; justify-content: center; }
430
+ .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; }
431
+ .ihooman-proactive-toast-btn.primary { background: ${accentBg}; color: ${accentText}; border: none; }
432
+ .ihooman-proactive-toast-btn.primary:hover { opacity: 0.85; }
433
+ .ihooman-proactive-toast-btn.secondary { background: transparent; color: ${textSecondary}; border: 1px solid ${borderColor}; }
434
+ .ihooman-proactive-toast-btn.secondary:hover { background: ${hoverBg}; }
435
+
436
+ /* ── Survey View ── */
437
+ .ihooman-survey-view { display: none; flex-direction: column; padding: 24px; gap: 16px; background: ${bgColor}; flex: 1; align-items: center; justify-content: center; }
391
438
  .ihooman-survey-view.show { display: flex; }
392
- .ihooman-survey-question { font-size: 16px; font-weight: 600; color: ${textColor}; text-align: center; }
439
+ .ihooman-survey-question { font-size: 16px; font-weight: 600; color: ${textColor}; text-align: center; letter-spacing: -0.01em; }
393
440
  .ihooman-survey-stars { display: flex; gap: 8px; }
394
- .ihooman-survey-star { width: 40px; height: 40px; cursor: pointer; color: ${mutedColor}; transition: all 0.2s; }
441
+ .ihooman-survey-star { width: 36px; height: 36px; cursor: pointer; color: ${mutedColor}; transition: all 0.15s ease; }
395
442
  .ihooman-survey-star:hover, .ihooman-survey-star.active { color: #fbbf24; transform: scale(1.1); }
396
443
  .ihooman-survey-star svg { width: 100%; height: 100%; }
397
- .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}; }
398
- .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; }
399
- .ihooman-survey-submit:hover { opacity: 0.9; }
444
+ .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; }
445
+ .ihooman-survey-comment:focus { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
446
+ .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; }
447
+ .ihooman-survey-submit:hover { opacity: 0.85; }
400
448
  .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; }
401
449
  .ihooman-survey-skip:hover { color: ${textColor}; }
402
- .ihooman-feedback-btns { display: flex; gap: 6px; margin-top: 6px; }
450
+
451
+ /* ── Feedback ── */
452
+ .ihooman-feedback-btns { display: flex; gap: 4px; margin-top: 4px; }
403
453
  .ihooman-feedback-btn svg { width: 12px; height: 12px; }
404
- .ihooman-carousel { display: flex; gap: 12px; overflow-x: auto; padding: 8px 0; scroll-snap-type: x mandatory; }
405
- .ihooman-carousel::-webkit-scrollbar { height: 4px; }
406
- .ihooman-carousel-card { min-width: 200px; max-width: 250px; border: 1px solid ${borderColor}; border-radius: 12px; overflow: hidden; scroll-snap-align: start; background: ${bgColor}; }
454
+
455
+ /* ── Carousel ── */
456
+ .ihooman-carousel { display: flex; gap: 10px; overflow-x: auto; padding: 8px 0; scroll-snap-type: x mandatory; }
457
+ .ihooman-carousel::-webkit-scrollbar { height: 3px; }
458
+ .ihooman-carousel::-webkit-scrollbar-thumb { background: ${isDark ? '#27272a' : '#d4d4d8'}; border-radius: 2px; }
459
+ .ihooman-carousel-card { min-width: 200px; max-width: 250px; border: 1px solid ${borderColor}; border-radius: 12px; overflow: hidden; scroll-snap-align: start; background: ${bgElevated}; }
407
460
  .ihooman-carousel-card img { width: 100%; height: 120px; object-fit: cover; }
408
461
  .ihooman-carousel-card-content { padding: 12px; }
409
- .ihooman-carousel-card-title { font-size: 14px; font-weight: 600; color: ${textColor}; margin-bottom: 4px; }
410
- .ihooman-carousel-card-desc { font-size: 12px; color: ${mutedColor}; margin-bottom: 8px; }
462
+ .ihooman-carousel-card-title { font-size: 13px; font-weight: 600; color: ${textColor}; margin-bottom: 4px; }
463
+ .ihooman-carousel-card-desc { font-size: 12px; color: ${textSecondary}; margin-bottom: 8px; }
411
464
  .ihooman-carousel-card-btns { display: flex; flex-direction: column; gap: 6px; }
465
+
466
+ /* ── Quick Replies ── */
412
467
  .ihooman-quick-replies { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
413
- @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; } }
468
+
469
+ /* ── Responsive ── */
470
+ @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; } }
414
471
  `;
415
472
  }
416
473
 
@@ -457,9 +514,9 @@ function createWidget(): void {
457
514
  <div class="ihooman-window" role="dialog" aria-label="Chat window">
458
515
  <div class="ihooman-container">
459
516
  <div class="ihooman-header">
460
- <div class="ihooman-header-avatar">${config.avatarUrl ? `<img src="${escapeHtml(config.avatarUrl)}" alt="Support">` : icons.bot}</div>
517
+ <div class="ihooman-header-avatar">${config.avatarUrl ? `<img src="${escapeHtml(config.avatarUrl)}" alt="Assistant">` : icons.sparkle}</div>
461
518
  <div class="ihooman-header-info">
462
- <div class="ihooman-header-title">${escapeHtml(config.title || 'Chat Support')}</div>
519
+ <div class="ihooman-header-title">${escapeHtml(config.title || 'AI Assistant')}</div>
463
520
  <div class="ihooman-header-status"><span class="ihooman-status-dot"></span><span class="ihooman-status-text">Online</span></div>
464
521
  </div>
465
522
  <div class="ihooman-header-actions">
@@ -481,7 +538,7 @@ function createWidget(): void {
481
538
  </div>
482
539
  </div>
483
540
  <div class="ihooman-ticket-view">
484
- <h4 class="ihooman-ticket-title">📝 Submit a Ticket</h4>
541
+ <h4 class="ihooman-ticket-title">Submit a Ticket</h4>
485
542
  <p class="ihooman-ticket-subtitle">We'll get back to you via email</p>
486
543
  <input class="ihooman-ticket-input" id="ihooman-ticket-name" placeholder="Your name" required>
487
544
  <input class="ihooman-ticket-input" id="ihooman-ticket-email" type="email" placeholder="Your email" required>
@@ -990,6 +1047,8 @@ async function handleRequestLiveAgent(): Promise<void> {
990
1047
  function startLiveAgentPolling(): void {
991
1048
  if (liveAgentPollInterval) return;
992
1049
 
1050
+ let agentConnected = false;
1051
+
993
1052
  liveAgentPollInterval = setInterval(async () => {
994
1053
  if (!state.sessionId || !isLiveAgentMode) {
995
1054
  stopLiveAgentPolling();
@@ -1006,6 +1065,12 @@ function startLiveAgentPolling(): void {
1006
1065
  // Check both ticket_status and conversation_status for agent handling
1007
1066
  if (data.ticket_status === 'in_progress' || data.conversation_status === 'active') {
1008
1067
  updateStatusBar('connected', '🟢 Connected to live agent');
1068
+ // Agent is connected — stop polling, WebSocket handles real-time updates.
1069
+ // Status changes (close/resolve) will come through WebSocket messages.
1070
+ if (!agentConnected) {
1071
+ agentConnected = true;
1072
+ stopLiveAgentPolling();
1073
+ }
1009
1074
  } else if (data.ticket_status === 'open') {
1010
1075
  updateStatusBar('waiting', data.position_in_queue > 1
1011
1076
  ? `⏳ Waiting for agent (Position: #${data.position_in_queue})`
@@ -1020,7 +1085,7 @@ function startLiveAgentPolling(): void {
1020
1085
  }
1021
1086
  }
1022
1087
  } catch { /* ignore */ }
1023
- }, 3000);
1088
+ }, 15000);
1024
1089
  }
1025
1090
 
1026
1091
  function stopLiveAgentPolling(): void {
@@ -1126,7 +1191,7 @@ function showTyping(): void {
1126
1191
 
1127
1192
  const typing = document.createElement('div');
1128
1193
  typing.className = 'ihooman-typing';
1129
- 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>`;
1194
+ 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>`;
1130
1195
  elements.messages.appendChild(typing);
1131
1196
  elements.messages.scrollTop = elements.messages.scrollHeight;
1132
1197
  }
@@ -1148,7 +1213,7 @@ function disableInput(): void {
1148
1213
  function enableInput(): void {
1149
1214
  if (elements.input) {
1150
1215
  elements.input.disabled = false;
1151
- elements.input.placeholder = config.placeholder || 'Type a message...';
1216
+ elements.input.placeholder = config.placeholder || 'Send a message...';
1152
1217
  }
1153
1218
  if (elements.sendBtn) elements.sendBtn.disabled = !elements.input?.value.trim();
1154
1219
  if (elements.attachBtn) elements.attachBtn.disabled = false;
@@ -1871,11 +1936,10 @@ function getFontWeightValue(weight: string): number {
1871
1936
  }
1872
1937
  }
1873
1938
 
1874
- // Default button styles - MUST match client-dashboard/src/components/widget/ButtonStylingEditor.tsx
1875
1939
  const DEFAULT_BUTTON_STYLES = {
1876
1940
  primary: {
1877
- backgroundColor: '#00aeff',
1878
- textColor: '#ffffff',
1941
+ backgroundColor: '#ededed',
1942
+ textColor: '#09090b',
1879
1943
  borderColor: 'transparent',
1880
1944
  borderWidth: 0,
1881
1945
  borderRadius: 8,
@@ -1886,8 +1950,8 @@ const DEFAULT_BUTTON_STYLES = {
1886
1950
  },
1887
1951
  secondary: {
1888
1952
  backgroundColor: 'transparent',
1889
- textColor: '#6b7280',
1890
- borderColor: '#e5e7eb',
1953
+ textColor: '#a1a1aa',
1954
+ borderColor: '#27272a',
1891
1955
  borderWidth: 1,
1892
1956
  borderRadius: 8,
1893
1957
  paddingVertical: 8,
@@ -1896,9 +1960,9 @@ const DEFAULT_BUTTON_STYLES = {
1896
1960
  fontWeight: 'medium',
1897
1961
  },
1898
1962
  presetQuestions: {
1899
- backgroundColor: 'rgba(0, 174, 255, 0.1)',
1900
- textColor: '#00aeff',
1901
- borderColor: 'rgba(0, 174, 255, 0.2)',
1963
+ backgroundColor: 'transparent',
1964
+ textColor: '#a1a1aa',
1965
+ borderColor: '#27272a',
1902
1966
  borderWidth: 1,
1903
1967
  borderRadius: 20,
1904
1968
  paddingVertical: 6,
@@ -1907,9 +1971,9 @@ const DEFAULT_BUTTON_STYLES = {
1907
1971
  fontWeight: 'medium',
1908
1972
  },
1909
1973
  quickReplies: {
1910
- backgroundColor: '#f3f4f6',
1911
- textColor: '#374151',
1912
- borderColor: '#e5e7eb',
1974
+ backgroundColor: '#1a1a1a',
1975
+ textColor: '#a1a1aa',
1976
+ borderColor: '#27272a',
1913
1977
  borderWidth: 1,
1914
1978
  borderRadius: 16,
1915
1979
  paddingVertical: 5,
@@ -1919,8 +1983,8 @@ const DEFAULT_BUTTON_STYLES = {
1919
1983
  },
1920
1984
  feedback: {
1921
1985
  backgroundColor: 'transparent',
1922
- textColor: '#9ca3af',
1923
- borderColor: '#e5e7eb',
1986
+ textColor: '#52525b',
1987
+ borderColor: '#27272a',
1924
1988
  borderWidth: 1,
1925
1989
  borderRadius: 6,
1926
1990
  paddingVertical: 4,
@@ -1929,19 +1993,19 @@ const DEFAULT_BUTTON_STYLES = {
1929
1993
  fontWeight: 'medium',
1930
1994
  },
1931
1995
  headerActions: {
1932
- backgroundColor: 'rgba(255, 255, 255, 0.1)',
1933
- textColor: '#ffffff',
1996
+ backgroundColor: 'transparent',
1997
+ textColor: '#a1a1aa',
1934
1998
  borderColor: 'transparent',
1935
1999
  borderWidth: 0,
1936
- borderRadius: 6,
2000
+ borderRadius: 8,
1937
2001
  paddingVertical: 6,
1938
2002
  paddingHorizontal: 6,
1939
2003
  fontSize: 14,
1940
2004
  fontWeight: 'medium',
1941
2005
  },
1942
2006
  escalation: {
1943
- backgroundColor: '#00aeff',
1944
- textColor: '#ffffff',
2007
+ backgroundColor: '#ededed',
2008
+ textColor: '#09090b',
1945
2009
  borderColor: 'transparent',
1946
2010
  borderWidth: 0,
1947
2011
  borderRadius: 8,
@@ -1951,21 +2015,21 @@ const DEFAULT_BUTTON_STYLES = {
1951
2015
  fontWeight: 'medium',
1952
2016
  },
1953
2017
  cardActions: {
1954
- backgroundColor: '#00aeff',
1955
- textColor: '#ffffff',
2018
+ backgroundColor: '#ededed',
2019
+ textColor: '#09090b',
1956
2020
  borderColor: 'transparent',
1957
2021
  borderWidth: 0,
1958
- borderRadius: 6,
2022
+ borderRadius: 8,
1959
2023
  paddingVertical: 6,
1960
2024
  paddingHorizontal: 12,
1961
2025
  fontSize: 12,
1962
2026
  fontWeight: 'medium',
1963
2027
  },
1964
2028
  toggleButton: {
1965
- backgroundColor: '#00aeff',
1966
- textColor: '#ffffff',
1967
- borderColor: 'transparent',
1968
- borderWidth: 0,
2029
+ backgroundColor: '#ededed',
2030
+ textColor: '#09090b',
2031
+ borderColor: '#27272a',
2032
+ borderWidth: 1,
1969
2033
  borderRadius: 30,
1970
2034
  paddingVertical: 0,
1971
2035
  paddingHorizontal: 0,
@@ -1974,7 +2038,7 @@ const DEFAULT_BUTTON_STYLES = {
1974
2038
  },
1975
2039
  attachButton: {
1976
2040
  backgroundColor: 'transparent',
1977
- textColor: '#6b7280',
2041
+ textColor: '#52525b',
1978
2042
  borderColor: 'transparent',
1979
2043
  borderWidth: 0,
1980
2044
  borderRadius: 8,