@akropolys/kiku 1.2.4 → 1.4.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.js CHANGED
@@ -29,7 +29,9 @@ __export(src_exports, {
29
29
  KikuButton: () => KikuButton,
30
30
  KikuChat: () => ChatWidget,
31
31
  SearchBar: () => SearchBar,
32
- Sparkle: () => Sparkle
32
+ Sparkle: () => Sparkle,
33
+ VisualSearch: () => VisualSearch,
34
+ VoiceButton: () => VoiceButton
33
35
  });
34
36
  module.exports = __toCommonJS(src_exports);
35
37
 
@@ -197,8 +199,8 @@ function SearchBar({
197
199
  }
198
200
 
199
201
  // src/components/ChatWidget.tsx
200
- var import_react2 = require("react");
201
- var import_sdk2 = require("@akropolys/sdk");
202
+ var import_react4 = require("react");
203
+ var import_sdk3 = require("@akropolys/sdk");
202
204
 
203
205
  // src/utils/markdown.tsx
204
206
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -285,19 +287,151 @@ function renderMarkdown(content) {
285
287
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: elements });
286
288
  }
287
289
 
288
- // src/components/ChatWidget.tsx
290
+ // src/components/VoiceButton.tsx
291
+ var import_react2 = require("react");
289
292
  var import_jsx_runtime3 = require("react/jsx-runtime");
290
- var SparkleIcon = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
291
- var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
292
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m5 12 7-7 7 7" }),
293
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 19V5" })
293
+ var MicIcon = ({ active }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
294
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { x: "9", y: "2", width: "6", height: "11", rx: "3", fill: active ? "currentColor" : "none" }),
295
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M5 10a7 7 0 0 0 14 0" }),
296
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
297
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
298
+ ] });
299
+ function VoiceButton({
300
+ onTranscript,
301
+ onInterim,
302
+ lang = "en-US",
303
+ className = "",
304
+ disabled = false
305
+ }) {
306
+ const [listening, setListening] = (0, import_react2.useState)(false);
307
+ const recognitionRef = (0, import_react2.useRef)(null);
308
+ const isSupported = typeof window !== "undefined" && ("SpeechRecognition" in window || "webkitSpeechRecognition" in window);
309
+ const start = (0, import_react2.useCallback)(() => {
310
+ if (!isSupported || listening) return;
311
+ const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
312
+ const recognition = new SR();
313
+ recognition.lang = lang;
314
+ recognition.interimResults = true;
315
+ recognition.maxAlternatives = 1;
316
+ recognitionRef.current = recognition;
317
+ recognition.onstart = () => setListening(true);
318
+ recognition.onend = () => setListening(false);
319
+ recognition.onerror = () => setListening(false);
320
+ recognition.onresult = (e) => {
321
+ const results = Array.from(e.results);
322
+ const transcript = results.map((r) => r[0].transcript).join("");
323
+ const isFinal = e.results[e.results.length - 1].isFinal;
324
+ if (isFinal) {
325
+ onTranscript(transcript);
326
+ setListening(false);
327
+ } else {
328
+ onInterim?.(transcript);
329
+ }
330
+ };
331
+ recognition.start();
332
+ }, [isSupported, listening, lang, onTranscript, onInterim]);
333
+ const stop = (0, import_react2.useCallback)(() => {
334
+ recognitionRef.current?.stop();
335
+ setListening(false);
336
+ }, []);
337
+ if (!isSupported) return null;
338
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
339
+ "button",
340
+ {
341
+ type: "button",
342
+ className: `kiku-voice-btn${listening ? " kiku-voice-btn--active" : ""} ${className}`,
343
+ onClick: listening ? stop : start,
344
+ disabled,
345
+ title: listening ? "Stop listening" : "Speak your search",
346
+ "aria-label": listening ? "Stop voice input" : "Start voice input",
347
+ children: [
348
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { active: listening }),
349
+ listening && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "kiku-voice-ripple", "aria-hidden": "true" })
350
+ ]
351
+ }
352
+ );
353
+ }
354
+
355
+ // src/components/VisualSearch.tsx
356
+ var import_react3 = require("react");
357
+ var import_sdk2 = require("@akropolys/sdk");
358
+ var import_jsx_runtime4 = require("react/jsx-runtime");
359
+ var CameraIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
360
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" }),
361
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "12", cy: "13", r: "4" })
362
+ ] });
363
+ var SpinnerIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "kiku-vs-spin", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
364
+ function fileToBase64(file) {
365
+ return new Promise((resolve, reject) => {
366
+ const reader = new FileReader();
367
+ reader.onload = () => resolve(reader.result);
368
+ reader.onerror = reject;
369
+ reader.readAsDataURL(file);
370
+ });
371
+ }
372
+ function VisualSearch({
373
+ onResults,
374
+ onError,
375
+ categoryHint,
376
+ className = "",
377
+ disabled = false
378
+ }) {
379
+ const client = (0, import_sdk2.useAkropolysContext)();
380
+ const inputRef = (0, import_react3.useRef)(null);
381
+ const [loading, setLoading] = (0, import_react3.useState)(false);
382
+ const handleFile = async (file) => {
383
+ if (!file.type.startsWith("image/")) return;
384
+ setLoading(true);
385
+ try {
386
+ const base64 = await fileToBase64(file);
387
+ const res = await client.api.searchByImage(base64, categoryHint);
388
+ onResults(res, base64);
389
+ } catch (e) {
390
+ onError?.(e instanceof Error ? e : new Error(String(e)));
391
+ } finally {
392
+ setLoading(false);
393
+ if (inputRef.current) inputRef.current.value = "";
394
+ }
395
+ };
396
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
397
+ "label",
398
+ {
399
+ className: `kiku-vs-btn${loading ? " kiku-vs-btn--loading" : ""} ${className}`,
400
+ title: "Search by photo",
401
+ "aria-label": "Search by uploading a photo",
402
+ style: { cursor: disabled || loading ? "not-allowed" : "pointer" },
403
+ children: [
404
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
405
+ "input",
406
+ {
407
+ ref: inputRef,
408
+ type: "file",
409
+ accept: "image/*",
410
+ capture: "environment",
411
+ onChange: (e) => e.target.files?.[0] && handleFile(e.target.files[0]),
412
+ disabled: disabled || loading,
413
+ hidden: true
414
+ }
415
+ ),
416
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpinnerIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraIcon, {})
417
+ ]
418
+ }
419
+ );
420
+ }
421
+
422
+ // src/components/ChatWidget.tsx
423
+ var import_jsx_runtime5 = require("react/jsx-runtime");
424
+ var SparkleIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
425
+ var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
426
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m5 12 7-7 7 7" }),
427
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 19V5" })
294
428
  ] });
295
429
  function SourceCard({ source, defaultCurrency, onSelect }) {
296
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-source-card", onClick: () => onSelect?.(source), children: [
297
- source.image && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { src: source.image, alt: source.name, className: "hsk-source-img" }),
298
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
299
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-source-name", children: source.name }),
300
- source.price && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-source-price", children: [
430
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-source-card", onClick: () => onSelect?.(source), children: [
431
+ source.image && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: source.image, alt: source.name, className: "hsk-source-img" }),
432
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
433
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-source-name", children: source.name }),
434
+ source.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-source-price", children: [
301
435
  source.currency ?? defaultCurrency,
302
436
  " ",
303
437
  source.price
@@ -314,15 +448,56 @@ function ChatWidget({
314
448
  className,
315
449
  theme,
316
450
  classNames = {},
317
- onSelectSource
451
+ onSelectSource,
452
+ enableVoice = false,
453
+ enableVision = false,
454
+ visionCategoryHint
318
455
  }) {
319
- const { messages, sources, loading, error, send, reset } = (0, import_sdk2.useKiku)();
320
- const [input, setInput] = (0, import_react2.useState)("");
321
- const bottomRef = (0, import_react2.useRef)(null);
322
- const textareaRef = (0, import_react2.useRef)(null);
323
- (0, import_react2.useEffect)(() => {
456
+ const { messages, sources, loading: chatLoading, error, send, reset } = (0, import_sdk3.useKiku)();
457
+ const [input, setInput] = (0, import_react4.useState)("");
458
+ const [visualLoading, setVisualLoading] = (0, import_react4.useState)(false);
459
+ const bottomRef = (0, import_react4.useRef)(null);
460
+ const textareaRef = (0, import_react4.useRef)(null);
461
+ const loading = chatLoading || visualLoading;
462
+ const [chatHistory, setChatHistory] = (0, import_react4.useState)([]);
463
+ const lastSyncedCount = (0, import_react4.useRef)(0);
464
+ (0, import_react4.useEffect)(() => {
465
+ if (messages.length === 0) {
466
+ setChatHistory([]);
467
+ lastSyncedCount.current = 0;
468
+ return;
469
+ }
470
+ if (messages.length > lastSyncedCount.current) {
471
+ const newMsgs = messages.slice(lastSyncedCount.current);
472
+ setChatHistory((prev) => [...prev, ...newMsgs]);
473
+ lastSyncedCount.current = messages.length;
474
+ } else if (messages.length < lastSyncedCount.current) {
475
+ setChatHistory(messages);
476
+ lastSyncedCount.current = messages.length;
477
+ } else {
478
+ setChatHistory((prev) => {
479
+ const next = [...prev];
480
+ let hookIdx = messages.length - 1;
481
+ let historyIdx = next.length - 1;
482
+ while (hookIdx >= 0 && historyIdx >= 0) {
483
+ if (next[historyIdx].role === messages[hookIdx].role) {
484
+ next[historyIdx] = {
485
+ ...next[historyIdx],
486
+ content: messages[hookIdx].content,
487
+ cartSnapshot: messages[hookIdx].cartSnapshot,
488
+ actionType: messages[hookIdx].actionType
489
+ };
490
+ break;
491
+ }
492
+ historyIdx--;
493
+ }
494
+ return next;
495
+ });
496
+ }
497
+ }, [messages]);
498
+ (0, import_react4.useEffect)(() => {
324
499
  bottomRef.current?.scrollIntoView({ behavior: "smooth" });
325
- }, [messages, loading]);
500
+ }, [chatHistory, loading]);
326
501
  const handleSend = async () => {
327
502
  const q = input.trim();
328
503
  if (!q || loading) return;
@@ -342,6 +517,56 @@ function ChatWidget({
342
517
  t.style.height = "auto";
343
518
  t.style.height = Math.min(t.scrollHeight, 120) + "px";
344
519
  };
520
+ const handleVisualResults = (res, preview) => {
521
+ const userMsg = {
522
+ role: "user",
523
+ content: "Uploaded a photo for visual search",
524
+ imagePreview: preview
525
+ };
526
+ const dna = res.style_dna;
527
+ let content = `I've analyzed your image! Here is the Style DNA I found:
528
+ `;
529
+ if (dna) {
530
+ if (dna.color_palette) content += `* **Palette:** ${dna.color_palette}
531
+ `;
532
+ if (dna.dominant_colors && dna.dominant_colors.length > 0) {
533
+ content += `* **Colors:** ${dna.dominant_colors.join(", ")}
534
+ `;
535
+ }
536
+ if (dna.aesthetic && dna.aesthetic.length > 0) {
537
+ content += `* **Aesthetic:** ${dna.aesthetic.join(", ")}
538
+ `;
539
+ }
540
+ if (dna.texture) content += `* **Texture:** ${dna.texture}
541
+ `;
542
+ if (dna.formality) content += `* **Formality:** ${dna.formality}
543
+ `;
544
+ }
545
+ const results = res.results || [];
546
+ if (results.length > 0) {
547
+ content += `
548
+ I found ${results.length} matching products in the store for you.`;
549
+ } else {
550
+ content += `
551
+ I couldn't find any matching products in the store.`;
552
+ }
553
+ const assistantMsg = {
554
+ role: "assistant",
555
+ content,
556
+ styleDNA: dna,
557
+ visualSources: results.map((r) => ({
558
+ id: r.id,
559
+ name: r.product.name,
560
+ price: r.product.price,
561
+ currency: r.product.currency,
562
+ category: r.product.category,
563
+ url: r.product.url,
564
+ image: r.product.images && r.product.images.length > 0 ? r.product.images[0] : void 0,
565
+ brand: r.product.brand
566
+ }))
567
+ };
568
+ setChatHistory((prev) => [...prev, userMsg, assistantMsg]);
569
+ };
345
570
  const customStyles = {
346
571
  ...theme?.primaryColor && { "--hsk-primary": theme.primaryColor },
347
572
  ...theme?.backgroundColor && { "--hsk-bg": theme.backgroundColor },
@@ -349,45 +574,60 @@ function ChatWidget({
349
574
  ...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
350
575
  ...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
351
576
  };
352
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
577
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
353
578
  "div",
354
579
  {
355
580
  className: cn("hsk-chat-widget", classNames.root, className),
356
581
  style: customStyles,
357
582
  children: [
358
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cn("hsk-chat-header", classNames.header), children: [
359
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-chat-header-icon", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {}) }),
360
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-chat-title", children: title }),
361
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-chat-badge", children: "AI" }),
362
- messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "hsk-chat-reset", onClick: reset, style: { marginLeft: "auto" }, children: "Clear" })
583
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("hsk-chat-header", classNames.header), children: [
584
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-chat-header-icon", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon, {}) }),
585
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-chat-title", children: title }),
586
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-chat-badge", children: "AI" }),
587
+ chatHistory.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-chat-reset", onClick: reset, style: { marginLeft: "auto" }, children: "Clear" })
363
588
  ] }),
364
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-chat-messages", children: [
365
- messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-chat-empty", children: [
366
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-chat-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {}) }),
367
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: emptyStateText }),
368
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-chat-empty-suggestions", children: emptyStateSuggestions })
369
- ] }) : messages.map((msg, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
370
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `hsk-msg-row ${msg.role}`, children: [
371
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: cn("hsk-msg-avatar", msg.role === "assistant" ? "ai" : "user"), children: msg.role === "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {}) : "U" }),
372
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: cn("hsk-msg-bubble", msg.role, classNames.messageBubble), children: renderMarkdown(msg.content) })
589
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-chat-messages", children: [
590
+ chatHistory.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-chat-empty", children: [
591
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-chat-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon, {}) }),
592
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: emptyStateText }),
593
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-chat-empty-suggestions", children: emptyStateSuggestions })
594
+ ] }) : chatHistory.map((msg, idx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
595
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `hsk-msg-row ${msg.role}`, children: [
596
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn("hsk-msg-avatar", msg.role === "assistant" ? "ai" : "user"), children: msg.role === "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon, {}) : "U" }),
597
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("hsk-msg-bubble", msg.role, classNames.messageBubble), children: [
598
+ msg.imagePreview && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kiku-vs-preview-bubble", style: { marginBottom: "8px" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: msg.imagePreview, alt: "Uploaded Preview", className: "kiku-vs-preview-bubble-img", style: { maxWidth: "200px", borderRadius: "8px" } }) }),
599
+ renderMarkdown(msg.content),
600
+ msg.styleDNA && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kiku-vs-preview-banner", style: { marginTop: "10px" }, children: [
601
+ chatHistory[idx - 1]?.imagePreview && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: chatHistory[idx - 1].imagePreview, alt: "Visual Search Input", className: "kiku-vs-preview-img" }),
602
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kiku-vs-preview-info", children: [
603
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kiku-vs-preview-label", children: "Visual Match Palette" }),
604
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kiku-vs-preview-palette", children: msg.styleDNA.color_palette || "Detected Style DNA" }),
605
+ msg.styleDNA.style_tags && msg.styleDNA.style_tags.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kiku-style-tags", children: msg.styleDNA.style_tags.map((tag, ti) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "kiku-style-tag", children: [
606
+ "#",
607
+ tag
608
+ ] }, ti)) })
609
+ ] })
610
+ ] })
611
+ ] })
373
612
  ] }),
374
- msg.role === "assistant" && idx === messages.length - 1 && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sources-container", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sources", children: sources.map((src, si) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) })
613
+ msg.role === "assistant" && msg.visualSources && msg.visualSources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-sources-container", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-sources", children: msg.visualSources.map((src, si) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) }),
614
+ msg.role === "assistant" && idx === chatHistory.length - 1 && !msg.visualSources && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-sources-container", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-sources", children: sources.map((src, si) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) })
375
615
  ] }, idx)),
376
- loading && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-msg-row", children: [
377
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-msg-avatar ai", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {}) }),
378
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-pending", role: "status", "aria-live": "polite", children: [
379
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-pending-glyph", children: [
380
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-pending-ring" }),
381
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-pending-dot" })
616
+ loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-msg-row", children: [
617
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-msg-avatar ai", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon, {}) }),
618
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-pending", role: "status", "aria-live": "polite", children: [
619
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-pending-glyph", children: [
620
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-pending-ring" }),
621
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-pending-dot" })
382
622
  ] }),
383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-pending-text", children: [
384
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-pending-step step-1", children: "Searching catalog" }),
385
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-pending-step step-2", children: "Reasoning" }),
386
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-pending-step step-3", children: "Composing" })
623
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-pending-text", children: [
624
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-pending-step step-1", children: "Searching catalog" }),
625
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-pending-step step-2", children: "Reasoning" }),
626
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-pending-step step-3", children: "Composing" })
387
627
  ] })
388
628
  ] })
389
629
  ] }),
390
- error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-chat-error", children: (() => {
630
+ error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-chat-error", children: (() => {
391
631
  try {
392
632
  const parsed = JSON.parse(error);
393
633
  return parsed.error || parsed.message || error;
@@ -395,10 +635,19 @@ function ChatWidget({
395
635
  return error;
396
636
  }
397
637
  })() }),
398
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: bottomRef })
638
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: bottomRef })
399
639
  ] }),
400
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-chat-input-area", children: [
401
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
640
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-chat-input-area", style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
641
+ enableVision && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
642
+ VisualSearch,
643
+ {
644
+ onResults: handleVisualResults,
645
+ onError: (err) => console.error("[VisualSearch] error:", err),
646
+ categoryHint: visionCategoryHint,
647
+ disabled: loading
648
+ }
649
+ ),
650
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
402
651
  "textarea",
403
652
  {
404
653
  ref: textareaRef,
@@ -408,17 +657,30 @@ function ChatWidget({
408
657
  onKeyDown: handleKey,
409
658
  placeholder,
410
659
  rows: 1,
660
+ disabled: loading,
661
+ style: { flex: 1 }
662
+ }
663
+ ),
664
+ enableVoice && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
665
+ VoiceButton,
666
+ {
667
+ onTranscript: (text) => {
668
+ setInput(text);
669
+ send(text);
670
+ setInput("");
671
+ },
672
+ onInterim: (text) => setInput(text),
411
673
  disabled: loading
412
674
  }
413
675
  ),
414
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
676
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
415
677
  "button",
416
678
  {
417
679
  className: "hsk-chat-send",
418
680
  onClick: handleSend,
419
681
  disabled: !input.trim() || loading,
420
682
  "aria-label": "Send message",
421
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ArrowUpIcon, {})
683
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ArrowUpIcon, {})
422
684
  }
423
685
  )
424
686
  ] })
@@ -428,14 +690,14 @@ function ChatWidget({
428
690
  }
429
691
 
430
692
  // src/components/KikuButton.tsx
431
- var import_react3 = require("react");
693
+ var import_react5 = require("react");
432
694
  var import_react_dom = require("react-dom");
433
- var import_sdk3 = require("@akropolys/sdk");
434
695
  var import_sdk4 = require("@akropolys/sdk");
435
696
  var import_sdk5 = require("@akropolys/sdk");
697
+ var import_sdk6 = require("@akropolys/sdk");
436
698
 
437
699
  // src/components/ComparisonMatrix.tsx
438
- var import_jsx_runtime4 = require("react/jsx-runtime");
700
+ var import_jsx_runtime6 = require("react/jsx-runtime");
439
701
  function extractSize(p) {
440
702
  const name = p.name;
441
703
  const cat = (p.category || "").toLowerCase();
@@ -547,9 +809,9 @@ function buildRows(products, currency) {
547
809
  }
548
810
  function ImageCell({ value, name }) {
549
811
  if (!value) {
550
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 28, textAlign: "center" }, children: "\u{1F4E6}" });
812
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 28, textAlign: "center" }, children: "\u{1F4E6}" });
551
813
  }
552
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
814
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
553
815
  "img",
554
816
  {
555
817
  src: value,
@@ -566,10 +828,10 @@ function ImageCell({ value, name }) {
566
828
  );
567
829
  }
568
830
  function AvailabilityCell({ value }) {
569
- if (!value) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: "#9ca3af" }, children: "\u2014" });
831
+ if (!value) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "#9ca3af" }, children: "\u2014" });
570
832
  const inStock = /in.?stock/i.test(value);
571
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--hsk-text, #111827)" }, children: [
572
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: {
833
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--hsk-text, #111827)" }, children: [
834
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: {
573
835
  width: 8,
574
836
  height: 8,
575
837
  borderRadius: "50%",
@@ -610,7 +872,7 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
610
872
  display: "flex",
611
873
  alignItems: "center"
612
874
  };
613
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
875
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
614
876
  "div",
615
877
  {
616
878
  className: "hsk-compare-matrix",
@@ -623,9 +885,9 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
623
885
  fontSize: 13
624
886
  },
625
887
  children: [
626
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "grid", gridTemplateColumns: colTemplate, background: "var(--hsk-surface2, #f9fafb)", borderBottom: "2px solid var(--hsk-border, rgba(0,0,0,0.09))" }, children: [
627
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { ...labelStyle, borderBottom: "none", color: "var(--hsk-text, #111)", fontSize: 12 }, children: "Feature" }),
628
- products.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
888
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "grid", gridTemplateColumns: colTemplate, background: "var(--hsk-surface2, #f9fafb)", borderBottom: "2px solid var(--hsk-border, rgba(0,0,0,0.09))" }, children: [
889
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { ...labelStyle, borderBottom: "none", color: "var(--hsk-text, #111)", fontSize: 12 }, children: "Feature" }),
890
+ products.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
629
891
  "a",
630
892
  {
631
893
  href: p.url || "#",
@@ -647,7 +909,7 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
647
909
  i
648
910
  ))
649
911
  ] }),
650
- rows.map((row, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
912
+ rows.map((row, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
651
913
  "div",
652
914
  {
653
915
  style: {
@@ -656,17 +918,17 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
656
918
  background: rowIdx % 2 === 1 ? "var(--hsk-surface2, rgba(0,0,0,0.015))" : "transparent"
657
919
  },
658
920
  children: [
659
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: labelStyle, children: row.label }),
921
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: labelStyle, children: row.label }),
660
922
  products.map((p, i) => {
661
923
  const val = row.values[i];
662
924
  const isBest = row.bestIdx === i && row.values.filter(Boolean).length > 1;
663
925
  if (row.type === "image") {
664
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { ...cellBase, justifyContent: "center", padding: "12px", borderLeft: i > 0 ? "1px solid var(--hsk-border, rgba(0,0,0,0.07))" : "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ImageCell, { value: val, name: p.name }) }, i);
926
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { ...cellBase, justifyContent: "center", padding: "12px", borderLeft: i > 0 ? "1px solid var(--hsk-border, rgba(0,0,0,0.07))" : "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ImageCell, { value: val, name: p.name }) }, i);
665
927
  }
666
928
  if (row.type === "availability") {
667
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { ...cellBase, borderLeft: i > 0 ? "1px solid var(--hsk-border, rgba(0,0,0,0.07))" : "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AvailabilityCell, { value: val }) }, i);
929
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { ...cellBase, borderLeft: i > 0 ? "1px solid var(--hsk-border, rgba(0,0,0,0.07))" : "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AvailabilityCell, { value: val }) }, i);
668
930
  }
669
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
931
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
670
932
  "div",
671
933
  {
672
934
  style: {
@@ -676,7 +938,7 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
676
938
  color: isBest ? "var(--hsk-primary, #ea580c)" : row.type === "price" ? "var(--hsk-text, #374151)" : "var(--hsk-text, #111827)",
677
939
  borderLeft: i > 0 ? "1px solid var(--hsk-border, rgba(0,0,0,0.07))" : "none"
678
940
  },
679
- children: val ?? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: "#9ca3af" }, children: "\u2014" })
941
+ children: val ?? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "#9ca3af" }, children: "\u2014" })
680
942
  },
681
943
  i
682
944
  );
@@ -691,8 +953,8 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
691
953
  }
692
954
 
693
955
  // src/components/KikuButton.tsx
694
- var import_jsx_runtime5 = require("react/jsx-runtime");
695
- var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
956
+ var import_jsx_runtime7 = require("react/jsx-runtime");
957
+ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
696
958
  "svg",
697
959
  {
698
960
  className: cn("hsk-brand-a", className),
@@ -703,7 +965,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_js
703
965
  xmlns: "http://www.w3.org/2000/svg",
704
966
  "aria-label": "Akropolys",
705
967
  children: [
706
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
968
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
707
969
  "path",
708
970
  {
709
971
  d: "M14.5 4.5 L6.5 25",
@@ -712,7 +974,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_js
712
974
  strokeLinecap: "round"
713
975
  }
714
976
  ),
715
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
977
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
716
978
  "path",
717
979
  {
718
980
  d: "M14.5 4.5 L22.5 25",
@@ -721,7 +983,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_js
721
983
  strokeLinecap: "round"
722
984
  }
723
985
  ),
724
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
986
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
725
987
  "path",
726
988
  {
727
989
  d: "M9.5 17 H19.5",
@@ -730,7 +992,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_js
730
992
  strokeLinecap: "round"
731
993
  }
732
994
  ),
733
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
995
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
734
996
  "path",
735
997
  {
736
998
  d: "M3 25 H10",
@@ -739,7 +1001,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_js
739
1001
  strokeLinecap: "round"
740
1002
  }
741
1003
  ),
742
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1004
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
743
1005
  "path",
744
1006
  {
745
1007
  d: "M19 25 H26",
@@ -748,7 +1010,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_js
748
1010
  strokeLinecap: "round"
749
1011
  }
750
1012
  ),
751
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1013
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
752
1014
  "path",
753
1015
  {
754
1016
  d: "M8.5 2.5 C10 2.5, 11 3.5, 11 5 C11 7, 8.5 8.5, 7.5 9.5",
@@ -763,25 +1025,39 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ (0, import_js
763
1025
  }
764
1026
  );
765
1027
  var SparkleIcon2 = AkropolysAIcon;
766
- var ArrowUpIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
767
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m5 12 7-7 7 7" }),
768
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 19V5" })
1028
+ var ArrowUpIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1029
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "m5 12 7-7 7 7" }),
1030
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 19V5" })
769
1031
  ] });
770
- var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
771
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
772
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1032
+ var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1033
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1034
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
773
1035
  ] });
774
- var ChevronRightIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m9 18 6-6-6-6" }) });
775
- var HistoryIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
776
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
777
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 3v5h5" }),
778
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 7v5l4 2" })
1036
+ var ChevronRightIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "m9 18 6-6-6-6" }) });
1037
+ var HistoryIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1038
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
1039
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M3 3v5h5" }),
1040
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 7v5l4 2" })
779
1041
  ] });
780
- var NewChatIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 5v14M5 12h14" }) });
781
- var ShoppingBagIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
782
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z" }),
783
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
784
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M16 10a4 4 0 0 1-8 0" })
1042
+ var NewChatIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 5v14M5 12h14" }) });
1043
+ var ShoppingBagIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1044
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z" }),
1045
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
1046
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M16 10a4 4 0 0 1-8 0" })
1047
+ ] });
1048
+ var PaperclipIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
1049
+ var MicIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1050
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z" }),
1051
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
1052
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
1053
+ ] });
1054
+ var MicOffIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1055
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "2", y1: "2", x2: "22", y2: "22" }),
1056
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M18.89 13.23A7.12 7.12 0 0 0 19 12v-2" }),
1057
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M5 10v2a7 7 0 0 0 12 5" }),
1058
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M15 9.34V5a3 3 0 0 0-5.68-1.33" }),
1059
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" }),
1060
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
785
1061
  ] });
786
1062
  var DEFAULT_CHIPS = [
787
1063
  "Cheapest smartphone",
@@ -821,25 +1097,25 @@ function CartContextCard({ cart, defaultCurrency }) {
821
1097
  if (!cart.items || cart.items.length === 0) return null;
822
1098
  const currency = cart.currency || defaultCurrency;
823
1099
  const total = cart.total ?? cart.items.reduce((s, i) => s + i.price_numeric * i.quantity, 0);
824
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cart-card", children: [
825
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cart-card-header", children: [
826
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ShoppingBagIcon, {}),
827
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
1100
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cart-card", children: [
1101
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cart-card-header", children: [
1102
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ShoppingBagIcon, {}),
1103
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
828
1104
  "Your cart \xB7 ",
829
1105
  cart.item_count ?? cart.items.length,
830
1106
  " item",
831
1107
  (cart.item_count ?? cart.items.length) !== 1 ? "s" : ""
832
1108
  ] })
833
1109
  ] }),
834
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cart-items", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cart-item", children: [
835
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cart-item-img-wrap", children: [
836
- item.image ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { className: "hsk-cart-item-img", src: item.image, alt: item.name, loading: "lazy" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cart-item-img-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ShoppingBagIcon, {}) }),
837
- item.quantity > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-cart-item-qty", children: item.quantity })
1110
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cart-items", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cart-item", children: [
1111
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cart-item-img-wrap", children: [
1112
+ item.image ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { className: "hsk-cart-item-img", src: item.image, alt: item.name, loading: "lazy" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cart-item-img-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ShoppingBagIcon, {}) }),
1113
+ item.quantity > 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-cart-item-qty", children: item.quantity })
838
1114
  ] }),
839
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cart-item-info", children: [
840
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cart-item-name", children: item.name }),
841
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cart-item-price", children: [
842
- item.quantity > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "hsk-cart-item-qty-label", children: [
1115
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cart-item-info", children: [
1116
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cart-item-name", children: item.name }),
1117
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cart-item-price", children: [
1118
+ item.quantity > 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "hsk-cart-item-qty-label", children: [
843
1119
  item.quantity,
844
1120
  "\xD7 "
845
1121
  ] }),
@@ -849,9 +1125,9 @@ function CartContextCard({ cart, defaultCurrency }) {
849
1125
  ] })
850
1126
  ] })
851
1127
  ] }, item.id)) }),
852
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cart-total", children: [
853
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Total" }),
854
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "hsk-cart-total-amount", children: [
1128
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cart-total", children: [
1129
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Total" }),
1130
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "hsk-cart-total-amount", children: [
855
1131
  currency,
856
1132
  " ",
857
1133
  total.toLocaleString()
@@ -883,14 +1159,14 @@ function ActionPills({ cart, actionType, onSend, loading }) {
883
1159
  }
884
1160
  }
885
1161
  if (pills.length === 0) return null;
886
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-action-pills", children: pills.map((pill) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1162
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-action-pills", children: pills.map((pill) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
887
1163
  "button",
888
1164
  {
889
1165
  className: "hsk-action-pill",
890
1166
  onClick: () => onSend(pill.query),
891
1167
  disabled: loading,
892
1168
  children: [
893
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-pill-emoji", children: pill.emoji }),
1169
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-pill-emoji", children: pill.emoji }),
894
1170
  pill.label
895
1171
  ]
896
1172
  },
@@ -898,17 +1174,17 @@ function ActionPills({ cart, actionType, onSend, loading }) {
898
1174
  )) });
899
1175
  }
900
1176
  function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
901
- const client = (0, import_sdk5.useAkropolysContext)();
1177
+ const client = (0, import_sdk6.useAkropolysContext)();
902
1178
  const isProperty = client?.vertical === "property";
903
- const railRef = (0, import_react3.useRef)(null);
904
- const [showNext, setShowNext] = (0, import_react3.useState)(false);
905
- const measure = (0, import_react3.useCallback)(() => {
1179
+ const railRef = (0, import_react5.useRef)(null);
1180
+ const [showNext, setShowNext] = (0, import_react5.useState)(false);
1181
+ const measure = (0, import_react5.useCallback)(() => {
906
1182
  const el = railRef.current;
907
1183
  if (!el) return;
908
1184
  const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;
909
1185
  setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);
910
1186
  }, []);
911
- (0, import_react3.useEffect)(() => {
1187
+ (0, import_react5.useEffect)(() => {
912
1188
  measure();
913
1189
  const el = railRef.current;
914
1190
  if (!el) return;
@@ -923,17 +1199,17 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
923
1199
  const scrollNext = () => {
924
1200
  railRef.current?.scrollBy({ left: 170, behavior: "smooth" });
925
1201
  };
926
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-sources-wrap", children: [
927
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-sources", ref: railRef, children: sources.map((src, si) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1202
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-sources-wrap", children: [
1203
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-sources", ref: railRef, children: sources.map((src, si) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
928
1204
  "div",
929
1205
  {
930
1206
  className: "hsk-cb-source",
931
1207
  style: { animationDelay: `${si * 50}ms` },
932
1208
  onClick: () => onSelectSource?.(src),
933
1209
  children: [
934
- src.image ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-src-imgwrap", style: { position: "relative" }, children: [
935
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: src.image, alt: src.name, loading: "lazy" }),
936
- isProperty && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
1210
+ src.image ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-src-imgwrap", style: { position: "relative" }, children: [
1211
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: src.image, alt: src.name, loading: "lazy" }),
1212
+ isProperty && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
937
1213
  position: "absolute",
938
1214
  top: "6px",
939
1215
  right: "6px",
@@ -948,11 +1224,11 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
948
1224
  color: "#fbbf24",
949
1225
  // Gold sparkle badge
950
1226
  boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
951
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon2, { size: 12 }) })
952
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-src-imgwrap-empty", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon2, {}) }),
953
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-src-info", children: [
954
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-src-name", children: src.name }),
955
- src.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-src-price", children: [
1227
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, { size: 12 }) })
1228
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-src-imgwrap-empty", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
1229
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-src-info", children: [
1230
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-src-name", children: src.name }),
1231
+ src.price && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-src-price", children: [
956
1232
  src.currency ?? defaultCurrency,
957
1233
  " ",
958
1234
  parseFloat(String(src.price).replace(/[^0-9.]/g, "") || "0").toLocaleString()
@@ -962,15 +1238,15 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
962
1238
  },
963
1239
  si
964
1240
  )) }),
965
- showNext && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
966
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1241
+ showNext && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1242
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
967
1243
  "div",
968
1244
  {
969
1245
  className: "hsk-cb-sources-fade",
970
1246
  style: { background: "linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))" }
971
1247
  }
972
1248
  ),
973
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronRightIcon, {}) })
1249
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronRightIcon, {}) })
974
1250
  ] })
975
1251
  ] });
976
1252
  }
@@ -989,7 +1265,7 @@ function SmartContextPills({
989
1265
  onSend,
990
1266
  loading
991
1267
  }) {
992
- const client = (0, import_sdk5.useAkropolysContext)();
1268
+ const client = (0, import_sdk6.useAkropolysContext)();
993
1269
  const isProperty = client?.vertical === "property";
994
1270
  if (!intent) return null;
995
1271
  const pills = [];
@@ -1058,14 +1334,14 @@ function SmartContextPills({
1058
1334
  pills.push({ emoji: "\u{1F4A1}", label: "Recommend something", query: "What do you recommend for me?" });
1059
1335
  }
1060
1336
  if (pills.length === 0) return null;
1061
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-action-pills", children: pills.map((pill) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1337
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-action-pills", children: pills.map((pill) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1062
1338
  "button",
1063
1339
  {
1064
1340
  className: "hsk-action-pill",
1065
1341
  onClick: () => onSend(pill.query),
1066
1342
  disabled: loading,
1067
1343
  children: [
1068
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-pill-emoji", children: pill.emoji }),
1344
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-pill-emoji", children: pill.emoji }),
1069
1345
  pill.label
1070
1346
  ]
1071
1347
  },
@@ -1124,17 +1400,71 @@ function ChatModal({
1124
1400
  defaultCurrency = "KES",
1125
1401
  chips = DEFAULT_CHIPS,
1126
1402
  theme,
1127
- classNames = {}
1403
+ classNames = {},
1404
+ enableVoice = false,
1405
+ enableVision = false,
1406
+ visionCategoryHint
1128
1407
  }) {
1129
- const client = (0, import_sdk5.useAkropolysContext)();
1130
- const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, reset } = (0, import_sdk3.useKiku)();
1131
- const [input, setInput] = (0, import_react3.useState)("");
1132
- const [loadingMessageIndex, setLoadingMessageIndex] = (0, import_react3.useState)(0);
1408
+ const client = (0, import_sdk6.useAkropolysContext)();
1409
+ const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, reset } = (0, import_sdk4.useKiku)();
1410
+ const [input, setInput] = (0, import_react5.useState)("");
1411
+ const [loadingMessageIndex, setLoadingMessageIndex] = (0, import_react5.useState)(0);
1412
+ const [attachments, setAttachments] = (0, import_react5.useState)([]);
1413
+ const imageInputRef = (0, import_react5.useRef)(null);
1414
+ const handleImageFiles = (files) => {
1415
+ if (!files || files.length === 0) return;
1416
+ Array.from(files).forEach((file) => {
1417
+ if (!file.type.startsWith("image/")) return;
1418
+ const reader = new FileReader();
1419
+ reader.onload = (e) => {
1420
+ const dataUrl = e.target?.result;
1421
+ if (dataUrl) {
1422
+ setAttachments((prev) => [...prev, { type: "image", data: dataUrl }]);
1423
+ }
1424
+ };
1425
+ reader.readAsDataURL(file);
1426
+ });
1427
+ };
1428
+ const removeAttachment = (idx) => {
1429
+ setAttachments((prev) => prev.filter((_, i) => i !== idx));
1430
+ };
1431
+ const [voiceState, setVoiceState] = (0, import_react5.useState)("idle");
1432
+ const recognitionRef = (0, import_react5.useRef)(null);
1433
+ const pendingVoiceRef = (0, import_react5.useRef)(null);
1434
+ const hasSpeechAPI = typeof window !== "undefined" && ("SpeechRecognition" in window || "webkitSpeechRecognition" in window);
1435
+ const startVoice = (0, import_react5.useCallback)(() => {
1436
+ if (!hasSpeechAPI || voiceState !== "idle") return;
1437
+ const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
1438
+ const recognition = new SR();
1439
+ recognition.lang = "en-US";
1440
+ recognition.interimResults = false;
1441
+ recognition.maxAlternatives = 1;
1442
+ recognitionRef.current = recognition;
1443
+ recognition.onstart = () => setVoiceState("listening");
1444
+ recognition.onresult = (event) => {
1445
+ const transcript = event.results[0][0].transcript;
1446
+ setInput(transcript);
1447
+ pendingVoiceRef.current = transcript;
1448
+ setVoiceState("processing");
1449
+ };
1450
+ recognition.onerror = () => setVoiceState("idle");
1451
+ recognition.onend = () => {
1452
+ setVoiceState((prev) => prev === "listening" ? "idle" : prev);
1453
+ };
1454
+ recognition.start();
1455
+ }, [hasSpeechAPI, voiceState]);
1456
+ const stopVoice = (0, import_react5.useCallback)(() => {
1457
+ recognitionRef.current?.stop();
1458
+ setVoiceState("idle");
1459
+ }, []);
1460
+ (0, import_react5.useEffect)(() => {
1461
+ return () => recognitionRef.current?.abort();
1462
+ }, []);
1133
1463
  const isProperty = client.vertical === "property";
1134
1464
  const activeChips = chips === DEFAULT_CHIPS && isProperty ? PROPERTY_CHIPS : chips;
1135
1465
  const activeTitle = title === "Shopping Assistant" && isProperty ? "Property Assistant" : title;
1136
1466
  const activePlaceholder = placeholder === "Ask me anything \u2014 gifts, budget, use case\u2026" && isProperty ? "Ask me anything \u2014 location, budget, bedrooms\u2026" : placeholder;
1137
- (0, import_react3.useEffect)(() => {
1467
+ (0, import_react5.useEffect)(() => {
1138
1468
  if (loading && !streaming) {
1139
1469
  const interval = setInterval(() => {
1140
1470
  setLoadingMessageIndex((prev) => (prev + 1) % LOADING_MESSAGES.length);
@@ -1144,21 +1474,21 @@ function ChatModal({
1144
1474
  setLoadingMessageIndex(0);
1145
1475
  }
1146
1476
  }, [loading, streaming]);
1147
- const [selectedProduct, setSelectedProduct] = (0, import_react3.useState)(null);
1148
- const bottomRef = (0, import_react3.useRef)(null);
1149
- const textareaRef = (0, import_react3.useRef)(null);
1150
- const [phoneInput, setPhoneInput] = (0, import_react3.useState)(() => {
1477
+ const [selectedProduct, setSelectedProduct] = (0, import_react5.useState)(null);
1478
+ const bottomRef = (0, import_react5.useRef)(null);
1479
+ const textareaRef = (0, import_react5.useRef)(null);
1480
+ const [phoneInput, setPhoneInput] = (0, import_react5.useState)(() => {
1151
1481
  if (typeof window !== "undefined") {
1152
1482
  return localStorage.getItem("akropolys_user_phone") || "";
1153
1483
  }
1154
1484
  return "";
1155
1485
  });
1156
- const [merchantRef, setMerchantRef] = (0, import_react3.useState)(null);
1157
- const [paymentPhase, setPaymentPhase] = (0, import_react3.useState)("idle");
1158
- const [sessions, setSessions] = (0, import_react3.useState)(() => loadSessions());
1159
- const [sidebarOpen, setSidebarOpen] = (0, import_react3.useState)(false);
1160
- const [replayMessages, setReplayMessages] = (0, import_react3.useState)(null);
1161
- const { status: pollStatus } = (0, import_sdk4.usePaymentPolling)({
1486
+ const [merchantRef, setMerchantRef] = (0, import_react5.useState)(null);
1487
+ const [paymentPhase, setPaymentPhase] = (0, import_react5.useState)("idle");
1488
+ const [sessions, setSessions] = (0, import_react5.useState)(() => loadSessions());
1489
+ const [sidebarOpen, setSidebarOpen] = (0, import_react5.useState)(false);
1490
+ const [replayMessages, setReplayMessages] = (0, import_react5.useState)(null);
1491
+ const { status: pollStatus } = (0, import_sdk5.usePaymentPolling)({
1162
1492
  client: client.api,
1163
1493
  merchantReference: merchantRef,
1164
1494
  onSuccess: () => {
@@ -1170,7 +1500,7 @@ function ChatModal({
1170
1500
  setMerchantRef(null);
1171
1501
  }
1172
1502
  });
1173
- (0, import_react3.useEffect)(() => {
1503
+ (0, import_react5.useEffect)(() => {
1174
1504
  if (!lastAction) return;
1175
1505
  if (lastAction.type === "request_phone") {
1176
1506
  setPaymentPhase("prompt_phone");
@@ -1211,8 +1541,8 @@ function ChatModal({
1211
1541
  setPaymentPhase("failed");
1212
1542
  }
1213
1543
  };
1214
- const msgsContainerRef = (0, import_react3.useRef)(null);
1215
- (0, import_react3.useEffect)(() => {
1544
+ const msgsContainerRef = (0, import_react5.useRef)(null);
1545
+ (0, import_react5.useEffect)(() => {
1216
1546
  const container = msgsContainerRef.current;
1217
1547
  if (!container) return;
1218
1548
  const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
@@ -1220,14 +1550,14 @@ function ChatModal({
1220
1550
  bottomRef.current?.scrollIntoView({ behavior: "smooth" });
1221
1551
  }
1222
1552
  }, [messages, loading, selectedProduct]);
1223
- (0, import_react3.useEffect)(() => {
1553
+ (0, import_react5.useEffect)(() => {
1224
1554
  const h = (e) => {
1225
1555
  if (e.key === "Escape") onClose();
1226
1556
  };
1227
1557
  document.addEventListener("keydown", h);
1228
1558
  return () => document.removeEventListener("keydown", h);
1229
1559
  }, []);
1230
- const saveCurrentSession = (0, import_react3.useCallback)(() => {
1560
+ const saveCurrentSession = (0, import_react5.useCallback)(() => {
1231
1561
  if (messages.length < 2) return;
1232
1562
  const firstUser = messages.find((m) => m.role === "user");
1233
1563
  const session = {
@@ -1240,7 +1570,7 @@ function ChatModal({
1240
1570
  setSessions(updated);
1241
1571
  saveSessions(updated);
1242
1572
  }, [messages, sessions]);
1243
- const handleReset = (0, import_react3.useCallback)(() => {
1573
+ const handleReset = (0, import_react5.useCallback)(() => {
1244
1574
  saveCurrentSession();
1245
1575
  reset();
1246
1576
  setReplayMessages(null);
@@ -1253,7 +1583,7 @@ function ChatModal({
1253
1583
  const q = `Tell me more about the ${src.name}${src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : ""} \u2014 what are its key specs, who is it best for, and is it worth buying?`;
1254
1584
  send(q);
1255
1585
  };
1256
- const handleSend = async (text) => {
1586
+ const handleSend = async (text, extraAttachments) => {
1257
1587
  const q = (text ?? input).trim();
1258
1588
  if (!q || loading) return;
1259
1589
  setReplayMessages(null);
@@ -1262,7 +1592,9 @@ function ChatModal({
1262
1592
  if (textareaRef.current) {
1263
1593
  textareaRef.current.style.height = "auto";
1264
1594
  }
1265
- await send(q);
1595
+ const toSend = extraAttachments ?? attachments;
1596
+ setAttachments([]);
1597
+ await send(q, void 0, toSend.length > 0 ? toSend : void 0);
1266
1598
  };
1267
1599
  const handleKeyDown = (e) => {
1268
1600
  if (e.key === "Enter" && !e.shiftKey) {
@@ -1276,6 +1608,20 @@ function ChatModal({
1276
1608
  t.style.height = "auto";
1277
1609
  t.style.height = `${Math.min(t.scrollHeight, 140)}px`;
1278
1610
  };
1611
+ (0, import_react5.useEffect)(() => {
1612
+ if (voiceState !== "processing") return;
1613
+ const transcript = pendingVoiceRef.current;
1614
+ if (!transcript) {
1615
+ setVoiceState("idle");
1616
+ return;
1617
+ }
1618
+ pendingVoiceRef.current = null;
1619
+ const timer = setTimeout(() => {
1620
+ setVoiceState("idle");
1621
+ handleSend(transcript);
1622
+ }, 400);
1623
+ return () => clearTimeout(timer);
1624
+ }, [voiceState]);
1279
1625
  const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "20px";
1280
1626
  const displayMessages = replayMessages ?? messages;
1281
1627
  const loadSession = (session) => {
@@ -1288,7 +1634,7 @@ function ChatModal({
1288
1634
  setSessions(updated);
1289
1635
  saveSessions(updated);
1290
1636
  };
1291
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1637
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1292
1638
  "div",
1293
1639
  {
1294
1640
  className: cn("hsk-cb-overlay", classNames.overlay),
@@ -1300,27 +1646,27 @@ function ChatModal({
1300
1646
  ...backdropColor ? { background: backdropColor } : {},
1301
1647
  ...customStyles
1302
1648
  },
1303
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("hsk-cb-panel hsk-cb-panel--with-sidebar", classNames.panel), onClick: (e) => e.stopPropagation(), children: [
1304
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("hsk-cb-sidebar", sidebarOpen && "hsk-cb-sidebar--open"), children: [
1305
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-sidebar-header", children: [
1306
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-cb-sidebar-title", children: "History" }),
1307
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1649
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("hsk-cb-panel hsk-cb-panel--with-sidebar", classNames.panel), onClick: (e) => e.stopPropagation(), children: [
1650
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("hsk-cb-sidebar", sidebarOpen && "hsk-cb-sidebar--open"), children: [
1651
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-sidebar-header", children: [
1652
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-cb-sidebar-title", children: "History" }),
1653
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1308
1654
  "button",
1309
1655
  {
1310
1656
  className: "hsk-cb-sidebar-new",
1311
1657
  onClick: handleReset,
1312
1658
  title: "New chat",
1313
1659
  children: [
1314
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NewChatIcon, {}),
1315
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "New chat" })
1660
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NewChatIcon, {}),
1661
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "New chat" })
1316
1662
  ]
1317
1663
  }
1318
1664
  )
1319
1665
  ] }),
1320
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-sidebar-list", children: sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-sidebar-empty", children: [
1321
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HistoryIcon, {}),
1322
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "No history yet" })
1323
- ] }) : sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1666
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-sidebar-list", children: sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-sidebar-empty", children: [
1667
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HistoryIcon, {}),
1668
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "No history yet" })
1669
+ ] }) : sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1324
1670
  "div",
1325
1671
  {
1326
1672
  className: cn(
@@ -1329,9 +1675,9 @@ function ChatModal({
1329
1675
  ),
1330
1676
  onClick: () => loadSession(session),
1331
1677
  children: [
1332
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-sidebar-session-title", children: session.title }),
1333
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-sidebar-session-meta", children: relativeTime(session.ts) }),
1334
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1678
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-sidebar-session-title", children: session.title }),
1679
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-sidebar-session-meta", children: relativeTime(session.ts) }),
1680
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1335
1681
  "button",
1336
1682
  {
1337
1683
  className: "hsk-cb-sidebar-session-del",
@@ -1345,10 +1691,10 @@ function ChatModal({
1345
1691
  session.id
1346
1692
  )) })
1347
1693
  ] }),
1348
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-main", children: [
1349
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar", children: [
1350
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar-left", children: [
1351
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1694
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-main", children: [
1695
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-topbar", children: [
1696
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-topbar-left", children: [
1697
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1352
1698
  "button",
1353
1699
  {
1354
1700
  className: cn("hsk-cb-sidebar-toggle", sidebarOpen && "hsk-cb-sidebar-toggle--active"),
@@ -1357,29 +1703,29 @@ function ChatModal({
1357
1703
  setSidebarOpen((v) => !v);
1358
1704
  },
1359
1705
  "aria-label": "Toggle history",
1360
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HistoryIcon, {})
1706
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HistoryIcon, {})
1361
1707
  }
1362
1708
  ),
1363
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon2, {}) }),
1364
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-topbar-title", children: activeTitle }) })
1709
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
1710
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-topbar-title", children: activeTitle }) })
1365
1711
  ] }),
1366
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar-actions", children: [
1367
- replayMessages ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-topbar-btn", onClick: () => {
1712
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-topbar-actions", children: [
1713
+ replayMessages ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-topbar-btn", onClick: () => {
1368
1714
  setReplayMessages(null);
1369
- }, children: "\u2190 Live chat" }) : messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-topbar-btn", onClick: handleReset, children: "Clear chat" }),
1370
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseIcon, {}) })
1715
+ }, children: "\u2190 Live chat" }) : messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-topbar-btn", onClick: handleReset, children: "Clear chat" }),
1716
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CloseIcon, {}) })
1371
1717
  ] })
1372
1718
  ] }),
1373
- replayMessages && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-replay-banner", children: [
1374
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HistoryIcon, {}),
1375
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "You're viewing a past conversation." }),
1376
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => setReplayMessages(null), children: "Back to chat \u2192" })
1719
+ replayMessages && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-replay-banner", children: [
1720
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HistoryIcon, {}),
1721
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "You're viewing a past conversation." }),
1722
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { onClick: () => setReplayMessages(null), children: "Back to chat \u2192" })
1377
1723
  ] }),
1378
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-msgs", ref: msgsContainerRef, children: [
1379
- displayMessages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-empty", children: [
1380
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-empty-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon2, {}) }),
1381
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-empty-title", children: "Find exactly what you need" }),
1382
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-chips", children: activeChips.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1724
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-msgs", ref: msgsContainerRef, children: [
1725
+ displayMessages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-empty", children: [
1726
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-empty-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
1727
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-empty-title", children: "Find exactly what you need" }),
1728
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-chips", children: activeChips.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1383
1729
  "button",
1384
1730
  {
1385
1731
  className: "hsk-cb-chip",
@@ -1392,12 +1738,15 @@ function ChatModal({
1392
1738
  const isLast = idx === displayMessages.length - 1 && !replayMessages;
1393
1739
  const isUser = msg.role === "user";
1394
1740
  const displayContent = !isUser && isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages ? stripMarkdownTables(msg.content) : msg.content;
1395
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
1396
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon2, {}) }),
1397
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-ai-body", children: [
1398
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-text", children: renderMarkdown(displayContent) }),
1399
- isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ComparisonMatrix, { sources, defaultCurrency }),
1400
- isLast && sources.length > 0 && lastIntent !== "compare" && lastAction?.type !== "request_phone" && lastAction?.type !== "awaiting_payment" && lastAction?.type !== "checkout" && !msg.cartSnapshot && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1741
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-user-msg", children: [
1742
+ msg.images && msg.images.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-user-imgs", children: msg.images.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: img, alt: `attachment ${i + 1}`, className: "hsk-cb-user-img-thumb" }, i)) }),
1743
+ msg.content && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-user-bubble", children: msg.content })
1744
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
1745
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
1746
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-body", children: [
1747
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-text", children: renderMarkdown(displayContent) }),
1748
+ isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComparisonMatrix, { sources, defaultCurrency }),
1749
+ isLast && sources.length > 0 && lastIntent !== "compare" && lastAction?.type !== "request_phone" && lastAction?.type !== "awaiting_payment" && lastAction?.type !== "checkout" && !msg.cartSnapshot && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1401
1750
  SourcesCarousel,
1402
1751
  {
1403
1752
  sources,
@@ -1405,14 +1754,14 @@ function ChatModal({
1405
1754
  onSelectSource: handleSourceClick
1406
1755
  }
1407
1756
  ),
1408
- msg.cartSnapshot && msg.cartSnapshot.items?.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1757
+ msg.cartSnapshot && msg.cartSnapshot.items?.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1409
1758
  CartContextCard,
1410
1759
  {
1411
1760
  cart: msg.cartSnapshot,
1412
1761
  defaultCurrency
1413
1762
  }
1414
1763
  ),
1415
- isLast && msg.cartSnapshot && !loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1764
+ isLast && msg.cartSnapshot && !loading && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1416
1765
  ActionPills,
1417
1766
  {
1418
1767
  cart: msg.cartSnapshot,
@@ -1421,7 +1770,7 @@ function ChatModal({
1421
1770
  loading
1422
1771
  }
1423
1772
  ),
1424
- isLast && !loading && !msg.cartSnapshot && !replayMessages && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1773
+ isLast && !loading && !msg.cartSnapshot && !replayMessages && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1425
1774
  SmartContextPills,
1426
1775
  {
1427
1776
  intent: lastIntent,
@@ -1433,16 +1782,16 @@ function ChatModal({
1433
1782
  ] })
1434
1783
  ] }) }, idx);
1435
1784
  }),
1436
- selectedProduct && loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1785
+ selectedProduct && loading && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1437
1786
  "div",
1438
1787
  {
1439
1788
  className: "hsk-cb-selected-product",
1440
1789
  onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
1441
1790
  children: [
1442
- selectedProduct.image && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
1443
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-selected-info", children: [
1444
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
1445
- selectedProduct.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-selected-price", children: [
1791
+ selectedProduct.image && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
1792
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-selected-info", children: [
1793
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
1794
+ selectedProduct.price && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-selected-price", children: [
1446
1795
  selectedProduct.currency ?? defaultCurrency,
1447
1796
  " ",
1448
1797
  parseFloat(String(selectedProduct.price ?? "").replace(/[^0-9.]/g, "") || "0").toLocaleString()
@@ -1451,34 +1800,34 @@ function ChatModal({
1451
1800
  ]
1452
1801
  }
1453
1802
  ),
1454
- loading && !streaming && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-typing-row", style: { display: "flex", alignItems: "flex-start", gap: "10px" }, children: [
1455
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center", marginTop: "4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon2, {}) }),
1456
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
1457
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: `
1803
+ loading && !streaming && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-typing-row", style: { display: "flex", alignItems: "flex-start", gap: "10px" }, children: [
1804
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center", marginTop: "4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
1805
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
1806
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
1458
1807
  @keyframes hsk-pulse {
1459
1808
  0%, 100% { opacity: 0.6; }
1460
1809
  50% { opacity: 1; }
1461
1810
  }
1462
1811
  ` }),
1463
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: "0.85rem", color: "#6b7280", fontStyle: "italic", animation: "hsk-pulse 1.5s infinite ease-in-out" }, children: LOADING_MESSAGES[loadingMessageIndex] }),
1464
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-typing", style: { margin: 0, alignSelf: "flex-start" }, children: [
1465
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" }),
1466
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" }),
1467
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" })
1812
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: "0.85rem", color: "#6b7280", fontStyle: "italic", animation: "hsk-pulse 1.5s infinite ease-in-out" }, children: LOADING_MESSAGES[loadingMessageIndex] }),
1813
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-typing", style: { margin: 0, alignSelf: "flex-start" }, children: [
1814
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot" }),
1815
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot" }),
1816
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot" })
1468
1817
  ] })
1469
1818
  ] })
1470
1819
  ] }),
1471
- error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-error", children: getFriendlyError(error) }),
1820
+ error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-error", children: getFriendlyError(error) }),
1472
1821
  !replayMessages && paymentPhase === "prompt_phone" && (() => {
1473
1822
  const isHistoryIntent = lastIntent === "capture" || lastIntent === "delete" || lastIntent === "view_history";
1474
1823
  if (isHistoryIntent) {
1475
1824
  return null;
1476
1825
  }
1477
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
1478
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon2, {}) }),
1479
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-phone-form", children: [
1480
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { className: "hsk-cb-phone-label", children: "Enter your M-Pesa number to pay" }),
1481
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1826
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
1827
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
1828
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-phone-form", children: [
1829
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("label", { className: "hsk-cb-phone-label", children: "Enter your M-Pesa number to pay" }),
1830
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1482
1831
  "input",
1483
1832
  {
1484
1833
  type: "tel",
@@ -1490,37 +1839,37 @@ function ChatModal({
1490
1839
  autoFocus: true
1491
1840
  }
1492
1841
  ),
1493
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-phone-submit", onClick: handlePhoneSubmit, children: "Send STK push" })
1842
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-phone-submit", onClick: handlePhoneSubmit, children: "Send STK push" })
1494
1843
  ] }) }) })
1495
1844
  ] });
1496
1845
  })(),
1497
- !replayMessages && paymentPhase === "awaiting" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--awaiting", children: [
1498
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-payment-pulse-ring" }),
1499
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { fontSize: "2rem" }, children: "\u{1F4F1}" }) }),
1500
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "hsk-cb-payment-label", style: { fontWeight: 600 }, children: "Check your phone" }),
1501
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "hsk-cb-payment-sub", children: [
1846
+ !replayMessages && paymentPhase === "awaiting" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--awaiting", children: [
1847
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-pulse-ring" }),
1848
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: "2rem" }, children: "\u{1F4F1}" }) }),
1849
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-label", style: { fontWeight: 600 }, children: "Check your phone" }),
1850
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "hsk-cb-payment-sub", children: [
1502
1851
  "An M-Pesa STK push has been sent.",
1503
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
1852
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("br", {}),
1504
1853
  "Enter your PIN to complete payment."
1505
1854
  ] }),
1506
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-payment-dots", children: [
1507
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" }),
1508
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" }),
1509
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" })
1855
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-dots", children: [
1856
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" }),
1857
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" }),
1858
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" })
1510
1859
  ] })
1511
1860
  ] }),
1512
- !replayMessages && paymentPhase === "done" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--success", children: [
1513
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-payment-success-ring" }),
1514
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { fontSize: "2.5rem" }, children: "\u2705" }) }),
1515
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "hsk-cb-payment-label", children: "Payment complete!" }),
1516
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "hsk-cb-payment-sub", children: "Thank you for your order. A confirmation has been sent." })
1861
+ !replayMessages && paymentPhase === "done" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--success", children: [
1862
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-success-ring" }),
1863
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: "2.5rem" }, children: "\u2705" }) }),
1864
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-label", children: "Payment complete!" }),
1865
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-sub", children: "Thank you for your order. A confirmation has been sent." })
1517
1866
  ] }),
1518
- !replayMessages && paymentPhase === "failed" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--failed", children: [
1519
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { fontSize: "2.5rem" }, children: "\u274C" }) }),
1520
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "hsk-cb-payment-label", children: "Payment failed or timed out" }),
1521
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "hsk-cb-payment-sub", children: "Please check your M-Pesa PIN and try again, or contact support." }),
1522
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-payment-actions", children: [
1523
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1867
+ !replayMessages && paymentPhase === "failed" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--failed", children: [
1868
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: "2.5rem" }, children: "\u274C" }) }),
1869
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-label", children: "Payment failed or timed out" }),
1870
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-sub", children: "Please check your M-Pesa PIN and try again, or contact support." }),
1871
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-actions", children: [
1872
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1524
1873
  "button",
1525
1874
  {
1526
1875
  className: "hsk-cb-pay-submit",
@@ -1531,7 +1880,7 @@ function ChatModal({
1531
1880
  children: "Try again"
1532
1881
  }
1533
1882
  ),
1534
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1883
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1535
1884
  "button",
1536
1885
  {
1537
1886
  className: "hsk-cb-pay-secondary",
@@ -1544,11 +1893,45 @@ function ChatModal({
1544
1893
  )
1545
1894
  ] })
1546
1895
  ] }),
1547
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: bottomRef, style: { height: 1 } })
1896
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: bottomRef, style: { height: 1 } })
1548
1897
  ] }),
1549
- !replayMessages && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-input-wrap", children: [
1550
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-input-box", children: [
1551
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1898
+ !replayMessages && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-input-wrap", children: [
1899
+ attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-img-strip", children: attachments.map((att, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-img-thumb-wrap", children: [
1900
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: att.data, alt: `attachment ${i + 1}`, className: "hsk-cb-img-thumb" }),
1901
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1902
+ "button",
1903
+ {
1904
+ className: "hsk-cb-img-thumb-remove",
1905
+ onClick: () => removeAttachment(i),
1906
+ "aria-label": "Remove image",
1907
+ children: "\xD7"
1908
+ }
1909
+ )
1910
+ ] }, i)) }),
1911
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-input-box", children: [
1912
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1913
+ "input",
1914
+ {
1915
+ ref: imageInputRef,
1916
+ type: "file",
1917
+ accept: "image/*",
1918
+ multiple: true,
1919
+ style: { display: "none" },
1920
+ onChange: (e) => handleImageFiles(e.target.files)
1921
+ }
1922
+ ),
1923
+ enableVision && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1924
+ "button",
1925
+ {
1926
+ className: "hsk-cb-attach-btn",
1927
+ onClick: () => imageInputRef.current?.click(),
1928
+ disabled: loading,
1929
+ "aria-label": "Attach image",
1930
+ title: "Attach image",
1931
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PaperclipIcon, {})
1932
+ }
1933
+ ),
1934
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1552
1935
  "textarea",
1553
1936
  {
1554
1937
  ref: textareaRef,
@@ -1562,18 +1945,36 @@ function ChatModal({
1562
1945
  autoFocus: true
1563
1946
  }
1564
1947
  ),
1565
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1948
+ hasSpeechAPI && enableVoice && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1949
+ "button",
1950
+ {
1951
+ className: cn(
1952
+ "hsk-cb-mic-btn",
1953
+ voiceState === "listening" && "hsk-cb-mic-btn--listening",
1954
+ voiceState === "processing" && "hsk-cb-mic-btn--processing"
1955
+ ),
1956
+ onClick: voiceState === "idle" ? startVoice : stopVoice,
1957
+ disabled: loading,
1958
+ "aria-label": voiceState === "idle" ? "Start voice input" : "Stop recording",
1959
+ title: voiceState === "idle" ? "Voice input" : "Stop",
1960
+ children: [
1961
+ voiceState === "listening" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MicOffIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MicIcon2, {}),
1962
+ voiceState === "listening" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-cb-mic-pulse" })
1963
+ ]
1964
+ }
1965
+ ),
1966
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1566
1967
  "button",
1567
1968
  {
1568
1969
  className: cn("hsk-cb-send", classNames.sendButton),
1569
1970
  onClick: () => handleSend(),
1570
- disabled: !input.trim() || loading,
1971
+ disabled: !input.trim() && attachments.length === 0 || loading,
1571
1972
  "aria-label": "Send message",
1572
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ArrowUpIcon2, {})
1973
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ArrowUpIcon2, {})
1573
1974
  }
1574
1975
  )
1575
1976
  ] }),
1576
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-hint", children: "Akropolys AI \xB7 searches the whole catalogue in real time" })
1977
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-hint", children: "Akropolys AI \xB7 searches the whole catalogue in real time" })
1577
1978
  ] })
1578
1979
  ] })
1579
1980
  ] })
@@ -1591,11 +1992,14 @@ function KikuButton({
1591
1992
  defaultCurrency,
1592
1993
  chips,
1593
1994
  theme,
1594
- classNames = {}
1995
+ classNames = {},
1996
+ enableVoice = false,
1997
+ enableVision = false,
1998
+ visionCategoryHint
1595
1999
  }) {
1596
- const [open, setOpen] = (0, import_react3.useState)(false);
1597
- const [mounted, setMounted] = (0, import_react3.useState)(false);
1598
- (0, import_react3.useEffect)(() => {
2000
+ const [open, setOpen] = (0, import_react5.useState)(false);
2001
+ const [mounted, setMounted] = (0, import_react5.useState)(false);
2002
+ (0, import_react5.useEffect)(() => {
1599
2003
  setMounted(true);
1600
2004
  if (typeof window !== "undefined" && !window.__akropolys_nav_patched) {
1601
2005
  window.__akropolys_nav_patched = true;
@@ -1629,8 +2033,8 @@ function KikuButton({
1629
2033
  ...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
1630
2034
  ...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
1631
2035
  } : void 0;
1632
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1633
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2036
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2037
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1634
2038
  "button",
1635
2039
  {
1636
2040
  className: cn("hsk-cb-btn", classNames.button, className),
@@ -1639,13 +2043,13 @@ function KikuButton({
1639
2043
  "data-hsk-theme": hskThemeAttr,
1640
2044
  "aria-label": "Open AI chat",
1641
2045
  children: [
1642
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon2, {}) }),
2046
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
1643
2047
  label !== void 0 ? label : null
1644
2048
  ]
1645
2049
  }
1646
2050
  ),
1647
2051
  open && mounted && (0, import_react_dom.createPortal)(
1648
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2052
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1649
2053
  ChatModal,
1650
2054
  {
1651
2055
  title,
@@ -1657,7 +2061,10 @@ function KikuButton({
1657
2061
  defaultCurrency,
1658
2062
  chips,
1659
2063
  theme,
1660
- classNames
2064
+ classNames,
2065
+ enableVoice,
2066
+ enableVision,
2067
+ visionCategoryHint
1661
2068
  }
1662
2069
  ),
1663
2070
  document.body
@@ -1666,11 +2073,11 @@ function KikuButton({
1666
2073
  }
1667
2074
 
1668
2075
  // src/components/Sparkle.tsx
1669
- var import_react4 = require("react");
2076
+ var import_react6 = require("react");
1670
2077
  var import_react_dom2 = require("react-dom");
1671
- var import_sdk6 = require("@akropolys/sdk");
1672
- var import_jsx_runtime6 = require("react/jsx-runtime");
1673
- var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2078
+ var import_sdk7 = require("@akropolys/sdk");
2079
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2080
+ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1674
2081
  "svg",
1675
2082
  {
1676
2083
  className: cn("hsk-brand-a", className),
@@ -1681,7 +2088,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_
1681
2088
  xmlns: "http://www.w3.org/2000/svg",
1682
2089
  "aria-label": "Akropolys",
1683
2090
  children: [
1684
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2091
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1685
2092
  "path",
1686
2093
  {
1687
2094
  d: "M14.5 4.5 L6.5 25",
@@ -1690,7 +2097,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_
1690
2097
  strokeLinecap: "round"
1691
2098
  }
1692
2099
  ),
1693
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2100
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1694
2101
  "path",
1695
2102
  {
1696
2103
  d: "M14.5 4.5 L22.5 25",
@@ -1699,7 +2106,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_
1699
2106
  strokeLinecap: "round"
1700
2107
  }
1701
2108
  ),
1702
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2109
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1703
2110
  "path",
1704
2111
  {
1705
2112
  d: "M9.5 17 H19.5",
@@ -1708,7 +2115,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_
1708
2115
  strokeLinecap: "round"
1709
2116
  }
1710
2117
  ),
1711
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2118
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1712
2119
  "path",
1713
2120
  {
1714
2121
  d: "M3 25 H10",
@@ -1717,7 +2124,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_
1717
2124
  strokeLinecap: "round"
1718
2125
  }
1719
2126
  ),
1720
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2127
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1721
2128
  "path",
1722
2129
  {
1723
2130
  d: "M19 25 H26",
@@ -1726,7 +2133,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_
1726
2133
  strokeLinecap: "round"
1727
2134
  }
1728
2135
  ),
1729
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2136
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1730
2137
  "path",
1731
2138
  {
1732
2139
  d: "M8.5 2.5 C10 2.5, 11 3.5, 11 5 C11 7, 8.5 8.5, 7.5 9.5",
@@ -1740,13 +2147,13 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_
1740
2147
  ]
1741
2148
  }
1742
2149
  );
1743
- var CloseIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1744
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1745
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2150
+ var CloseIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2151
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2152
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1746
2153
  ] });
1747
- var ArrowUpIcon3 = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1748
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m5 12 7-7 7 7" }),
1749
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 19V5" })
2154
+ var ArrowUpIcon3 = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2155
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "m5 12 7-7 7 7" }),
2156
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 19V5" })
1750
2157
  ] });
1751
2158
  var getFriendlyError2 = (err) => {
1752
2159
  let str = "";
@@ -1779,18 +2186,18 @@ function SparkleModal({
1779
2186
  classNames = {},
1780
2187
  product: initialProduct
1781
2188
  }) {
1782
- const client = (0, import_sdk6.useAkropolysContext)();
1783
- const [fetchedProduct, setFetchedProduct] = (0, import_react4.useState)(null);
2189
+ const client = (0, import_sdk7.useAkropolysContext)();
2190
+ const [fetchedProduct, setFetchedProduct] = (0, import_react6.useState)(null);
1784
2191
  const displayProduct = initialProduct || fetchedProduct;
1785
- const { results, loading: searchLoading, search } = (0, import_sdk6.useSearch)();
1786
- const { messages, sources, loading: chatLoading, error: chatError, send } = (0, import_sdk6.useKiku)();
1787
- const [chatInput, setChatInput] = (0, import_react4.useState)("");
1788
- const [isMobile, setIsMobile] = (0, import_react4.useState)(false);
1789
- const [showSpecs, setShowSpecs] = (0, import_react4.useState)(false);
1790
- const [collapseSimilar, setCollapseSimilar] = (0, import_react4.useState)(false);
1791
- const chatBottomRef = (0, import_react4.useRef)(null);
1792
- const chatTextareaRef = (0, import_react4.useRef)(null);
1793
- (0, import_react4.useEffect)(() => {
2192
+ const { results, loading: searchLoading, search } = (0, import_sdk7.useSearch)();
2193
+ const { messages, sources, loading: chatLoading, error: chatError, send } = (0, import_sdk7.useKiku)();
2194
+ const [chatInput, setChatInput] = (0, import_react6.useState)("");
2195
+ const [isMobile, setIsMobile] = (0, import_react6.useState)(false);
2196
+ const [showSpecs, setShowSpecs] = (0, import_react6.useState)(false);
2197
+ const [collapseSimilar, setCollapseSimilar] = (0, import_react6.useState)(false);
2198
+ const chatBottomRef = (0, import_react6.useRef)(null);
2199
+ const chatTextareaRef = (0, import_react6.useRef)(null);
2200
+ (0, import_react6.useEffect)(() => {
1794
2201
  if (!initialProduct && !fetchedProduct) {
1795
2202
  client.api.searchVector(productName, 1).then((res) => {
1796
2203
  if (res.results && res.results.length > 0) {
@@ -1800,7 +2207,7 @@ function SparkleModal({
1800
2207
  }
1801
2208
  search(productName, limit);
1802
2209
  }, [productName, initialProduct, fetchedProduct, client, limit, search]);
1803
- (0, import_react4.useEffect)(() => {
2210
+ (0, import_react6.useEffect)(() => {
1804
2211
  const handleResize = () => setIsMobile(window.innerWidth <= 768);
1805
2212
  handleResize();
1806
2213
  if (typeof window !== "undefined") {
@@ -1808,17 +2215,17 @@ function SparkleModal({
1808
2215
  return () => window.removeEventListener("resize", handleResize);
1809
2216
  }
1810
2217
  }, []);
1811
- (0, import_react4.useEffect)(() => {
2218
+ (0, import_react6.useEffect)(() => {
1812
2219
  if (results.length > 0) onResult?.(results);
1813
2220
  }, [results, onResult]);
1814
- (0, import_react4.useEffect)(() => {
2221
+ (0, import_react6.useEffect)(() => {
1815
2222
  const h = (e) => {
1816
2223
  if (e.key === "Escape") onClose();
1817
2224
  };
1818
2225
  document.addEventListener("keydown", h);
1819
2226
  return () => document.removeEventListener("keydown", h);
1820
2227
  }, [onClose]);
1821
- (0, import_react4.useEffect)(() => {
2228
+ (0, import_react6.useEffect)(() => {
1822
2229
  chatBottomRef.current?.scrollIntoView({ behavior: "smooth" });
1823
2230
  }, [messages, chatLoading]);
1824
2231
  const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "16px";
@@ -1872,7 +2279,7 @@ Question: ${q}`;
1872
2279
  }
1873
2280
  ] : messages;
1874
2281
  if (isMobile) {
1875
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2282
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1876
2283
  "div",
1877
2284
  {
1878
2285
  className: cn("hsk-sp-backdrop hsk-sp-mobile-view", classNames.backdrop),
@@ -1883,13 +2290,13 @@ Question: ${q}`;
1883
2290
  background: bg ?? void 0,
1884
2291
  ...customStyles
1885
2292
  },
1886
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: cn("hsk-sp-card hsk-sp-fullscreen hsk-sp-mobile-card", classNames.card), onClick: (e) => e.stopPropagation(), children: [
1887
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-header", children: [
1888
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparkleIcon3, {}) }),
1889
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-header-body", children: [
1890
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-header-title-row", children: [
1891
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
1892
- displayProduct && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2293
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cn("hsk-sp-card hsk-sp-fullscreen hsk-sp-mobile-card", classNames.card), onClick: (e) => e.stopPropagation(), children: [
2294
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-header", children: [
2295
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SparkleIcon3, {}) }),
2296
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-header-body", children: [
2297
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-header-title-row", children: [
2298
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
2299
+ displayProduct && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1893
2300
  "button",
1894
2301
  {
1895
2302
  type: "button",
@@ -1899,32 +2306,32 @@ Question: ${q}`;
1899
2306
  }
1900
2307
  )
1901
2308
  ] }),
1902
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-header-sub", children: "Akropolys AI Shopping Assistant" })
2309
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-header-sub", children: "Akropolys AI Shopping Assistant" })
1903
2310
  ] }),
1904
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CloseIcon2, {}) })
2311
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseIcon2, {}) })
1905
2312
  ] }),
1906
- searchLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-bar" }),
1907
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-chat-container", children: [
1908
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-msgs", children: [
2313
+ searchLoading && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-bar" }),
2314
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-chat-container", children: [
2315
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-msgs", children: [
1909
2316
  displayMessages.map((msg, idx) => {
1910
2317
  const isUser = msg.role === "user";
1911
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
1912
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparkleIcon3, {}) }),
1913
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-ai-body", children: [
1914
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
1915
- idx === 0 && displayProduct && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-attachment-deck", children: [
1916
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-main-card", children: [
1917
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-mobile-main-card-img", children: displayProduct.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u{1F6CD}" }) }),
1918
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-main-card-info", children: [
1919
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-mobile-main-card-brand", children: displayProduct.brand || displayProduct.category || "Product" }),
1920
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-mobile-main-card-name", children: displayProduct.name }),
1921
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-main-card-price", children: [
2318
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
2319
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SparkleIcon3, {}) }),
2320
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-ai-body", children: [
2321
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
2322
+ idx === 0 && displayProduct && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-attachment-deck", children: [
2323
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-main-card", children: [
2324
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-main-card-img", children: displayProduct.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "\u{1F6CD}" }) }),
2325
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-main-card-info", children: [
2326
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-main-card-brand", children: displayProduct.brand || displayProduct.category || "Product" }),
2327
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-main-card-name", children: displayProduct.name }),
2328
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-main-card-price", children: [
1922
2329
  displayProduct.currency ?? "KES",
1923
2330
  " ",
1924
2331
  parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString()
1925
2332
  ] })
1926
2333
  ] }),
1927
- (displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2334
+ (displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1928
2335
  "button",
1929
2336
  {
1930
2337
  type: "button",
@@ -1943,21 +2350,21 @@ Question: ${q}`;
1943
2350
  }
1944
2351
  );
1945
2352
  if (similarProducts.length === 0) return null;
1946
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-inline", children: [
1947
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-title", children: "Similar Products" }),
1948
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-list", children: similarProducts.map((r) => {
2353
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-inline", children: [
2354
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-title", children: "Similar Products" }),
2355
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-list", children: similarProducts.map((r) => {
1949
2356
  const price = parseFloat(r.product.price?.replace(/[^0-9.]/g, "") || "0");
1950
2357
  const currency = r.product.currency ?? "KES";
1951
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2358
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1952
2359
  "div",
1953
2360
  {
1954
2361
  className: "hsk-sp-mobile-similar-carousel-item",
1955
2362
  onClick: () => handleNav(r),
1956
2363
  children: [
1957
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-img", children: r.product.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: r.product.images[0], alt: r.product.name }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u{1F6CD}" }) }),
1958
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-meta", children: [
1959
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-name", title: r.product.name, children: r.product.name }),
1960
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-price", children: [
2364
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-img", children: r.product.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: r.product.images[0], alt: r.product.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "\u{1F6CD}" }) }),
2365
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-meta", children: [
2366
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-name", title: r.product.name, children: r.product.name }),
2367
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-price", children: [
1961
2368
  currency,
1962
2369
  " ",
1963
2370
  price.toLocaleString()
@@ -1974,19 +2381,19 @@ Question: ${q}`;
1974
2381
  ] })
1975
2382
  ] }) }, idx);
1976
2383
  }),
1977
- chatLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-typing-row", children: [
1978
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparkleIcon3, {}) }),
1979
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-typing", children: [
1980
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-dot" }),
1981
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-dot" }),
1982
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-dot" })
2384
+ chatLoading && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-typing-row", children: [
2385
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SparkleIcon3, {}) }),
2386
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-typing", children: [
2387
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-dot" }),
2388
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-dot" }),
2389
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-dot" })
1983
2390
  ] })
1984
2391
  ] }),
1985
- chatError && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
1986
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: chatBottomRef, style: { height: 1 } })
2392
+ chatError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
2393
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: chatBottomRef, style: { height: 1 } })
1987
2394
  ] }),
1988
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-input-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-input-box", children: [
1989
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2395
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-input-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-input-box", children: [
2396
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1990
2397
  "textarea",
1991
2398
  {
1992
2399
  ref: chatTextareaRef,
@@ -1999,34 +2406,34 @@ Question: ${q}`;
1999
2406
  disabled: chatLoading
2000
2407
  }
2001
2408
  ),
2002
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2409
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2003
2410
  "button",
2004
2411
  {
2005
2412
  className: "hsk-cb-send",
2006
2413
  onClick: () => handleSend(),
2007
2414
  disabled: !chatInput.trim() || chatLoading,
2008
2415
  "aria-label": "Send message",
2009
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArrowUpIcon3, {})
2416
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ArrowUpIcon3, {})
2010
2417
  }
2011
2418
  )
2012
2419
  ] }) })
2013
2420
  ] }),
2014
- showSpecs && displayProduct && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-mobile-specs-overlay", onClick: () => setShowSpecs(false), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-specs-drawer", onClick: (e) => e.stopPropagation(), children: [
2015
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-specs-header", children: [
2016
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: "Specifications" }),
2017
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => setShowSpecs(false), children: "Close" })
2421
+ showSpecs && displayProduct && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-specs-overlay", onClick: () => setShowSpecs(false), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-specs-drawer", onClick: (e) => e.stopPropagation(), children: [
2422
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-specs-header", children: [
2423
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Specifications" }),
2424
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", onClick: () => setShowSpecs(false), children: "Close" })
2018
2425
  ] }),
2019
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-specs-body", children: [
2020
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h4", { className: "hsk-sp-mobile-specs-title", children: displayProduct.name }),
2021
- displayProduct.description && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-specs-desc", children: [
2022
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h5", { children: "Description" }),
2023
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: displayProduct.description })
2426
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-specs-body", children: [
2427
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { className: "hsk-sp-mobile-specs-title", children: displayProduct.name }),
2428
+ displayProduct.description && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-specs-desc", children: [
2429
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h5", { children: "Description" }),
2430
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: displayProduct.description })
2024
2431
  ] }),
2025
- displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-specs-list", children: [
2026
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h5", { children: "Details" }),
2027
- Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-mobile-spec-row", children: [
2028
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-mobile-spec-label", children: key }),
2029
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-mobile-spec-value", children: val })
2432
+ displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-specs-list", children: [
2433
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h5", { children: "Details" }),
2434
+ Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-spec-row", children: [
2435
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-mobile-spec-label", children: key }),
2436
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-mobile-spec-value", children: val })
2030
2437
  ] }, key))
2031
2438
  ] })
2032
2439
  ] })
@@ -2035,7 +2442,7 @@ Question: ${q}`;
2035
2442
  }
2036
2443
  );
2037
2444
  }
2038
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2445
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2039
2446
  "div",
2040
2447
  {
2041
2448
  className: cn("hsk-sp-backdrop", classNames.backdrop),
@@ -2046,65 +2453,65 @@ Question: ${q}`;
2046
2453
  background: bg ?? void 0,
2047
2454
  ...customStyles
2048
2455
  },
2049
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: cn("hsk-sp-card hsk-sp-fullscreen", classNames.card), onClick: (e) => e.stopPropagation(), children: [
2050
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-header", children: [
2051
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparkleIcon3, {}) }),
2052
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-header-body", children: [
2053
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
2054
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-header-sub", children: "Ask questions, compare specs, or check similar products" })
2456
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cn("hsk-sp-card hsk-sp-fullscreen", classNames.card), onClick: (e) => e.stopPropagation(), children: [
2457
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-header", children: [
2458
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SparkleIcon3, {}) }),
2459
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-header-body", children: [
2460
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
2461
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-header-sub", children: "Ask questions, compare specs, or check similar products" })
2055
2462
  ] }),
2056
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CloseIcon2, {}) })
2463
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseIcon2, {}) })
2057
2464
  ] }),
2058
- searchLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-bar" }),
2059
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-body", children: [
2060
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-details-pane", children: [
2061
- displayProduct && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-product-profile-container", children: [
2062
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-product-profile", children: [
2063
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-details-imgwrap", children: displayProduct.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\u{1F6CD}" }) }),
2064
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-details-meta", children: [
2065
- displayProduct.brand && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-item-brand", children: displayProduct.brand }),
2066
- displayProduct.category && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-item-cat", children: displayProduct.category }),
2067
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { className: "hsk-sp-details-name", children: displayProduct.name }),
2068
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-item-price-row", children: [
2069
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-item-currency", children: displayProduct.currency ?? "KES" }),
2070
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-item-price", children: parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
2071
- displayProduct.originalPrice && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-item-original-price", children: parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
2072
- displayProduct.discount && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "hsk-sp-item-discount", children: [
2465
+ searchLoading && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-bar" }),
2466
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-body", children: [
2467
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-details-pane", children: [
2468
+ displayProduct && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-product-profile-container", children: [
2469
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-product-profile", children: [
2470
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-details-imgwrap", children: displayProduct.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\u{1F6CD}" }) }),
2471
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-details-meta", children: [
2472
+ displayProduct.brand && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-brand", children: displayProduct.brand }),
2473
+ displayProduct.category && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-cat", children: displayProduct.category }),
2474
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { className: "hsk-sp-details-name", children: displayProduct.name }),
2475
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-item-price-row", children: [
2476
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-currency", children: displayProduct.currency ?? "KES" }),
2477
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-price", children: parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
2478
+ displayProduct.originalPrice && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-original-price", children: parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
2479
+ displayProduct.discount && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "hsk-sp-item-discount", children: [
2073
2480
  "(",
2074
2481
  displayProduct.discount,
2075
2482
  ")"
2076
2483
  ] })
2077
2484
  ] }),
2078
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-item-meta-badges", children: [
2079
- displayProduct.rating && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-rating", children: [
2485
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-item-meta-badges", children: [
2486
+ displayProduct.rating && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-rating", children: [
2080
2487
  "\u2605 ",
2081
2488
  parseFloat(displayProduct.rating.toString()).toFixed(1),
2082
2489
  " ",
2083
2490
  displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ""
2084
2491
  ] }),
2085
- displayProduct.availability && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: `hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes("in") ? "in-stock" : "out-stock"}`, children: displayProduct.availability }),
2086
- displayProduct.stock && !displayProduct.availability && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-stock", children: [
2492
+ displayProduct.availability && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: `hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes("in") ? "in-stock" : "out-stock"}`, children: displayProduct.availability }),
2493
+ displayProduct.stock && !displayProduct.availability && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-stock", children: [
2087
2494
  "Stock: ",
2088
2495
  displayProduct.stock
2089
2496
  ] })
2090
2497
  ] })
2091
2498
  ] })
2092
2499
  ] }),
2093
- displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-specs-horizontal", children: Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-spec-item-horizontal", children: [
2094
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "hsk-sp-spec-label-horizontal", children: [
2500
+ displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-specs-horizontal", children: Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-spec-item-horizontal", children: [
2501
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "hsk-sp-spec-label-horizontal", children: [
2095
2502
  key,
2096
2503
  ":"
2097
2504
  ] }),
2098
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-spec-value-horizontal", title: val, children: val })
2505
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-spec-value-horizontal", title: val, children: val })
2099
2506
  ] }, key)) }),
2100
- displayProduct.description && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-details-desc", children: [
2101
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h4", { children: "Description" }),
2102
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: displayProduct.description })
2507
+ displayProduct.description && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-details-desc", children: [
2508
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { children: "Description" }),
2509
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: displayProduct.description })
2103
2510
  ] })
2104
2511
  ] }),
2105
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-similar-section", children: [
2106
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: "Similar Products" }),
2107
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-results", children: (() => {
2512
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-similar-section", children: [
2513
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Similar Products" }),
2514
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-results", children: (() => {
2108
2515
  const similarProducts = results.filter(
2109
2516
  (r) => {
2110
2517
  const isSameName = r.product.name.toLowerCase() === displayProduct?.name?.toLowerCase();
@@ -2113,29 +2520,29 @@ Question: ${q}`;
2113
2520
  }
2114
2521
  );
2115
2522
  if (!searchLoading && similarProducts.length === 0) {
2116
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-empty", children: "No similar products found." });
2523
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-empty", children: "No similar products found." });
2117
2524
  }
2118
2525
  return similarProducts.map((r, i) => {
2119
2526
  const price = parseFloat(r.product.price?.replace(/[^0-9.]/g, "") || "0");
2120
2527
  const currency = r.product.currency ?? "KES";
2121
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2528
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2122
2529
  "div",
2123
2530
  {
2124
2531
  className: cn("hsk-sp-item", classNames.item),
2125
2532
  style: { animationDelay: `${i * 55}ms`, cursor: "pointer" },
2126
2533
  onClick: () => handleNav(r),
2127
2534
  children: [
2128
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-img-wrap", children: r.product.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: r.product.images[0], alt: r.product.name }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\u{1F6CD}" }) }),
2129
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-item-body", children: [
2130
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
2131
- r.product.category && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-item-cat", children: r.product.category }),
2132
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-item-name", title: r.product.name, children: r.product.name })
2535
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-img-wrap", children: r.product.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: r.product.images[0], alt: r.product.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\u{1F6CD}" }) }),
2536
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-item-body", children: [
2537
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
2538
+ r.product.category && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-item-cat", children: r.product.category }),
2539
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-item-name", title: r.product.name, children: r.product.name })
2133
2540
  ] }),
2134
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-item-price-row", children: [
2135
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-item-currency", children: currency }),
2136
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-item-price", children: price.toLocaleString() })
2541
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-item-price-row", children: [
2542
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-currency", children: currency }),
2543
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-price", children: price.toLocaleString() })
2137
2544
  ] }),
2138
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-actions", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2545
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-actions", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2139
2546
  "button",
2140
2547
  {
2141
2548
  className: "hsk-sp-action hsk-sp-action-primary",
@@ -2155,29 +2562,29 @@ Question: ${q}`;
2155
2562
  })() })
2156
2563
  ] })
2157
2564
  ] }),
2158
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-sp-chat-pane", children: [
2159
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-msgs", children: [
2565
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-chat-pane", children: [
2566
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-msgs", children: [
2160
2567
  displayMessages.map((msg, idx) => {
2161
2568
  const isUser = msg.role === "user";
2162
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
2163
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparkleIcon3, {}) }),
2164
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }) })
2569
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
2570
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SparkleIcon3, {}) }),
2571
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }) })
2165
2572
  ] }) }, idx);
2166
2573
  }),
2167
- chatLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-typing-row", children: [
2168
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparkleIcon3, {}) }),
2169
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-typing", children: [
2170
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-dot" }),
2171
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-dot" }),
2172
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-dot" })
2574
+ chatLoading && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-typing-row", children: [
2575
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SparkleIcon3, {}) }),
2576
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-typing", children: [
2577
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-dot" }),
2578
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-dot" }),
2579
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-dot" })
2173
2580
  ] })
2174
2581
  ] }),
2175
- chatError && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
2176
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: chatBottomRef, style: { height: 1 } })
2582
+ chatError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
2583
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: chatBottomRef, style: { height: 1 } })
2177
2584
  ] }),
2178
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-input-wrap", children: [
2179
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-input-box", children: [
2180
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2585
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-input-wrap", children: [
2586
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-cb-input-box", children: [
2587
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2181
2588
  "textarea",
2182
2589
  {
2183
2590
  ref: chatTextareaRef,
@@ -2190,22 +2597,22 @@ Question: ${q}`;
2190
2597
  disabled: chatLoading
2191
2598
  }
2192
2599
  ),
2193
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2600
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2194
2601
  "button",
2195
2602
  {
2196
2603
  className: "hsk-cb-send",
2197
2604
  onClick: () => handleSend(),
2198
2605
  disabled: !chatInput.trim() || chatLoading,
2199
2606
  "aria-label": "Send message",
2200
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArrowUpIcon3, {})
2607
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ArrowUpIcon3, {})
2201
2608
  }
2202
2609
  )
2203
2610
  ] }),
2204
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-hint", children: "Akropolys \xB7 instant product knowledge" })
2611
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-hint", children: "Akropolys \xB7 instant product knowledge" })
2205
2612
  ] })
2206
2613
  ] })
2207
2614
  ] }),
2208
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-sp-footer", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hsk-sp-esc", children: "Esc to close" }) })
2615
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-footer", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-esc", children: "Esc to close" }) })
2209
2616
  ] })
2210
2617
  }
2211
2618
  );
@@ -2223,9 +2630,9 @@ function Sparkle({
2223
2630
  product,
2224
2631
  children
2225
2632
  }) {
2226
- const [open, setOpen] = (0, import_react4.useState)(false);
2227
- const [mounted, setMounted] = (0, import_react4.useState)(false);
2228
- (0, import_react4.useEffect)(() => {
2633
+ const [open, setOpen] = (0, import_react6.useState)(false);
2634
+ const [mounted, setMounted] = (0, import_react6.useState)(false);
2635
+ (0, import_react6.useEffect)(() => {
2229
2636
  setMounted(true);
2230
2637
  }, []);
2231
2638
  const customStyles = {
@@ -2235,8 +2642,8 @@ function Sparkle({
2235
2642
  ...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
2236
2643
  ...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
2237
2644
  };
2238
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2239
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2645
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2646
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2240
2647
  "button",
2241
2648
  {
2242
2649
  className: cn("hsk-sp-btn", classNames.button, className),
@@ -2244,11 +2651,11 @@ function Sparkle({
2244
2651
  style: customStyles,
2245
2652
  title: "Find similar products",
2246
2653
  "aria-label": "Find similar products",
2247
- children: children || /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparkleIcon3, {})
2654
+ children: children || /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SparkleIcon3, {})
2248
2655
  }
2249
2656
  ),
2250
2657
  open && mounted && (0, import_react_dom2.createPortal)(
2251
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2658
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2252
2659
  SparkleModal,
2253
2660
  {
2254
2661
  productName,
@@ -2269,62 +2676,62 @@ function Sparkle({
2269
2676
  }
2270
2677
 
2271
2678
  // src/components/CartBadge.tsx
2272
- var import_sdk7 = require("@akropolys/sdk");
2273
- var import_jsx_runtime7 = require("react/jsx-runtime");
2679
+ var import_sdk8 = require("@akropolys/sdk");
2680
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2274
2681
  function CartBadge({ className }) {
2275
- const { cart } = (0, import_sdk7.useCart)();
2682
+ const { cart } = (0, import_sdk8.useCart)();
2276
2683
  if (!cart || cart.item_count === 0) return null;
2277
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: cn("hsk-cart-badge", className), children: cart.item_count });
2684
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: cn("hsk-cart-badge", className), children: cart.item_count });
2278
2685
  }
2279
2686
 
2280
2687
  // src/components/CartDrawer.tsx
2281
- var import_react6 = require("react");
2688
+ var import_react8 = require("react");
2282
2689
  var import_react_dom4 = require("react-dom");
2283
- var import_sdk9 = require("@akropolys/sdk");
2690
+ var import_sdk10 = require("@akropolys/sdk");
2284
2691
 
2285
2692
  // src/components/CheckoutModal.tsx
2286
- var import_react5 = require("react");
2693
+ var import_react7 = require("react");
2287
2694
  var import_react_dom3 = require("react-dom");
2288
- var import_sdk8 = require("@akropolys/sdk");
2289
- var import_jsx_runtime8 = require("react/jsx-runtime");
2695
+ var import_sdk9 = require("@akropolys/sdk");
2696
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2290
2697
  function CheckoutModal({
2291
2698
  onClose,
2292
2699
  theme,
2293
2700
  customStyles,
2294
2701
  hskThemeAttr
2295
2702
  }) {
2296
- const { cart, loading: cartLoading } = (0, import_sdk8.useCart)();
2297
- const client = (0, import_sdk8.useAkropolysContext)();
2298
- const [config, setConfig] = (0, import_react5.useState)(null);
2299
- const [loadingConfig, setLoadingConfig] = (0, import_react5.useState)(true);
2300
- const [phone, setPhone] = (0, import_react5.useState)(() => {
2703
+ const { cart, loading: cartLoading } = (0, import_sdk9.useCart)();
2704
+ const client = (0, import_sdk9.useAkropolysContext)();
2705
+ const [config, setConfig] = (0, import_react7.useState)(null);
2706
+ const [loadingConfig, setLoadingConfig] = (0, import_react7.useState)(true);
2707
+ const [phone, setPhone] = (0, import_react7.useState)(() => {
2301
2708
  if (typeof window !== "undefined") {
2302
2709
  return localStorage.getItem("akropolys_user_phone") || "";
2303
2710
  }
2304
2711
  return "";
2305
2712
  });
2306
- const [email, setEmail] = (0, import_react5.useState)(() => {
2713
+ const [email, setEmail] = (0, import_react7.useState)(() => {
2307
2714
  if (typeof window !== "undefined") {
2308
2715
  return localStorage.getItem("akropolys_user_email") || "";
2309
2716
  }
2310
2717
  return "";
2311
2718
  });
2312
- const [firstName, setFirstName] = (0, import_react5.useState)(() => {
2719
+ const [firstName, setFirstName] = (0, import_react7.useState)(() => {
2313
2720
  if (typeof window !== "undefined") {
2314
2721
  return localStorage.getItem("akropolys_user_firstname") || "";
2315
2722
  }
2316
2723
  return "";
2317
2724
  });
2318
- const [lastName, setLastName] = (0, import_react5.useState)(() => {
2725
+ const [lastName, setLastName] = (0, import_react7.useState)(() => {
2319
2726
  if (typeof window !== "undefined") {
2320
2727
  return localStorage.getItem("akropolys_user_lastname") || "";
2321
2728
  }
2322
2729
  return "";
2323
2730
  });
2324
- const [phase, setPhase] = (0, import_react5.useState)("idle");
2325
- const [merchantRef, setMerchantRef] = (0, import_react5.useState)(null);
2326
- const [payError, setPayError] = (0, import_react5.useState)(null);
2327
- const {} = (0, import_sdk8.usePaymentPolling)({
2731
+ const [phase, setPhase] = (0, import_react7.useState)("idle");
2732
+ const [merchantRef, setMerchantRef] = (0, import_react7.useState)(null);
2733
+ const [payError, setPayError] = (0, import_react7.useState)(null);
2734
+ const {} = (0, import_sdk9.usePaymentPolling)({
2328
2735
  client: client.api,
2329
2736
  merchantReference: merchantRef,
2330
2737
  onSuccess: () => {
@@ -2337,7 +2744,7 @@ function CheckoutModal({
2337
2744
  setMerchantRef(null);
2338
2745
  }
2339
2746
  });
2340
- (0, import_react5.useEffect)(() => {
2747
+ (0, import_react7.useEffect)(() => {
2341
2748
  client.api.getCheckoutConfig().then((res) => setConfig(res.payment_methods)).catch(() => {
2342
2749
  }).finally(() => setLoadingConfig(false));
2343
2750
  }, [client]);
@@ -2372,20 +2779,20 @@ function CheckoutModal({
2372
2779
  const total = cart?.total || 0;
2373
2780
  const backdropStyle = { ...customStyles, fontSize: "15px", fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', zIndex: 999999 };
2374
2781
  return (0, import_react_dom3.createPortal)(
2375
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2782
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2376
2783
  "div",
2377
2784
  {
2378
2785
  className: "hsk-checkout-backdrop-full",
2379
2786
  style: backdropStyle,
2380
2787
  "data-hsk-theme": hskThemeAttr,
2381
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2788
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2382
2789
  "div",
2383
2790
  {
2384
2791
  className: "hsk-checkout-modal-full",
2385
2792
  style: customStyles,
2386
2793
  "data-hsk-theme": hskThemeAttr,
2387
2794
  children: [
2388
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2795
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2389
2796
  "button",
2390
2797
  {
2391
2798
  onClick: (e) => {
@@ -2395,71 +2802,71 @@ function CheckoutModal({
2395
2802
  },
2396
2803
  className: "hsk-checkout-close-x",
2397
2804
  "aria-label": "Close checkout",
2398
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2399
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2400
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2805
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2806
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2807
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2401
2808
  ] })
2402
2809
  }
2403
2810
  ),
2404
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-panel-left", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-left-content", children: [
2405
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { onClick: (e) => {
2811
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-panel-left", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-left-content", children: [
2812
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { onClick: (e) => {
2406
2813
  e.preventDefault();
2407
2814
  e.stopPropagation();
2408
2815
  onClose();
2409
2816
  }, className: "hsk-checkout-back-btn", children: [
2410
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2411
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
2412
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "12 19 5 12 12 5" })
2817
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2818
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
2819
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("polyline", { points: "12 19 5 12 12 5" })
2413
2820
  ] }),
2414
2821
  "Back to store"
2415
2822
  ] }),
2416
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-store-info", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { children: "Secure Checkout" }) }),
2417
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-amount-due", children: [
2418
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-checkout-label-muted", children: "Pay total" }),
2419
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-grand-total", children: [
2823
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-store-info", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { children: "Secure Checkout" }) }),
2824
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-amount-due", children: [
2825
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-checkout-label-muted", children: "Pay total" }),
2826
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-grand-total", children: [
2420
2827
  currency,
2421
2828
  " ",
2422
2829
  total.toLocaleString(void 0, { minimumFractionDigits: 2 })
2423
2830
  ] })
2424
2831
  ] }),
2425
- cartLoading || !cart ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-cart-loading", children: "Loading order..." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-items-list-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { className: "hsk-checkout-items-list", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("li", { className: "hsk-checkout-item-row", children: [
2426
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-item-img-container", children: [
2427
- item.image ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: item.image, alt: item.name, className: "hsk-checkout-item-img" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-item-img-placeholder", children: "\u{1F6D2}" }),
2428
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-checkout-item-qty-badge", children: item.quantity })
2832
+ cartLoading || !cart ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "hsk-cart-loading", children: "Loading order..." }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-items-list-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "hsk-checkout-items-list", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { className: "hsk-checkout-item-row", children: [
2833
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-item-img-container", children: [
2834
+ item.image ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("img", { src: item.image, alt: item.name, className: "hsk-checkout-item-img" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-item-img-placeholder", children: "\u{1F6D2}" }),
2835
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-checkout-item-qty-badge", children: item.quantity })
2429
2836
  ] }),
2430
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-item-details", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-checkout-item-name", children: item.name }) }),
2431
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "hsk-checkout-item-price", children: [
2837
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-item-details", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-checkout-item-name", children: item.name }) }),
2838
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "hsk-checkout-item-price", children: [
2432
2839
  item.currency,
2433
2840
  " ",
2434
2841
  (item.price_numeric * item.quantity).toLocaleString(void 0, { minimumFractionDigits: 2 })
2435
2842
  ] })
2436
2843
  ] }, item.id)) }) })
2437
2844
  ] }) }),
2438
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-panel-right", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-right-content", children: phase === "done" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-card success", children: [
2439
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-icon-wrap success", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2440
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
2441
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "22 4 12 14.01 9 11.01" })
2845
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-panel-right", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-right-content", children: phase === "done" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-card success", children: [
2846
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-icon-wrap success", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2847
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
2848
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("polyline", { points: "22 4 12 14.01 9 11.01" })
2442
2849
  ] }) }),
2443
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Payment Successful!" }),
2444
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "Your transaction has been confirmed. Thank you for your order!" }),
2445
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: onClose, className: "hsk-pay-btn hsk-btn-primary", style: { marginTop: "1.5rem" }, children: "Continue Shopping" })
2446
- ] }) : phase === "awaiting" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-card awaiting", children: [
2447
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-spinner-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-spinner" }) }),
2448
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Confirm payment on your phone" }),
2449
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { children: [
2850
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Payment Successful!" }),
2851
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "Your transaction has been confirmed. Thank you for your order!" }),
2852
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: onClose, className: "hsk-pay-btn hsk-btn-primary", style: { marginTop: "1.5rem" }, children: "Continue Shopping" })
2853
+ ] }) : phase === "awaiting" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-card awaiting", children: [
2854
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-spinner-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-spinner" }) }),
2855
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Confirm payment on your phone" }),
2856
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { children: [
2450
2857
  "We've sent an M-Pesa STK push prompt to ",
2451
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("strong", { children: [
2858
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("strong", { children: [
2452
2859
  "254",
2453
2860
  phone
2454
2861
  ] }),
2455
2862
  "."
2456
2863
  ] }),
2457
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-stk-instructions", children: [
2458
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "1. Check your phone lockscreen for the M-Pesa prompt." }),
2459
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "2. Enter your M-Pesa PIN and press OK." }),
2460
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "3. Wait here \u2014 this page auto-updates once confirmed." })
2864
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-stk-instructions", children: [
2865
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "1. Check your phone lockscreen for the M-Pesa prompt." }),
2866
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "2. Enter your M-Pesa PIN and press OK." }),
2867
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "3. Wait here \u2014 this page auto-updates once confirmed." })
2461
2868
  ] }),
2462
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2869
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2463
2870
  "button",
2464
2871
  {
2465
2872
  onClick: () => {
@@ -2470,43 +2877,43 @@ function CheckoutModal({
2470
2877
  children: "Cancel payment"
2471
2878
  }
2472
2879
  )
2473
- ] }) : phase === "cancelled" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-card cancelled", children: [
2474
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-icon-wrap cancelled", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2475
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "m15 9-6 6M9 9l6 6" }),
2476
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "12", cy: "12", r: "10" })
2880
+ ] }) : phase === "cancelled" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-card cancelled", children: [
2881
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-icon-wrap cancelled", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2882
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m15 9-6 6M9 9l6 6" }),
2883
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" })
2477
2884
  ] }) }),
2478
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Payment Cancelled" }),
2479
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "No charge was made. You can update your phone number and try again whenever you're ready." }),
2480
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-actions", children: [
2481
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: () => {
2885
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Payment Cancelled" }),
2886
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "No charge was made. You can update your phone number and try again whenever you're ready." }),
2887
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-actions", children: [
2888
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: () => {
2482
2889
  setPhase("idle");
2483
2890
  setPayError(null);
2484
2891
  }, className: "hsk-pay-btn hsk-btn-primary", children: "Try again" }),
2485
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: onClose, className: "hsk-checkout-cancel-btn", children: "Back to cart" })
2892
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: onClose, className: "hsk-checkout-cancel-btn", children: "Back to cart" })
2486
2893
  ] })
2487
- ] }) : phase === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-card failed", children: [
2488
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-icon-wrap failed", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2489
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2490
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
2491
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
2894
+ ] }) : phase === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-card failed", children: [
2895
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-icon-wrap failed", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2896
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2897
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
2898
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
2492
2899
  ] }) }),
2493
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Payment Failed" }),
2494
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-checkout-error-text", children: payError || "Could not verify M-Pesa transaction. Please check your phone and try again." }),
2495
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-actions", children: [
2496
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: () => {
2900
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Payment Failed" }),
2901
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "hsk-checkout-error-text", children: payError || "Could not verify M-Pesa transaction. Please check your phone and try again." }),
2902
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-actions", children: [
2903
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: () => {
2497
2904
  setPhase("idle");
2498
2905
  setPayError(null);
2499
2906
  }, className: "hsk-pay-btn hsk-btn-primary", children: "Try again" }),
2500
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: onClose, className: "hsk-checkout-cancel-btn", children: "Back to cart" })
2907
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: onClose, className: "hsk-checkout-cancel-btn", children: "Back to cart" })
2501
2908
  ] })
2502
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-payment-form-wrap", children: [
2503
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "hsk-checkout-section-title", children: "Payment details" }),
2504
- loadingConfig ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-cart-loading", children: "Loading payment configuration..." }) : !hasPaymentMethods ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-checkout-error", children: "No payment methods configured for this store." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: handlePay, className: "hsk-stripe-checkout-form", children: [
2505
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-group", children: [
2506
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "hsk-form-label", children: "M-Pesa Mobile Number" }),
2507
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-phone-input-container", children: [
2508
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-phone-prefix", children: "254" }),
2509
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2909
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-payment-form-wrap", children: [
2910
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "hsk-checkout-section-title", children: "Payment details" }),
2911
+ loadingConfig ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "hsk-cart-loading", children: "Loading payment configuration..." }) : !hasPaymentMethods ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "hsk-checkout-error", children: "No payment methods configured for this store." }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: handlePay, className: "hsk-stripe-checkout-form", children: [
2912
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-group", children: [
2913
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "hsk-form-label", children: "M-Pesa Mobile Number" }),
2914
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-phone-input-container", children: [
2915
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-phone-prefix", children: "254" }),
2916
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2510
2917
  "input",
2511
2918
  {
2512
2919
  type: "tel",
@@ -2520,11 +2927,11 @@ function CheckoutModal({
2520
2927
  }
2521
2928
  )
2522
2929
  ] }),
2523
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-form-hint", children: "Enter your 9-digit number (e.g. 712345678)" })
2930
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-form-hint", children: "Enter your 9-digit number (e.g. 712345678)" })
2524
2931
  ] }),
2525
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-group", children: [
2526
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "hsk-form-label", children: "Email address" }),
2527
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2932
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-group", children: [
2933
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "hsk-form-label", children: "Email address" }),
2934
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2528
2935
  "input",
2529
2936
  {
2530
2937
  type: "email",
@@ -2535,10 +2942,10 @@ function CheckoutModal({
2535
2942
  }
2536
2943
  )
2537
2944
  ] }),
2538
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-row", children: [
2539
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-group", children: [
2540
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "hsk-form-label", children: "First Name" }),
2541
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2945
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-row", children: [
2946
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-group", children: [
2947
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "hsk-form-label", children: "First Name" }),
2948
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2542
2949
  "input",
2543
2950
  {
2544
2951
  type: "text",
@@ -2549,9 +2956,9 @@ function CheckoutModal({
2549
2956
  }
2550
2957
  )
2551
2958
  ] }),
2552
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-group", children: [
2553
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "hsk-form-label", children: "Last Name" }),
2554
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2959
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-group", children: [
2960
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "hsk-form-label", children: "Last Name" }),
2961
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2555
2962
  "input",
2556
2963
  {
2557
2964
  type: "text",
@@ -2563,14 +2970,14 @@ function CheckoutModal({
2563
2970
  )
2564
2971
  ] })
2565
2972
  ] }),
2566
- payError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-form-error-banner", children: payError }),
2567
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "submit", className: "hsk-checkout-submit-btn", children: [
2973
+ payError && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-form-error-banner", children: payError }),
2974
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "submit", className: "hsk-checkout-submit-btn", children: [
2568
2975
  "Pay ",
2569
2976
  currency,
2570
2977
  " ",
2571
2978
  total.toLocaleString()
2572
2979
  ] }),
2573
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-footer-brand", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Powered by Akropolys" }) })
2980
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-footer-brand", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Powered by Akropolys" }) })
2574
2981
  ] })
2575
2982
  ] }) }) })
2576
2983
  ]
@@ -2583,18 +2990,18 @@ function CheckoutModal({
2583
2990
  }
2584
2991
 
2585
2992
  // src/components/CartDrawer.tsx
2586
- var import_jsx_runtime9 = require("react/jsx-runtime");
2993
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2587
2994
  function CartDrawer({
2588
2995
  trigger,
2589
2996
  className,
2590
2997
  theme
2591
2998
  }) {
2592
- const { cart, loading } = (0, import_sdk9.useCart)();
2593
- const [open, setOpen] = (0, import_react6.useState)(false);
2594
- const [showCheckout, setShowCheckout] = (0, import_react6.useState)(false);
2595
- const [mounted, setMounted] = (0, import_react6.useState)(false);
2596
- const client = (0, import_sdk9.useAkropolysContext)();
2597
- (0, import_react6.useEffect)(() => {
2999
+ const { cart, loading } = (0, import_sdk10.useCart)();
3000
+ const [open, setOpen] = (0, import_react8.useState)(false);
3001
+ const [showCheckout, setShowCheckout] = (0, import_react8.useState)(false);
3002
+ const [mounted, setMounted] = (0, import_react8.useState)(false);
3003
+ const client = (0, import_sdk10.useAkropolysContext)();
3004
+ (0, import_react8.useEffect)(() => {
2598
3005
  setMounted(true);
2599
3006
  const handleTriggerCheckout = () => {
2600
3007
  setShowCheckout(true);
@@ -2605,7 +3012,7 @@ function CartDrawer({
2605
3012
  window.removeEventListener("akropolys:trigger_checkout", handleTriggerCheckout);
2606
3013
  };
2607
3014
  }, []);
2608
- (0, import_react6.useEffect)(() => {
3015
+ (0, import_react8.useEffect)(() => {
2609
3016
  if (open) {
2610
3017
  document.body.style.overflow = "hidden";
2611
3018
  } else {
@@ -2634,8 +3041,8 @@ function CartDrawer({
2634
3041
  ...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
2635
3042
  ...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
2636
3043
  } : void 0;
2637
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2638
- trigger ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { onClick: () => setOpen(true), style: { display: "inline-block" }, children: trigger }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3044
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3045
+ trigger ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { onClick: () => setOpen(true), style: { display: "inline-block" }, children: trigger }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2639
3046
  "button",
2640
3047
  {
2641
3048
  onClick: () => setOpen(true),
@@ -2644,24 +3051,24 @@ function CartDrawer({
2644
3051
  "data-hsk-theme": hskThemeAttr,
2645
3052
  "aria-label": "Open cart",
2646
3053
  children: [
2647
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2648
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "9", cy: "21", r: "1" }),
2649
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "20", cy: "21", r: "1" }),
2650
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6" })
3054
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3055
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "9", cy: "21", r: "1" }),
3056
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "20", cy: "21", r: "1" }),
3057
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6" })
2651
3058
  ] }),
2652
- cart && cart.item_count > 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "hsk-cart-trigger-badge", children: cart.item_count }) : null
3059
+ cart && cart.item_count > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "hsk-cart-trigger-badge", children: cart.item_count }) : null
2653
3060
  ]
2654
3061
  }
2655
3062
  ),
2656
3063
  open && mounted && (0, import_react_dom4.createPortal)(
2657
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3064
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2658
3065
  "div",
2659
3066
  {
2660
3067
  className: "hsk-cart-backdrop",
2661
3068
  style: customStyles,
2662
3069
  "data-hsk-theme": hskThemeAttr,
2663
3070
  onClick: () => setOpen(false),
2664
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3071
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2665
3072
  "div",
2666
3073
  {
2667
3074
  className: "hsk-cart-bottom-sheet",
@@ -2669,36 +3076,36 @@ function CartDrawer({
2669
3076
  "data-hsk-theme": hskThemeAttr,
2670
3077
  onClick: (e) => e.stopPropagation(),
2671
3078
  children: [
2672
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "hsk-cart-sheet-handle" }),
2673
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "hsk-cart-sheet-header", children: [
2674
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { children: "Your Cart" }),
2675
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { onClick: () => setOpen(false), className: "hsk-close-btn", children: "\xD7" })
3079
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hsk-cart-sheet-handle" }),
3080
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-sheet-header", children: [
3081
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { children: "Your Cart" }),
3082
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: () => setOpen(false), className: "hsk-close-btn", children: "\xD7" })
2676
3083
  ] }),
2677
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "hsk-cart-sheet-content", children: loading && !cart ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "hsk-cart-loading", children: "Loading cart..." }) : !cart || cart.items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "hsk-cart-empty", children: "Your cart is empty." }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "hsk-cart-items", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("li", { className: "hsk-cart-item", children: [
2678
- item.image && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: item.image, alt: item.name, className: "hsk-cart-item-img" }),
2679
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "hsk-cart-item-info", children: [
2680
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "hsk-cart-item-name", children: item.name }),
2681
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "hsk-cart-item-price", children: [
3084
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hsk-cart-sheet-content", children: loading && !cart ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hsk-cart-loading", children: "Loading cart..." }) : !cart || cart.items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hsk-cart-empty", children: "Your cart is empty." }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "hsk-cart-items", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { className: "hsk-cart-item", children: [
3085
+ item.image && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("img", { src: item.image, alt: item.name, className: "hsk-cart-item-img" }),
3086
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-item-info", children: [
3087
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "hsk-cart-item-name", children: item.name }),
3088
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "hsk-cart-item-price", children: [
2682
3089
  item.currency,
2683
3090
  " ",
2684
3091
  item.price_numeric.toLocaleString(void 0, { minimumFractionDigits: 2 })
2685
3092
  ] })
2686
3093
  ] }),
2687
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "hsk-cart-item-qty", children: [
3094
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-item-qty", children: [
2688
3095
  "x",
2689
3096
  item.quantity
2690
3097
  ] })
2691
3098
  ] }, item.id)) }) }),
2692
- cart && cart.items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "hsk-cart-sheet-footer", children: [
2693
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "hsk-cart-total", children: [
2694
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Total" }),
2695
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
3099
+ cart && cart.items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-sheet-footer", children: [
3100
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-total", children: [
3101
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Total" }),
3102
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
2696
3103
  cart.currency,
2697
3104
  " ",
2698
3105
  cart.total.toLocaleString(void 0, { minimumFractionDigits: 2 })
2699
3106
  ] })
2700
3107
  ] }),
2701
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { onClick: handleCheckout, className: "hsk-checkout-btn", children: "Checkout securely" })
3108
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: handleCheckout, className: "hsk-checkout-btn", children: "Checkout securely" })
2702
3109
  ] })
2703
3110
  ]
2704
3111
  }
@@ -2707,7 +3114,7 @@ function CartDrawer({
2707
3114
  ),
2708
3115
  document.body
2709
3116
  ),
2710
- showCheckout && mounted && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3117
+ showCheckout && mounted && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2711
3118
  CheckoutModal,
2712
3119
  {
2713
3120
  onClose: () => {
@@ -2731,6 +3138,8 @@ function CartDrawer({
2731
3138
  KikuButton,
2732
3139
  KikuChat,
2733
3140
  SearchBar,
2734
- Sparkle
3141
+ Sparkle,
3142
+ VisualSearch,
3143
+ VoiceButton
2735
3144
  });
2736
3145
  //# sourceMappingURL=index.js.map