@courseecho/ai-core-sdk 1.0.22 → 1.0.25

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.
@@ -24,6 +24,11 @@ export declare class AiCommunicationService {
24
24
  * Send query to backend API
25
25
  */
26
26
  sendQuery(request: AiQueryRequest): Promise<AiQueryResponse>;
27
+ /**
28
+ * Exchange an API key for a short-lived JWT via POST /api/auth/token.
29
+ * Returns the JWT string on success; throws ApiError on failure.
30
+ */
31
+ fetchToken(apiKey: string): Promise<string>;
27
32
  /**
28
33
  * Check backend health
29
34
  */
@@ -80,6 +80,32 @@ export class AiCommunicationService {
80
80
  throw new ApiError(`Failed to send query: ${String(error)}`, 500);
81
81
  }
82
82
  }
83
+ /**
84
+ * Exchange an API key for a short-lived JWT via POST /api/auth/token.
85
+ * Returns the JWT string on success; throws ApiError on failure.
86
+ */
87
+ async fetchToken(apiKey) {
88
+ try {
89
+ const response = await fetch(`${this.apiEndpoint}/api/auth/token`, {
90
+ method: 'POST',
91
+ headers: { 'Content-Type': 'application/json' },
92
+ body: JSON.stringify({ apiKey }),
93
+ });
94
+ const data = await safeJson(response);
95
+ if (!response.ok) {
96
+ throw new ApiError(data?.error || `Token exchange failed: HTTP ${response.status}`, response.status, data);
97
+ }
98
+ if (!data?.token) {
99
+ throw new ApiError('No token returned from auth endpoint', 500);
100
+ }
101
+ return data.token;
102
+ }
103
+ catch (error) {
104
+ if (error instanceof ApiError)
105
+ throw error;
106
+ throw new ApiError(`Failed to fetch token: ${String(error)}`, 500);
107
+ }
108
+ }
83
109
  /**
84
110
  * Check backend health
85
111
  */
package/dist/index.d.ts CHANGED
@@ -9,4 +9,3 @@ export { PageContentScanner, AiSuggestionGenerator, type PageContent, } from './
9
9
  export { AiWidgetSDK } from './sdk';
10
10
  export type { StateListener } from './state-manager';
11
11
  export { WIDGET_CSS } from './widget-css';
12
- export { ICONS, EMOJI_GRADUATION, EMOJI_CLIPBOARD, EMOJI_TROPHY, EMOJI_DOWN_ARROW, EMOJI_CHART_UP, EMOJI_HAND_RAISE, EMOJI_BULB, EMOJI_MEMO, EMOJI_RIGHT_ARROW, EMOJI_SOS, EMOJI_LIFT, EMOJI_SEARCH, EMOJI_BOOKS, EMOJI_PACKAGE, EMOJI_CARD, EMOJI_CART, EMOJI_FREE, EMOJI_MONEY, EMOJI_LOCK, EMOJI_TICKET, EMOJI_USER, EMOJI_LAPTOP, EMOJI_BUG, EMOJI_WRENCH, EMOJI_CHAT, EMOJI_ROCKET, EMOJI_BOOK, EMOJI_TOOLS, EMOJI_WARNING, } from './icons';
package/dist/index.js CHANGED
@@ -13,5 +13,3 @@ export { PageContentScanner, AiSuggestionGenerator, } from './auto-suggestion-ge
13
13
  export { AiWidgetSDK } from './sdk';
14
14
  // Canonical widget CSS (used by all framework packages)
15
15
  export { WIDGET_CSS } from './widget-css';
16
- // Shared SVG icons + encoding-safe emoji strings
17
- export { ICONS, EMOJI_GRADUATION, EMOJI_CLIPBOARD, EMOJI_TROPHY, EMOJI_DOWN_ARROW, EMOJI_CHART_UP, EMOJI_HAND_RAISE, EMOJI_BULB, EMOJI_MEMO, EMOJI_RIGHT_ARROW, EMOJI_SOS, EMOJI_LIFT, EMOJI_SEARCH, EMOJI_BOOKS, EMOJI_PACKAGE, EMOJI_CARD, EMOJI_CART, EMOJI_FREE, EMOJI_MONEY, EMOJI_LOCK, EMOJI_TICKET, EMOJI_USER, EMOJI_LAPTOP, EMOJI_BUG, EMOJI_WRENCH, EMOJI_CHAT, EMOJI_ROCKET, EMOJI_BOOK, EMOJI_TOOLS, EMOJI_WARNING, } from './icons';
package/dist/sdk.d.ts CHANGED
@@ -21,6 +21,17 @@ export declare class AiWidgetSDK {
21
21
  * Initialize auto-suggestions based on page content
22
22
  */
23
23
  initializeAutoSuggestions(): Promise<void>;
24
+ /**
25
+ * Auto-authenticate: exchange apiKey for a JWT via POST /api/auth/token,
26
+ * set it on the communication service, then refresh suggestions.
27
+ * No-op if already authenticated or no apiKey is configured.
28
+ */
29
+ autoAuthenticate(): Promise<void>;
30
+ /**
31
+ * Re-generate suggestions for the current URL (call after SPA navigation).
32
+ * Clears stale suggestions and rescans the new page content.
33
+ */
34
+ refreshSuggestionsForCurrentUrl(): Promise<void>;
24
35
  /**
25
36
  * Validate configuration
26
37
  */
package/dist/sdk.js CHANGED
@@ -66,6 +66,37 @@ export class AiWidgetSDK {
66
66
  }, scanInterval);
67
67
  }
68
68
  }
69
+ /**
70
+ * Auto-authenticate: exchange apiKey for a JWT via POST /api/auth/token,
71
+ * set it on the communication service, then refresh suggestions.
72
+ * No-op if already authenticated or no apiKey is configured.
73
+ */
74
+ async autoAuthenticate() {
75
+ if (this.communicationService.isAuthenticated())
76
+ return;
77
+ if (!this.config.apiKey)
78
+ return;
79
+ const jwt = await this.communicationService.fetchToken(this.config.apiKey);
80
+ this.communicationService.setJwtToken(jwt);
81
+ // Refresh suggestions now that auth is established
82
+ if (this.config.suggestionConfig?.autoGenerate !== false) {
83
+ this.suggestionManager.clearSuggestions();
84
+ await this.initializeAutoSuggestions();
85
+ }
86
+ }
87
+ /**
88
+ * Re-generate suggestions for the current URL (call after SPA navigation).
89
+ * Clears stale suggestions and rescans the new page content.
90
+ */
91
+ async refreshSuggestionsForCurrentUrl() {
92
+ this.suggestionManager.clearSuggestions();
93
+ // PageContentScanner caches by URL, so a new URL will be scanned fresh.
94
+ // Also clear the old-URL cache entry to free memory.
95
+ this.pageContentScanner.clearCache();
96
+ if (this.config.suggestionConfig?.autoGenerate !== false) {
97
+ await this.initializeAutoSuggestions();
98
+ }
99
+ }
69
100
  /**
70
101
  * Validate configuration
71
102
  */
@@ -11,4 +11,4 @@
11
11
  * Each package is responsible for loading the Inter font into document <head>
12
12
  * separately (React: ensureFont(), jQuery: injectFontLink()).
13
13
  */
14
- export declare const WIDGET_CSS = "\n/* \u2500\u2500 Shadow-DOM host isolation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host {\n all: initial !important;\n display: block !important;\n}\n\n/* Scoped box-model reset \u2014 only touches widget elements, not all of shadow DOM */\n.aiwg-root *, .aiwg-root *::before, .aiwg-root *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n/* \u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-root {\n --aiwg-primary: #6366f1;\n --aiwg-primary-dark: #8b5cf6;\n --aiwg-fg-color: #ffffff;\n --aiwg-bg-color: #ffffff;\n --aiwg-chat-bg: #f1f5f9;\n\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #1a1a2e;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border-radius: 16px;\n background: var(--aiwg-bg-color);\n position: fixed !important;\n bottom: 24px;\n right: 24px;\n width: 380px !important;\n max-width: calc(100vw - 48px) !important;\n z-index: 99999;\n transition: height 0.25s ease;\n box-shadow: 0 24px 64px rgba(0,0,0,0.18);\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-header {\n background: linear-gradient(135deg, var(--aiwg-primary) 0%, var(--aiwg-primary-dark) 100%);\n padding: 16px 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n position: relative;\n overflow: hidden;\n}\n.aiwg-header::before {\n content: '';\n position: absolute;\n width: 140px; height: 140px;\n background: rgba(255,255,255,0.08);\n border-radius: 50%;\n top: -50px; right: -30px;\n}\n.aiwg-avatar {\n width: 40px; height: 40px;\n background: rgba(255,255,255,0.25);\n border-radius: 50%;\n display: flex; align-items: center; justify-content: center;\n font-size: 18px;\n flex-shrink: 0;\n border: 2px solid rgba(255,255,255,0.4);\n color: #fff;\n}\n.aiwg-avatar svg { display: block; width: 22px; height: 22px; }\n.aiwg-header-info { flex: 1; }\n.aiwg-title { color: #fff; font-weight: 600; font-size: 15px; }\n.aiwg-subtitle {\n color: rgba(255,255,255,0.75);\n font-size: 12px;\n display: flex; align-items: center; gap: 5px;\n}\n.aiwg-online-dot {\n width: 7px; height: 7px;\n background: #4ade80;\n border-radius: 50%;\n display: inline-block;\n animation: aiwg-pulse 2s ease-in-out infinite;\n}\n@keyframes aiwg-pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.6; transform: scale(0.85); }\n}\n.aiwg-minimize-btn {\n width: 36px; height: 36px;\n background: rgba(255,255,255,0.18);\n border: 1.5px solid rgba(255,255,255,0.3);\n border-radius: 50%;\n color: #fff; cursor: pointer;\n display: flex; align-items: center; justify-content: center;\n font-size: 18px; line-height: 1;\n transition: background 0.15s, transform 0.15s;\n flex-shrink: 0;\n position: relative; z-index: 2;\n}\n.aiwg-minimize-btn * { cursor: pointer !important; pointer-events: none; }\n.aiwg-minimize-btn svg { display: block; width: 16px; height: 16px; }\n.aiwg-minimize-btn:hover { background: rgba(255,255,255,0.32); transform: scale(1.08); }\n\n/* \u2500\u2500 Messages area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-messages {\n flex: 1;\n overflow-y: auto;\n padding: 20px 16px 8px;\n scroll-behavior: smooth;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.aiwg-messages::-webkit-scrollbar { width: 4px; }\n.aiwg-messages::-webkit-scrollbar-thumb { background: #e2e8f0; border-radius: 99px; }\n\n/* \u2500\u2500 Welcome card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-welcome {\n text-align: center;\n padding: 24px 16px;\n display: flex; flex-direction: column; align-items: center; gap: 8px;\n}\n.aiwg-welcome-icon {\n display: flex; align-items: center; justify-content: center;\n margin-bottom: 4px;\n color: var(--aiwg-primary);\n}\n.aiwg-welcome-icon svg { width: 36px; height: 36px; }\n.aiwg-welcome h4 { font-size: 15px; font-weight: 600; color: #1a1a2e; }\n.aiwg-welcome p { font-size: 13px; color: #64748b; }\n\n/* \u2500\u2500 Message bubbles \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-msg {\n display: flex;\n gap: 8px;\n align-items: flex-end;\n animation: aiwg-fade-up 0.2s ease both;\n}\n@keyframes aiwg-fade-up {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.aiwg-msg--user { flex-direction: row-reverse; }\n.aiwg-msg-avatar {\n width: 28px; height: 28px; border-radius: 50%;\n display: flex; align-items: center; justify-content: center;\n font-size: 13px; flex-shrink: 0;\n margin-bottom: 2px;\n}\n.aiwg-msg-avatar svg { display: block; width: 16px; height: 16px; }\n.aiwg-msg--bot .aiwg-msg-avatar { background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark)); color: var(--aiwg-fg-color); }\n.aiwg-msg--user .aiwg-msg-avatar { background: #e2e8f0; color: #64748b; }\n.aiwg-msg-body { max-width: 78%; }\n.aiwg-msg-bubble {\n padding: 10px 14px;\n border-radius: 18px;\n font-size: 14px;\n line-height: 1.55;\n word-break: break-word;\n}\n.aiwg-msg--bot .aiwg-msg-bubble { background: var(--aiwg-chat-bg); color: #1a1a2e; border-bottom-left-radius: 4px; }\n.aiwg-msg--user .aiwg-msg-bubble { background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark)); color: var(--aiwg-fg-color); border-bottom-right-radius: 4px; }\n.aiwg-msg-time { font-size: 10px; color: #94a3b8; margin-top: 4px; text-align: right; padding: 0 4px; }\n.aiwg-msg--bot .aiwg-msg-time { text-align: left; }\n\n/* \u2500\u2500 Typing indicator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-typing { padding: 10px 14px; }\n.aiwg-typing-dots { display: flex; gap: 4px; align-items: center; }\n.aiwg-typing-dots span {\n width: 7px; height: 7px;\n background: #94a3b8; border-radius: 50%;\n animation: aiwg-bounce 1.2s ease-in-out infinite;\n}\n.aiwg-typing-dots span:nth-child(2) { animation-delay: 0.2s; }\n.aiwg-typing-dots span:nth-child(3) { animation-delay: 0.4s; }\n@keyframes aiwg-bounce {\n 0%, 80%, 100% { transform: translateY(0); }\n 40% { transform: translateY(-6px); }\n}\n\n/* \u2500\u2500 Quick-reply chips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-chip-row {\n padding: 6px 16px 2px;\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex-shrink: 0;\n}\n.aiwg-chip {\n background: #f1f5f9;\n border: 1px solid #e2e8f0;\n border-radius: 99px;\n padding: 4px 12px;\n font-size: 12px;\n color: #4f46e5;\n cursor: pointer;\n transition: all 0.15s;\n white-space: nowrap;\n font-weight: 500;\n}\n.aiwg-chip:hover { background: #ede9fe; border-color: #a5b4fc; }\n.aiwg-chip-shimmer {\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n border: 1px solid transparent;\n border-radius: 99px;\n padding: 4px 34px;\n animation: aiwg-shimmer 1.4s ease-in-out infinite;\n cursor: default;\n pointer-events: none;\n}\n.aiwg-chip-ai-badge {\n display: inline-block;\n font-size: 9px; font-weight: 700;\n background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark));\n color: #fff;\n padding: 1px 5px;\n border-radius: 99px;\n margin-left: 5px;\n vertical-align: middle;\n letter-spacing: 0.04em;\n}\n@keyframes aiwg-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* \u2500\u2500 Input area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-input-area {\n padding: 12px 16px 16px;\n flex-shrink: 0;\n background: #fff;\n border-top: 1px solid #f1f5f9;\n position: relative;\n}\n.aiwg-input-row { display: flex; gap: 8px; align-items: flex-end; }\n.aiwg-input {\n flex: 1;\n border: 1.5px solid #e2e8f0;\n border-radius: 12px;\n padding: 10px 14px;\n font-size: 14px;\n font-family: inherit;\n outline: none;\n resize: none;\n background: #f8fafc;\n color: #1a1a2e;\n transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;\n line-height: 1.4;\n max-height: 120px;\n overflow-y: auto;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n.aiwg-input::-webkit-scrollbar { display: none; }\n.aiwg-input::placeholder { color: #94a3b8; }\n.aiwg-input:focus {\n border-color: var(--aiwg-primary-dark);\n background: #fff;\n box-shadow: 0 0 0 3px rgba(139,92,246,0.1);\n}\n.aiwg-send-btn {\n width: 42px; height: 42px;\n background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark));\n border: none; border-radius: 12px;\n color: var(--aiwg-fg-color); cursor: pointer;\n display: flex; align-items: center; justify-content: center;\n flex-shrink: 0;\n transition: transform 0.15s, box-shadow 0.15s, opacity 0.15s;\n box-shadow: 0 4px 12px rgba(99,102,241,0.35);\n}\n.aiwg-send-btn svg { width: 18px; height: 18px; }\n.aiwg-send-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(99,102,241,0.4); }\n.aiwg-send-btn:active { transform: translateY(0); }\n.aiwg-send-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }\n\n/* \u2500\u2500 Autocomplete suggestions dropdown \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-suggestions {\n position: absolute;\n bottom: calc(100% + 4px);\n left: 16px; right: 16px;\n background: #fff;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.12);\n overflow: hidden;\n z-index: 100;\n animation: aiwg-fade-up 0.15s ease both;\n}\n.aiwg-suggestions-header {\n padding: 8px 14px 4px;\n font-size: 11px; font-weight: 600;\n color: #94a3b8;\n text-transform: uppercase; letter-spacing: 0.06em;\n border-bottom: 1px solid #f1f5f9;\n}\n.aiwg-suggestion-item {\n display: flex; align-items: center; gap: 10px;\n padding: 10px 14px;\n cursor: pointer;\n transition: background 0.1s;\n border-bottom: 1px solid #f8fafc;\n}\n.aiwg-suggestion-item:last-child { border-bottom: none; }\n.aiwg-suggestion-item:hover,\n.aiwg-suggestion-item.aiwg-active { background: #f5f3ff; }\n.aiwg-suggestion-icon { font-size: 16px; flex-shrink: 0; }\n.aiwg-suggestion-main { flex: 1; min-width: 0; }\n.aiwg-suggestion-text { font-size: 13px; font-weight: 500; color: #1a1a2e; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.aiwg-suggestion-text mark { background: none; color: #6366f1; font-weight: 600; }\n.aiwg-suggestion-desc { font-size: 11px; color: #94a3b8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.aiwg-suggestion-badge { font-size: 10px; font-weight: 600; padding: 2px 8px; border-radius: 99px; background: #ede9fe; color: #6366f1; flex-shrink: 0; }\n.aiwg-kbd-hint {\n padding: 6px 14px;\n font-size: 11px; color: #cbd5e1; background: #f8fafc;\n display: flex; justify-content: flex-end; gap: 10px;\n}\n.aiwg-kbd-hint kbd { font-family: inherit; background: #e2e8f0; border-radius: 4px; padding: 1px 5px; font-size: 10px; color: #64748b; }\n\n/* \u2500\u2500 Error toast \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-error {\n margin: 0 16px 8px;\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 8px;\n font-size: 12px;\n color: #dc2626;\n}\n\n/* \u2500\u2500 Minimized state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-root.aiwg-minimized .aiwg-messages,\n.aiwg-root.aiwg-minimized .aiwg-chip-row,\n.aiwg-root.aiwg-minimized .aiwg-error,\n.aiwg-root.aiwg-minimized .aiwg-input-area,\n.aiwg-root.aiwg-minimized .aiwg-powered { display: none !important; }\n.aiwg-root.aiwg-minimized .aiwg-minimize-btn { display: none !important; }\n.aiwg-root.aiwg-minimized { cursor: pointer; box-shadow: 0 8px 32px rgba(0,0,0,0.28); }\n.aiwg-root.aiwg-minimized .aiwg-header { cursor: pointer !important; }\n\n/* \u2500\u2500 Powered-by footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-powered {\n text-align: center;\n padding: 6px 16px 10px;\n font-size: 11px; color: #94a3b8;\n flex-shrink: 0;\n border-top: 1px solid #f1f5f9;\n background: #fff;\n}\n.aiwg-powered a { color: #6366f1; text-decoration: none; font-weight: 500; }\n.aiwg-powered a:hover { text-decoration: underline; }\n\n/* \u2500\u2500 Markdown rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-msg-bubble strong { font-weight: 600; }\n.aiwg-msg-bubble em { font-style: italic; }\n.aiwg-msg-bubble code { background: rgba(0,0,0,0.08); padding: 1px 5px; border-radius: 4px; font-family: 'Fira Code','Consolas',monospace; font-size: 0.9em; }\n.aiwg-msg--user .aiwg-msg-bubble code { background: rgba(255,255,255,0.2); }\n.aiwg-msg-bubble ol, .aiwg-msg-bubble ul { padding-left: 18px; margin: 6px 0; display: flex; flex-direction: column; gap: 3px; }\n.aiwg-msg-bubble ol { list-style: decimal; }\n.aiwg-msg-bubble ul { list-style: disc; }\n.aiwg-msg-bubble li { line-height: 1.5; }\n.aiwg-msg-bubble h3, .aiwg-msg-bubble h4 { font-weight: 600; margin: 8px 0 4px; }\n.aiwg-msg-bubble p { margin: 2px 0; }\n\n/* \u2500\u2500 Dark theme \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-root.aiwg-dark { background: #0f172a; color: #e2e8f0; }\n.aiwg-dark .aiwg-msg--bot .aiwg-msg-bubble { background: #1e293b; color: #e2e8f0; }\n.aiwg-dark .aiwg-input-area { background: #0f172a; border-top-color: #1e293b; }\n.aiwg-dark .aiwg-input { background: #1e293b; border-color: #334155; color: #e2e8f0; }\n.aiwg-dark .aiwg-input:focus { border-color: #8b5cf6; background: #1e293b; box-shadow: 0 0 0 3px rgba(139,92,246,0.2); }\n.aiwg-dark .aiwg-suggestions { background: #1e293b; border-color: #334155; }\n.aiwg-dark .aiwg-suggestions-header { color: #64748b; border-bottom-color: #334155; }\n.aiwg-dark .aiwg-suggestion-item { border-bottom-color: #0f172a; }\n.aiwg-dark .aiwg-suggestion-item:hover,\n.aiwg-dark .aiwg-suggestion-item.aiwg-active { background: #2d1b69; }\n.aiwg-dark .aiwg-suggestion-text { color: #e2e8f0; }\n.aiwg-dark .aiwg-chip { background: #1e293b; border-color: #334155; }\n.aiwg-dark .aiwg-chip:hover { background: #2d1b69; }\n.aiwg-dark .aiwg-chip-shimmer { background: linear-gradient(90deg, #1e293b 25%, #334155 50%, #1e293b 75%); background-size: 200% 100%; }\n.aiwg-dark .aiwg-kbd-hint { background: #1e293b; }\n.aiwg-dark .aiwg-welcome h4 { color: #e2e8f0; }\n.aiwg-dark .aiwg-powered { background: #0f172a; border-top-color: #1e293b; }\n";
14
+ export declare const WIDGET_CSS = "\n/* \u2500\u2500 Shadow-DOM host isolation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host {\n all: initial !important;\n display: block !important;\n}\n\n/* Scoped box-model reset \u2014 only touches widget elements, not all of shadow DOM */\n.aiwg-root *, .aiwg-root *::before, .aiwg-root *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n/* \u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-root {\n --aiwg-primary: #6366f1;\n --aiwg-primary-dark: #8b5cf6;\n --aiwg-fg-color: #ffffff;\n --aiwg-bg-color: #ffffff;\n --aiwg-chat-bg: #f1f5f9;\n\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #1a1a2e;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border-radius: 16px;\n background: var(--aiwg-bg-color);\n position: fixed !important;\n bottom: 24px;\n right: 24px;\n width: 380px !important;\n max-width: calc(100vw - 48px) !important;\n z-index: 99999;\n transition: height 0.25s ease;\n box-shadow: 0 24px 64px rgba(0,0,0,0.18);\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-header {\n background: linear-gradient(135deg, var(--aiwg-primary) 0%, var(--aiwg-primary-dark) 100%);\n padding: 16px 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n position: relative;\n overflow: hidden;\n}\n.aiwg-header::before {\n content: '';\n position: absolute;\n width: 140px; height: 140px;\n background: rgba(255,255,255,0.08);\n border-radius: 50%;\n top: -50px; right: -30px;\n}\n.aiwg-avatar {\n width: 40px; height: 40px;\n background: rgba(255,255,255,0.25);\n border-radius: 50%;\n display: flex; align-items: center; justify-content: center;\n font-size: 18px;\n flex-shrink: 0;\n border: 2px solid rgba(255,255,255,0.4);\n}\n.aiwg-header-info { flex: 1; }\n.aiwg-title { color: #fff; font-weight: 600; font-size: 15px; }\n.aiwg-subtitle {\n color: rgba(255,255,255,0.75);\n font-size: 12px;\n display: flex; align-items: center; gap: 5px;\n}\n.aiwg-online-dot {\n width: 7px; height: 7px;\n background: #4ade80;\n border-radius: 50%;\n display: inline-block;\n animation: aiwg-pulse 2s ease-in-out infinite;\n}\n@keyframes aiwg-pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.6; transform: scale(0.85); }\n}\n.aiwg-minimize-btn {\n width: 36px; height: 36px;\n background: rgba(255,255,255,0.18);\n border: 1.5px solid rgba(255,255,255,0.3);\n border-radius: 50%;\n color: #fff; cursor: pointer;\n display: flex; align-items: center; justify-content: center;\n font-size: 18px; line-height: 1;\n transition: background 0.15s, transform 0.15s;\n flex-shrink: 0;\n position: relative; z-index: 2;\n}\n.aiwg-minimize-btn * { cursor: pointer !important; pointer-events: none; }\n.aiwg-minimize-btn:hover { background: rgba(255,255,255,0.32); transform: scale(1.08); }\n\n/* \u2500\u2500 Messages area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-messages {\n flex: 1;\n overflow-y: auto;\n padding: 20px 16px 8px;\n scroll-behavior: smooth;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.aiwg-messages::-webkit-scrollbar { width: 4px; }\n.aiwg-messages::-webkit-scrollbar-thumb { background: #e2e8f0; border-radius: 99px; }\n\n/* \u2500\u2500 Welcome card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-welcome {\n text-align: center;\n padding: 24px 16px;\n display: flex; flex-direction: column; align-items: center; gap: 8px;\n}\n.aiwg-welcome-icon { font-size: 36px; margin-bottom: 4px; }\n.aiwg-welcome h4 { font-size: 15px; font-weight: 600; color: #1a1a2e; }\n.aiwg-welcome p { font-size: 13px; color: #64748b; }\n\n/* \u2500\u2500 Message bubbles \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-msg {\n display: flex;\n gap: 8px;\n align-items: flex-end;\n animation: aiwg-fade-up 0.2s ease both;\n}\n@keyframes aiwg-fade-up {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.aiwg-msg--user { flex-direction: row-reverse; }\n.aiwg-msg-avatar {\n width: 28px; height: 28px; border-radius: 50%;\n display: flex; align-items: center; justify-content: center;\n font-size: 13px; flex-shrink: 0;\n margin-bottom: 2px;\n}\n.aiwg-msg--bot .aiwg-msg-avatar { background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark)); color: var(--aiwg-fg-color); }\n.aiwg-msg--user .aiwg-msg-avatar { background: #e2e8f0; color: #64748b; }\n.aiwg-msg-body { max-width: 78%; }\n.aiwg-msg-bubble {\n padding: 10px 14px;\n border-radius: 18px;\n font-size: 14px;\n line-height: 1.55;\n word-break: break-word;\n}\n.aiwg-msg--bot .aiwg-msg-bubble { background: var(--aiwg-chat-bg); color: #1a1a2e; border-bottom-left-radius: 4px; }\n.aiwg-msg--user .aiwg-msg-bubble { background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark)); color: var(--aiwg-fg-color); border-bottom-right-radius: 4px; }\n.aiwg-msg-time { font-size: 10px; color: #94a3b8; margin-top: 4px; text-align: right; padding: 0 4px; }\n.aiwg-msg--bot .aiwg-msg-time { text-align: left; }\n\n/* \u2500\u2500 Typing indicator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-typing { padding: 10px 14px; }\n.aiwg-typing-dots { display: flex; gap: 4px; align-items: center; }\n.aiwg-typing-dots span {\n width: 7px; height: 7px;\n background: #94a3b8; border-radius: 50%;\n animation: aiwg-bounce 1.2s ease-in-out infinite;\n}\n.aiwg-typing-dots span:nth-child(2) { animation-delay: 0.2s; }\n.aiwg-typing-dots span:nth-child(3) { animation-delay: 0.4s; }\n@keyframes aiwg-bounce {\n 0%, 80%, 100% { transform: translateY(0); }\n 40% { transform: translateY(-6px); }\n}\n\n/* \u2500\u2500 Quick-reply chips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-chip-row {\n padding: 6px 16px 2px;\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex-shrink: 0;\n}\n.aiwg-chip {\n background: #f1f5f9;\n border: 1px solid #e2e8f0;\n border-radius: 99px;\n padding: 4px 12px;\n font-size: 12px;\n color: #4f46e5;\n cursor: pointer;\n transition: all 0.15s;\n white-space: nowrap;\n font-weight: 500;\n}\n.aiwg-chip:hover { background: #ede9fe; border-color: #a5b4fc; }\n.aiwg-chip-shimmer {\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n border: 1px solid transparent;\n border-radius: 99px;\n padding: 4px 34px;\n animation: aiwg-shimmer 1.4s ease-in-out infinite;\n cursor: default;\n pointer-events: none;\n}\n.aiwg-chip-ai-badge {\n display: inline-block;\n font-size: 9px; font-weight: 700;\n background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark));\n color: #fff;\n padding: 1px 5px;\n border-radius: 99px;\n margin-left: 5px;\n vertical-align: middle;\n letter-spacing: 0.04em;\n}\n@keyframes aiwg-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* \u2500\u2500 Input area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-input-area {\n padding: 12px 16px 16px;\n flex-shrink: 0;\n background: #fff;\n border-top: 1px solid #f1f5f9;\n position: relative;\n}\n.aiwg-input-row { display: flex; gap: 8px; align-items: flex-end; }\n.aiwg-input {\n flex: 1;\n border: 1.5px solid #e2e8f0;\n border-radius: 12px;\n padding: 10px 14px;\n font-size: 14px;\n font-family: inherit;\n outline: none;\n resize: none;\n background: #f8fafc;\n color: #1a1a2e;\n transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;\n line-height: 1.4;\n max-height: 120px;\n overflow-y: auto;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n.aiwg-input::-webkit-scrollbar { display: none; }\n.aiwg-input::placeholder { color: #94a3b8; }\n.aiwg-input:focus {\n border-color: var(--aiwg-primary-dark);\n background: #fff;\n box-shadow: 0 0 0 3px rgba(139,92,246,0.1);\n}\n.aiwg-send-btn {\n width: 42px; height: 42px;\n background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark));\n border: none; border-radius: 12px;\n color: var(--aiwg-fg-color); cursor: pointer;\n display: flex; align-items: center; justify-content: center;\n flex-shrink: 0;\n transition: transform 0.15s, box-shadow 0.15s, opacity 0.15s;\n box-shadow: 0 4px 12px rgba(99,102,241,0.35);\n}\n.aiwg-send-btn svg { width: 18px; height: 18px; }\n.aiwg-send-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(99,102,241,0.4); }\n.aiwg-send-btn:active { transform: translateY(0); }\n.aiwg-send-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }\n\n/* \u2500\u2500 Autocomplete suggestions dropdown \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-suggestions {\n position: absolute;\n bottom: calc(100% + 4px);\n left: 16px; right: 16px;\n background: #fff;\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.12);\n overflow: hidden;\n z-index: 100;\n animation: aiwg-fade-up 0.15s ease both;\n}\n.aiwg-suggestions-header {\n padding: 8px 14px 4px;\n font-size: 11px; font-weight: 600;\n color: #94a3b8;\n text-transform: uppercase; letter-spacing: 0.06em;\n border-bottom: 1px solid #f1f5f9;\n}\n.aiwg-suggestion-item {\n display: flex; align-items: center; gap: 10px;\n padding: 10px 14px;\n cursor: pointer;\n transition: background 0.1s;\n border-bottom: 1px solid #f8fafc;\n}\n.aiwg-suggestion-item:last-child { border-bottom: none; }\n.aiwg-suggestion-item:hover,\n.aiwg-suggestion-item.aiwg-active { background: #f5f3ff; }\n.aiwg-suggestion-icon { font-size: 16px; flex-shrink: 0; }\n.aiwg-suggestion-main { flex: 1; min-width: 0; }\n.aiwg-suggestion-text { font-size: 13px; font-weight: 500; color: #1a1a2e; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.aiwg-suggestion-text mark { background: none; color: #6366f1; font-weight: 600; }\n.aiwg-suggestion-desc { font-size: 11px; color: #94a3b8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.aiwg-suggestion-badge { font-size: 10px; font-weight: 600; padding: 2px 8px; border-radius: 99px; background: #ede9fe; color: #6366f1; flex-shrink: 0; }\n.aiwg-kbd-hint {\n padding: 6px 14px;\n font-size: 11px; color: #cbd5e1; background: #f8fafc;\n display: flex; justify-content: flex-end; gap: 10px;\n}\n.aiwg-kbd-hint kbd { font-family: inherit; background: #e2e8f0; border-radius: 4px; padding: 1px 5px; font-size: 10px; color: #64748b; }\n\n/* \u2500\u2500 Error toast \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-error {\n margin: 0 16px 8px;\n padding: 8px 12px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n border-radius: 8px;\n font-size: 12px;\n color: #dc2626;\n}\n\n/* \u2500\u2500 Minimized state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-root.aiwg-minimized .aiwg-messages,\n.aiwg-root.aiwg-minimized .aiwg-chip-row,\n.aiwg-root.aiwg-minimized .aiwg-error,\n.aiwg-root.aiwg-minimized .aiwg-input-area,\n.aiwg-root.aiwg-minimized .aiwg-powered { display: none !important; }\n.aiwg-root.aiwg-minimized .aiwg-minimize-btn { display: none !important; }\n.aiwg-root.aiwg-minimized { cursor: pointer; box-shadow: 0 8px 32px rgba(0,0,0,0.28); }\n.aiwg-root.aiwg-minimized .aiwg-header { cursor: pointer !important; }\n\n/* \u2500\u2500 Powered-by footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-powered {\n text-align: center;\n padding: 6px 16px 10px;\n font-size: 11px; color: #94a3b8;\n flex-shrink: 0;\n border-top: 1px solid #f1f5f9;\n background: #fff;\n}\n.aiwg-powered a { color: #6366f1; text-decoration: none; font-weight: 500; }\n.aiwg-powered a:hover { text-decoration: underline; }\n\n/* \u2500\u2500 Markdown rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-msg-bubble strong { font-weight: 600; }\n.aiwg-msg-bubble em { font-style: italic; }\n.aiwg-msg-bubble code { background: rgba(0,0,0,0.08); padding: 1px 5px; border-radius: 4px; font-family: 'Fira Code','Consolas',monospace; font-size: 0.9em; }\n.aiwg-msg--user .aiwg-msg-bubble code { background: rgba(255,255,255,0.2); }\n.aiwg-msg-bubble ol, .aiwg-msg-bubble ul { padding-left: 18px; margin: 6px 0; display: flex; flex-direction: column; gap: 3px; }\n.aiwg-msg-bubble ol { list-style: decimal; }\n.aiwg-msg-bubble ul { list-style: disc; }\n.aiwg-msg-bubble li { line-height: 1.5; }\n.aiwg-msg-bubble h3, .aiwg-msg-bubble h4 { font-weight: 600; margin: 8px 0 4px; }\n.aiwg-msg-bubble p { margin: 2px 0; }\n\n/* \u2500\u2500 Dark theme \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.aiwg-root.aiwg-dark { background: #0f172a; color: #e2e8f0; }\n.aiwg-dark .aiwg-msg--bot .aiwg-msg-bubble { background: #1e293b; color: #e2e8f0; }\n.aiwg-dark .aiwg-input-area { background: #0f172a; border-top-color: #1e293b; }\n.aiwg-dark .aiwg-input { background: #1e293b; border-color: #334155; color: #e2e8f0; }\n.aiwg-dark .aiwg-input:focus { border-color: #8b5cf6; background: #1e293b; box-shadow: 0 0 0 3px rgba(139,92,246,0.2); }\n.aiwg-dark .aiwg-suggestions { background: #1e293b; border-color: #334155; }\n.aiwg-dark .aiwg-suggestions-header { color: #64748b; border-bottom-color: #334155; }\n.aiwg-dark .aiwg-suggestion-item { border-bottom-color: #0f172a; }\n.aiwg-dark .aiwg-suggestion-item:hover,\n.aiwg-dark .aiwg-suggestion-item.aiwg-active { background: #2d1b69; }\n.aiwg-dark .aiwg-suggestion-text { color: #e2e8f0; }\n.aiwg-dark .aiwg-chip { background: #1e293b; border-color: #334155; }\n.aiwg-dark .aiwg-chip:hover { background: #2d1b69; }\n.aiwg-dark .aiwg-chip-shimmer { background: linear-gradient(90deg, #1e293b 25%, #334155 50%, #1e293b 75%); background-size: 200% 100%; }\n.aiwg-dark .aiwg-kbd-hint { background: #1e293b; }\n.aiwg-dark .aiwg-welcome h4 { color: #e2e8f0; }\n.aiwg-dark .aiwg-powered { background: #0f172a; border-top-color: #1e293b; }\n";
@@ -79,9 +79,7 @@ export const WIDGET_CSS = `
79
79
  font-size: 18px;
80
80
  flex-shrink: 0;
81
81
  border: 2px solid rgba(255,255,255,0.4);
82
- color: #fff;
83
82
  }
84
- .aiwg-avatar svg { display: block; width: 22px; height: 22px; }
85
83
  .aiwg-header-info { flex: 1; }
86
84
  .aiwg-title { color: #fff; font-weight: 600; font-size: 15px; }
87
85
  .aiwg-subtitle {
@@ -113,7 +111,6 @@ export const WIDGET_CSS = `
113
111
  position: relative; z-index: 2;
114
112
  }
115
113
  .aiwg-minimize-btn * { cursor: pointer !important; pointer-events: none; }
116
- .aiwg-minimize-btn svg { display: block; width: 16px; height: 16px; }
117
114
  .aiwg-minimize-btn:hover { background: rgba(255,255,255,0.32); transform: scale(1.08); }
118
115
 
119
116
  /* ── Messages area ────────────────────────────────────────────────────────── */
@@ -135,12 +132,7 @@ export const WIDGET_CSS = `
135
132
  padding: 24px 16px;
136
133
  display: flex; flex-direction: column; align-items: center; gap: 8px;
137
134
  }
138
- .aiwg-welcome-icon {
139
- display: flex; align-items: center; justify-content: center;
140
- margin-bottom: 4px;
141
- color: var(--aiwg-primary);
142
- }
143
- .aiwg-welcome-icon svg { width: 36px; height: 36px; }
135
+ .aiwg-welcome-icon { font-size: 36px; margin-bottom: 4px; }
144
136
  .aiwg-welcome h4 { font-size: 15px; font-weight: 600; color: #1a1a2e; }
145
137
  .aiwg-welcome p { font-size: 13px; color: #64748b; }
146
138
 
@@ -162,7 +154,6 @@ export const WIDGET_CSS = `
162
154
  font-size: 13px; flex-shrink: 0;
163
155
  margin-bottom: 2px;
164
156
  }
165
- .aiwg-msg-avatar svg { display: block; width: 16px; height: 16px; }
166
157
  .aiwg-msg--bot .aiwg-msg-avatar { background: linear-gradient(135deg, var(--aiwg-primary), var(--aiwg-primary-dark)); color: var(--aiwg-fg-color); }
167
158
  .aiwg-msg--user .aiwg-msg-avatar { background: #e2e8f0; color: #64748b; }
168
159
  .aiwg-msg-body { max-width: 78%; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@courseecho/ai-core-sdk",
3
- "version": "1.0.22",
3
+ "version": "1.0.25",
4
4
  "description": "Framework-agnostic core AI chat SDK. Shared logic for all framework wrappers.",
5
5
  "license": "MIT",
6
6
  "author": "CourseEcho",