@hachther/akilio-widget 0.5.0 → 0.6.2

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/types.d.ts CHANGED
@@ -5,6 +5,7 @@ export type AkilioLocale = string;
5
5
  export type AkilioMessageRole = 'user' | 'assistant';
6
6
  export type AkilioFeedbackRating = 'up' | 'down';
7
7
  export type AkilioAssistantMode = 'auto' | 'general' | 'knowledge' | 'ecommerce' | 'hybrid';
8
+ export type AkilioWidgetBranding = 'akilio_required' | 'removable' | 'white_label';
8
9
  export type AkilioCommerceCapabilityType = 'product_search' | 'product_recommendation';
9
10
  export type AkilioCommerceEventType = 'search' | 'recommendation' | 'compare' | 'add_to_cart' | 'checkout' | 'purchase';
10
11
  export type AkilioCredentialsMode = 'omit' | 'same-origin' | 'include';
@@ -36,6 +37,7 @@ export interface AkilioAuthConfig {
36
37
  }
37
38
  export interface AkilioThemeConfig {
38
39
  primary?: string;
40
+ primaryDark?: string;
39
41
  primaryForeground?: string;
40
42
  accent?: string;
41
43
  surface?: string;
@@ -116,10 +118,21 @@ export interface AkilioProjectConfig {
116
118
  theme_config: AkilioThemeConfig;
117
119
  default_language: string;
118
120
  supported_languages: string[];
121
+ widget_policy?: AkilioWidgetPolicy;
119
122
  privacy_notice?: string;
120
123
  privacy_notice_url?: string;
121
124
  require_consent?: boolean;
122
125
  }
126
+ export interface AkilioWidgetPolicy {
127
+ /** Whether the widget may currently accept user interactions. */
128
+ available: boolean;
129
+ /** Server-authoritative assistant behavior for this project. */
130
+ assistant_mode: AkilioAssistantMode;
131
+ /** Whether product results and commerce events may be used. */
132
+ commerce_enabled: boolean;
133
+ /** Branding treatment the widget must apply. */
134
+ branding: AkilioWidgetBranding;
135
+ }
123
136
  export interface AkilioChatRequest {
124
137
  project_key: string;
125
138
  conversation_id?: string;
@@ -165,6 +178,54 @@ export interface AkilioChatResponse {
165
178
  assistant_mode?: string;
166
179
  active_route?: string;
167
180
  }
181
+ export type AkilioStreamEventName = 'status' | 'conversation' | 'answer.delta' | 'final' | 'error' | 'done';
182
+ export interface AkilioStreamEvent {
183
+ event: AkilioStreamEventName | string;
184
+ data: Record<string, unknown>;
185
+ }
186
+ export interface AkilioChatStreamHandlers {
187
+ onEvent?: (event: AkilioStreamEvent) => void;
188
+ onStatus?: (stage: string, data: Record<string, unknown>) => void;
189
+ onConversation?: (conversationId: string) => void;
190
+ onDelta?: (delta: string) => void;
191
+ }
192
+ export type AkilioPublicApiErrorCode = 'NOT_READY' | 'INVALID_QUESTION' | 'EMPTY_DRAFT' | 'BUSY' | 'TYPING_CANCELLED' | 'STREAM_FAILED' | 'RESET_FAILED';
193
+ export interface AkilioDraftOptions {
194
+ focus?: boolean;
195
+ clearExisting?: boolean;
196
+ }
197
+ export interface AkilioTypeDraftOptions extends AkilioDraftOptions {
198
+ interval?: number;
199
+ }
200
+ export interface AkilioPublicState {
201
+ ready: boolean;
202
+ open: boolean;
203
+ busy: boolean;
204
+ typing: boolean;
205
+ draft: string;
206
+ conversationId: string | null;
207
+ }
208
+ export interface AkilioPublicApi {
209
+ open(): Promise<void>;
210
+ close(): Promise<void>;
211
+ setDraft(text: string, options?: AkilioDraftOptions): Promise<void>;
212
+ typeDraft(text: string, options?: AkilioTypeDraftOptions): Promise<void>;
213
+ clearDraft(): Promise<void>;
214
+ cancelTyping(): void;
215
+ submit(): Promise<AkilioChatResponse>;
216
+ ask(text: string, options?: AkilioDraftOptions): Promise<AkilioChatResponse>;
217
+ reset(): Promise<void>;
218
+ getState(): AkilioPublicState;
219
+ }
220
+ declare global {
221
+ interface Window {
222
+ AkilioWidget?: AkilioPublicApi;
223
+ }
224
+ }
225
+ export declare class AkilioPublicApiError extends Error {
226
+ readonly code: AkilioPublicApiErrorCode;
227
+ constructor(code: AkilioPublicApiErrorCode, message: string);
228
+ }
168
229
  export interface AkilioConversationMessageResponse {
169
230
  id: string;
170
231
  role: AkilioMessageRole;
@@ -198,6 +259,8 @@ export interface AkilioChatMessage {
198
259
  costUsd?: string;
199
260
  commerce?: AkilioCommerceCapability | null;
200
261
  suggestions?: string[];
262
+ /** True while answer deltas are still arriving. */
263
+ streaming?: boolean;
201
264
  error?: boolean;
202
265
  feedback?: AkilioFeedbackRating;
203
266
  }
@@ -209,6 +272,10 @@ export interface AkilioCopyOverrides {
209
272
  helper?: string;
210
273
  submit?: string;
211
274
  loading?: string;
275
+ searching?: string;
276
+ reviewingSources?: string;
277
+ checkingAnswer?: string;
278
+ preparingAnswer?: string;
212
279
  emptyState?: string;
213
280
  sources?: string;
214
281
  confidence?: string;
@@ -228,6 +295,8 @@ export interface AkilioCopyOverrides {
228
295
  privacyDecline?: string;
229
296
  privacyReview?: string;
230
297
  privacyRequired?: string;
298
+ widgetUnavailable?: string;
299
+ poweredBy?: string;
231
300
  privacyDefaultNotice?: string;
232
301
  switchToLightMode?: string;
233
302
  switchToDarkMode?: string;
@@ -245,14 +314,24 @@ export interface AkilioLauncherRenderProps {
245
314
  toggleChat: () => void;
246
315
  }
247
316
  export type AkilioLauncher = 'default' | 'hidden' | ((controls: AkilioLauncherRenderProps) => ReactNode);
317
+ export type AkilioStyleIsolation = 'shadow' | 'scoped' | 'none';
248
318
  export interface AkilioWidgetProps {
249
- apiBaseUrl: string;
319
+ apiBaseUrl?: string;
250
320
  projectKey: string;
251
321
  locale?: AkilioLocale;
252
322
  mode?: AkilioMode;
253
323
  colorMode?: AkilioColorMode;
254
324
  /** Show a header control that lets visitors override the configured/system theme. */
255
325
  allowColorModeToggle?: boolean;
326
+ /**
327
+ * Show Akilio branding when widget_policy.branding is "removable".
328
+ * Ignored when branding is required or the project is white-labelled.
329
+ */
330
+ showAkilioBranding?: boolean;
331
+ /** Use the authenticated SSE chat endpoint. Set false for synchronous compatibility. */
332
+ streaming?: boolean;
333
+ /** Isolate widget CSS from the host page. Shadow DOM is the safest default. */
334
+ styleIsolation?: AkilioStyleIsolation;
256
335
  defaultOpen?: boolean;
257
336
  /** Controlled open state. Pair with onOpenChange. */
258
337
  open?: boolean;
package/dist/vanilla.d.ts CHANGED
@@ -22,6 +22,7 @@ export interface AkilioVanillaApi {
22
22
  declare global {
23
23
  interface Window {
24
24
  Akilio?: AkilioVanillaApi;
25
+ __AKILIO_WIDGET_AUTO_MOUNTED__?: boolean;
25
26
  }
26
27
  }
27
28
  declare function mount(options: AkilioVanillaOptions): AkilioVanillaInstance;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachther/akilio-widget",
3
- "version": "0.5.0",
3
+ "version": "0.6.2",
4
4
  "description": "Embeddable React AI assistant widget for Akilio backend.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -17,10 +17,11 @@
17
17
  "scripts": {
18
18
  "dev": "vite --host 0.0.0.0",
19
19
  "build": "npm run build:react && npm run build:vanilla",
20
- "build:react": "vite build && tsc -p tsconfig.build.json",
20
+ "build:react": "vite build && tsc -p tsconfig.build.json && cp src/styles.css dist/style.css",
21
21
  "build:vanilla": "vite build --config vite.vanilla.config.ts",
22
22
  "preview": "vite preview",
23
23
  "typecheck": "tsc --noEmit",
24
+ "test": "vitest run",
24
25
  "lint": "eslint src --ext .ts,.tsx",
25
26
  "format": "prettier --check --ignore-path .gitignore .",
26
27
  "format:fix": "prettier --write --ignore-path .gitignore ."
@@ -31,22 +32,24 @@
31
32
  },
32
33
  "dependencies": {
33
34
  "clsx": "^2.1.1",
34
- "driver.js": "^1.8.0",
35
35
  "react-markdown": "^10.1.0",
36
36
  "rehype-highlight": "^7.0.2",
37
37
  "remark-gfm": "^4.0.1"
38
38
  },
39
39
  "devDependencies": {
40
+ "@testing-library/react": "^16.3.2",
40
41
  "@types/react": "^19.0.0",
41
42
  "@types/react-dom": "^19.0.0",
42
43
  "@vitejs/plugin-react": "^5.0.0",
43
44
  "eslint-config-prettier": "^9.1.0",
45
+ "jsdom": "^29.1.1",
44
46
  "prettier": "^3.9.0",
45
47
  "prettier-plugin-organize-imports": "^3.2.4",
46
48
  "react": "^19.2.7",
47
49
  "react-dom": "^19.2.7",
48
50
  "typescript": "^5.8.0",
49
- "vite": "^7.0.0"
51
+ "vite": "^7.0.0",
52
+ "vitest": "^4.1.10"
50
53
  },
51
54
  "unpkg": "dist/akilio-widget.min.js",
52
55
  "jsdelivr": "dist/akilio-widget.min.js",
@@ -1 +0,0 @@
1
- .driver-popover{all:unset;font-family:var(--driver-popover-font-family,"Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif);box-sizing:border-box;color:#2d2d2d;z-index:1000000000;background-color:#fff;border-radius:5px;min-width:250px;max-width:300px;margin:0;padding:15px;position:fixed;top:0;right:0;box-shadow:0 1px 10px #0006}.driver-popover-title{zoom:1;margin:0;font-size:19px;font-weight:700;line-height:1.5;display:block;position:relative}.driver-popover-close-btn{all:unset;cursor:pointer;color:#d2d2d2;z-index:1;text-align:center;width:32px;height:28px;font-size:18px;font-weight:500;transition:color .2s;position:absolute;top:0;right:0}.driver-popover-close-btn:hover,.driver-popover-close-btn:focus{color:#2d2d2d}.driver-popover-title[style*=block]+.driver-popover-description{margin-top:5px}.driver-popover-description{zoom:1;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.5}.driver-popover-footer{text-align:right;zoom:1;justify-content:space-between;align-items:center;margin-top:15px;display:flex}.driver-popover-progress-text{color:#727272;zoom:1;font-size:13px;font-weight:400}.driver-popover-footer-btn{all:unset;box-sizing:border-box;color:#2d2d2d;cursor:pointer;zoom:1;background-color:#fff;border:1px solid #ccc;border-radius:3px;outline:0;padding:3px 7px;font-size:12px;line-height:1.3;text-decoration:none;display:inline-block}.driver-popover-footer .driver-popover-btn-disabled{opacity:.5;pointer-events:none}.driver-popover-footer-btn:hover,.driver-popover-footer-btn:focus{background-color:#f7f7f7}.driver-popover-navigation-btns{flex-grow:1;justify-content:flex-end;display:flex}.driver-popover-navigation-btns button+button{margin-left:4px}.driver-popover-arrow{content:"";border:5px solid #fff;position:absolute}.driver-popover-arrow-side-over{display:none}.driver-popover-arrow-side-left{border-top-color:#0000;border-bottom-color:#0000;border-right-color:#0000;left:100%}.driver-popover-arrow-side-right{border-top-color:#0000;border-bottom-color:#0000;border-left-color:#0000;right:100%}.driver-popover-arrow-side-top{border-bottom-color:#0000;border-left-color:#0000;border-right-color:#0000;top:100%}.driver-popover-arrow-side-bottom{border-top-color:#0000;border-left-color:#0000;border-right-color:#0000;bottom:100%}.driver-popover-arrow-side-center,.driver-popover-arrow-none{display:none}.driver-active .driver-overlay{pointer-events:none}.driver-active.driver-no-scroll{overflow:hidden}.driver-active *{pointer-events:none}.driver-active .driver-active-element,.driver-active .driver-active-element *,.driver-popover,.driver-popover *{pointer-events:auto}@keyframes animate-fade-in{0%{opacity:0}to{opacity:1}}.driver-fade .driver-overlay{animation:animate-fade-in var(--driver-animation-duration,.4s) ease-in-out}.driver-fade .driver-popover{animation:animate-fade-in var(--driver-animation-duration,.4s)}.driver-active-element-parent-no-scroll{overflow:hidden!important}.driver-no-interaction,.driver-no-interaction *{pointer-events:none!important}:root{--akilio-primary: #0891b2;--akilio-primary-foreground: #ffffff;--akilio-accent: #2563eb;--akilio-radius: 22px;--akilio-panel-width: 440px;--akilio-z-index: 2147483000}@media(min-width:1280px){html.akilio-panel-open body{padding-right:var(--akilio-panel-width);transition:padding-right .26s ease}html.akilio-panel-open #akilio-launcher{transform:translate(calc(-1 * var(--akilio-panel-width)))}}.akilio-root,.akilio-root *{box-sizing:border-box}.akilio-root{color:#18181b;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.akilio-launcher{position:fixed;right:22px;bottom:22px;z-index:calc(var(--akilio-z-index) - 10);display:inline-flex;align-items:center;gap:10px;border:1px solid rgba(255,255,255,.22);border-radius:999px;background:linear-gradient(135deg,#09090b,#27272a);color:#fff;padding:11px 16px 11px 12px;cursor:pointer;box-shadow:0 24px 60px #18181b40,0 0 0 1px #09090b14;transition:transform .26s ease,box-shadow .18s ease,background .18s ease}.akilio-launcher:hover{transform:translateY(-2px);box-shadow:0 28px 70px #0891b240,0 0 0 1px #09090b14}.akilio-launcher span{display:grid;width:30px;height:30px;place-items:center;overflow:hidden;border-radius:999px;background:#fff}.akilio-launcher-logo{display:block;width:22px;height:22px;object-fit:contain}.akilio-launcher strong{font-size:14px;font-weight:750;letter-spacing:-.01em}.akilio-overlay{position:fixed;inset:0;z-index:calc(var(--akilio-z-index) - 2);border:0;background:#09090b75;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);cursor:default}.akilio-panel{position:fixed;top:0;right:0;z-index:var(--akilio-z-index);display:flex;width:min(100vw,var(--akilio-panel-width));height:100dvh;transform:translate(103%);flex-direction:column;overflow:hidden;border-left:1px solid rgba(212,212,216,.9);background:#f8fafc;box-shadow:-30px 0 90px #0f172a3d;transition:transform .26s cubic-bezier(.2,.8,.2,1)}.akilio-panel--open{transform:translate(0)}.akilio-root[data-akilio-mode=floating] .akilio-panel{top:auto;right:22px;bottom:88px;width:min(400px,calc(100vw - 32px));height:min(650px,calc(100dvh - 116px));min-height:420px;transform:translateY(18px) scale(.98);transform-origin:right bottom;border:1px solid rgba(212,212,216,.9);border-radius:var(--akilio-radius);box-shadow:0 28px 80px #0f172a3d;opacity:0;visibility:hidden;pointer-events:none;transition:transform .22s cubic-bezier(.2,.8,.2,1),opacity .18s ease,visibility .18s ease}.akilio-root[data-akilio-mode=floating] .akilio-panel--open{transform:translateY(0) scale(1);opacity:1;visibility:visible;pointer-events:auto}.akilio-panel-glow{position:absolute;inset:0 0 auto;height:185px;pointer-events:none;background:radial-gradient(circle at 0% 0%,color-mix(in srgb,var(--akilio-primary) 35%,transparent),transparent 36%),radial-gradient(circle at 100% 0%,rgba(37,99,235,.22),transparent 34%)}.akilio-panel-header{position:relative;display:flex;align-items:flex-start;gap:12px;border-bottom:1px solid rgba(212,212,216,.82);background:#ffffffc7;padding:16px;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.akilio-logo,.akilio-empty-icon{display:grid;flex-shrink:0;place-items:center}.akilio-logo{width:94px;height:34px}.akilio-logo img{display:block;width:100%;height:100%;object-fit:contain;object-position:left center}.akilio-empty-icon{width:64px;height:64px;border:1px solid rgba(124,58,237,.12);border-radius:calc(var(--akilio-radius) - 4px);background:#ffffffe0;box-shadow:0 18px 42px #6d28d929}.akilio-empty-icon img{display:block;width:42px;height:42px;object-fit:contain}.akilio-header-content{min-width:0;flex:1}.akilio-header-topline{display:flex;min-width:0;align-items:center;justify-content:space-between;gap:10px}.akilio-header-title{display:flex;min-width:0;align-items:center;gap:8px}.akilio-header-title h2{overflow:hidden;margin:0;color:#09090b;font-size:14px;font-weight:800;letter-spacing:-.015em;text-overflow:ellipsis;white-space:nowrap}.akilio-online{display:inline-flex;align-items:center;gap:5px;border-radius:999px;background:#10b9811f;color:#047857;padding:3px 8px;font-size:10px;font-weight:800;white-space:nowrap}.akilio-online i{width:6px;height:6px;border-radius:999px;background:#10b981}.akilio-header-description{display:-webkit-box;margin:6px 0 0;overflow:hidden;color:#71717a;font-size:12px;line-height:1.55;-webkit-box-orient:vertical;-webkit-line-clamp:3}.akilio-header-actions{display:flex;flex-shrink:0;align-items:center;gap:4px}.akilio-header-actions button{display:grid;width:36px;height:36px;place-items:center;border:0;border-radius:999px;background:transparent;color:#71717a;cursor:pointer;transition:background .16s ease,color .16s ease}.akilio-header-actions button:hover{background:#f4f4f5;color:#09090b}.akilio-header-actions svg{width:18px;height:18px}.akilio-thread{position:relative;display:flex;flex:1;flex-direction:column;gap:14px;overflow-y:auto;padding:18px 16px 22px}.akilio-message-row{display:flex;width:100%}.akilio-message-row--user{justify-content:flex-end}.akilio-message-row--assistant{justify-content:flex-start}.akilio-bubble{max-width:88%;overflow:hidden;border:1px solid rgba(212,212,216,.86);border-radius:26px 26px 26px 8px;background:#fffffff0;color:#27272a;padding:13px 15px;box-shadow:0 10px 28px #0f172a12}.akilio-bubble--user{border-color:#ffffff26;border-bottom-right-radius:8px;border-bottom-left-radius:26px;background:linear-gradient(135deg,#09090b,#27272a);color:#fff}.akilio-bubble--error{border-color:#f8717159;background:#fef2f2;color:#991b1b}.akilio-bubble-meta{display:flex;align-items:center;gap:7px;margin-bottom:8px;color:var(--akilio-primary);font-size:10px;font-weight:850;letter-spacing:.15em;text-transform:uppercase}.akilio-mini-icon{width:14px;height:14px}.akilio-confidence{margin-left:auto;border-radius:999px;background:color-mix(in srgb,var(--akilio-primary) 11%,transparent);padding:2px 7px;color:var(--akilio-primary);letter-spacing:0;text-transform:none}.akilio-answer{color:inherit;font-size:14px;line-height:1.7}.akilio-answer p{margin:.5rem 0}.akilio-answer p:first-child{margin-top:0}.akilio-answer p:last-child{margin-bottom:0}.akilio-answer ul,.akilio-answer ol{margin:.625rem 0 .625rem 1.25rem;padding-left:.75rem}.akilio-answer ul{list-style:disc}.akilio-answer ol{list-style:decimal}.akilio-answer li{margin:.25rem 0}.akilio-answer a{color:var(--akilio-primary);font-weight:700;text-decoration:underline;text-underline-offset:3px}.akilio-answer code{border-radius:7px;background:#0f172a14;padding:.12rem .35rem;font-size:.86em}.akilio-answer pre{margin:.75rem 0;overflow-x:auto;border:1px solid rgba(148,163,184,.2);border-radius:16px;background:#020617;padding:13px}.akilio-answer pre code{background:transparent;color:#e2e8f0;padding:0}.akilio-answer .hljs-keyword,.akilio-answer .hljs-selector-tag,.akilio-answer .hljs-built_in{color:#f0abfc}.akilio-answer .hljs-string,.akilio-answer .hljs-attr,.akilio-answer .hljs-symbol{color:#86efac}.akilio-answer .hljs-number,.akilio-answer .hljs-literal{color:#fcd34d}.akilio-answer .hljs-comment{color:#64748b;font-style:italic}.akilio-answer .hljs-title,.akilio-answer .hljs-function{color:#7dd3fc}.akilio-answer .hljs-variable{color:#fdba74}.akilio-answer--user{white-space:pre-wrap}.akilio-answer--user code{background:#ffffff29}.akilio-sources{margin-top:11px;overflow:hidden;border:1px solid rgba(212,212,216,.85);border-radius:16px;background:#f4f4f5c7}.akilio-sources summary{cursor:pointer;padding:9px 11px;color:#52525b;font-size:12px;font-weight:800}.akilio-sources-list{display:grid;gap:8px;border-top:1px solid rgba(212,212,216,.85);padding:8px}.akilio-source-card{display:grid;gap:3px;border:1px solid rgba(212,212,216,.82);border-radius:13px;background:#fff;padding:8px;font-size:12px}.akilio-source-card strong{color:#18181b}.akilio-source-card span{color:#71717a}.akilio-source-card a{overflow:hidden;color:var(--akilio-primary);text-overflow:ellipsis;white-space:nowrap}.akilio-feedback{display:flex;align-items:center;gap:7px;margin-top:11px;color:#71717a;font-size:11px}.akilio-feedback span{margin-right:auto}.akilio-feedback button{display:grid;width:28px;height:28px;place-items:center;border:1px solid rgba(212,212,216,.9);border-radius:999px;background:#fff;color:#71717a;cursor:pointer}.akilio-feedback button:hover,.akilio-feedback .akilio-feedback-active{border-color:color-mix(in srgb,var(--akilio-primary) 35%,#d4d4d8);color:var(--akilio-primary)}.akilio-feedback svg{width:14px;height:14px}.akilio-dots{display:flex;gap:6px;padding:2px 0}.akilio-dots span{width:8px;height:8px;border-radius:999px;background:var(--akilio-primary);animation:akilio-bounce .9s infinite ease-in-out}.akilio-dots span:nth-child(2){animation-delay:.1s}.akilio-dots span:nth-child(3){animation-delay:.2s}@keyframes akilio-bounce{0%,80%,to{transform:translateY(0);opacity:.45}40%{transform:translateY(-4px);opacity:1}}.akilio-empty{margin:auto;display:flex;max-width:340px;flex-direction:column;align-items:center;padding:34px 0;text-align:center}.akilio-empty-icon{width:58px;height:58px;margin-bottom:16px}.akilio-empty h3{margin:0;color:#09090b;font-size:17px;font-weight:850;letter-spacing:-.02em}.akilio-empty p{margin:8px 0 0;color:#71717a;font-size:14px;line-height:1.65}.akilio-suggestions{display:grid;width:100%;gap:9px;margin-top:18px}.akilio-suggestions button{border:1px solid rgba(212,212,216,.9);border-radius:16px;background:#fff;color:#3f3f46;cursor:pointer;padding:10px 12px;text-align:left;font-size:12px;font-weight:700;box-shadow:0 5px 14px #0f172a0a;transition:transform .15s ease,border-color .15s ease,box-shadow .15s ease}.akilio-suggestions button:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--akilio-primary) 35%,#d4d4d8);box-shadow:0 12px 22px #0f172a14}.akilio-composer{position:relative;border-top:1px solid rgba(212,212,216,.85);background:#ffffffdb;padding:12px;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.akilio-composer-box{border:1px solid rgba(212,212,216,.95);border-radius:24px;background:#f8fafc;padding:8px;box-shadow:inset 0 1px 2px #0f172a0a;transition:border-color .15s ease,background .15s ease,box-shadow .15s ease}.akilio-composer-box:focus-within{border-color:color-mix(in srgb,var(--akilio-primary) 55%,#d4d4d8);background:#fff;box-shadow:0 0 0 4px color-mix(in srgb,var(--akilio-primary) 13%,transparent),inset 0 1px 2px #0f172a08}.akilio-composer textarea{width:100%;min-height:48px;max-height:148px;resize:none;border:0;outline:0;background:transparent;color:#09090b;padding:8px 10px;font:inherit;font-size:14px;line-height:1.55}.akilio-composer textarea::placeholder{color:#a1a1aa}.akilio-composer-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 2px 2px 7px}.akilio-composer-footer span{color:#71717a;font-size:11px}.akilio-composer-footer button{display:inline-flex;align-items:center;gap:8px;border:0;border-radius:999px;background:#09090b;color:#fff;cursor:pointer;padding:10px 15px;font-size:12px;font-weight:850;box-shadow:0 10px 24px #0f172a24;transition:transform .15s ease,opacity .15s ease}.akilio-composer-footer button:hover:not(:disabled){transform:translateY(-1px)}.akilio-composer-footer button:disabled{cursor:not-allowed;opacity:.45}.akilio-composer-footer svg{width:15px;height:15px}.akilio-tour{max-width:360px;border-radius:18px!important}@media(max-width:640px){.akilio-launcher{right:16px;bottom:16px;padding:10px 12px}.akilio-launcher strong{display:none}.akilio-panel{width:100vw}.akilio-bubble{max-width:94%}.akilio-composer-footer span{display:none}}.akilio-root[data-akilio-mode=inline]{width:100%;height:100%;min-height:520px}.akilio-panel--inline{position:relative;inset:auto;width:100%;height:100%;min-height:520px;transform:none;border:1px solid rgba(212,212,216,.9);border-radius:var(--akilio-radius);box-shadow:0 18px 50px #0f172a1f}.akilio-privacy{display:grid;gap:8px;border-top:1px solid rgba(212,212,216,.82);background:#ffffffe6;padding:10px 14px;font-size:11px;line-height:1.45}.akilio-privacy strong{color:#18181b}.akilio-privacy p{margin:2px 0 0;color:#71717a}.akilio-privacy a{color:var(--akilio-primary);font-weight:700}.akilio-privacy label{display:flex;align-items:flex-start;gap:8px;color:#3f3f46;cursor:pointer}.akilio-privacy input{margin-top:2px;accent-color:var(--akilio-primary)}.akilio-composer textarea:disabled{cursor:not-allowed;opacity:.65}.akilio-root button:focus-visible,.akilio-root a:focus-visible,.akilio-root input:focus-visible{outline:3px solid color-mix(in srgb,var(--akilio-primary) 45%,transparent);outline-offset:2px}.akilio-root .akilio-composer textarea:focus,.akilio-root .akilio-composer textarea:focus-visible{border:0;outline:none;box-shadow:none}@media(prefers-reduced-motion:reduce){.akilio-root *,.akilio-root *:before,.akilio-root *:after{scroll-behavior:auto!important;animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.akilio-root[data-akilio-color-mode=dark]{color:#e4e4e7}.akilio-root[data-akilio-color-mode=dark] .akilio-panel,.akilio-root[data-akilio-color-mode=dark] .akilio-panel--inline{background:var(--akilio-surface, #09090b);border-color:#27272a}.akilio-root[data-akilio-color-mode=dark] .akilio-panel-header,.akilio-root[data-akilio-color-mode=dark] .akilio-privacy{background:#18181beb;border-color:#3f3f46}.akilio-root[data-akilio-color-mode=dark] .akilio-header-title h2,.akilio-root[data-akilio-color-mode=dark] .akilio-empty h3,.akilio-root[data-akilio-color-mode=dark] .akilio-privacy strong{color:var(--akilio-text, #fafafa)}.akilio-root[data-akilio-color-mode=dark] .akilio-header-description,.akilio-root[data-akilio-color-mode=dark] .akilio-empty p,.akilio-root[data-akilio-color-mode=dark] .akilio-privacy p,.akilio-root[data-akilio-color-mode=dark] .akilio-privacy label{color:var(--akilio-muted, #a1a1aa)}.akilio-root[data-akilio-color-mode=dark] .akilio-bubble{background:#18181b;border-color:#3f3f46;color:#e4e4e7;box-shadow:none}.akilio-root[data-akilio-color-mode=dark] .akilio-bubble--user{background:linear-gradient(135deg,var(--akilio-primary),var(--akilio-accent));color:var(--akilio-primary-foreground)}.akilio-root[data-akilio-color-mode=dark] .akilio-sources{background:#09090b;border-color:#3f3f46}.akilio-root[data-akilio-color-mode=dark] .akilio-sources-list{border-color:#3f3f46}.akilio-root[data-akilio-color-mode=dark] .akilio-source-card,.akilio-root[data-akilio-color-mode=dark] .akilio-feedback button,.akilio-root[data-akilio-color-mode=dark] .akilio-composer-box{background:#18181b;border-color:#3f3f46;color:#e4e4e7}.akilio-root[data-akilio-color-mode=dark] .akilio-source-card strong{color:#fafafa}.akilio-root[data-akilio-color-mode=dark] .akilio-source-card span,.akilio-root[data-akilio-color-mode=dark] .akilio-feedback{color:#a1a1aa}@media(prefers-color-scheme:dark){.akilio-root[data-akilio-color-mode=system] .akilio-panel,.akilio-root[data-akilio-color-mode=system] .akilio-panel--inline{background:#09090b;border-color:#27272a}.akilio-root[data-akilio-color-mode=system] .akilio-panel-header,.akilio-root[data-akilio-color-mode=system] .akilio-privacy{background:#18181beb;border-color:#3f3f46}.akilio-root[data-akilio-color-mode=system] .akilio-header-title h2,.akilio-root[data-akilio-color-mode=system] .akilio-empty h3,.akilio-root[data-akilio-color-mode=system] .akilio-privacy strong{color:#fafafa}.akilio-root[data-akilio-color-mode=system] .akilio-header-description,.akilio-root[data-akilio-color-mode=system] .akilio-empty p,.akilio-root[data-akilio-color-mode=system] .akilio-privacy p,.akilio-root[data-akilio-color-mode=system] .akilio-privacy label{color:#a1a1aa}.akilio-root[data-akilio-color-mode=system] .akilio-bubble{background:#18181b;border-color:#3f3f46;color:#e4e4e7;box-shadow:none}.akilio-root[data-akilio-color-mode=system] .akilio-bubble--user{background:linear-gradient(135deg,var(--akilio-primary),var(--akilio-accent));color:var(--akilio-primary-foreground)}.akilio-root[data-akilio-color-mode=system] .akilio-source-card,.akilio-root[data-akilio-color-mode=system] .akilio-feedback button,.akilio-root[data-akilio-color-mode=system] .akilio-composer-box{background:#18181b;border-color:#3f3f46;color:#e4e4e7}}@media(max-width:640px){.akilio-launcher{right:14px;bottom:max(14px,env(safe-area-inset-bottom));padding:10px}.akilio-launcher strong{display:none}.akilio-panel{width:100vw;height:100dvh;border-left:0}.akilio-root[data-akilio-mode=floating] .akilio-panel{right:14px;bottom:calc(76px + env(safe-area-inset-bottom));width:calc(100vw - 28px);height:min(640px,calc(100dvh - 104px - env(safe-area-inset-bottom)));min-height:min(420px,calc(100dvh - 104px));border:1px solid rgba(212,212,216,.9);border-radius:18px}.akilio-panel-header{padding-top:max(14px,env(safe-area-inset-top))}.akilio-thread{padding-inline:12px}.akilio-bubble{max-width:94%}.akilio-composer{padding-bottom:max(10px,env(safe-area-inset-bottom))}.akilio-root[data-akilio-mode=inline]{min-height:480px}.akilio-panel--inline{min-height:480px;border-radius:16px}}.akilio-root[data-akilio-color-mode=dark] .akilio-composer{background:#18181beb;border-color:#3f3f46}.akilio-root[data-akilio-color-mode=dark] .akilio-composer textarea{color:var(--akilio-text, #fafafa);caret-color:var(--akilio-text, #fafafa);-webkit-text-fill-color:var(--akilio-text, #fafafa)}.akilio-root[data-akilio-color-mode=dark] .akilio-composer textarea::placeholder{color:var(--akilio-muted, #a1a1aa);-webkit-text-fill-color:var(--akilio-muted, #a1a1aa);opacity:1}.akilio-root[data-akilio-color-mode=dark] .akilio-composer-footer span{color:var(--akilio-muted, #a1a1aa)}.akilio-root[data-akilio-color-mode=dark] .akilio-composer-box:focus-within{background:#18181b}@media(max-width:420px){.akilio-logo{width:78px;height:30px}}.akilio-privacy-consent-copy{margin-top:6px!important}.akilio-privacy-actions{display:flex;justify-content:flex-end;gap:8px}.akilio-privacy-actions button{border:1px solid rgba(161,161,170,.65);border-radius:999px;padding:6px 12px;font:inherit;font-weight:700;cursor:pointer}.akilio-privacy-decline{background:transparent;color:#52525b}.akilio-privacy-accept{border-color:var(--akilio-primary)!important;background:var(--akilio-primary);color:#fff}.akilio-privacy-review{border:0;background:transparent;color:var(--akilio-primary);font:inherit;font-weight:700;text-decoration:underline;cursor:pointer;padding:0}.akilio-products{margin-top:14px;min-width:0}.akilio-products-heading{display:flex;align-items:center;justify-content:space-between;margin-bottom:9px;font-size:12px;color:#64748b}.akilio-products-heading span{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 7px;border-radius:999px;background:#eef2ff;color:#4338ca;font-weight:700}.akilio-product-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.akilio-product-card{min-width:0;overflow:hidden;border:1px solid #e2e8f0;border-radius:16px;background:#fff;box-shadow:0 6px 20px #0f172a0f}.akilio-product-media{position:relative;aspect-ratio:4 / 3;overflow:hidden;background:#f1f5f9}.akilio-product-media img{width:100%;height:100%;display:block;object-fit:cover;transition:transform .18s ease}.akilio-product-card:hover .akilio-product-media img{transform:scale(1.025)}.akilio-product-placeholder{width:100%;height:100%;display:grid;place-items:center;color:var(--akilio-primary);font-size:30px;font-weight:800;background:linear-gradient(145deg,#0891b21f,#2563eb14)}.akilio-stock{position:absolute;top:8px;right:8px;max-width:calc(100% - 16px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:4px 7px;border-radius:999px;background:#7f1d1de6;color:#fff;font-size:9px;font-weight:700}.akilio-stock--available{background:#065f46e6}.akilio-product-body{padding:11px}.akilio-product-vendor,.akilio-product-variant{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#64748b;font-size:10px}.akilio-product-card h4{margin:4px 0 8px;min-height:34px;overflow:hidden;color:#0f172a;font-size:13px;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.akilio-product-price{min-height:37px;display:flex;flex-wrap:wrap;align-items:baseline;gap:5px;margin-bottom:9px}.akilio-product-price strong{color:#0f172a;font-size:14px}.akilio-product-price del{color:#94a3b8;font-size:10px}.akilio-product-action{width:100%;min-height:34px;display:inline-flex;align-items:center;justify-content:center;padding:7px 10px;border:0;border-radius:10px;background:var(--akilio-primary);color:var(--akilio-primary-foreground);font:inherit;font-size:11px;font-weight:700;text-decoration:none;cursor:pointer}.akilio-product-action:hover{filter:brightness(.96)}.akilio-product-action:focus-visible{outline:3px solid color-mix(in srgb,var(--akilio-primary) 28%,transparent);outline-offset:2px}.akilio-product-action:disabled{opacity:.55;cursor:not-allowed}.akilio-root[data-akilio-color-mode=dark] .akilio-products-heading{color:#94a3b8}.akilio-root[data-akilio-color-mode=dark] .akilio-products-heading span{background:#312e81;color:#e0e7ff}.akilio-root[data-akilio-color-mode=dark] .akilio-product-card{background:#111827;border-color:#334155;box-shadow:none}.akilio-root[data-akilio-color-mode=dark] .akilio-product-media{background:#1e293b}.akilio-root[data-akilio-color-mode=dark] .akilio-product-card h4,.akilio-root[data-akilio-color-mode=dark] .akilio-product-price strong{color:#f8fafc}.akilio-root[data-akilio-color-mode=dark] .akilio-product-vendor,.akilio-root[data-akilio-color-mode=dark] .akilio-product-variant{color:#94a3b8}@media(max-width:390px){.akilio-product-grid{grid-template-columns:1fr}.akilio-product-media{aspect-ratio:16 / 9}}.akilio-response-suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.akilio-response-suggestions button{appearance:none;border:1px solid color-mix(in srgb,var(--akilio-primary) 26%,#d4d4d8);border-radius:999px;background:color-mix(in srgb,var(--akilio-primary) 7%,#ffffff);color:color-mix(in srgb,var(--akilio-primary) 72%,#18181b);cursor:pointer;padding:8px 11px;text-align:left;font:inherit;font-size:12px;font-weight:700;line-height:1.35;transition:transform .15s ease,border-color .15s ease,background .15s ease}.akilio-response-suggestions button:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--akilio-primary) 52%,#d4d4d8);background:color-mix(in srgb,var(--akilio-primary) 12%,#ffffff)}.akilio-response-suggestions button:focus-visible{outline:3px solid color-mix(in srgb,var(--akilio-primary) 24%,transparent);outline-offset:2px}.akilio-root[data-akilio-color-mode=dark] .akilio-response-suggestions button{border-color:color-mix(in srgb,var(--akilio-primary) 34%,#3f3f46);background:color-mix(in srgb,var(--akilio-primary) 14%,#18181b);color:#f4f4f5}