@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.cjs.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
@@ -14,20 +14,20 @@ Object.defineProperty(exports, '__esModule', { value: true });
14
14
  * Enhanced with professional features
15
15
  * @version 3.0.0
16
16
  */
17
- const VERSION = '3.0.21';
17
+ const VERSION = '4.0.0';
18
18
  const STORAGE_PREFIX = 'ihooman_chat_';
19
19
  const DEFAULT_SERVER_URL = 'https://api.ihooman.ai';
20
20
  const defaultConfig = {
21
21
  serverUrl: DEFAULT_SERVER_URL,
22
- theme: 'light',
22
+ theme: 'dark',
23
23
  position: 'bottom-right',
24
- title: 'Chat Support',
25
- subtitle: 'We typically reply within minutes',
26
- welcomeMessage: 'Hi there! 👋 How can we help you today?',
27
- placeholder: 'Type a message...',
28
- primaryColor: '#00aeff',
29
- gradientFrom: '#00aeff',
30
- gradientTo: '#0066ff',
24
+ title: 'AI Assistant',
25
+ subtitle: 'Always here to help',
26
+ welcomeMessage: 'Hello! How can I help you today?',
27
+ placeholder: 'Send a message...',
28
+ primaryColor: '#ededed',
29
+ gradientFrom: '#171717',
30
+ gradientTo: '#171717',
31
31
  showTimestamps: true,
32
32
  showTypingIndicator: true,
33
33
  enableSounds: true,
@@ -35,11 +35,11 @@ const defaultConfig = {
35
35
  startOpen: false,
36
36
  persistSession: true,
37
37
  zIndex: 9999,
38
- width: 380,
39
- height: 560,
40
- buttonSize: 60,
38
+ width: 400,
39
+ height: 620,
40
+ buttonSize: 52,
41
41
  borderRadius: 16,
42
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
42
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, sans-serif',
43
43
  avatarUrl: '',
44
44
  poweredBy: true,
45
45
  presetQuestions: [],
@@ -49,18 +49,18 @@ const defaultConfig = {
49
49
  allowLocalhost: true,
50
50
  };
51
51
  const icons = {
52
- 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>`,
53
- 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>`,
54
- 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>`,
55
- 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>`,
56
- 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>`,
57
- 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>`,
58
- 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>`,
59
- 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>`,
60
- 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>`,
61
- 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>`,
62
- 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>`,
63
- 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>`};
52
+ 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>`,
53
+ 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>`,
54
+ 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>`,
55
+ 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>`,
56
+ 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>`,
57
+ 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>`,
58
+ 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>`,
59
+ 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>`,
60
+ 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>`,
61
+ 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>`,
62
+ 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>`,
63
+ 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>`};
64
64
  let config = { widgetId: '', ...defaultConfig };
65
65
  let state = {
66
66
  isOpen: false,
@@ -206,21 +206,32 @@ function matchUrlPattern(pattern) {
206
206
  // STYLES
207
207
  // ============================================================================
208
208
  function generateStyles() {
209
- const { primaryColor, gradientFrom, gradientTo, fontFamily, borderRadius, zIndex, width, height, buttonSize } = config;
210
- const isDark = config.theme === 'dark';
211
- const bgColor = isDark ? '#1a1a2e' : '#ffffff';
212
- const textColor = isDark ? '#e4e4e7' : '#1f2937';
213
- const mutedColor = isDark ? '#71717a' : '#6b7280';
214
- const borderColor = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.08)';
215
- const inputBg = isDark ? '#16162a' : '#f9fafb';
216
- const messageBgUser = `linear-gradient(135deg, ${gradientFrom}, ${gradientTo})`;
217
- const messageBgBot = isDark ? '#252542' : '#f1f5f9';
209
+ const { fontFamily, borderRadius, zIndex, width, height, buttonSize } = config;
210
+ const isDark = config.theme === 'dark' || config.theme === 'auto';
211
+ // Professional dark/light color tokens Vercel-inspired
212
+ const bgColor = isDark ? '#0a0a0a' : '#ffffff';
213
+ const bgElevated = isDark ? '#141414' : '#fafafa';
214
+ const bgSurface = isDark ? '#1a1a1a' : '#f4f4f5';
215
+ const textColor = isDark ? '#ededed' : '#09090b';
216
+ const textSecondary = isDark ? '#a1a1aa' : '#71717a';
217
+ const mutedColor = isDark ? '#52525b' : '#a1a1aa';
218
+ const borderColor = isDark ? '#27272a' : '#e4e4e7';
219
+ const borderSubtle = isDark ? '#1f1f23' : '#f4f4f5';
220
+ const inputBg = isDark ? '#141414' : '#fafafa';
221
+ const hoverBg = isDark ? '#1c1c1c' : '#f4f4f5';
222
+ const accentColor = isDark ? '#ededed' : '#18181b';
223
+ const accentBg = isDark ? '#ededed' : '#18181b';
224
+ const accentText = isDark ? '#09090b' : '#fafafa';
225
+ const userMsgBg = isDark ? '#27272a' : '#18181b';
226
+ const userMsgText = isDark ? '#ededed' : '#fafafa';
227
+ const botMsgBg = 'transparent';
218
228
  const positionRight = config.position?.includes('right') ?? true;
219
229
  const positionBottom = config.position?.includes('bottom') ?? true;
230
+ 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)';
220
231
  return `
221
232
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
222
233
  :host { all: initial; }
223
- .ihooman-widget { font-family: ${fontFamily}; font-size: 14px; line-height: 1.5; color: ${textColor}; -webkit-font-smoothing: antialiased; }
234
+ .ihooman-widget { font-family: ${fontFamily}; font-size: 14px; line-height: 1.6; color: ${textColor}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
224
235
  button {
225
236
  font-family: inherit;
226
237
  font-size: 100%;
@@ -233,144 +244,188 @@ function generateStyles() {
233
244
  cursor: pointer;
234
245
  outline: none;
235
246
  }
236
- .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; }
237
- .ihooman-toggle:hover { transform: scale(1.08); box-shadow: 0 6px 28px rgba(0, 174, 255, 0.45); }
238
- .ihooman-toggle:active { transform: scale(0.95); }
239
- .ihooman-toggle::before { content: ''; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(255,255,255,0.2), transparent); border-radius: 50%; }
240
- .ihooman-toggle svg { width: 26px; height: 26px; color: white; transition: transform 0.3s ease, opacity 0.2s ease; position: relative; z-index: 1; }
241
- .ihooman-toggle .chat-icon { display: flex; align-items: center; justify-content: center; transition: transform 0.3s ease, opacity 0.2s ease; }
242
- .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; }
247
+ button:focus-visible { outline: 2px solid ${accentColor}; outline-offset: 2px; }
248
+
249
+ /* ── Toggle Button ── */
250
+ .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; }
251
+ .ihooman-toggle:hover { transform: scale(1.05); box-shadow: ${shadowLg}; }
252
+ .ihooman-toggle:active { transform: scale(0.96); }
253
+ .ihooman-toggle svg { width: 22px; height: 22px; color: ${accentText}; transition: transform 0.25s ease-out, opacity 0.15s ease; position: relative; z-index: 1; }
254
+ .ihooman-toggle .chat-icon { display: flex; align-items: center; justify-content: center; transition: transform 0.25s ease-out, opacity 0.15s ease; }
255
+ .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; }
243
256
  .ihooman-toggle.open .chat-icon { transform: rotate(90deg) scale(0); opacity: 0; }
244
257
  .ihooman-toggle.open .close-icon { transform: rotate(0) scale(1); opacity: 1; }
245
- .ihooman-pulse { position: absolute; inset: 0; border-radius: 50%; background: ${primaryColor}; animation: ihooman-pulse 2s ease-out infinite; }
246
- @keyframes ihooman-pulse { 0% { transform: scale(1); opacity: 0.5; } 100% { transform: scale(1.6); opacity: 0; } }
247
- .ihooman-toggle.open .ihooman-pulse { display: none; }
248
- .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; }
258
+ .ihooman-pulse { display: none; }
259
+ .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}; }
249
260
  .ihooman-badge:empty { display: none; }
250
- .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; }
261
+
262
+ /* ── Window ── */
263
+ .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; }
251
264
  .ihooman-window.open { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
252
- .ihooman-container { position: relative; width: 100%; height: 100%; display: flex; flex-direction: column; border-radius: ${borderRadius}px; overflow: hidden; flex-shrink: 0; }
253
- .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); }
254
- .ihooman-container > * { position: relative; z-index: 1; }
255
- .ihooman-header { padding: 16px 20px; background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
256
- .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; }
257
- .ihooman-header-avatar img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
258
- .ihooman-header-avatar svg { width: 22px; height: 22px; }
265
+
266
+ /* ── Container ── */
267
+ .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}; }
268
+
269
+ /* ── Header ── */
270
+ .ihooman-header { padding: 14px 16px; background: ${bgElevated}; color: ${textColor}; display: flex; align-items: center; gap: 12px; flex-shrink: 0; border-bottom: 1px solid ${borderColor}; }
271
+ .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}; }
272
+ .ihooman-header-avatar img { width: 100%; height: 100%; border-radius: 10px; object-fit: cover; }
273
+ .ihooman-header-avatar svg { width: 18px; height: 18px; color: ${textSecondary}; }
259
274
  .ihooman-header-info { flex: 1; min-width: 0; }
260
- .ihooman-header-title { font-size: 16px; font-weight: 600; margin-bottom: 2px; }
261
- .ihooman-header-status { display: flex; align-items: center; gap: 6px; font-size: 12px; opacity: 0.9; }
262
- .ihooman-status-dot { width: 8px; height: 8px; border-radius: 50%; background: #22c55e; }
263
- .ihooman-status-dot.offline { background: #f59e0b; }
264
- .ihooman-header-actions { display: flex; gap: 8px; }
265
- .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; }
266
- .ihooman-header-btn:hover { background: rgba(255,255,255,0.25); }
267
- .ihooman-header-btn svg { width: 14px; height: 14px; }
268
- .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; }
269
- .ihooman-messages::-webkit-scrollbar { width: 6px; }
275
+ .ihooman-header-title { font-size: 14px; font-weight: 600; margin-bottom: 1px; letter-spacing: -0.01em; color: ${textColor}; }
276
+ .ihooman-header-status { display: flex; align-items: center; gap: 5px; font-size: 12px; color: ${textSecondary}; }
277
+ .ihooman-status-dot { width: 6px; height: 6px; border-radius: 50%; background: #22c55e; flex-shrink: 0; }
278
+ .ihooman-status-dot.offline { background: #a1a1aa; }
279
+ .ihooman-header-actions { display: flex; gap: 4px; }
280
+ .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; }
281
+ .ihooman-header-btn:hover { background: ${hoverBg}; color: ${textColor}; }
282
+ .ihooman-header-btn svg { width: 15px; height: 15px; }
283
+
284
+ /* ── Messages ── */
285
+ .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; }
286
+ .ihooman-messages::-webkit-scrollbar { width: 4px; }
270
287
  .ihooman-messages::-webkit-scrollbar-track { background: transparent; }
271
- .ihooman-messages::-webkit-scrollbar-thumb { background: ${borderColor}; border-radius: 3px; }
272
- .ihooman-message { display: flex; flex-direction: column; max-width: 85%; animation: ihooman-fadeIn 0.3s ease; }
273
- @keyframes ihooman-fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
288
+ .ihooman-messages::-webkit-scrollbar-thumb { background: ${isDark ? '#27272a' : '#d4d4d8'}; border-radius: 2px; }
289
+ .ihooman-message { display: flex; flex-direction: column; max-width: 88%; animation: ihooman-fadeIn 0.25s ease-out; }
290
+ @keyframes ihooman-fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
274
291
  .ihooman-message.user { align-self: flex-end; align-items: flex-end; }
275
- .ihooman-message.bot { align-self: flex-start; align-items: flex-start; }
276
- .ihooman-message-content { padding: 12px 16px; border-radius: 16px; word-wrap: break-word; }
277
- .ihooman-message.user .ihooman-message-content { background: ${messageBgUser}; color: white; border-bottom-right-radius: 4px; }
278
- .ihooman-message.bot .ihooman-message-content { background: ${messageBgBot}; color: ${textColor}; border-bottom-left-radius: 4px; }
279
- .ihooman-message-content code { background: rgba(0,0,0,0.1); padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 13px; }
280
- .ihooman-message-time { font-size: 11px; color: ${mutedColor}; margin-top: 4px; padding: 0 4px; }
281
- .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; }
282
- .ihooman-typing-dots { display: flex; gap: 4px; }
283
- .ihooman-typing-dot { width: 8px; height: 8px; background: ${mutedColor}; border-radius: 50%; animation: ihooman-typing 1.4s infinite; }
284
- .ihooman-typing-dot:nth-child(2) { animation-delay: 0.2s; }
285
- .ihooman-typing-dot:nth-child(3) { animation-delay: 0.4s; }
286
- @keyframes ihooman-typing { 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; } 30% { transform: translateY(-4px); opacity: 1; } }
292
+ .ihooman-message.bot { align-self: flex-start; align-items: flex-start; max-width: 100%; }
293
+ .ihooman-message-content { padding: 10px 14px; border-radius: 14px; word-wrap: break-word; overflow-wrap: break-word; font-size: 14px; line-height: 1.6; }
294
+ .ihooman-message.user .ihooman-message-content { background: ${userMsgBg}; color: ${userMsgText}; border-bottom-right-radius: 4px; }
295
+ .ihooman-message.bot .ihooman-message-content { background: ${botMsgBg}; color: ${textColor}; padding: 6px 2px; }
296
+ .ihooman-message-content a { color: ${isDark ? '#60a5fa' : '#2563eb'}; text-decoration: underline; text-underline-offset: 2px; }
297
+ .ihooman-message-content a:hover { opacity: 0.8; }
298
+ .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}; }
299
+ .ihooman-message-content strong { font-weight: 600; }
300
+ .ihooman-message-time { font-size: 11px; color: ${mutedColor}; margin-top: 3px; padding: 0 4px; }
301
+
302
+ /* ── Typing Indicator — Shimmer ── */
303
+ .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; }
304
+ .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; }
305
+ @keyframes ihooman-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
306
+ .ihooman-typing-dots { display: flex; gap: 3px; align-items: center; }
307
+ .ihooman-typing-dot { width: 5px; height: 5px; background: ${mutedColor}; border-radius: 50%; animation: ihooman-typing 1.2s ease-in-out infinite; }
308
+ .ihooman-typing-dot:nth-child(2) { animation-delay: 0.15s; }
309
+ .ihooman-typing-dot:nth-child(3) { animation-delay: 0.3s; }
310
+ @keyframes ihooman-typing { 0%, 60%, 100% { opacity: 0.3; transform: scale(0.8); } 30% { opacity: 1; transform: scale(1); } }
311
+
312
+ /* ── Input Area ── */
287
313
  .ihooman-input-area { padding: 12px 16px; background: ${bgColor}; border-top: 1px solid ${borderColor}; flex-shrink: 0; }
288
- .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; }
289
- .ihooman-input-wrapper:focus-within { border-color: ${primaryColor}; box-shadow: 0 0 0 3px rgba(0, 174, 255, 0.1); }
290
- .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; }
314
+ .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; }
315
+ .ihooman-input-wrapper:focus-within { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
316
+ .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; }
291
317
  .ihooman-input::placeholder { color: ${mutedColor}; }
292
- .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}; }
293
- .ihooman-input-btn:hover { background: ${borderColor}; color: ${textColor}; }
294
- .ihooman-input-btn.send { background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; }
295
- .ihooman-input-btn.send:hover { opacity: 0.9; }
296
- .ihooman-input-btn.send:disabled { opacity: 0.5; cursor: not-allowed; }
318
+ .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; }
319
+ .ihooman-input-btn:hover { color: ${textColor}; background: ${hoverBg}; }
320
+ .ihooman-input-btn.send { background: ${accentBg}; color: ${accentText}; }
321
+ .ihooman-input-btn.send:hover { opacity: 0.85; }
322
+ .ihooman-input-btn.send:disabled { opacity: 0.3; cursor: not-allowed; }
297
323
  .ihooman-input-btn svg { width: 16px; height: 16px; }
298
- .ihooman-input:disabled { opacity: 0.6; cursor: not-allowed; }
299
- .ihooman-input-btn.attach:disabled { opacity: 0.4; cursor: not-allowed; }
324
+ .ihooman-input:disabled { opacity: 0.5; cursor: not-allowed; }
325
+ .ihooman-input-btn.attach:disabled { opacity: 0.3; cursor: not-allowed; }
300
326
  .ihooman-file-input { display: none; }
301
- .ihooman-powered { text-align: center; padding: 8px; font-size: 11px; color: ${mutedColor}; background: ${bgColor}; }
302
- .ihooman-powered a { color: ${primaryColor}; text-decoration: none; }
327
+
328
+ /* ── Powered By ── */
329
+ .ihooman-powered { text-align: center; padding: 8px; font-size: 11px; color: ${mutedColor}; background: ${bgColor}; border-top: 1px solid ${borderSubtle}; }
330
+ .ihooman-powered a { color: ${textSecondary}; text-decoration: none; font-weight: 500; }
331
+ .ihooman-powered a:hover { color: ${textColor}; }
332
+
333
+ /* ── Escalation ── */
303
334
  .ihooman-escalation-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
304
335
  .ihooman-escalation-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
305
- .ihooman-status-bar { padding: 10px 16px; text-align: center; font-size: 13px; display: none; }
336
+
337
+ /* ── Status Bar ── */
338
+ .ihooman-status-bar { padding: 8px 16px; text-align: center; font-size: 12px; display: none; font-weight: 500; }
306
339
  .ihooman-status-bar.show { display: block; }
307
- .ihooman-status-bar.waiting { background: #fef3c7; color: #92400e; }
308
- .ihooman-status-bar.connected { background: #dcfce7; color: #166534; }
340
+ .ihooman-status-bar.waiting { background: ${isDark ? '#1c1917' : '#fef9c3'}; color: ${isDark ? '#fbbf24' : '#92400e'}; border-bottom: 1px solid ${isDark ? '#292524' : '#fef08a'}; }
341
+ .ihooman-status-bar.connected { background: ${isDark ? '#052e16' : '#dcfce7'}; color: ${isDark ? '#4ade80' : '#166534'}; border-bottom: 1px solid ${isDark ? '#14532d' : '#bbf7d0'}; }
342
+
343
+ /* ── Chat View ── */
309
344
  .ihooman-chat-view { display: flex; flex-direction: column; flex: 1; overflow: hidden; min-height: 0; }
310
345
  .ihooman-chat-view.hidden { display: none; }
311
- .ihooman-ticket-view { display: none; flex-direction: column; padding: 20px; gap: 16px; background: ${bgColor}; flex: 1; overflow-y: auto; min-height: 0; }
346
+
347
+ /* ── Ticket View ── */
348
+ .ihooman-ticket-view { display: none; flex-direction: column; padding: 20px; gap: 14px; background: ${bgColor}; flex: 1; overflow-y: auto; min-height: 0; }
312
349
  .ihooman-ticket-view.show { display: flex; }
313
- .ihooman-ticket-title { font-size: 18px; font-weight: 600; color: ${textColor}; margin: 0; }
314
- .ihooman-ticket-subtitle { font-size: 13px; color: ${mutedColor}; margin: 0; }
315
- .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; }
316
- .ihooman-ticket-input:focus { border-color: ${primaryColor}; }
350
+ .ihooman-ticket-title { font-size: 16px; font-weight: 600; color: ${textColor}; margin: 0; letter-spacing: -0.01em; }
351
+ .ihooman-ticket-subtitle { font-size: 13px; color: ${textSecondary}; margin: 0; }
352
+ .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; }
353
+ .ihooman-ticket-input:focus { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
317
354
  .ihooman-ticket-input::placeholder { color: ${mutedColor}; }
318
355
  .ihooman-ticket-textarea { min-height: 100px; resize: vertical; }
319
- .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; }
320
- .ihooman-ticket-submit:hover { opacity: 0.9; }
321
- .ihooman-ticket-submit:disabled { opacity: 0.5; cursor: not-allowed; }
322
- .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; }
323
- .ihooman-ticket-back:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)'}; }
356
+ .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; }
357
+ .ihooman-ticket-submit:hover { opacity: 0.85; }
358
+ .ihooman-ticket-submit:disabled { opacity: 0.4; cursor: not-allowed; }
359
+ .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; }
360
+ .ihooman-ticket-back:hover { background: ${hoverBg}; color: ${textColor}; }
361
+
362
+ /* ── History View ── */
324
363
  .ihooman-history-view { display: none; flex-direction: column; flex: 1; overflow: hidden; background: ${bgColor}; }
325
364
  .ihooman-history-view.show { display: flex; }
326
365
  .ihooman-history-header { padding: 12px 16px; border-bottom: 1px solid ${borderColor}; display: flex; justify-content: space-between; align-items: center; }
327
- .ihooman-history-title { font-size: 14px; font-weight: 600; color: ${textColor}; margin: 0; }
328
- .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; }
329
- .ihooman-history-new:hover { opacity: 0.9; }
366
+ .ihooman-history-title { font-size: 13px; font-weight: 600; color: ${textColor}; margin: 0; }
367
+ .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; }
368
+ .ihooman-history-new:hover { opacity: 0.85; }
330
369
  .ihooman-history-new svg { width: 12px; height: 12px; flex-shrink: 0; }
331
370
  .ihooman-history-list { flex: 1; overflow-y: auto; padding: 8px; overscroll-behavior: contain; }
332
- .ihooman-history-item { padding: 12px; border: 1px solid ${borderColor}; border-radius: 8px; margin-bottom: 6px; cursor: pointer; transition: all 0.2s; background: ${bgColor}; }
333
- .ihooman-history-item:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : '#f8fafc'}; }
334
- .ihooman-history-item.active { background: ${isDark ? 'rgba(0, 174, 255, 0.1)' : '#eff6ff'}; border-color: ${primaryColor}; }
371
+ .ihooman-history-item { padding: 12px; border: 1px solid ${borderColor}; border-radius: 10px; margin-bottom: 6px; cursor: pointer; transition: all 0.15s ease; background: ${bgColor}; }
372
+ .ihooman-history-item:hover { background: ${hoverBg}; }
373
+ .ihooman-history-item.active { background: ${hoverBg}; border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
335
374
  .ihooman-history-preview { font-size: 13px; color: ${textColor}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
336
375
  .ihooman-history-meta { font-size: 11px; color: ${mutedColor}; margin-top: 4px; display: flex; justify-content: space-between; }
337
- .ihooman-history-empty { padding: 40px; text-align: center; color: ${mutedColor}; font-size: 14px; }
338
- .ihooman-preset-questions { padding: 10px 16px; display: flex; flex-wrap: wrap; gap: 6px; background: ${bgColor}; border-top: 1px solid ${borderColor}; }
376
+ .ihooman-history-empty { padding: 40px; text-align: center; color: ${mutedColor}; font-size: 13px; }
377
+
378
+ /* ── Preset Questions ── */
379
+ .ihooman-preset-questions { padding: 10px 16px; display: flex; flex-wrap: wrap; gap: 6px; background: ${bgColor}; border-top: 1px solid ${borderSubtle}; }
339
380
  .ihooman-preset-questions:empty { display: none; }
340
381
  .ihooman-preset-questions.hidden { display: none; }
341
- .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}; }
382
+
383
+ /* ── Proactive Toast ── */
384
+ .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}; }
342
385
  .ihooman-proactive-toast.show { opacity: 1; visibility: visible; transform: translateY(0); }
343
- .ihooman-proactive-toast-content { font-size: 14px; color: ${textColor}; margin-bottom: 12px; }
386
+ .ihooman-proactive-toast-content { font-size: 14px; color: ${textColor}; margin-bottom: 12px; line-height: 1.5; }
344
387
  .ihooman-proactive-toast-actions { display: flex; gap: 8px; }
345
- .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; }
346
- .ihooman-proactive-toast-btn.primary { background: linear-gradient(135deg, ${gradientFrom}, ${gradientTo}); color: white; border: none; }
347
- .ihooman-proactive-toast-btn.primary:hover { opacity: 0.9; }
348
- .ihooman-proactive-toast-btn.secondary { background: transparent; color: ${mutedColor}; border: 1px solid ${borderColor}; }
349
- .ihooman-proactive-toast-btn.secondary:hover { background: ${isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)'}; }
350
- .ihooman-survey-view { display: none; flex-direction: column; padding: 20px; gap: 16px; background: ${bgColor}; flex: 1; align-items: center; justify-content: center; }
388
+ .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; }
389
+ .ihooman-proactive-toast-btn.primary { background: ${accentBg}; color: ${accentText}; border: none; }
390
+ .ihooman-proactive-toast-btn.primary:hover { opacity: 0.85; }
391
+ .ihooman-proactive-toast-btn.secondary { background: transparent; color: ${textSecondary}; border: 1px solid ${borderColor}; }
392
+ .ihooman-proactive-toast-btn.secondary:hover { background: ${hoverBg}; }
393
+
394
+ /* ── Survey View ── */
395
+ .ihooman-survey-view { display: none; flex-direction: column; padding: 24px; gap: 16px; background: ${bgColor}; flex: 1; align-items: center; justify-content: center; }
351
396
  .ihooman-survey-view.show { display: flex; }
352
- .ihooman-survey-question { font-size: 16px; font-weight: 600; color: ${textColor}; text-align: center; }
397
+ .ihooman-survey-question { font-size: 16px; font-weight: 600; color: ${textColor}; text-align: center; letter-spacing: -0.01em; }
353
398
  .ihooman-survey-stars { display: flex; gap: 8px; }
354
- .ihooman-survey-star { width: 40px; height: 40px; cursor: pointer; color: ${mutedColor}; transition: all 0.2s; }
399
+ .ihooman-survey-star { width: 36px; height: 36px; cursor: pointer; color: ${mutedColor}; transition: all 0.15s ease; }
355
400
  .ihooman-survey-star:hover, .ihooman-survey-star.active { color: #fbbf24; transform: scale(1.1); }
356
401
  .ihooman-survey-star svg { width: 100%; height: 100%; }
357
- .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}; }
358
- .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; }
359
- .ihooman-survey-submit:hover { opacity: 0.9; }
402
+ .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; }
403
+ .ihooman-survey-comment:focus { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
404
+ .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; }
405
+ .ihooman-survey-submit:hover { opacity: 0.85; }
360
406
  .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; }
361
407
  .ihooman-survey-skip:hover { color: ${textColor}; }
362
- .ihooman-feedback-btns { display: flex; gap: 6px; margin-top: 6px; }
408
+
409
+ /* ── Feedback ── */
410
+ .ihooman-feedback-btns { display: flex; gap: 4px; margin-top: 4px; }
363
411
  .ihooman-feedback-btn svg { width: 12px; height: 12px; }
364
- .ihooman-carousel { display: flex; gap: 12px; overflow-x: auto; padding: 8px 0; scroll-snap-type: x mandatory; }
365
- .ihooman-carousel::-webkit-scrollbar { height: 4px; }
366
- .ihooman-carousel-card { min-width: 200px; max-width: 250px; border: 1px solid ${borderColor}; border-radius: 12px; overflow: hidden; scroll-snap-align: start; background: ${bgColor}; }
412
+
413
+ /* ── Carousel ── */
414
+ .ihooman-carousel { display: flex; gap: 10px; overflow-x: auto; padding: 8px 0; scroll-snap-type: x mandatory; }
415
+ .ihooman-carousel::-webkit-scrollbar { height: 3px; }
416
+ .ihooman-carousel::-webkit-scrollbar-thumb { background: ${isDark ? '#27272a' : '#d4d4d8'}; border-radius: 2px; }
417
+ .ihooman-carousel-card { min-width: 200px; max-width: 250px; border: 1px solid ${borderColor}; border-radius: 12px; overflow: hidden; scroll-snap-align: start; background: ${bgElevated}; }
367
418
  .ihooman-carousel-card img { width: 100%; height: 120px; object-fit: cover; }
368
419
  .ihooman-carousel-card-content { padding: 12px; }
369
- .ihooman-carousel-card-title { font-size: 14px; font-weight: 600; color: ${textColor}; margin-bottom: 4px; }
370
- .ihooman-carousel-card-desc { font-size: 12px; color: ${mutedColor}; margin-bottom: 8px; }
420
+ .ihooman-carousel-card-title { font-size: 13px; font-weight: 600; color: ${textColor}; margin-bottom: 4px; }
421
+ .ihooman-carousel-card-desc { font-size: 12px; color: ${textSecondary}; margin-bottom: 8px; }
371
422
  .ihooman-carousel-card-btns { display: flex; flex-direction: column; gap: 6px; }
423
+
424
+ /* ── Quick Replies ── */
372
425
  .ihooman-quick-replies { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
373
- @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; } }
426
+
427
+ /* ── Responsive ── */
428
+ @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; } }
374
429
  `;
375
430
  }
376
431
  // ============================================================================
@@ -410,9 +465,9 @@ function createWidget() {
410
465
  <div class="ihooman-window" role="dialog" aria-label="Chat window">
411
466
  <div class="ihooman-container">
412
467
  <div class="ihooman-header">
413
- <div class="ihooman-header-avatar">${config.avatarUrl ? `<img src="${escapeHtml(config.avatarUrl)}" alt="Support">` : icons.bot}</div>
468
+ <div class="ihooman-header-avatar">${config.avatarUrl ? `<img src="${escapeHtml(config.avatarUrl)}" alt="Assistant">` : icons.sparkle}</div>
414
469
  <div class="ihooman-header-info">
415
- <div class="ihooman-header-title">${escapeHtml(config.title || 'Chat Support')}</div>
470
+ <div class="ihooman-header-title">${escapeHtml(config.title || 'AI Assistant')}</div>
416
471
  <div class="ihooman-header-status"><span class="ihooman-status-dot"></span><span class="ihooman-status-text">Online</span></div>
417
472
  </div>
418
473
  <div class="ihooman-header-actions">
@@ -434,7 +489,7 @@ function createWidget() {
434
489
  </div>
435
490
  </div>
436
491
  <div class="ihooman-ticket-view">
437
- <h4 class="ihooman-ticket-title">📝 Submit a Ticket</h4>
492
+ <h4 class="ihooman-ticket-title">Submit a Ticket</h4>
438
493
  <p class="ihooman-ticket-subtitle">We'll get back to you via email</p>
439
494
  <input class="ihooman-ticket-input" id="ihooman-ticket-name" placeholder="Your name" required>
440
495
  <input class="ihooman-ticket-input" id="ihooman-ticket-email" type="email" placeholder="Your email" required>
@@ -893,6 +948,7 @@ async function handleRequestLiveAgent() {
893
948
  function startLiveAgentPolling() {
894
949
  if (liveAgentPollInterval)
895
950
  return;
951
+ let agentConnected = false;
896
952
  liveAgentPollInterval = setInterval(async () => {
897
953
  if (!state.sessionId || !isLiveAgentMode) {
898
954
  stopLiveAgentPolling();
@@ -906,6 +962,12 @@ function startLiveAgentPolling() {
906
962
  // Check both ticket_status and conversation_status for agent handling
907
963
  if (data.ticket_status === 'in_progress' || data.conversation_status === 'active') {
908
964
  updateStatusBar('connected', '🟢 Connected to live agent');
965
+ // Agent is connected — stop polling, WebSocket handles real-time updates.
966
+ // Status changes (close/resolve) will come through WebSocket messages.
967
+ if (!agentConnected) {
968
+ agentConnected = true;
969
+ stopLiveAgentPolling();
970
+ }
909
971
  }
910
972
  else if (data.ticket_status === 'open') {
911
973
  updateStatusBar('waiting', data.position_in_queue > 1
@@ -923,7 +985,7 @@ function startLiveAgentPolling() {
923
985
  }
924
986
  }
925
987
  catch { /* ignore */ }
926
- }, 3000);
988
+ }, 15000);
927
989
  }
928
990
  function stopLiveAgentPolling() {
929
991
  if (liveAgentPollInterval) {
@@ -1018,7 +1080,7 @@ function showTyping() {
1018
1080
  return;
1019
1081
  const typing = document.createElement('div');
1020
1082
  typing.className = 'ihooman-typing';
1021
- 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>`;
1083
+ 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>`;
1022
1084
  elements.messages.appendChild(typing);
1023
1085
  elements.messages.scrollTop = elements.messages.scrollHeight;
1024
1086
  }
@@ -1040,7 +1102,7 @@ function disableInput() {
1040
1102
  function enableInput() {
1041
1103
  if (elements.input) {
1042
1104
  elements.input.disabled = false;
1043
- elements.input.placeholder = config.placeholder || 'Type a message...';
1105
+ elements.input.placeholder = config.placeholder || 'Send a message...';
1044
1106
  }
1045
1107
  if (elements.sendBtn)
1046
1108
  elements.sendBtn.disabled = !elements.input?.value.trim();
@@ -1330,7 +1392,7 @@ function connectWebSocket(chatEndpoint) {
1330
1392
  emit('connected');
1331
1393
  startHeartbeat();
1332
1394
  };
1333
- ws.onclose = (_event) => {
1395
+ ws.onclose = (event) => {
1334
1396
  state.isConnected = false;
1335
1397
  state.connectionStatus = 'disconnected';
1336
1398
  updateStatus(false);
@@ -1340,6 +1402,9 @@ function connectWebSocket(chatEndpoint) {
1340
1402
  intentionalDisconnect = false;
1341
1403
  return;
1342
1404
  }
1405
+ // Code 4002 means this connection was replaced by a newer one — don't reconnect
1406
+ if (event.code === 4002)
1407
+ return;
1343
1408
  if (!state.isOpen)
1344
1409
  return;
1345
1410
  if (reconnectAttempts < maxReconnectAttempts) {
@@ -1661,11 +1726,10 @@ function getFontWeightValue(weight) {
1661
1726
  default: return 500;
1662
1727
  }
1663
1728
  }
1664
- // Default button styles - MUST match client-dashboard/src/components/widget/ButtonStylingEditor.tsx
1665
1729
  const DEFAULT_BUTTON_STYLES = {
1666
1730
  primary: {
1667
- backgroundColor: '#00aeff',
1668
- textColor: '#ffffff',
1731
+ backgroundColor: '#ededed',
1732
+ textColor: '#09090b',
1669
1733
  borderColor: 'transparent',
1670
1734
  borderWidth: 0,
1671
1735
  borderRadius: 8,
@@ -1676,8 +1740,8 @@ const DEFAULT_BUTTON_STYLES = {
1676
1740
  },
1677
1741
  secondary: {
1678
1742
  backgroundColor: 'transparent',
1679
- textColor: '#6b7280',
1680
- borderColor: '#e5e7eb',
1743
+ textColor: '#a1a1aa',
1744
+ borderColor: '#27272a',
1681
1745
  borderWidth: 1,
1682
1746
  borderRadius: 8,
1683
1747
  paddingVertical: 8,
@@ -1686,9 +1750,9 @@ const DEFAULT_BUTTON_STYLES = {
1686
1750
  fontWeight: 'medium',
1687
1751
  },
1688
1752
  presetQuestions: {
1689
- backgroundColor: 'rgba(0, 174, 255, 0.1)',
1690
- textColor: '#00aeff',
1691
- borderColor: 'rgba(0, 174, 255, 0.2)',
1753
+ backgroundColor: 'transparent',
1754
+ textColor: '#a1a1aa',
1755
+ borderColor: '#27272a',
1692
1756
  borderWidth: 1,
1693
1757
  borderRadius: 20,
1694
1758
  paddingVertical: 6,
@@ -1697,9 +1761,9 @@ const DEFAULT_BUTTON_STYLES = {
1697
1761
  fontWeight: 'medium',
1698
1762
  },
1699
1763
  quickReplies: {
1700
- backgroundColor: '#f3f4f6',
1701
- textColor: '#374151',
1702
- borderColor: '#e5e7eb',
1764
+ backgroundColor: '#1a1a1a',
1765
+ textColor: '#a1a1aa',
1766
+ borderColor: '#27272a',
1703
1767
  borderWidth: 1,
1704
1768
  borderRadius: 16,
1705
1769
  paddingVertical: 5,
@@ -1709,8 +1773,8 @@ const DEFAULT_BUTTON_STYLES = {
1709
1773
  },
1710
1774
  feedback: {
1711
1775
  backgroundColor: 'transparent',
1712
- textColor: '#9ca3af',
1713
- borderColor: '#e5e7eb',
1776
+ textColor: '#52525b',
1777
+ borderColor: '#27272a',
1714
1778
  borderWidth: 1,
1715
1779
  borderRadius: 6,
1716
1780
  paddingVertical: 4,
@@ -1719,19 +1783,19 @@ const DEFAULT_BUTTON_STYLES = {
1719
1783
  fontWeight: 'medium',
1720
1784
  },
1721
1785
  headerActions: {
1722
- backgroundColor: 'rgba(255, 255, 255, 0.1)',
1723
- textColor: '#ffffff',
1786
+ backgroundColor: 'transparent',
1787
+ textColor: '#a1a1aa',
1724
1788
  borderColor: 'transparent',
1725
1789
  borderWidth: 0,
1726
- borderRadius: 6,
1790
+ borderRadius: 8,
1727
1791
  paddingVertical: 6,
1728
1792
  paddingHorizontal: 6,
1729
1793
  fontSize: 14,
1730
1794
  fontWeight: 'medium',
1731
1795
  },
1732
1796
  escalation: {
1733
- backgroundColor: '#00aeff',
1734
- textColor: '#ffffff',
1797
+ backgroundColor: '#ededed',
1798
+ textColor: '#09090b',
1735
1799
  borderColor: 'transparent',
1736
1800
  borderWidth: 0,
1737
1801
  borderRadius: 8,
@@ -1741,21 +1805,21 @@ const DEFAULT_BUTTON_STYLES = {
1741
1805
  fontWeight: 'medium',
1742
1806
  },
1743
1807
  cardActions: {
1744
- backgroundColor: '#00aeff',
1745
- textColor: '#ffffff',
1808
+ backgroundColor: '#ededed',
1809
+ textColor: '#09090b',
1746
1810
  borderColor: 'transparent',
1747
1811
  borderWidth: 0,
1748
- borderRadius: 6,
1812
+ borderRadius: 8,
1749
1813
  paddingVertical: 6,
1750
1814
  paddingHorizontal: 12,
1751
1815
  fontSize: 12,
1752
1816
  fontWeight: 'medium',
1753
1817
  },
1754
1818
  toggleButton: {
1755
- backgroundColor: '#00aeff',
1756
- textColor: '#ffffff',
1757
- borderColor: 'transparent',
1758
- borderWidth: 0,
1819
+ backgroundColor: '#ededed',
1820
+ textColor: '#09090b',
1821
+ borderColor: '#27272a',
1822
+ borderWidth: 1,
1759
1823
  borderRadius: 30,
1760
1824
  paddingVertical: 0,
1761
1825
  paddingHorizontal: 0,
@@ -1764,7 +1828,7 @@ const DEFAULT_BUTTON_STYLES = {
1764
1828
  },
1765
1829
  attachButton: {
1766
1830
  backgroundColor: 'transparent',
1767
- textColor: '#6b7280',
1831
+ textColor: '#52525b',
1768
1832
  borderColor: 'transparent',
1769
1833
  borderWidth: 0,
1770
1834
  borderRadius: 8,