@akropolys/kiku 1.7.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +103 -176
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +103 -176
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +230 -294
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/SearchBar.tsx","../src/utils/cn.ts","../src/components/ChatWidget.tsx","../src/utils/markdown.tsx","../src/components/VoiceButton.tsx","../src/components/VisualSearch.tsx","../src/components/KikuButton.tsx","../src/components/ComparisonMatrix.tsx","../src/components/Sparkle.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport { useSearch, SearchResult, AkropolysTheme, useAkropolysContext } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\n\nexport interface SearchBarProps {\n placeholder?: string;\n limit?: number;\n /** Debounce in ms — default 150 for instant type-ahead */\n debounceMs?: number;\n onSelect?: (result: SearchResult) => void;\n className?: string;\n inputClassName?: string;\n dropdownClassName?: string;\n renderResult?: (result: SearchResult) => React.ReactNode;\n theme?: AkropolysTheme;\n classNames?: {\n root?: string;\n input?: string;\n dropdown?: string;\n row?: string;\n };\n}\n\n/* SVG search glass — pure inline so no icon dependency */\nconst SearchIcon = () => (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\"/>\n <line x1=\"13\" y1=\"13\" x2=\"18\" y2=\"18\"/>\n </svg>\n);\n\nexport function SearchBar({\n placeholder = 'Search products…',\n limit = 10,\n debounceMs = 150,\n onSelect,\n className,\n inputClassName,\n dropdownClassName,\n renderResult,\n theme,\n classNames = {},\n}: SearchBarProps) {\n const [query, setQuery] = useState('');\n const [open, setOpen] = useState(false);\n const { results, loading, search, clear } = useSearch({ debounceMs });\n const client = useAkropolysContext();\n const wrap = useRef<HTMLDivElement>(null);\n const ignoreNextQueryChange = useRef(false);\n\n /* useSearch debounces internally — fire on every keystroke, keep stale results visible */\n useEffect(() => {\n if (ignoreNextQueryChange.current) {\n ignoreNextQueryChange.current = false;\n return;\n }\n if (!query.trim()) {\n clear();\n setOpen(false);\n return;\n }\n setOpen(true); // open immediately (stale results show while fetching)\n search(query, limit);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [query]);\n\n /* Click-outside to close */\n useEffect(() => {\n const h = (e: MouseEvent) => {\n if (wrap.current && !wrap.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', h);\n return () => document.removeEventListener('mousedown', h);\n }, []);\n\n const handleSelect = (r: SearchResult) => {\n if (query.trim()) {\n // keepalive: onSelect commonly navigates the page right after this call —\n // without it the browser aborts the in-flight log request mid-navigation.\n client.api.searchVector(query, 1, undefined, true).catch(() => {});\n }\n ignoreNextQueryChange.current = true;\n setOpen(false);\n setQuery(r.entity.title ?? r.entity.name ?? '');\n onSelect?.(r);\n };\n\n const handleCommitSearch = () => {\n if (!query.trim()) return;\n client.api.searchVector(query, 1, undefined, true).catch(() => {});\n if (results.length > 0) {\n handleSelect(results[0]);\n }\n };\n\n const showDrop = open && query.trim().length > 0;\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div className={cn(\"hsk-sb-wrap\", classNames.root, className)} ref={wrap} style={customStyles}>\n <span className=\"hsk-sb-icon\"><SearchIcon /></span>\n <input\n className={cn(\"hsk-sb-input\", classNames.input, inputClassName)}\n type=\"text\"\n value={query}\n placeholder={placeholder}\n onChange={e => setQuery(e.target.value)}\n onFocus={() => results.length > 0 && query.trim() && setOpen(true)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n handleCommitSearch();\n }\n }}\n autoComplete=\"off\"\n spellCheck={false}\n />\n {showDrop && (\n <div className={cn(\"hsk-sb-drop\", classNames.dropdown, dropdownClassName)} style={{ position: 'absolute' }}>\n {loading && <div className=\"hsk-sb-loading-bar\" />}\n\n {loading && results.length === 0 ? (\n <>\n <div className=\"hsk-sb-skeleton-row\">\n <span className=\"hsk-sb-skeleton-icon\" />\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-skeleton-text1\" />\n <div className=\"hsk-sb-skeleton-text2\" />\n </div>\n </div>\n <div className=\"hsk-sb-skeleton-row\">\n <span className=\"hsk-sb-skeleton-icon\" />\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-skeleton-text1\" style={{ width: '45%' }} />\n <div className=\"hsk-sb-skeleton-text2\" style={{ width: '25%' }} />\n </div>\n </div>\n </>\n ) : (\n <>\n {results.length === 0 && !loading && (\n <div className=\"hsk-sb-empty\">No results for “{query}”</div>\n )}\n\n {results.map((r, i) => {\n if (renderResult) {\n return (\n <div\n key={r.id}\n onClick={() => handleSelect(r)}\n className=\"hsk-sb-fade\"\n style={{ animationDelay: `${i * 18}ms` }}\n >\n {renderResult(r)}\n </div>\n );\n }\n const thumb = r.entity.image ?? r.entity.thumbnail ?? r.entity.images?.[0];\n return (\n <div\n key={r.id}\n className={cn(\"hsk-sb-row hsk-sb-fade\", classNames.row)}\n style={{ animationDelay: `${i * 18}ms` }}\n onClick={() => handleSelect(r)}\n >\n <span className=\"hsk-sb-row-thumb\">\n {thumb ? (\n <img\n src={thumb}\n alt=\"\"\n loading=\"lazy\"\n onError={e => { e.currentTarget.style.display = 'none'; }}\n />\n ) : (\n <SearchIcon />\n )}\n </span>\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-row-title\">{r.entity.title ?? r.entity.name}</div>\n {(r.entity.category || r.entity.brand) && (\n <div className=\"hsk-sb-row-sub\">\n {r.entity.category ?? r.entity.brand}\n </div>\n )}\n </div>\n </div>\n );\n })}\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merges Tailwind classes intelligently, allowing overrides.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import React, { useState, useRef, useEffect } from 'react';\nimport { useKiku, ChatMessage, ChatSource } from '@akropolys/sdk';\nimport { renderMarkdown } from '../utils/markdown';\nimport { AkropolysTheme } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\nimport { VoiceButton } from './VoiceButton';\nimport { VisualSearch } from './VisualSearch';\n\n// Better Prop Interface for SDKs\nexport interface ChatWidgetProps {\n title?: string;\n placeholder?: string;\n emptyStateText?: string;\n emptyStateSuggestions?: string;\n defaultCurrency?: string;\n className?: string;\n \n // Allow overriding styles via standard CSS variables\n theme?: AkropolysTheme;\n \n // Allow targeting specific elements with custom classes (e.g. Tailwind)\n classNames?: {\n root?: string;\n header?: string;\n messageBubble?: string;\n input?: string;\n };\n \n onSelectSource?: (source: ChatSource) => void;\n\n /** Enable 🎙️ voice input via browser Web Speech API (free) */\n enableVoice?: boolean;\n /** Enable 📷 visual style-match search via Gemini (requires backend GEMINI_API_KEY) */\n enableVision?: boolean;\n /** Optional category hint for visual search (e.g. 'dress', 'curtains') */\n visionCategoryHint?: string;\n}\n\n// Simple SVG Icons instead of text characters\nconst SparkleIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <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\"/>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\nfunction SourceCard({\n source,\n defaultCurrency,\n onSelect,\n isReferenced\n}: {\n source: ChatSource;\n defaultCurrency: string;\n onSelect?: (s: ChatSource) => void;\n isReferenced?: boolean;\n}) {\n return (\n <div\n className={cn(\"hsk-source-card\", isReferenced && \"hsk-source-card--referenced\")}\n onClick={() => onSelect?.(source)}\n >\n {source.image && <img src={source.image} alt={source.name} className=\"hsk-source-img\" />}\n <div style={{ flex: 1, minWidth: 0, position: 'relative' }}>\n {isReferenced && (\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\" style={{ top: '0', right: '0' }}>\n <SparkleIcon />\n </div>\n )}\n <div className=\"hsk-source-name\" style={{ paddingRight: isReferenced ? '20px' : undefined }}>{source.name}</div>\n {source.price && (\n <div className=\"hsk-source-price\">{source.currency ?? defaultCurrency} {source.price}</div>\n )}\n </div>\n </div>\n );\n}\n\ninterface ChatMessageWithVisual extends ChatMessage {\n imagePreview?: string;\n styleDNA?: any;\n visualSources?: ChatSource[];\n}\n\nexport function ChatWidget({ \n title = 'AI Shopping Assistant',\n placeholder = 'Ask about anything in our store…', \n emptyStateText = 'Ask me anything about our products',\n emptyStateSuggestions = '\"Find me headphones under KSh 5,000\" · \"Gift ideas\"',\n defaultCurrency = 'KES',\n className,\n theme,\n classNames = {},\n onSelectSource,\n enableVoice = false,\n enableVision = false,\n visionCategoryHint\n}: ChatWidgetProps) {\n const { messages, sources, referencedIds, loading: chatLoading, streaming, error, send, reset } = useKiku();\n const [input, setInput] = useState('');\n const [visualLoading, setVisualLoading] = useState(false);\n const bottomRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const loading = chatLoading || visualLoading;\n\n const [chatHistory, setChatHistory] = useState<ChatMessageWithVisual[]>([]);\n const lastSyncedCount = useRef(0);\n\n useEffect(() => {\n if (messages.length === 0) {\n setChatHistory([]);\n lastSyncedCount.current = 0;\n return;\n }\n\n if (messages.length > lastSyncedCount.current) {\n const newMsgs = messages.slice(lastSyncedCount.current);\n setChatHistory(prev => [...prev, ...newMsgs]);\n lastSyncedCount.current = messages.length;\n } else if (messages.length < lastSyncedCount.current) {\n setChatHistory(messages);\n lastSyncedCount.current = messages.length;\n } else {\n setChatHistory(prev => {\n const next = [...prev];\n let hookIdx = messages.length - 1;\n let historyIdx = next.length - 1;\n while (hookIdx >= 0 && historyIdx >= 0) {\n if (next[historyIdx].role === messages[hookIdx].role) {\n next[historyIdx] = {\n ...next[historyIdx],\n content: messages[hookIdx].content,\n actionType: messages[hookIdx].actionType,\n };\n break;\n }\n historyIdx--;\n }\n return next;\n });\n }\n }, [messages]);\n\n useEffect(() => {\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [chatHistory, loading]);\n\n const handleSend = async () => {\n const q = input.trim();\n if (!q || loading) return;\n setInput('');\n if (textareaRef.current) textareaRef.current.style.height = 'auto';\n await send(q);\n };\n\n const handleKey = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = Math.min(t.scrollHeight, 120) + 'px';\n };\n\n const handleVisualResults = (res: any, preview: string) => {\n const userMsg: ChatMessageWithVisual = {\n role: 'user',\n content: 'Uploaded a photo for visual search',\n imagePreview: preview,\n };\n\n const dna = res.style_dna;\n let content = `I've analyzed your image! Here is the Style DNA I found:\\n`;\n if (dna) {\n if (dna.color_palette) content += `* **Palette:** ${dna.color_palette}\\n`;\n if (dna.dominant_colors && dna.dominant_colors.length > 0) {\n content += `* **Colors:** ${dna.dominant_colors.join(', ')}\\n`;\n }\n if (dna.aesthetic && dna.aesthetic.length > 0) {\n content += `* **Aesthetic:** ${dna.aesthetic.join(', ')}\\n`;\n }\n if (dna.texture) content += `* **Texture:** ${dna.texture}\\n`;\n if (dna.formality) content += `* **Formality:** ${dna.formality}\\n`;\n }\n\n const results = res.results || [];\n if (results.length > 0) {\n content += `\\nI found ${results.length} matching products in the store for you.`;\n } else {\n content += `\\nI couldn't find any matching products in the store.`;\n }\n\n const assistantMsg: ChatMessageWithVisual = {\n role: 'assistant',\n content,\n styleDNA: dna,\n visualSources: results.map((r: any) => ({\n id: r.id,\n name: r.product.name,\n price: r.product.price,\n currency: r.product.currency,\n category: r.product.category,\n url: r.product.url,\n image: r.product.images && r.product.images.length > 0 ? r.product.images[0] : undefined,\n brand: r.product.brand,\n })),\n };\n\n setChatHistory(prev => [...prev, userMsg, assistantMsg]);\n };\n\n // Apply custom CSS variables inline to the root wrapper\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div \n className={cn(\"hsk-chat-widget\", classNames.root, className)} \n style={customStyles}\n >\n <div className={cn(\"hsk-chat-header\", classNames.header)}>\n <span className=\"hsk-chat-header-icon\"><SparkleIcon /></span>\n <span className=\"hsk-chat-title\">{title}</span>\n <span className=\"hsk-chat-badge\">AI</span>\n {chatHistory.length > 0 && (\n <button className=\"hsk-chat-reset\" onClick={reset} style={{ marginLeft: 'auto' }}>Clear</button>\n )}\n </div>\n\n <div className=\"hsk-chat-messages\">\n {chatHistory.length === 0 ? (\n <div className=\"hsk-chat-empty\">\n <div className=\"hsk-chat-empty-icon\"><SparkleIcon /></div>\n <div>{emptyStateText}</div>\n <div className=\"hsk-chat-empty-suggestions\">{emptyStateSuggestions}</div>\n </div>\n ) : (\n chatHistory.map((msg, idx) => (\n <div key={idx}>\n <div className={`hsk-msg-row ${msg.role}`}>\n <div className={cn(\"hsk-msg-avatar\", msg.role === 'assistant' ? 'ai' : 'user')}>\n {msg.role === 'assistant' ? <SparkleIcon /> : 'U'}\n </div>\n <div className={cn(\"hsk-msg-bubble\", msg.role, classNames.messageBubble)}>\n {msg.imagePreview && (\n <div className=\"kiku-vs-preview-bubble\" style={{ marginBottom: '8px' }}>\n <img src={msg.imagePreview} alt=\"Uploaded Preview\" className=\"kiku-vs-preview-bubble-img\" style={{ maxWidth: '200px', borderRadius: '8px' }} />\n </div>\n )}\n {renderMarkdown(msg.content)}\n {msg.styleDNA && (\n <div className=\"kiku-vs-preview-banner\" style={{ marginTop: '10px' }}>\n {chatHistory[idx - 1]?.imagePreview && (\n <img src={chatHistory[idx - 1].imagePreview} alt=\"Visual Search Input\" className=\"kiku-vs-preview-img\" />\n )}\n <div className=\"kiku-vs-preview-info\">\n <div className=\"kiku-vs-preview-label\">Visual Match Palette</div>\n <div className=\"kiku-vs-preview-palette\">{msg.styleDNA.color_palette || 'Detected Style DNA'}</div>\n {msg.styleDNA.style_tags && msg.styleDNA.style_tags.length > 0 && (\n <div className=\"kiku-style-tags\">\n {msg.styleDNA.style_tags.map((tag: string, ti: number) => (\n <span key={ti} className=\"kiku-style-tag\">#{tag}</span>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n {msg.role === 'assistant' && msg.visualSources && msg.visualSources.length > 0 && (\n <div className=\"hsk-sources-container\">\n <div className=\"hsk-sources\">\n {msg.visualSources.map((src, si) => (\n <SourceCard key={si} source={src} defaultCurrency={defaultCurrency} onSelect={onSelectSource} />\n ))}\n </div>\n </div>\n )}\n {msg.role === 'assistant' && idx === chatHistory.length - 1 && !msg.visualSources && sources.length > 0 && (() => {\n const isStreamingActive = chatLoading || streaming;\n if (isStreamingActive) {\n return (\n <div className=\"hsk-sources-container\">\n <div className=\"hsk-sources\">\n {sources.map((src, si) => {\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\n return (\n <SourceCard\n key={si}\n source={src}\n defaultCurrency={defaultCurrency}\n onSelect={onSelectSource}\n isReferenced={isReferenced}\n />\n );\n })}\n </div>\n </div>\n );\n }\n\n // Streaming finished: show the products the answer actually\n // references. Only fall back to the full candidate list when the\n // answer referenced none — showing unrelated matches (a kids'\n // sandal for a \"heels to match my dress\" query) reads as a bug.\n const featured = sources.filter(src => src.id && referencedIds.includes(src.id));\n // Only fall back to the candidate list when the answer referenced\n // nothing at all. If it referenced specific items, show just those —\n // never dump unrelated matches (e.g. phones for a sofa question).\n const general = referencedIds.length > 0\n ? []\n : sources.filter(src => !src.id || !referencedIds.includes(src.id));\n\n return (\n <div className=\"hsk-sources-container\">\n {featured.length > 0 && (\n <div className=\"hsk-sources-group\" style={{ marginBottom: '10px' }}>\n <div className=\"hsk-sources-group-title\">⭐ Featured in response</div>\n <div className=\"hsk-sources\">\n {featured.map((src, si) => (\n <SourceCard\n key={`feat-${si}`}\n source={src}\n defaultCurrency={defaultCurrency}\n onSelect={onSelectSource}\n isReferenced={true}\n />\n ))}\n </div>\n </div>\n )}\n {general.length > 0 && (\n <div className=\"hsk-sources-group\">\n {featured.length > 0 && <div className=\"hsk-sources-group-title\">All matches</div>}\n <div className=\"hsk-sources\">\n {general.map((src, si) => (\n <SourceCard\n key={`gen-${si}`}\n source={src}\n defaultCurrency={defaultCurrency}\n onSelect={onSelectSource}\n isReferenced={false}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n );\n })()}\n </div>\n ))\n )}\n\n {loading && (\n <div className=\"hsk-msg-row\">\n <div className=\"hsk-msg-avatar ai\"><SparkleIcon /></div>\n <div className=\"hsk-pending\" role=\"status\" aria-live=\"polite\">\n <div className=\"hsk-pending-glyph\">\n <span className=\"hsk-pending-ring\" />\n <span className=\"hsk-pending-dot\" />\n </div>\n <div className=\"hsk-pending-text\">\n <span className=\"hsk-pending-step step-1\">Searching catalog</span>\n <span className=\"hsk-pending-step step-2\">Reasoning</span>\n <span className=\"hsk-pending-step step-3\">Composing</span>\n </div>\n </div>\n </div>\n )}\n\n {error && (\n <div className=\"hsk-chat-error\">\n {(() => {\n try {\n const parsed = JSON.parse(error);\n return parsed.error || parsed.message || error;\n } catch {\n return error;\n }\n })()}\n </div>\n )}\n <div ref={bottomRef} />\n </div>\n\n <div className=\"hsk-chat-input-area\" style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n {enableVision && (\n <VisualSearch\n onResults={handleVisualResults}\n onError={(err) => console.error('[VisualSearch] error:', err)}\n categoryHint={visionCategoryHint}\n disabled={loading}\n />\n )}\n <textarea\n ref={textareaRef}\n className={cn(\"hsk-chat-input\", classNames.input)}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKey}\n placeholder={placeholder}\n rows={1}\n disabled={loading}\n style={{ flex: 1 }}\n />\n {enableVoice && (\n <VoiceButton\n onTranscript={(text) => {\n setInput(text);\n send(text);\n setInput('');\n }}\n onInterim={(text) => setInput(text)}\n disabled={loading}\n />\n )}\n <button\n className=\"hsk-chat-send\"\n onClick={handleSend}\n disabled={!input.trim() || loading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n </div>\n );\n}\n\n\n","import React from 'react';\n\n// Helper to parse inline styles (bold, images, links, and inline code) safely into React nodes\nconst parseInline = (text: string, keyPrefix: string): React.ReactNode => {\n // Regex matches: images , links [text](url), bold **text**, inline code `code`\n const tokenRegex = /(!\\[[^\\]]*\\]\\([^)]+\\)|\\[[^\\]]+\\]\\([^)]+\\)|\\*\\*[^*]+\\*\\*|`[^`]+`)/g;\n const parts = text.split(tokenRegex);\n\n return parts.map((part, index) => {\n if (!part) return null;\n const key = `${keyPrefix}-inline-${index}`;\n\n // Handle Inline Code\n if (part.startsWith('`') && part.endsWith('`')) {\n return (\n <code key={key} className=\"hsk-markdown-code\">\n {part.slice(1, -1)}\n </code>\n );\n }\n\n // Handle Bold\n if (part.startsWith('**') && part.endsWith('**')) {\n return <strong key={key}>{parseInline(part.slice(2, -2), key)}</strong>;\n }\n\n // Handle Images: \n const imageMatch = part.match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\n if (imageMatch) {\n const alt = imageMatch[1];\n const url = imageMatch[2];\n const isSafeUrl = /^(https?|data:image):/i.test(url);\n if (isSafeUrl) {\n return (\n <img\n key={key}\n src={url}\n alt={alt || 'Product image'}\n className=\"hsk-markdown-img\"\n loading=\"lazy\"\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\n />\n );\n }\n return null;\n }\n\n // Handle Links: [text](url)\n const linkMatch = part.match(/^\\[([^\\]]+)\\]\\(([^)]+)\\)$/);\n if (linkMatch) {\n // Basic sanitization: ensure the URL doesn't contain javascript:\n const url = linkMatch[2];\n const isSafeUrl = /^(https?|mailto|tel):/i.test(url) || url.startsWith('/');\n if (isSafeUrl) {\n return (\n <a key={key} href={url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"hsk-markdown-link\">\n {parseInline(linkMatch[1], key)}\n </a>\n );\n }\n return <span key={key}>{parseInline(linkMatch[1], key)}</span>; // Fallback to plain text if unsafe\n }\n\n // Return standard text\n return part;\n });\n};\n\nexport function renderMarkdown(content: string): React.ReactNode {\n const lines = content.split('\\n');\n const elements: React.ReactNode[] = [];\n \n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n const key = `md-line-${i}`;\n\n // 1. Empty lines (spacing)\n if (!line.trim()) {\n i++;\n continue;\n }\n\n // 2. Standalone image lines: \n const standaloneImageMatch = line.trim().match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\n if (standaloneImageMatch) {\n const alt = standaloneImageMatch[1];\n const url = standaloneImageMatch[2];\n const isSafeUrl = /^(https?|data:image):/i.test(url);\n if (isSafeUrl) {\n elements.push(\n <div key={key} className=\"hsk-markdown-img-block\">\n <img\n src={url}\n alt={alt || 'Product image'}\n className=\"hsk-markdown-img\"\n loading=\"lazy\"\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\n />\n </div>\n );\n }\n i++;\n continue;\n }\n\n // 3. Headers\n const headerMatch = line.match(/^(#{1,3})\\s+(.*)/);\n if (headerMatch) {\n const level = headerMatch[1].length;\n const Tag = `h${level + 3}` as keyof JSX.IntrinsicElements; // Maps # to h4, ## to h5 to avoid messing up host page hierarchy\n elements.push(<Tag key={key} className={`hsk-markdown-h${level}`}>{parseInline(headerMatch[2], key)}</Tag>);\n i++;\n continue;\n }\n\n // 4. Unordered Lists\n if (line.match(/^[-*]\\s+/)) {\n const listItems: React.ReactNode[] = [];\n while (i < lines.length && lines[i].match(/^[-*]\\s+/)) {\n const itemText = lines[i].replace(/^[-*]\\s+/, '');\n listItems.push(<li key={`li-${i}`}>{parseInline(itemText, `li-${i}`)}</li>);\n i++;\n }\n elements.push(<ul key={`ul-${key}`} className=\"hsk-markdown-list\">{listItems}</ul>);\n continue;\n }\n\n // 5. Tables\n if (line.trim().startsWith('|')) {\n const tableRows: React.ReactNode[] = [];\n let isHeader = true;\n\n while (i < lines.length && lines[i].trim().startsWith('|')) {\n const rowLine = lines[i].trim();\n // Skip markdown table separator (e.g., |---|---|)\n if (rowLine.match(/^\\|[-:| ]+\\|$/)) {\n i++;\n isHeader = false;\n continue;\n }\n\n // Slice to remove outer pipes and map trim to handle empty cells properly\n const cells = rowLine.split('|').slice(1, -1).map(c => c.trim());\n const Tag = isHeader ? 'th' : 'td';\n \n tableRows.push(\n <tr key={`tr-${i}`}>\n {cells.map((cell, cIdx) => (\n <Tag key={`td-${i}-${cIdx}`}>{parseInline(cell, `td-${i}-${cIdx}`)}</Tag>\n ))}\n </tr>\n );\n i++;\n }\n \n elements.push(\n <div key={`table-wrapper-${key}`} className=\"hsk-table-wrapper\">\n <table className=\"hsk-markdown-table\">\n <tbody>{tableRows}</tbody>\n </table>\n </div>\n );\n continue;\n }\n\n // 6. Default Paragraph\n elements.push(\n <p key={key} className=\"hsk-markdown-p\">\n {parseInline(line, key)}\n </p>\n );\n i++;\n }\n\n return <>{elements}</>;\n}\n","import React, { useState, useRef, useCallback } from 'react';\n\nexport interface VoiceButtonProps {\n onTranscript: (text: string) => void;\n onInterim?: (text: string) => void;\n /** BCP-47 language tag. Defaults to 'en-US'. */\n lang?: string;\n className?: string;\n disabled?: boolean;\n}\n\nconst MicIcon = ({ active }: { active: boolean }) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"9\" y=\"2\" width=\"6\" height=\"11\" rx=\"3\" fill={active ? 'currentColor' : 'none'} />\n <path d=\"M5 10a7 7 0 0 0 14 0\" />\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n </svg>\n);\n\n/**\n * VoiceButton — converts speech to text using the browser's free Web Speech API.\n * No API key, no backend call, no cost.\n *\n * @example\n * <VoiceButton onTranscript={(text) => setQuery(text)} />\n */\nexport function VoiceButton({\n onTranscript,\n onInterim,\n lang = 'en-US',\n className = '',\n disabled = false,\n}: VoiceButtonProps) {\n const [listening, setListening] = useState(false);\n const recognitionRef = useRef<any>(null);\n\n const isSupported =\n typeof window !== 'undefined' &&\n ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window);\n\n const start = useCallback(() => {\n if (!isSupported || listening) return;\n\n const SR: any =\n (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n const recognition = new SR();\n recognition.lang = lang;\n recognition.interimResults = true;\n recognition.maxAlternatives = 1;\n recognitionRef.current = recognition;\n\n recognition.onstart = () => setListening(true);\n recognition.onend = () => setListening(false);\n recognition.onerror = () => setListening(false);\n\n recognition.onresult = (e: any) => {\n const results = Array.from(e.results as any[]);\n const transcript = results.map((r: any) => r[0].transcript).join('');\n const isFinal = (e.results[e.results.length - 1] as any).isFinal;\n if (isFinal) {\n onTranscript(transcript);\n setListening(false);\n } else {\n onInterim?.(transcript);\n }\n };\n\n recognition.start();\n }, [isSupported, listening, lang, onTranscript, onInterim]);\n\n const stop = useCallback(() => {\n recognitionRef.current?.stop();\n setListening(false);\n }, []);\n\n // Silently render nothing if the browser doesn't support Web Speech API\n if (!isSupported) return null;\n\n return (\n <button\n type=\"button\"\n className={`kiku-voice-btn${listening ? ' kiku-voice-btn--active' : ''} ${className}`}\n onClick={listening ? stop : start}\n disabled={disabled}\n title={listening ? 'Stop listening' : 'Speak your search'}\n aria-label={listening ? 'Stop voice input' : 'Start voice input'}\n >\n <MicIcon active={listening} />\n {listening && <span className=\"kiku-voice-ripple\" aria-hidden=\"true\" />}\n </button>\n );\n}\n","import React, { useRef, useState } from 'react';\nimport { useAkropolysContext } from '@akropolys/sdk';\nimport type { VisualSearchResponse } from '@akropolys/sdk';\n\nexport interface VisualSearchProps {\n /** Called with search results + the base64 preview when Gemini responds. */\n onResults: (res: VisualSearchResponse, previewBase64: string) => void;\n onError?: (err: Error) => void;\n /**\n * Category hint sent to Gemini to sharpen the match_query.\n * e.g. \"dress\", \"curtains\", \"sofa\", \"shoes\"\n */\n categoryHint?: string;\n className?: string;\n disabled?: boolean;\n}\n\nconst CameraIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <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\" />\n <circle cx=\"12\" cy=\"13\" r=\"4\" />\n </svg>\n);\n\nconst SpinnerIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"kiku-vs-spin\">\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n\nfunction fileToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n}\n\n/**\n * VisualSearch — camera/image-upload button that powers style-match search.\n *\n * User picks a photo → it's base64-encoded in-browser → sent to POST /search/visual\n * → Gemini Flash extracts Style DNA → results returned via onResults().\n *\n * @example\n * <VisualSearch\n * categoryHint=\"dress\"\n * onResults={(res, preview) => setVisualResults(res)}\n * />\n */\nexport function VisualSearch({\n onResults,\n onError,\n categoryHint,\n className = '',\n disabled = false,\n}: VisualSearchProps) {\n const client = useAkropolysContext();\n const inputRef = useRef<HTMLInputElement>(null);\n const [loading, setLoading] = useState(false);\n\n const handleFile = async (file: File) => {\n if (!file.type.startsWith('image/')) return;\n setLoading(true);\n try {\n const base64 = await fileToBase64(file);\n const res = await (client.api as any).searchByImage(base64, categoryHint);\n onResults(res as VisualSearchResponse, base64);\n } catch (e: any) {\n onError?.(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n // Reset so the same file can be picked again\n if (inputRef.current) inputRef.current.value = '';\n }\n };\n\n return (\n <label\n className={`kiku-vs-btn${loading ? ' kiku-vs-btn--loading' : ''} ${className}`}\n title=\"Search by photo\"\n aria-label=\"Search by uploading a photo\"\n style={{ cursor: disabled || loading ? 'not-allowed' : 'pointer' }}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n onChange={e => e.target.files?.[0] && handleFile(e.target.files[0])}\n disabled={disabled || loading}\n hidden\n />\n {loading ? <SpinnerIcon /> : <CameraIcon />}\n </label>\n );\n}\n","'use client';\r\n\r\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { useKiku, ChatMessage, ChatSource } from '@akropolys/sdk';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport { renderMarkdown } from '../utils/markdown';\r\nimport { AkropolysTheme, ChatAttachment, CaptureTarget } from '@akropolys/sdk';\r\nimport { cn } from '../utils/cn';\r\nimport { ComparisonMatrix } from './ComparisonMatrix';\r\n\r\n\r\nexport interface KikuButtonProps {\r\n label?: string;\r\n title?: string;\r\n placeholder?: string;\r\n backdropColor?: string;\r\n backdropBlur?: string | number;\r\n className?: string;\r\n onSelectSource?: (source: ChatSource) => void;\r\n defaultCurrency?: string;\r\n chips?: string[];\r\n theme?: 'light' | 'dark' | AkropolysTheme;\r\n classNames?: {\r\n button?: string;\r\n overlay?: string;\r\n panel?: string;\r\n input?: string;\r\n sendButton?: string;\r\n };\r\n /** Enable 🎙️ voice input via browser Web Speech API (free) */\r\n enableVoice?: boolean;\r\n /** BCP-47 tag for voice transcription (e.g. 'sw-KE', 'fr-FR'). Defaults to\r\n the page's <html lang>, then the browser language. */\r\n voiceLang?: string;\r\n /** Enable 📷 visual style-match search via Gemini (requires backend GEMINI_API_KEY) */\r\n enableVision?: boolean;\r\n /** Optional category hint for visual search (e.g. 'dress', 'curtains') */\r\n visionCategoryHint?: string;\r\n}\r\n\r\n// ─── Icons ────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Akropolys brand mark — an ancient serif capital Alpha (Α)\r\n * with an animated smooth breathing mark (spiritus lenis ʻ) at top-left.\r\n * The mark pulses gently, like a breath.\r\n */\r\nconst AkropolysAIcon = ({ className, size = 18 }: { className?: string; size?: number }) => (\r\n <svg\r\n className={cn(\"hsk-brand-a\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 28 30\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-label=\"Akropolys\"\r\n >\r\n {/* Left leg: elegant thin stroke */}\r\n <path\r\n d=\"M14.5 4.5 L6.5 25\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2.2\"\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Right leg: bold ancient serif thick stroke */}\r\n <path\r\n d=\"M14.5 4.5 L22.5 25\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"4.2\"\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Crossbar */}\r\n <path\r\n d=\"M9.5 17 H19.5\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Left base serif */}\r\n <path\r\n d=\"M3 25 H10\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Right base serif */}\r\n <path\r\n d=\"M19 25 H26\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2.5\"\r\n strokeLinecap=\"round\"\r\n />\r\n {/* Smooth breathing mark (spiritus lenis) at top-left — animated */}\r\n <path\r\n d=\"M8.5 2.5 C10 2.5, 11 3.5, 11 5 C11 7, 8.5 8.5, 7.5 9.5\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n fill=\"none\"\r\n className=\"hsk-akr-breath\"\r\n />\r\n </svg>\r\n);\r\n\r\n/** Keep a tiny sparkle alias for places that still want the star (sources, etc.) */\r\nconst SparkleIcon = AkropolysAIcon;\r\n\r\nconst ArrowUpIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m5 12 7-7 7 7\"/>\r\n <path d=\"M12 19V5\"/>\r\n </svg>\r\n);\r\n\r\nconst StopIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"5\" y=\"5\" width=\"14\" height=\"14\" rx=\"2\"/>\r\n </svg>\r\n);\r\n\r\nconst CloseIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nconst ChevronRightIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m9 18 6-6-6-6\"/>\r\n </svg>\r\n);\r\n\r\nconst HistoryIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/>\r\n <path d=\"M3 3v5h5\"/>\r\n <path d=\"M12 7v5l4 2\"/>\r\n </svg>\r\n);\r\n\r\nconst BookmarkIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M19 21 12 16l-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z\"/>\r\n </svg>\r\n);\r\n\r\nconst TrashIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M3 6h18\"/>\r\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/>\r\n </svg>\r\n);\r\n\r\nconst SecureShieldIcon = ({ className, size = 18 }: { className?: string; size?: number }) => (\r\n <svg\r\n className={className}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2.5\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n <path d=\"M12 11a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z\" />\r\n <path d=\"M12 11v4\" />\r\n </svg>\r\n);\r\n\r\nconst PaperclipIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <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\"/>\r\n </svg>\r\n);\r\n\r\nconst MicIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\"/>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\r\n </svg>\r\n);\r\n\r\nconst MicOffIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\"/>\r\n <path d=\"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2\"/>\r\n <path d=\"M5 10v2a7 7 0 0 0 12 5\"/>\r\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\"/>\r\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\r\n </svg>\r\n);\r\n\r\n// ─── Constants ────────────────────────────────────────────────────────────────\r\n\r\nconst DEFAULT_CHIPS = [\r\n 'Cheapest smartphone',\r\n 'Smart TV under KSh 20,000',\r\n 'Noise-cancelling headphones',\r\n 'Best laptop for students',\r\n];\r\n\r\n// ─── @kiku Mention System ─────────────────────────────────────────────────────\r\n\r\n/**\r\n * Parses the user's input for an @kiku mention prefix.\r\n * Returns the resolved intent + a cleaned query (product name only, no @kiku prefix)\r\n * that gets sent as the actual search text. Returns null if not an @kiku command.\r\n */\r\nfunction parseAtKiku(raw: string): { intent: string; cleanQuery: string } | null {\r\n const trimmed = raw.trim();\r\n if (!/^@kiku\\b/i.test(trimmed)) return null;\r\n\r\n const rest = trimmed.slice(5).trim(); // everything after \"@kiku\"\r\n\r\n if (rest === '' || /^(capture|save)\\b/i.test(rest)) {\r\n return {\r\n intent: 'capture',\r\n cleanQuery: rest.replace(/^(capture|save)\\s*/i, '').trim() || trimmed,\r\n };\r\n }\r\n if (/^(history|what have you|show my|my items|what did you|saved|captures|recall)\\b/i.test(rest)) {\r\n return { intent: 'view_history', cleanQuery: 'show my saved items' };\r\n }\r\n if (/^(delete|forget|remove|unsave)\\b/i.test(rest)) {\r\n return {\r\n intent: 'delete',\r\n cleanQuery: rest.replace(/^(delete|forget|remove|unsave)\\s*/i, '').trim() || trimmed,\r\n };\r\n }\r\n // Bare \"@kiku <text>\" defaults to capture\r\n return { intent: 'capture', cleanQuery: rest || trimmed };\r\n}\r\n\r\n// ─── @kiku Picker Menu ────────────────────────────────────────────────────────\r\n\r\ninterface KikuPickerMenuProps {\r\n sources: ChatSource[];\r\n referencedIds: string[];\r\n defaultCurrency: string;\r\n onCapture: (product: ChatSource) => void;\r\n onCaptureAll: (products: ChatSource[]) => void;\r\n onViewHistory: () => void;\r\n onDelete: () => void;\r\n onDismiss: () => void;\r\n}\r\n\r\nfunction KikuPickerMenu({\r\n sources,\r\n referencedIds,\r\n defaultCurrency,\r\n onCapture,\r\n onCaptureAll,\r\n onViewHistory,\r\n onDelete,\r\n onDismiss,\r\n}: KikuPickerMenuProps) {\r\n // Show products that were actually referenced in this conversation\r\n const discussed = sources.filter(s => s.id && referencedIds.includes(s.id));\r\n\r\n return (\r\n <div\r\n className=\"hsk-kiku-picker\"\r\n role=\"menu\"\r\n aria-label=\"@kiku commands\"\r\n onMouseDown={e => e.preventDefault()} // keep textarea focused\r\n >\r\n {discussed.map((src, i) => (\r\n <button\r\n key={src.id ?? i}\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onCapture(src); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\">\r\n {src.image ? <img src={src.image} alt=\"\" /> : <BookmarkIcon />}\r\n </span>\r\n <span className=\"hsk-kiku-picker-item-name\">{src.name}</span>\r\n {src.price && (\r\n <span className=\"hsk-kiku-picker-item-price\">\r\n {src.currency ?? defaultCurrency} {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </span>\r\n )}\r\n </button>\r\n ))}\r\n {discussed.length > 1 && (\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onCaptureAll(discussed); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\"><BookmarkIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">Capture all ({discussed.length})</span>\r\n </button>\r\n )}\r\n {discussed.length === 0 && (\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onCapture({ name: 'current page', id: undefined }); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\"><BookmarkIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">Capture current page</span>\r\n </button>\r\n )}\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onViewHistory(); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\"><HistoryIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">What have you saved?</span>\r\n </button>\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onDelete(); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\"><TrashIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">Delete this</span>\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\n// ─── @ Extension Picker Menu ──────────────────────────────────────────────────\r\n\r\ninterface AtPickerMenuProps {\r\n onSelect: (extension: string) => void;\r\n onDismiss: () => void;\r\n}\r\n\r\nfunction AtPickerMenu({ onSelect, onDismiss }: AtPickerMenuProps) {\r\n return (\r\n <div\r\n className=\"hsk-kiku-picker\"\r\n role=\"menu\"\r\n aria-label=\"Extensions\"\r\n onMouseDown={e => e.preventDefault()} // keep textarea focused\r\n >\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => onSelect('@kiku')}\r\n >\r\n <span className=\"hsk-kiku-picker-icon hsk-kiku-picker-icon--accent\"><SparkleIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">kiku — capture & remember</span>\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\n// ─── Sources Carousel ──────────────────────────────────────────────────────────\r\n\r\ninterface SourcesCarouselProps {\r\n sources: ChatSource[];\r\n defaultCurrency: string;\r\n onSelectSource?: (src: ChatSource) => void;\r\n onImageClick?: (src: string) => void;\r\n referencedIds?: string[];\r\n}\r\n\r\nfunction SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClick, referencedIds = [] }: SourcesCarouselProps) {\r\n const client = useAkropolysContext();\r\n const isProperty = client?.vertical === 'property';\r\n const railRef = useRef<HTMLDivElement>(null);\r\n const [showNext, setShowNext] = useState(false);\r\n\r\n const measure = useCallback(() => {\r\n const el = railRef.current;\r\n if (!el) return;\r\n const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;\r\n setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);\r\n }, []);\r\n\r\n useEffect(() => {\r\n measure();\r\n const el = railRef.current;\r\n if (!el) return;\r\n const ro = new ResizeObserver(measure);\r\n ro.observe(el);\r\n el.addEventListener('scroll', measure, { passive: true });\r\n return () => { ro.disconnect(); el.removeEventListener('scroll', measure); };\r\n }, [measure, sources]);\r\n\r\n const scrollNext = () => {\r\n railRef.current?.scrollBy({ left: 170, behavior: 'smooth' });\r\n };\r\n\r\n // Show only the products the answer referenced via <entity_ref>. If it\r\n // referenced none, show none — never dump raw retrieval candidates, which is\r\n // what surfaced product cards for questions nobody asked.\r\n const display = sources.filter(s => s.id && referencedIds.includes(s.id));\r\n if (display.length === 0) return null;\r\n\r\n return (\r\n <div className=\"hsk-cb-sources-wrap\">\r\n <div className=\"hsk-cb-sources\" ref={railRef}>\r\n {display.map((src, si) => {\r\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\r\n return (\r\n <div\r\n key={si}\r\n className={cn(\"hsk-cb-source\", isReferenced && \"hsk-cb-source--referenced\")}\r\n style={{ animationDelay: `${si * 50}ms` }}\r\n onClick={() => onSelectSource?.(src)}\r\n >\r\n {src.image ? (\r\n <div className=\"hsk-cb-src-imgwrap\" style={{ position: 'relative' }}>\r\n <img\r\n src={src.image}\r\n alt={src.name}\r\n loading=\"lazy\"\r\n onClick={onImageClick ? (e) => { e.stopPropagation(); onImageClick(src.image!); } : undefined}\r\n />\r\n {isReferenced && (\r\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\">\r\n <SparkleIcon size={10} />\r\n </div>\r\n )}\r\n {isProperty && (\r\n <div style={{\r\n position: 'absolute',\r\n top: '6px',\r\n right: '6px',\r\n background: 'rgba(14, 14, 15, 0.75)',\r\n backdropFilter: 'blur(4px)',\r\n borderRadius: '50%',\r\n width: '24px',\r\n height: '24px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: '#fbbf24', // Gold sparkle badge\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)'\r\n }}>\r\n <SparkleIcon size={12} />\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"hsk-cb-src-imgwrap-empty\" style={{ position: 'relative' }}>\r\n <SparkleIcon />\r\n {isReferenced && (\r\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\">\r\n <SparkleIcon size={10} />\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n <div className=\"hsk-cb-src-info\">\r\n <div className=\"hsk-cb-src-name\">{src.name}</div>\r\n {src.price && (\r\n <div className=\"hsk-cb-src-price\">\r\n {src.currency ?? defaultCurrency}{' '}\r\n {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n {showNext && (\r\n <>\r\n <div\r\n className=\"hsk-cb-sources-fade\"\r\n style={{ background: 'linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))' }}\r\n />\r\n <button className=\"hsk-cb-sources-next\" onClick={scrollNext} aria-label=\"See more\">\r\n <ChevronRightIcon />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ─── Strip markdown tables (used for compare view to avoid duplicate) ──────────\r\n\r\nfunction stripMarkdownTables(content: string): string {\r\n const lines = content.split('\\n');\r\n const out: string[] = [];\r\n for (const line of lines) {\r\n if (line.trim().startsWith('|')) continue; // table row or separator\r\n out.push(line);\r\n }\r\n // Collapse runs of 3+ blank lines down to 2\r\n return out.join('\\n').replace(/\\n{3,}/g, '\\n\\n').trim();\r\n}\r\n\r\n// ─── Smart context pills ──────────────────────────────────────────────────────\r\n// Shown after every assistant response (when there's no cart action).\r\n// Pills are generated from the current intent + sources so they're always relevant.\r\n\r\nfunction SmartContextPills({\r\n intent,\r\n sources,\r\n onSend,\r\n loading,\r\n}: {\r\n intent: string | null;\r\n sources: ChatSource[];\r\n onSend: (text: string) => void;\r\n loading: boolean;\r\n}) {\r\n const client = useAkropolysContext();\r\n const isProperty = client?.vertical === 'property';\r\n if (!intent) return null;\r\n\r\n const pills: { label: string; query: string; emoji: string }[] = [];\r\n\r\n // Find the cheapest product in the sources list\r\n const cheapest =\r\n sources.length > 0\r\n ? sources.reduce((min, s) => {\r\n const p = parseFloat(String(s.price ?? '').replace(/[^0-9.]/g, ''));\r\n const m = parseFloat(String(min.price ?? '').replace(/[^0-9.]/g, ''));\r\n return !isNaN(p) && (isNaN(m) || p < m) ? s : min;\r\n }, sources[0])\r\n : null;\r\n\r\n const firstName = sources[0]?.name ?? '';\r\n const firstTwo = sources.slice(0, 2).map(s => s.name);\r\n\r\n if (intent === 'search' && sources.length > 0) {\r\n if (firstTwo.length >= 2) {\r\n pills.push({\r\n emoji: '⚖️',\r\n label: 'Compare top 2',\r\n query: `Compare the ${firstTwo[0]} and ${firstTwo[1]}`,\r\n });\r\n }\r\n if (cheapest && !isProperty && cheapest.name) {\r\n const short = cheapest.name.split(' ').slice(0, 3).join(' ');\r\n pills.push({\r\n emoji: '💡',\r\n label: `More on ${short}`,\r\n query: `Tell me more about the ${cheapest.name}`,\r\n });\r\n }\r\n if (isProperty) {\r\n pills.push({ emoji: '💰', label: 'Under KSh 5M', query: 'Show me options under KSh 5,000,000' });\r\n } else {\r\n pills.push({ emoji: '💰', label: 'Under KSh 20K', query: 'Show me options under KSh 20,000' });\r\n }\r\n } else if (intent === 'compare' && sources.length > 0) {\r\n if (firstName) {\r\n pills.push({\r\n emoji: '🔍',\r\n label: 'Similar options',\r\n query: isProperty\r\n ? `Show me more properties similar to the ${firstName}`\r\n : `Show me more products similar to the ${firstName}`,\r\n });\r\n }\r\n pills.push({ emoji: '💡', label: 'Which is best?', query: 'Which one would you recommend and why?' });\r\n } else if (intent === 'specs' && sources.length > 0) {\r\n if (firstName) {\r\n pills.push({\r\n emoji: '🔄',\r\n label: 'Find alternatives',\r\n query: `What are good alternatives to the ${firstName}?`,\r\n });\r\n }\r\n } else if (intent === 'general') {\r\n if (isProperty) {\r\n pills.push({ emoji: '🔍', label: 'Show popular listings', query: 'What are your most popular properties?' });\r\n } else {\r\n pills.push({ emoji: '🔍', label: 'Show popular items', query: 'What are your most popular products?' });\r\n }\r\n pills.push({ emoji: '💡', label: 'Recommend something', query: 'What do you recommend for me?' });\r\n }\r\n\r\n if (pills.length === 0) return null;\r\n\r\n return (\r\n <div className=\"hsk-action-pills\">\r\n {pills.map(pill => (\r\n <button\r\n key={pill.query}\r\n className=\"hsk-action-pill\"\r\n onClick={() => onSend(pill.query)}\r\n disabled={loading}\r\n >\r\n <span className=\"hsk-pill-emoji\">{pill.emoji}</span>\r\n {pill.label}\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\n// ─── Error helper ──────────────────────────────────────────────────────────────\r\n\r\nconst getFriendlyError = (err: any) => {\r\n let str = '';\r\n if (typeof err === 'string') str = err;\r\n else if (err && typeof err === 'object' && err.message) str = err.message;\r\n else try { str = JSON.stringify(err); } catch { str = String(err); }\r\n\r\n const lower = str.toLowerCase();\r\n if (\r\n lower.includes('429') ||\r\n lower.includes('too many requests') ||\r\n lower.includes('requests per minute limit exceeded') ||\r\n lower.includes('too_many_requests_error') ||\r\n lower.includes('request_quota_exceeded') ||\r\n lower.includes('quota')\r\n ) {\r\n return 'The assistant is currently receiving too many requests. Please try again in a few moments.';\r\n }\r\n\r\n if (lower.includes('token limit')) {\r\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\r\n }\r\n\r\n // Never let a raw status or network failure reach a shopper.\r\n if (lower.includes('failed to fetch') || lower.includes('networkerror') || lower.includes('request failed')) {\r\n return \"The assistant couldn't respond just now — please try again in a moment.\";\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(str);\r\n return parsed.error || parsed.message || str;\r\n } catch {\r\n return str;\r\n }\r\n};\r\n\r\n// The kiku key is the shopper's portable, anonymous identity (kiku_<hex>) —\r\n// server-minted, shown exactly once. Entering the same key on any site (or\r\n// giving it to an AI agent) opens the same memory. Lost key = lost memory.\r\nconst KIKU_KEY_REVEAL_SECONDS = 60;\r\n\r\n// ─── ChatModal Props ───────────────────────────────────────────────────────────\r\n\r\ninterface ChatModalProps extends Pick<KikuButtonProps, 'title' | 'placeholder' | 'backdropColor' | 'backdropBlur' | 'onSelectSource' | 'defaultCurrency' | 'chips' | 'theme' | 'classNames' | 'enableVoice' | 'voiceLang' | 'enableVision' | 'visionCategoryHint'> {\r\n theme?: 'light' | 'dark' | AkropolysTheme;\r\n classNames?: any;\r\n onClose: () => void;\r\n}\r\n\r\n// ─── ChatModal ─────────────────────────────────────────────────────────────────\r\n\r\nfunction parseThinking(text: string): { thinking: string; content: string; isComplete: boolean } {\r\n const openMatch = text.match(/<\\s*thinking\\s*>/i);\r\n if (!openMatch) {\r\n return { thinking: '', content: text, isComplete: true };\r\n }\r\n\r\n const openIdx = openMatch.index ?? 0;\r\n const openTagLength = openMatch[0].length;\r\n const start = openIdx + openTagLength;\r\n \r\n const contentBefore = text.slice(0, openIdx);\r\n const textAfterOpen = text.slice(start);\r\n \r\n const closeMatch = textAfterOpen.match(/<\\/\\s*thinking\\s*>/i);\r\n if (!closeMatch) {\r\n return { \r\n thinking: textAfterOpen, \r\n content: contentBefore, \r\n isComplete: false \r\n };\r\n }\r\n\r\n const closeIdx = closeMatch.index ?? 0;\r\n const closeTagLength = closeMatch[0].length;\r\n \r\n return {\r\n thinking: textAfterOpen.slice(0, closeIdx),\r\n content: contentBefore + textAfterOpen.slice(closeIdx + closeTagLength),\r\n isComplete: true\r\n };\r\n}\r\n\r\nfunction ThinkingBlock({ text, isComplete }: { text: string; isComplete: boolean }) {\r\n const [isOpen, setIsOpen] = useState(true);\r\n\r\n // Auto-expand when streaming thinking content\r\n useEffect(() => {\r\n if (!isComplete) {\r\n setIsOpen(true);\r\n }\r\n }, [isComplete]);\r\n\r\n return (\r\n <div style={{\r\n marginBottom: '12px',\r\n borderLeft: '2px solid #e4e4e7',\r\n paddingLeft: '10px',\r\n fontSize: '0.825rem',\r\n backgroundColor: 'rgba(244, 244, 245, 0.4)',\r\n padding: '8px 10px',\r\n borderRadius: '0 6px 6px 0'\r\n }}>\r\n <div \r\n onClick={() => setIsOpen(!isOpen)} \r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n color: '#71717a',\r\n cursor: 'pointer',\r\n fontWeight: 500,\r\n userSelect: 'none'\r\n }}\r\n >\r\n <span style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ animation: !isComplete ? 'spin 3s linear infinite' : 'none' }}>\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <path d=\"M12 6v6l4 2\" />\r\n </svg>\r\n Thinking Process\r\n </span>\r\n {!isComplete && (\r\n <span style={{\r\n width: '6px',\r\n height: '6px',\r\n borderRadius: '50%',\r\n backgroundColor: '#3b82f6',\r\n display: 'inline-block',\r\n animation: 'hsk-pulse 1.2s infinite ease-in-out'\r\n }} />\r\n )}\r\n <span style={{ \r\n fontSize: '0.7rem', \r\n marginLeft: 'auto',\r\n transform: isOpen ? 'rotate(90deg)' : 'none', \r\n transition: 'transform 0.1s' \r\n }}>▶</span>\r\n </div>\r\n {isOpen && (\r\n <div style={{\r\n marginTop: '6px',\r\n color: '#52525b',\r\n whiteSpace: 'pre-wrap',\r\n lineHeight: '1.4',\r\n fontStyle: 'italic'\r\n }}>\r\n {text}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nconst PROPERTY_CHIPS = [\r\n '3 bedroom apartments',\r\n 'Houses under KSh 5,000,000',\r\n 'Properties in Palm Beach',\r\n 'Studio apartments with pool',\r\n];\r\n\r\nfunction ChatModal({\r\n title = 'Shopping Assistant',\r\n placeholder = 'Ask me anything — gifts, budget, use case…',\r\n backdropColor,\r\n backdropBlur,\r\n onClose,\r\n onSelectSource,\r\n defaultCurrency = 'KES',\r\n chips = DEFAULT_CHIPS,\r\n theme,\r\n classNames = {},\r\n enableVoice = false,\r\n voiceLang,\r\n enableVision = false,\r\n visionCategoryHint,\r\n}: ChatModalProps) {\r\n const client = useAkropolysContext();\r\n const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, reset, referencedIds } = useKiku();\r\n const [input, setInput] = useState('');\r\n\r\n // ── Image attachments ────────────────────────────────────────────────────────\r\n const [attachments, setAttachments] = useState<ChatAttachment[]>([]);\r\n const imageInputRef = useRef<HTMLInputElement>(null);\r\n\r\n const handleImageFiles = (files: FileList | null) => {\r\n if (!files || files.length === 0) return;\r\n Array.from(files).forEach(file => {\r\n if (!file.type.startsWith('image/')) return;\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const dataUrl = e.target?.result as string;\r\n if (dataUrl) {\r\n setAttachments(prev => [...prev, { type: 'image', data: dataUrl }]);\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n };\r\n\r\n const removeAttachment = (idx: number) => {\r\n setAttachments(prev => prev.filter((_, i) => i !== idx));\r\n };\r\n\r\n // ── Voice mode (Web Speech API) ──────────────────────────────────────────────\r\n const [voiceState, setVoiceState] = useState<'idle' | 'listening' | 'processing'>('idle');\r\n const recognitionRef = useRef<any>(null);\r\n const pendingVoiceRef = useRef<string | null>(null); // transcript queued for auto-send\r\n const hasSpeechAPI = typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window);\r\n\r\n const startVoice = useCallback(() => {\r\n if (!hasSpeechAPI || voiceState !== 'idle') return;\r\n const SR = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\r\n const recognition = new SR();\r\n // Transcribe in the site's language, not a dictated one: developer override\r\n // → page <html lang> → browser language → English as last resort.\r\n recognition.lang = voiceLang || document.documentElement.lang || navigator.language || 'en-US';\r\n // Stream partial results so the user SEES words appear as they speak —\r\n // without this there's no feedback that anything was captured until the end.\r\n recognition.interimResults = true;\r\n recognition.maxAlternatives = 1;\r\n recognitionRef.current = recognition;\r\n\r\n recognition.onstart = () => setVoiceState('listening');\r\n recognition.onresult = (event: any) => {\r\n let finalText = '';\r\n let interimText = '';\r\n for (let i = 0; i < event.results.length; i++) {\r\n const seg = event.results[i][0].transcript;\r\n if (event.results[i].isFinal) finalText += seg;\r\n else interimText += seg;\r\n }\r\n // Live feedback: show the (final + in-progress) text in the input box.\r\n const live = (finalText + ' ' + interimText).trim();\r\n if (live) setInput(live);\r\n // Only auto-send once we have a finalized transcript.\r\n if (finalText.trim()) {\r\n pendingVoiceRef.current = finalText.trim();\r\n setVoiceState('processing');\r\n }\r\n };\r\n recognition.onerror = (event: any) => {\r\n // Surface the cause (most often denied mic permission or no speech) so the\r\n // user isn't left guessing whether it worked.\r\n const err = event?.error;\r\n if (err === 'not-allowed' || err === 'service-not-allowed') {\r\n setInput('Microphone access was blocked — enable it in your browser to use voice.');\r\n } else if (err === 'no-speech') {\r\n setInput(\"Didn't catch that — tap the mic and try again.\");\r\n }\r\n setVoiceState('idle');\r\n };\r\n recognition.onend = () => {\r\n // Only reset if we didn't already move to processing\r\n setVoiceState(prev => prev === 'listening' ? 'idle' : prev);\r\n };\r\n recognition.start();\r\n }, [hasSpeechAPI, voiceState, voiceLang]);\r\n\r\n const stopVoice = useCallback(() => {\r\n recognitionRef.current?.stop();\r\n setVoiceState('idle');\r\n }, []);\r\n\r\n // Clean up recognition on unmount\r\n useEffect(() => {\r\n return () => recognitionRef.current?.abort();\r\n }, []);\r\n\r\n const isProperty = client.vertical === 'property';\r\n const activeChips = chips === DEFAULT_CHIPS && isProperty ? PROPERTY_CHIPS : chips;\r\n const activeTitle = title === 'Shopping Assistant' && isProperty ? 'Property Assistant' : title;\r\n const activePlaceholder = placeholder === 'Ask me anything — gifts, budget, use case…' && isProperty\r\n ? 'Ask me anything — location, budget, bedrooms…'\r\n : placeholder;\r\n\r\n\r\n const [selectedProduct, setSelectedProduct] = useState<ChatSource | null>(null);\r\n const [lightboxSrc, setLightboxSrc] = useState<string | null>(null);\r\n const bottomRef = useRef<HTMLDivElement>(null);\r\n const textareaRef = useRef<HTMLTextAreaElement>(null);\r\n const [keyInput, setKeyInput] = useState('');\r\n const [keyPhase, setKeyPhase] = useState<'idle' | 'prompt_key'>('idle');\r\n const [mintedKey, setMintedKey] = useState<string | null>(null);\r\n const [keyCountdown, setKeyCountdown] = useState(KIKU_KEY_REVEAL_SECONDS);\r\n const [minting, setMinting] = useState(false);\r\n const [showKikuPicker, setShowKikuPicker] = useState(false);\r\n const [showAtPicker, setShowAtPicker] = useState(false);\r\n\r\n // React to lastAction from chat\r\n useEffect(() => {\r\n if (!lastAction) return;\r\n if (lastAction.type === 'request_kiku_key') {\r\n setKeyPhase('prompt_key');\r\n }\r\n }, [lastAction]);\r\n\r\n // Show-once countdown: the minted key is visible for a fixed window, then\r\n // gone for good — it stays active on this device, but is never shown again.\r\n useEffect(() => {\r\n if (!mintedKey) return;\r\n setKeyCountdown(KIKU_KEY_REVEAL_SECONDS);\r\n const t = setInterval(() => {\r\n setKeyCountdown(s => {\r\n if (s <= 1) {\r\n clearInterval(t);\r\n setMintedKey(null);\r\n return 0;\r\n }\r\n return s - 1;\r\n });\r\n }, 1000);\r\n return () => clearInterval(t);\r\n }, [mintedKey]);\r\n\r\n const isStringTheme = typeof theme === 'string';\r\n const hskThemeAttr = isStringTheme ? theme : undefined;\r\n\r\n const customStyles = (!isStringTheme && theme) ? {\r\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\r\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\r\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\r\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\r\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\r\n } as React.CSSProperties : undefined;\r\n\r\n // Retry the interrupted request (e.g. the capture) under the new identity.\r\n // Goes through handleSend so an \"@kiku …\" prefix is re-parsed back into a\r\n // forced intent instead of being sent as literal query text.\r\n const retryLastMessage = async () => {\r\n const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');\r\n if (lastUserMsg) await handleSend(lastUserMsg.content);\r\n };\r\n\r\n // Returning shopper: paste an existing kiku key.\r\n const handleUseExistingKey = async () => {\r\n const key = keyInput.trim();\r\n if (!key) return;\r\n client.setKikuKey(key);\r\n setKeyInput('');\r\n setKeyPhase('idle');\r\n await retryLastMessage();\r\n };\r\n\r\n // New shopper: mint a key server-side and reveal it exactly once.\r\n const handleCreateKey = async () => {\r\n if (minting) return;\r\n setMinting(true);\r\n try {\r\n const key = await client.mintKikuKey();\r\n setMintedKey(key);\r\n setKeyPhase('idle');\r\n await retryLastMessage();\r\n } catch {\r\n // mint failed — keep the prompt open so the shopper can try again\r\n } finally {\r\n setMinting(false);\r\n }\r\n };\r\n\r\n // Auto-scroll. A freshly sent user message is pinned to the top of the\r\n // view (like Claude) so the question and the start of the answer are both\r\n // visible without scrolling. While a response streams in, we only follow it\r\n // to the bottom if the user is already pinned there — this lets them freely\r\n // scroll up to re-read earlier messages.\r\n const msgsContainerRef = useRef<HTMLDivElement>(null);\r\n const messageRefs = useRef<(HTMLDivElement | null)[]>([]);\r\n useEffect(() => {\r\n const container = msgsContainerRef.current;\r\n if (!container) return;\r\n const lastMsg = messages[messages.length - 1];\r\n if (lastMsg?.role === 'user') {\r\n messageRefs.current[messages.length - 1]?.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n return;\r\n }\r\n const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;\r\n if (distanceFromBottom < 120) {\r\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }\r\n }, [messages, loading, selectedProduct]);\r\n\r\n // Lock the host page's own scroll while the panel is open, so only the\r\n // widget's internal message list scrolls — otherwise both scrollbars show.\r\n useEffect(() => {\r\n const prev = document.body.style.overflow;\r\n document.body.style.overflow = 'hidden';\r\n return () => { document.body.style.overflow = prev; };\r\n }, []);\r\n\r\n useEffect(() => {\r\n const h = (e: KeyboardEvent) => {\r\n if (e.key !== 'Escape') return;\r\n if (lightboxSrc) { setLightboxSrc(null); return; }\r\n onClose();\r\n };\r\n document.addEventListener('keydown', h);\r\n return () => document.removeEventListener('keydown', h);\r\n }, [lightboxSrc, onClose]);\r\n\r\n const handleReset = useCallback(() => {\r\n reset();\r\n setKeyPhase('idle');\r\n }, [reset]);\r\n\r\n const handleSourceClick = (src: ChatSource) => {\r\n setSelectedProduct(src);\r\n onSelectSource?.(src);\r\n const q = `Tell me more about the ${src.name}${src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : ''} — what are its key specs, who is it best for, and is it worth buying?`;\r\n send(q);\r\n };\r\n\r\n const handleSend = async (text?: string, extraAttachments?: ChatAttachment[], forcedIntent?: string, captureTargets?: CaptureTarget[]) => {\r\n const raw = (text ?? input).trim();\r\n if (!raw || loading) return;\r\n\r\n const kiku = parseAtKiku(raw);\r\n const q = kiku ? kiku.cleanQuery : raw;\r\n const resolvedForcedIntent = forcedIntent ?? kiku?.intent;\r\n\r\n setSelectedProduct(null);\r\n setShowKikuPicker(false);\r\n setShowAtPicker(false);\r\n setInput('');\r\n if (textareaRef.current) {\r\n textareaRef.current.style.height = 'auto';\r\n }\r\n const toSend = extraAttachments ?? attachments;\r\n setAttachments([]);\r\n await send(q, raw /* displayQuery */, toSend.length > 0 ? toSend : undefined, resolvedForcedIntent, captureTargets);\r\n };\r\n\r\n const handleSelectExtension = (ext: string) => {\r\n setInput(ext + ' ');\r\n setShowAtPicker(false);\r\n setShowKikuPicker(true);\r\n if (textareaRef.current) {\r\n textareaRef.current.focus();\r\n }\r\n };\r\n\r\n // Convenience wrappers for @kiku picker actions\r\n const handleKikuCapture = useCallback((product: ChatSource) => {\r\n const name = product.name || '';\r\n const display = `@kiku capture${name ? ' ' + name : ''}`;\r\n const q = name || 'capture current page';\r\n setInput('');\r\n setSelectedProduct(null);\r\n const toSend = attachments;\r\n setAttachments([]);\r\n send(q, display, toSend.length > 0 ? toSend : undefined, 'capture');\r\n }, [attachments, send]);\r\n\r\n const handleKikuCaptureAll = useCallback((products: ChatSource[]) => {\r\n const targets: CaptureTarget[] = products\r\n .filter(p => p.id)\r\n .map(p => ({\r\n name: p.name || '',\r\n url: (p as any).url || '',\r\n image: p.image || '',\r\n price: p.price ? String(p.price) : '',\r\n currency: p.currency || defaultCurrency,\r\n }));\r\n const names = products.map(p => p.name).filter(Boolean).join(', ');\r\n const display = `@kiku capture all (${products.length} items)`;\r\n setInput('');\r\n setSelectedProduct(null);\r\n setAttachments([]);\r\n send(names || 'capture all', display, undefined, 'capture_all', targets);\r\n }, [defaultCurrency, send]);\r\n\r\n const handleKikuViewHistory = useCallback(() => {\r\n const display = '@kiku what have you saved?';\r\n setInput('');\r\n setSelectedProduct(null);\r\n setAttachments([]);\r\n send('show my saved items', display, undefined, 'view_history');\r\n }, [send]);\r\n\r\n const handleKikuDelete = useCallback(() => {\r\n const display = '@kiku delete this';\r\n setInput('');\r\n setSelectedProduct(null);\r\n setAttachments([]);\r\n send('delete this', display, undefined, 'delete');\r\n }, [send]);\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\r\n if (e.key === 'Escape' && showKikuPicker) { e.preventDefault(); setShowKikuPicker(false); return; }\r\n if (e.key === 'Escape' && showAtPicker) { e.preventDefault(); setShowAtPicker(false); return; }\r\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }\r\n };\r\n\r\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n const val = e.target.value;\r\n setInput(val);\r\n const trimmed = val.trim();\r\n // Show @ picker when input is exactly '@'\r\n setShowAtPicker(trimmed === '@');\r\n // Show @kiku picker whenever the input starts with @kiku\r\n setShowKikuPicker(/^@kiku\\b/i.test(trimmed));\r\n const t = e.target;\r\n t.style.height = 'auto';\r\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\r\n };\r\n\r\n // Auto-send voice transcript once processing state is reached\r\n useEffect(() => {\r\n if (voiceState !== 'processing') return;\r\n const transcript = pendingVoiceRef.current;\r\n if (!transcript) { setVoiceState('idle'); return; }\r\n pendingVoiceRef.current = null;\r\n // Brief delay so user sees the transcript fill in before it fires\r\n const timer = setTimeout(() => {\r\n setVoiceState('idle');\r\n handleSend(transcript);\r\n }, 400);\r\n return () => clearTimeout(timer);\r\n }, [voiceState]);\r\n\r\n\r\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '20px');\r\n\r\n const displayMessages = messages;\r\n\r\n return (\r\n <div\r\n className={cn(\"hsk-cb-overlay\", classNames.overlay)}\r\n onClick={onClose}\r\n data-hsk-theme={hskThemeAttr}\r\n style={{\r\n backdropFilter: `blur(${blurVal})`,\r\n WebkitBackdropFilter: `blur(${blurVal})`,\r\n ...(backdropColor ? { background: backdropColor } : {}),\r\n ...customStyles,\r\n }}\r\n >\r\n <div\r\n className={cn(\"hsk-cb-panel\", classNames.panel)}\r\n onClick={e => {\r\n e.stopPropagation();\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === 'IMG' && (target.classList.contains('hsk-markdown-img') || target.classList.contains('hsk-cb-user-img-thumb'))) {\r\n const src = (target as HTMLImageElement).src;\r\n if (src) setLightboxSrc(src);\r\n }\r\n }}\r\n >\r\n {lightboxSrc && (\r\n <div className=\"hsk-lightbox\" onClick={() => setLightboxSrc(null)}>\r\n <button className=\"hsk-lightbox-close\" onClick={() => setLightboxSrc(null)} aria-label=\"Close image\">\r\n <CloseIcon />\r\n </button>\r\n <img src={lightboxSrc} alt=\"\" className=\"hsk-lightbox-img\" onClick={e => e.stopPropagation()} />\r\n </div>\r\n )}\r\n\r\n {/* ── Main Chat Area ── */}\r\n <div className=\"hsk-cb-main\">\r\n\r\n {/* Top bar */}\r\n <div className=\"hsk-cb-topbar\">\r\n <div className=\"hsk-cb-topbar-left\">\r\n <span className=\"hsk-cb-topbar-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </span>\r\n <div>\r\n <div className=\"hsk-cb-topbar-title\">{activeTitle}</div>\r\n </div>\r\n </div>\r\n <div className=\"hsk-cb-topbar-actions\">\r\n {messages.length > 0 && (\r\n <button className=\"hsk-cb-topbar-btn\" onClick={handleReset}>Clear chat</button>\r\n )}\r\n <button className=\"hsk-cb-close\" onClick={onClose} aria-label=\"Close\">\r\n <CloseIcon />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Messages */}\r\n <div className=\"hsk-cb-msgs\" ref={msgsContainerRef}>\r\n {displayMessages.length === 0 ? (\r\n <div className=\"hsk-cb-empty\">\r\n <div className=\"hsk-cb-empty-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-empty-title\">Find exactly what you need</div>\r\n <div className=\"hsk-cb-chips\">\r\n {activeChips.map(chip => (\r\n <button\r\n key={chip}\r\n className=\"hsk-cb-chip\"\r\n onClick={() => handleSend(chip)}\r\n >\r\n {chip}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n ) : (\r\n displayMessages.map((msg: ChatMessage, idx: number) => {\r\n const isLast = idx === displayMessages.length - 1;\r\n const isUser = msg.role === 'user';\r\n // Strip the LLM's markdown table for compare so ComparisonMatrix isn't duplicated\r\n const displayContent =\r\n !isUser && isLast && lastIntent === 'compare' && sources.length >= 2\r\n ? stripMarkdownTables(msg.content)\r\n : msg.content;\r\n return (\r\n <div key={idx} className=\"hsk-cb-msg-group\" ref={(el) => { messageRefs.current[idx] = el; }}>\r\n {isUser ? (\r\n <div className=\"hsk-cb-user-msg\">\r\n {/* Image thumbnails in user bubble */}\r\n {msg.images && msg.images.length > 0 && (\r\n <div className=\"hsk-cb-user-imgs\">\r\n {msg.images.map((img, i) => (\r\n <img key={i} src={img} alt={`attachment ${i + 1}`} className=\"hsk-cb-user-img-thumb\" />\r\n ))}\r\n </div>\r\n )}\r\n {msg.content && (\r\n <div className=\"hsk-cb-user-bubble\">\r\n {/* @kiku badge */}\r\n {/^@kiku\\b/i.test(msg.content) && (\r\n <span className=\"hsk-kiku-badge\">@kiku</span>\r\n )}\r\n {msg.content}\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n {(() => {\r\n const { thinking, content, isComplete } = parseThinking(displayContent);\r\n return (\r\n <>\r\n {thinking && (\r\n <ThinkingBlock text={thinking} isComplete={isComplete} />\r\n )}\r\n {content && (\r\n <div className=\"hsk-cb-ai-text\">\r\n {renderMarkdown(content)}\r\n {isLast && streaming && (\r\n <span style={{ display: 'inline-block', width: '0.5em', height: '1.05em', marginLeft: '2px', verticalAlign: 'text-bottom', background: 'currentColor', opacity: 0.55, borderRadius: '1px' }} />\r\n )}\r\n </div>\r\n )}\r\n </>\r\n );\r\n })()}\r\n\r\n {msg.visualizing && (\r\n <div className=\"hsk-cb-viz hsk-cb-viz--loading\">\r\n <span className=\"hsk-cb-viz-spinner\" />\r\n <span>Visualizing…</span>\r\n </div>\r\n )}\r\n {msg.visualization && (\r\n <div className=\"hsk-cb-viz\">\r\n <img\r\n src={msg.visualization}\r\n alt=\"Product visualized in your photo\"\r\n className=\"hsk-markdown-img\"\r\n loading=\"lazy\"\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Comparison matrix — replaces the markdown table when comparing products */}\r\n {isLast && lastIntent === 'compare' && sources.length >= 2 && (\r\n <ComparisonMatrix sources={sources} defaultCurrency={defaultCurrency} />\r\n )}\r\n\r\n {(() => {\r\n const msgReferencedIds = isLast ? referencedIds : (msg.referencedIds ?? []);\r\n const msgSources = isLast ? sources : (msg.sources ?? []);\r\n const showCarousel = msgReferencedIds.length > 0 &&\r\n (isLast ? lastIntent !== 'compare' : msg.intent !== 'compare') &&\r\n lastAction?.type !== 'request_kiku_key' && lastAction?.type !== 'capture' &&\r\n lastAction?.type !== 'delete' && lastAction?.type !== 'view_history';\r\n return showCarousel && (\r\n <SourcesCarousel\r\n sources={msgSources}\r\n defaultCurrency={defaultCurrency}\r\n onSelectSource={handleSourceClick}\r\n onImageClick={setLightboxSrc}\r\n referencedIds={msgReferencedIds}\r\n />\r\n );\r\n })()}\r\n\r\n {/* Registered action link — the site executes; we just route */}\r\n {isLast && !loading && lastAction?.url && (\r\n <div className=\"hsk-action-pills\">\r\n <a className=\"hsk-action-pill\" href={lastAction.url}>\r\n {String(lastAction.type || 'continue').replace(/_/g, ' ')} →\r\n </a>\r\n </div>\r\n )}\r\n\r\n {/* Smart context pills — built only from products the answer referenced */}\r\n {isLast && !loading && (\r\n <SmartContextPills\r\n intent={lastIntent}\r\n sources={sources.filter(s => s.id && referencedIds.includes(s.id))}\r\n onSend={handleSend}\r\n loading={loading}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })\r\n )}\r\n\r\n {/* Selected product pinned card — shows while LLM fetches details */}\r\n {selectedProduct && loading && (\r\n <div\r\n className=\"hsk-cb-selected-product\"\r\n onClick={() => selectedProduct.url && window.open(selectedProduct.url, '_blank')}\r\n >\r\n {selectedProduct.image && (\r\n <img className=\"hsk-cb-selected-img\" src={selectedProduct.image} alt={selectedProduct.name} />\r\n )}\r\n <div className=\"hsk-cb-selected-info\">\r\n <div className=\"hsk-cb-selected-name\">{selectedProduct.name}</div>\r\n {selectedProduct.price && (\r\n <div className=\"hsk-cb-selected-price\">\r\n {selectedProduct.currency ?? defaultCurrency} {parseFloat(String(selectedProduct.price ?? '').replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Typing dots — shown ONLY while waiting for the server (loading).\r\n Once the response arrives and token streaming begins (!loading && streaming)\r\n the text animates in directly with no dots visible. */}\r\n {loading && !streaming && (\r\n <div className=\"hsk-cb-typing-row\" style={{ display: 'flex', alignItems: 'flex-start', gap: '10px' }}>\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center', marginTop: '4px' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\r\n <style>{`\r\n @keyframes hsk-pulse {\r\n 0%, 100% { opacity: 0.6; }\r\n 50% { opacity: 1; }\r\n }\r\n `}</style>\r\n <div style={{ fontSize: '0.85rem', color: '#6b7280', fontStyle: 'italic', animation: 'hsk-pulse 1.5s infinite ease-in-out' }}>\r\n Thinking…\r\n </div>\r\n <div className=\"hsk-cb-typing\" style={{ margin: 0, alignSelf: 'flex-start' }}>\r\n <div className=\"hsk-cb-dot\" />\r\n <div className=\"hsk-cb-dot\" />\r\n <div className=\"hsk-cb-dot\" />\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {error && <div className=\"hsk-cb-error\">{getFriendlyError(error)}</div>}\r\n\r\n {/* Carry-your-items prompt: paste an existing kiku key, or mint a\r\n new one (shown exactly once). No phone, no account. */}\r\n {keyPhase === 'prompt_key' && (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n <div className=\"hsk-cb-ai-text\">\r\n <div className=\"hsk-cb-phone-form\">\r\n <label className=\"hsk-cb-phone-label\">Paste your kiku key — or create one</label>\r\n <input\r\n type=\"text\"\r\n className=\"hsk-cb-phone-input\"\r\n placeholder=\"kiku_…\"\r\n value={keyInput}\r\n onChange={e => setKeyInput(e.target.value)}\r\n onKeyDown={e => e.key === 'Enter' && handleUseExistingKey()}\r\n autoFocus\r\n />\r\n <div style={{ display: 'flex', gap: 8 }}>\r\n <button className=\"hsk-cb-phone-submit\" onClick={handleUseExistingKey} disabled={!keyInput.trim()}>\r\n Use my key\r\n </button>\r\n <button className=\"hsk-cb-phone-submit\" onClick={handleCreateKey} disabled={minting}>\r\n {minting ? 'Creating…' : \"I'm new — create my key\"}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {mintedKey && (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n <div className=\"hsk-cb-ai-text\">\r\n <div style={{ padding: '10px 12px', border: '1px solid var(--hsk-border, #e5e5e5)', borderRadius: 8 }}>\r\n <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 4 }}>🔑 Your kiku key — shown only once</div>\r\n <code style={{ display: 'block', fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: 'break-all' }}>{mintedKey}</code>\r\n <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\r\n <button className=\"hsk-cb-phone-submit\" style={{ padding: '4px 10px' }} onClick={() => { try { navigator.clipboard?.writeText(mintedKey); } catch { /* ignore */ } }}>Copy</button>\r\n <span style={{ fontSize: 11, opacity: 0.7 }}>\r\n Disappears in {keyCountdown}s. Save it like a password — if lost, the memory it opens is lost with it.\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={bottomRef} style={{ height: 1 }} />\r\n </div>\r\n\r\n <div className=\"hsk-cb-input-wrap\">\r\n {/* @ extension picker — floats above the input area */}\r\n {showAtPicker && (\r\n <AtPickerMenu\r\n onSelect={handleSelectExtension}\r\n onDismiss={() => setShowAtPicker(false)}\r\n />\r\n )}\r\n {/* @kiku command picker — floats above the input area */}\r\n {showKikuPicker && (\r\n <KikuPickerMenu\r\n sources={sources}\r\n referencedIds={referencedIds}\r\n defaultCurrency={defaultCurrency}\r\n onCapture={handleKikuCapture}\r\n onCaptureAll={handleKikuCaptureAll}\r\n onViewHistory={handleKikuViewHistory}\r\n onDelete={handleKikuDelete}\r\n onDismiss={() => setShowKikuPicker(false)}\r\n />\r\n )}\r\n {/* Image attachment strip */}\r\n {attachments.length > 0 && (\r\n <div className=\"hsk-cb-img-strip\">\r\n {attachments.map((att, i) => (\r\n <div key={i} className=\"hsk-cb-img-thumb-wrap\">\r\n <img src={att.data} alt={`attachment ${i + 1}`} className=\"hsk-cb-img-thumb\" />\r\n <button\r\n className=\"hsk-cb-img-thumb-remove\"\r\n onClick={() => removeAttachment(i)}\r\n aria-label=\"Remove image\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n <div className=\"hsk-cb-input-box\">\r\n {/* Hidden file input */}\r\n <input\r\n ref={imageInputRef}\r\n type=\"file\"\r\n accept=\"image/*\"\r\n multiple\r\n style={{ display: 'none' }}\r\n onChange={e => handleImageFiles(e.target.files)}\r\n />\r\n {/* Attach button — only shown if vision is enabled */}\r\n {enableVision && (\r\n <button\r\n className=\"hsk-cb-attach-btn\"\r\n onClick={() => imageInputRef.current?.click()}\r\n disabled={loading}\r\n aria-label=\"Attach image\"\r\n title=\"Attach image\"\r\n >\r\n <PaperclipIcon />\r\n </button>\r\n )}\r\n <textarea\r\n ref={textareaRef}\r\n className={cn(\"hsk-cb-textarea\", classNames.input)}\r\n value={input}\r\n onChange={handleInput}\r\n onKeyDown={handleKeyDown}\r\n placeholder={\r\n voiceState === 'listening' ? '🎙️ Listening… tap the mic to stop'\r\n : voiceState === 'processing' ? 'Got it — sending…'\r\n : activePlaceholder\r\n }\r\n rows={1}\r\n disabled={loading}\r\n autoFocus\r\n />\r\n {/* Voice button — only shown if SpeechRecognition is supported and enabled */}\r\n {hasSpeechAPI && enableVoice && (\r\n <button\r\n className={cn(\r\n \"hsk-cb-mic-btn\",\r\n voiceState === 'listening' && \"hsk-cb-mic-btn--listening\",\r\n voiceState === 'processing' && \"hsk-cb-mic-btn--processing\"\r\n )}\r\n onClick={voiceState === 'idle' ? startVoice : stopVoice}\r\n disabled={loading}\r\n aria-label={voiceState === 'idle' ? 'Start voice input' : 'Stop recording'}\r\n title={voiceState === 'idle' ? 'Voice input' : 'Stop'}\r\n >\r\n {voiceState === 'listening' ? <MicOffIcon /> : <MicIcon />}\r\n {voiceState === 'listening' && <span className=\"hsk-cb-mic-pulse\" />}\r\n </button>\r\n )}\r\n {(loading || streaming) ? (\r\n <button\r\n className={cn(\"hsk-cb-send\", \"hsk-cb-send--stop\", classNames.sendButton)}\r\n onClick={stop}\r\n aria-label=\"Stop generating\"\r\n title=\"Stop generating\"\r\n >\r\n <StopIcon />\r\n </button>\r\n ) : (\r\n <button\r\n className={cn(\"hsk-cb-send\", classNames.sendButton)}\r\n onClick={() => handleSend()}\r\n disabled={!input.trim() && attachments.length === 0}\r\n aria-label=\"Send message\"\r\n >\r\n <ArrowUpIcon />\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"hsk-cb-hint\">Akropolys AI · searches the whole catalogue in real time</div>\r\n </div>\r\n\r\n </div>{/* end .hsk-cb-main */}\r\n\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ─── KikuButton (public export) ─────────────────────────────────────────────\r\n\r\nexport function KikuButton({\r\n label,\r\n title,\r\n placeholder,\r\n backdropColor,\r\n backdropBlur,\r\n className,\r\n onSelectSource,\r\n defaultCurrency,\r\n chips,\r\n theme,\r\n classNames = {},\r\n enableVoice = false,\r\n voiceLang,\r\n enableVision = false,\r\n visionCategoryHint,\r\n}: KikuButtonProps) {\r\n const [open, setOpen] = useState(false);\r\n const [mounted, setMounted] = useState(false);\r\n\r\n useEffect(() => {\r\n setMounted(true);\r\n\r\n if (typeof window !== 'undefined' && !(window as any).__akropolys_nav_patched) {\r\n (window as any).__akropolys_nav_patched = true;\r\n const originalPush = window.history.pushState;\r\n const originalReplace = window.history.replaceState;\r\n\r\n window.history.pushState = function(...args) {\r\n originalPush.apply(this, args);\r\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\r\n };\r\n\r\n window.history.replaceState = function(...args) {\r\n originalReplace.apply(this, args);\r\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\r\n };\r\n }\r\n\r\n const handleNavigation = () => {\r\n setOpen(false);\r\n };\r\n\r\n window.addEventListener('popstate', handleNavigation);\r\n window.addEventListener('akropolys:navigation', handleNavigation);\r\n\r\n return () => {\r\n window.removeEventListener('popstate', handleNavigation);\r\n window.removeEventListener('akropolys:navigation', handleNavigation);\r\n };\r\n }, []);\r\n\r\n const isStringTheme = typeof theme === 'string';\r\n const hskThemeAttr = isStringTheme ? theme : undefined;\r\n\r\n const customStyles = (!isStringTheme && theme) ? {\r\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\r\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\r\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\r\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\r\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\r\n } as React.CSSProperties : undefined;\r\n\r\n return (\r\n <>\r\n <button\r\n className={cn(\"hsk-cb-btn\", classNames.button, className)}\r\n onClick={() => setOpen(true)}\r\n style={customStyles}\r\n data-hsk-theme={hskThemeAttr}\r\n aria-label=\"Open AI chat\"\r\n >\r\n <span className=\"hsk-cb-btn-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </span>\r\n {label !== undefined ? label : null}\r\n </button>\r\n {open && mounted && createPortal(\r\n <ChatModal\r\n title={title}\r\n placeholder={placeholder}\r\n backdropColor={backdropColor}\r\n backdropBlur={backdropBlur}\r\n onClose={() => setOpen(false)}\r\n onSelectSource={onSelectSource}\r\n defaultCurrency={defaultCurrency}\r\n chips={chips}\r\n theme={theme}\r\n classNames={classNames}\r\n enableVoice={enableVoice}\r\n voiceLang={voiceLang}\r\n enableVision={enableVision}\r\n visionCategoryHint={visionCategoryHint}\r\n />,\r\n document.body\r\n )}\r\n </>\r\n );\r\n}\r\n","import React from 'react';\nimport type { ChatSource } from '@akropolys/sdk';\nimport { resolveDisplayFields } from '@akropolys/sdk';\n\nexport interface ComparisonMatrixProps {\n sources: ChatSource[];\n defaultCurrency?: string;\n displayConfig?: Record<string, string>;\n}\n\ninterface Row {\n label: string;\n values: (string | null)[];\n type?: 'image' | 'price' | 'availability' | 'text';\n bestIdx?: number;\n}\n\nfunction normalizeKey(key: string): string {\n let s = key.replace(/[_-]+/g, ' ');\n s = s.replace(/([a-z])([A-Z])/g, '$1 $2');\n return s.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');\n}\n\nfunction getBaseGroup(normalized: string): string {\n const norm = normalized.toLowerCase().trim();\n if (norm.startsWith('salary') || norm.startsWith('pay') || norm.startsWith('wage')) {\n return 'Salary';\n }\n if (norm.startsWith('price') || norm.startsWith('cost') || norm.startsWith('rate')) {\n return 'Price';\n }\n if (norm.startsWith('location') || norm.startsWith('address') || norm.startsWith('city')) {\n return 'Location';\n }\n if (norm.startsWith('image') || norm.startsWith('photo') || norm.startsWith('pic') || norm.startsWith('thumb')) {\n return 'Image';\n }\n if (norm.startsWith('title') || norm.startsWith('name') || norm.startsWith('label') || norm.startsWith('heading')) {\n return 'Title';\n }\n return normalized;\n}\n\nfunction buildRows(products: ChatSource[], displayConfig?: Record<string, string>, defaultCurrency = 'KES'): Row[] {\n const rows: Row[] = [];\n const resolved = products.map(p => resolveDisplayFields(p.fields || p, displayConfig));\n\n rows.push({\n label: 'Product Preview',\n values: resolved.map(r => r.image || null),\n type: 'image',\n });\n\n const prices = resolved.map(r => {\n const n = parseFloat(String(r.price ?? '').replace(/[^0-9.]/g, ''));\n return isNaN(n) ? null : n;\n });\n\n const priceLabels = products.map((p, i) => {\n const c = p.fields?.currency || p.currency || defaultCurrency;\n const n = prices[i];\n return n !== null\n ? `${c} ${n.toLocaleString('en-KE', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`\n : null;\n });\n\n const validPrices = prices.filter((p): p is number => p !== null);\n const minPrice = validPrices.length ? Math.min(...validPrices) : null;\n rows.push({\n label: 'Price',\n values: priceLabels,\n type: 'price',\n bestIdx: minPrice !== null ? prices.indexOf(minPrice) : undefined,\n });\n\n const keysToExclude = new Set<string>([\n 'url', 'fields', 'id', 'score', 'currency', 'status', 'indexed_at', 'indexedAt'\n ]);\n \n if (displayConfig) {\n Object.values(displayConfig).forEach(v => {\n if (v) keysToExclude.add(v);\n });\n }\n\n const commonKeys = [\n 'title', 'name', 'label', 'headline', 'subject', 'job_title', 'listing_title', 'common_name', 'product_name',\n 'image', 'images', 'thumbnail', 'photo', 'cover', 'featured_image', 'hero_image', 'listing_image', 'logo',\n 'price', 'cost', 'listingPrice', 'rate', 'fee', 'startingFrom',\n 'brand', 'category', 'location', 'type', 'variety', 'make'\n ];\n commonKeys.forEach(k => keysToExclude.add(k));\n\n const allFieldKeys = new Set<string>();\n products.forEach(p => {\n const f = p.fields || p;\n if (f) {\n Object.keys(f).forEach(k => {\n if (!keysToExclude.has(k)) {\n allFieldKeys.add(k);\n }\n });\n }\n });\n\n const groupedKeys = new Map<string, string[]>();\n allFieldKeys.forEach(k => {\n const norm = normalizeKey(k);\n const base = getBaseGroup(norm);\n if (!groupedKeys.has(base)) {\n groupedKeys.set(base, []);\n }\n groupedKeys.get(base)!.push(k);\n });\n\n const sortedGroups = Array.from(groupedKeys.keys()).sort();\n\n sortedGroups.forEach(group => {\n const originalKeys = groupedKeys.get(group)!;\n const values = products.map(p => {\n const f = (p.fields || p) as Record<string, any>;\n if (!f) return null;\n for (const k of originalKeys) {\n if (f[k] !== undefined && f[k] !== null) {\n if (typeof f[k] === 'object') {\n return JSON.stringify(f[k]);\n }\n return String(f[k]);\n }\n }\n return null;\n });\n\n if (values.some(v => v !== null)) {\n rows.push({\n label: group,\n values,\n type: 'text',\n });\n }\n });\n\n const avail = products.map(s => {\n const f = s.fields || s;\n const a = (f.availability as string) || '';\n if (!a) return null;\n if (/in.?stock/i.test(a)) return 'In-Stock';\n if (/out.?of.?stock/i.test(a)) return 'Out of Stock';\n return a;\n });\n if (avail.some(Boolean)) {\n rows.push({ label: 'Availability', values: avail, type: 'availability' });\n }\n\n const cats = products.map(s => {\n const f = s.fields || s;\n return (f.category as string) || null;\n });\n if (cats.some(Boolean)) rows.push({ label: 'Category', values: cats });\n\n return rows;\n}\n\nfunction ImageCell({ value, name }: { value: string | null; name: string }) {\n if (!value) {\n return <div style={{ fontSize: 28, textAlign: 'center' }}>📦</div>;\n }\n return (\n <img\n src={value}\n alt={name}\n style={{\n width: 72,\n height: 72,\n objectFit: 'contain',\n borderRadius: 8,\n background: '#f5f5f5',\n display: 'block',\n }}\n />\n );\n}\n\n// Custom green pulsing ring on availability dot to match design guidelines\nfunction AvailabilityCell({ value }: { value: string | null }) {\n if (!value) return <span style={{ color: '#9ca3af' }}>—</span>;\n const inStock = /in.?stock/i.test(value);\n return (\n <span style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 13, color: 'var(--hsk-text, #111827)' }}>\n <span style={{\n width: 8, height: 8, borderRadius: '50%', flexShrink: 0,\n background: inStock ? '#22c55e' : '#ef4444',\n boxShadow: inStock ? '0 0 0 3px rgba(34,197,94,0.2)' : '0 0 0 3px rgba(239,68,68,0.2)',\n display: 'inline-block',\n }} />\n {value}\n </span>\n );\n}\n\nexport function ComparisonMatrix({ sources, defaultCurrency = 'KES', displayConfig }: ComparisonMatrixProps) {\n if (!sources || sources.length < 2) return null;\n\n const products = sources.slice(0, 3);\n const rows = buildRows(products, displayConfig, defaultCurrency);\n const colTemplate = `140px repeat(${products.length}, 1fr)`;\n\n const labelStyle: React.CSSProperties = {\n padding: '10px 12px',\n fontSize: 11,\n fontWeight: 700,\n color: 'var(--hsk-text-muted, #4b5563)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n borderBottom: '1px solid var(--hsk-border, rgba(0,0,0,0.07))',\n verticalAlign: 'middle',\n whiteSpace: 'nowrap',\n display: 'flex',\n alignItems: 'center',\n };\n\n const cellBase: React.CSSProperties = {\n padding: '10px 14px',\n fontSize: 13,\n color: 'var(--hsk-text, #111827)',\n borderBottom: '1px solid var(--hsk-border, rgba(0,0,0,0.07))',\n verticalAlign: 'middle',\n display: 'flex',\n alignItems: 'center',\n };\n\n return (\n <div\n className=\"hsk-compare-matrix\"\n style={{\n marginTop: 10,\n borderRadius: 12,\n overflow: 'hidden',\n border: '1px solid var(--hsk-border, rgba(0,0,0,0.09))',\n background: 'var(--hsk-surface, #fff)',\n fontSize: 13,\n }}\n >\n <div style={{ display: 'grid', gridTemplateColumns: colTemplate, background: 'var(--hsk-surface2, #f9fafb)', borderBottom: '2px solid var(--hsk-border, rgba(0,0,0,0.09))' }}>\n <div style={{ ...labelStyle, borderBottom: 'none', color: 'var(--hsk-text, #111)', fontSize: 12 }}>Feature</div>\n {products.map((p, i) => {\n const { title } = resolveDisplayFields(p.fields || p, displayConfig);\n return (\n <a\n key={i}\n href={p.url || '#'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{\n display: 'flex',\n alignItems: 'center',\n padding: '10px 14px',\n fontSize: 12,\n fontWeight: 700,\n color: 'var(--hsk-primary, #16a34a)',\n textDecoration: 'none',\n lineHeight: 1.3,\n borderLeft: i > 0 ? '1px solid var(--hsk-border, rgba(0,0,0,0.07))' : 'none',\n }}\n >\n {title}\n </a>\n );\n })}\n </div>\n\n {rows.map((row, rowIdx) => (\n <div\n key={rowIdx}\n style={{\n display: 'grid',\n gridTemplateColumns: colTemplate,\n background: rowIdx % 2 === 1 ? 'var(--hsk-surface2, rgba(0,0,0,0.015))' : 'transparent',\n }}\n >\n <div style={labelStyle}>{row.label}</div>\n\n {products.map((p, i) => {\n const val = row.values[i];\n const isBest = row.bestIdx === i && row.values.filter(Boolean).length > 1;\n const { title } = resolveDisplayFields(p.fields || p, displayConfig);\n\n if (row.type === 'image') {\n return (\n <div key={i} style={{ ...cellBase, justifyContent: 'center', padding: '12px', borderLeft: i > 0 ? '1px solid var(--hsk-border, rgba(0,0,0,0.07))' : 'none' }}>\n <ImageCell value={val} name={title} />\n </div>\n );\n }\n if (row.type === 'availability') {\n return (\n <div key={i} style={{ ...cellBase, borderLeft: i > 0 ? '1px solid var(--hsk-border, rgba(0,0,0,0.07))' : 'none' }}>\n <AvailabilityCell value={val} />\n </div>\n );\n }\n return (\n <div\n key={i}\n style={{\n ...cellBase,\n fontWeight: isBest ? 700 : 400,\n color: isBest\n ? 'var(--hsk-primary, #ea580c)'\n : row.type === 'price'\n ? 'var(--hsk-text, #374151)'\n : 'var(--hsk-text, #111827)',\n borderLeft: i > 0 ? '1px solid var(--hsk-border, rgba(0,0,0,0.07))' : 'none',\n }}\n >\n {val ?? <span style={{ color: '#9ca3af' }}>—</span>}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n );\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useSearch, useKiku, useAkropolysContext } from '@akropolys/sdk';\nimport { renderMarkdown } from '../utils/markdown';\nimport { SearchResult, Product, AkropolysTheme } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\n\nexport interface SparkleProps {\n productName: string;\n limit?: number;\n onResult?: (results: SearchResult[]) => void;\n /** Override the backdrop colour (any CSS colour/gradient) */\n backdropColor?: string;\n /** Override backdrop blur — e.g. \"8px\" or 8 */\n backdropBlur?: string | number;\n /** Extra classes on the trigger button */\n className?: string;\n /** Called when user clicks a result — return false to prevent default navigation */\n onNavigate?: (result: SearchResult) => boolean | void;\n theme?: AkropolysTheme;\n classNames?: {\n button?: string;\n backdrop?: string;\n card?: string;\n item?: string;\n };\n product?: Product;\n children?: React.ReactNode;\n}\n\n/* ── Modal ────────────────────────────────────────────────────────────────── */\ninterface ModalProps extends Pick<SparkleProps, 'productName' | 'limit' | 'backdropColor' | 'backdropBlur' | 'onNavigate' | 'onResult' | 'theme' | 'classNames' | 'product'> {\n onClose: () => void;\n}\n\nconst SparkleIcon = ({ className, size = 16 }: { className?: string; size?: number }) => (\n <svg\n className={cn(\"hsk-brand-a\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 28 30\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-label=\"Akropolys\"\n >\n {/* Left leg: elegant thin stroke */}\n <path\n d=\"M14.5 4.5 L6.5 25\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n />\n {/* Right leg: bold ancient serif thick stroke */}\n <path\n d=\"M14.5 4.5 L22.5 25\"\n stroke=\"currentColor\"\n strokeWidth=\"4.2\"\n strokeLinecap=\"round\"\n />\n {/* Crossbar */}\n <path\n d=\"M9.5 17 H19.5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n {/* Left base serif */}\n <path\n d=\"M3 25 H10\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n {/* Right base serif */}\n <path\n d=\"M19 25 H26\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n {/* Smooth breathing mark (spiritus lenis) at top-left — animated */}\n <path\n d=\"M8.5 2.5 C10 2.5, 11 3.5, 11 5 C11 7, 8.5 8.5, 7.5 9.5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n fill=\"none\"\n className=\"hsk-akr-breath\"\n />\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\n/* ── Modal ────────────────────────────────────────────────────────────────── */\ninterface ModalProps extends Pick<SparkleProps, 'productName' | 'limit' | 'backdropColor' | 'backdropBlur' | 'onNavigate' | 'onResult' | 'theme' | 'classNames' | 'product'> {\n onClose: () => void;\n}\n\nconst getFriendlyError = (err: any) => {\n let str = '';\n if (typeof err === 'string') str = err;\n else if (err && typeof err === 'object' && err.message) str = err.message;\n else try { str = JSON.stringify(err); } catch { str = String(err); }\n\n if (str.toLowerCase().includes('token limit')) {\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\n }\n\n try {\n const parsed = JSON.parse(str);\n return parsed.error || parsed.message || str;\n } catch {\n return str;\n }\n};\n\nfunction SparkleModal({ \n productName, \n limit, \n backdropColor, \n backdropBlur, \n onClose, \n onNavigate, \n onResult,\n theme,\n classNames = {},\n product: initialProduct,\n}: ModalProps) {\n const client = useAkropolysContext();\n const [fetchedProduct, setFetchedProduct] = useState<Product | null>(null);\n const displayProduct = initialProduct || fetchedProduct;\n const { results, loading: searchLoading, search } = useSearch({ type: 'vector' });\n const { messages, sources, loading: chatLoading, error: chatError, send } = useKiku();\n const [chatInput, setChatInput] = useState('');\n const [isMobile, setIsMobile] = useState(false);\n const [showSpecs, setShowSpecs] = useState(false);\n const [collapseSimilar, setCollapseSimilar] = useState(false);\n const chatBottomRef = useRef<HTMLDivElement>(null);\n const chatTextareaRef = useRef<HTMLTextAreaElement>(null);\n\n /* auto-search and product fetching on open */\n useEffect(() => {\n if (!initialProduct && !fetchedProduct) {\n client.api.searchVector(productName, 1)\n .then(res => {\n if (res.results && res.results.length > 0) {\n setFetchedProduct(res.results[0].entity);\n }\n })\n .catch(err => console.error('[Akropolys] Failed to fetch product details', err));\n }\n search(productName, limit);\n }, [productName, initialProduct, fetchedProduct, client, limit, search]);\n\n /* handle window resize for mobile check */\n useEffect(() => {\n const handleResize = () => setIsMobile(window.innerWidth <= 768);\n handleResize();\n if (typeof window !== 'undefined') {\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }\n }, []);\n\n /* fire callback */\n useEffect(() => { if (results.length > 0) onResult?.(results); }, [results, onResult]);\n\n /* Escape key */\n useEffect(() => {\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, [onClose]);\n\n /* Scroll chat to bottom */\n useEffect(() => {\n chatBottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages, chatLoading]);\n\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '16px');\n const bg = backdropColor ?? undefined;\n\n const handleNav = (r: SearchResult) => {\n const prevent = onNavigate?.(r);\n if (prevent !== false) {\n onClose();\n if (r.entity.url) window.location.href = r.entity.url;\n }\n };\n\n const handleSend = async (text?: string) => {\n const q = (text ?? chatInput).trim();\n if (!q || chatLoading) return;\n setChatInput('');\n if (chatTextareaRef.current) {\n chatTextareaRef.current.style.height = 'auto';\n }\n\n if (messages.length === 0 && displayProduct) {\n const contextQuery = `[Context: Shopper is viewing \"${displayProduct.name}\". Price: ${displayProduct.price}. Description: ${displayProduct.description || ''}]\\n\\nQuestion: ${q}`;\n await send(contextQuery, q);\n } else {\n await send(q);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setChatInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\n };\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n const displayMessages = messages.length === 0 && displayProduct\n ? [\n {\n role: 'assistant' as const,\n content: `Hi! I can help you with **${displayProduct.name}**. Ask me about its specifications, features, compare it with other options, or find alternatives!`,\n },\n ]\n : messages;\n\n if (isMobile) {\n return (\n <div\n className={cn(\"hsk-sp-backdrop hsk-sp-mobile-view\", classNames.backdrop)}\n onClick={onClose}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n background: bg ?? undefined,\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-sp-card hsk-sp-fullscreen hsk-sp-mobile-card\", classNames.card)} onClick={e => e.stopPropagation()}>\n {/* Header */}\n <div className=\"hsk-sp-header\">\n <span className=\"hsk-sp-header-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div className=\"hsk-sp-header-body\">\n <div className=\"hsk-sp-header-title-row\">\n <div className=\"hsk-sp-header-title\">{displayProduct?.name || productName}</div>\n {displayProduct && (\n <button \n type=\"button\" \n className=\"hsk-sp-header-specs-btn\"\n onClick={() => setShowSpecs(true)}\n >\n Specs\n </button>\n )}\n </div>\n <div className=\"hsk-sp-header-sub\">Akropolys AI Shopping Assistant</div>\n </div>\n <button className=\"hsk-sp-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n\n {searchLoading && <div className=\"hsk-sp-bar\" />}\n\n {/* Chat Assistant */}\n <div className=\"hsk-sp-mobile-chat-container\">\n <div className=\"hsk-cb-msgs\">\n {displayMessages.map((msg, idx) => {\n const isUser = msg.role === 'user';\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\n </div>\n ) : (\n <div className=\"hsk-cb-ai-msg\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-ai-body\">\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\n \n {/* Inline Claude-like attachments under the first assistant message */}\n {idx === 0 && displayProduct && (\n <div className=\"hsk-sp-mobile-attachment-deck\">\n {/* Main Product Card */}\n <div className=\"hsk-sp-mobile-main-card\">\n <div className=\"hsk-sp-mobile-main-card-img\">\n {displayProduct.images?.[0] ? (\n <img src={displayProduct.images[0]} alt={displayProduct.name} />\n ) : (\n <span>ðŸ›</span>\n )}\n </div>\n <div className=\"hsk-sp-mobile-main-card-info\">\n <div className=\"hsk-sp-mobile-main-card-brand\">\n {displayProduct.brand || displayProduct.category || 'Product'}\n </div>\n <div className=\"hsk-sp-mobile-main-card-name\">{displayProduct.name}</div>\n <div className=\"hsk-sp-mobile-main-card-price\">\n {displayProduct.currency ?? 'KES'} {parseFloat(displayProduct.price?.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n </div>\n {((displayProduct.specs && Object.keys(displayProduct.specs).length > 0) || displayProduct.description) && (\n <button \n type=\"button\"\n className=\"hsk-sp-mobile-main-card-specs-btn\"\n onClick={() => setShowSpecs(true)}\n >\n Specs\n </button>\n )}\n </div>\n\n {/* Similar Products Carousel */}\n {(() => {\n const similarProducts = results.filter(\n r => {\n const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());\n const isSameSlug = r.entity.slug && displayProduct?.slug && r.entity.slug.toLowerCase() === displayProduct.slug.toLowerCase();\n return !isSameName && !isSameSlug;\n }\n );\n\n if (similarProducts.length === 0) return null;\n\n return (\n <div className=\"hsk-sp-mobile-similar-carousel-inline\">\n <div className=\"hsk-sp-mobile-similar-carousel-title\">Similar Products</div>\n <div className=\"hsk-sp-mobile-similar-carousel-list\">\n {similarProducts.map((r) => {\n const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, '') || '0');\n const currency = r.entity.currency ?? 'KES';\n return (\n <div\n key={r.id}\n className=\"hsk-sp-mobile-similar-carousel-item\"\n onClick={() => handleNav(r)}\n >\n <div className=\"hsk-sp-mobile-similar-carousel-img\">\n {r.entity.images?.[0] ? (\n <img src={r.entity.images[0]} alt={r.entity.name} />\n ) : (\n <span>ðŸ›</span>\n )}\n </div>\n <div className=\"hsk-sp-mobile-similar-carousel-meta\">\n <div className=\"hsk-sp-mobile-similar-carousel-name\" title={r.entity.name}>\n {r.entity.name}\n </div>\n <div className=\"hsk-sp-mobile-similar-carousel-price\">\n {currency} {price.toLocaleString()}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n })()}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n })}\n\n {chatLoading && (\n <div className=\"hsk-cb-typing-row\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-typing\">\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n )}\n\n {chatError && <div className=\"hsk-cb-error\">{getFriendlyError(chatError)}</div>}\n <div ref={chatBottomRef} style={{ height: 1 }} />\n </div>\n\n <div className=\"hsk-cb-input-wrap\">\n <div className=\"hsk-cb-input-box\">\n <textarea\n ref={chatTextareaRef}\n className=\"hsk-cb-textarea\"\n value={chatInput}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder=\"Ask about this product, specs, or comparison...\"\n rows={1}\n disabled={chatLoading}\n />\n <button\n className=\"hsk-cb-send\"\n onClick={() => handleSend()}\n disabled={!chatInput.trim() || chatLoading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n </div>\n </div>\n\n {/* Specs Sheet Drawer Overlay */}\n {showSpecs && displayProduct && (\n <div className=\"hsk-sp-mobile-specs-overlay\" onClick={() => setShowSpecs(false)}>\n <div className=\"hsk-sp-mobile-specs-drawer\" onClick={e => e.stopPropagation()}>\n <div className=\"hsk-sp-mobile-specs-header\">\n <h3>Specifications</h3>\n <button type=\"button\" onClick={() => setShowSpecs(false)}>Close</button>\n </div>\n <div className=\"hsk-sp-mobile-specs-body\">\n <h4 className=\"hsk-sp-mobile-specs-title\">{displayProduct.name}</h4>\n {displayProduct.description && (\n <div className=\"hsk-sp-mobile-specs-desc\">\n <h5>Description</h5>\n <p>{displayProduct.description}</p>\n </div>\n )}\n {displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && (\n <div className=\"hsk-sp-mobile-specs-list\">\n <h5>Details</h5>\n {Object.entries(displayProduct.specs).map(([key, val]) => (\n <div key={key} className=\"hsk-sp-mobile-spec-row\">\n <span className=\"hsk-sp-mobile-spec-label\">{key}</span>\n <span className=\"hsk-sp-mobile-spec-value\">{val}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"hsk-sp-backdrop\", classNames.backdrop)}\n onClick={onClose}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n background: bg ?? undefined,\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-sp-card hsk-sp-fullscreen\", classNames.card)} onClick={e => e.stopPropagation()}>\n <div className=\"hsk-sp-header\">\n <span className=\"hsk-sp-header-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div className=\"hsk-sp-header-body\">\n <div className=\"hsk-sp-header-title\">{displayProduct?.name || productName}</div>\n <div className=\"hsk-sp-header-sub\">Ask questions, compare specs, or check similar products</div>\n </div>\n <button className=\"hsk-sp-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n\n {searchLoading && <div className=\"hsk-sp-bar\" />}\n\n {/* Split pane body */}\n <div className=\"hsk-sp-body\">\n {/* Left Pane: Product Profile */}\n <div className=\"hsk-sp-details-pane\">\n {displayProduct && (\n <div className=\"hsk-sp-product-profile-container\">\n <div className=\"hsk-sp-product-profile\">\n <div className=\"hsk-sp-details-imgwrap\">\n {displayProduct.images?.[0] ? (\n <img src={displayProduct.images[0]} alt={displayProduct.name} />\n ) : (\n <span className=\"hsk-sp-img-placeholder\">ðŸ›</span>\n )}\n </div>\n <div className=\"hsk-sp-details-meta\">\n {displayProduct.brand && <span className=\"hsk-sp-item-brand\">{displayProduct.brand}</span>}\n {displayProduct.category && <span className=\"hsk-sp-item-cat\">{displayProduct.category}</span>}\n <h2 className=\"hsk-sp-details-name\">{displayProduct.name}</h2>\n <div className=\"hsk-sp-item-price-row\">\n <span className=\"hsk-sp-item-currency\">{displayProduct.currency ?? 'KES'}</span>\n <span className=\"hsk-sp-item-price\">{parseFloat(displayProduct.price?.replace(/[^0-9.]/g, '') || '0').toLocaleString()}</span>\n {displayProduct.originalPrice && (\n <span className=\"hsk-sp-item-original-price\">\n {parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </span>\n )}\n {displayProduct.discount && (\n <span className=\"hsk-sp-item-discount\">({displayProduct.discount})</span>\n )}\n </div>\n \n <div className=\"hsk-sp-item-meta-badges\">\n {displayProduct.rating && (\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-rating\">\n ★ {parseFloat(displayProduct.rating.toString()).toFixed(1)} {displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ''}\n </span>\n )}\n {displayProduct.availability && (\n <span className={`hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes('in') ? 'in-stock' : 'out-stock'}`}>\n {displayProduct.availability}\n </span>\n )}\n {displayProduct.stock && !displayProduct.availability && (\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-stock\">\n Stock: {displayProduct.stock}\n </span>\n )}\n </div>\n </div>\n </div>\n\n {displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && (\n <div className=\"hsk-sp-specs-horizontal\">\n {Object.entries(displayProduct.specs).map(([key, val]) => (\n <div key={key} className=\"hsk-sp-spec-item-horizontal\">\n <span className=\"hsk-sp-spec-label-horizontal\">{key}:</span>\n <span className=\"hsk-sp-spec-value-horizontal\" title={val}>{val}</span>\n </div>\n ))}\n </div>\n )}\n\n {displayProduct.description && (\n <div className=\"hsk-sp-details-desc\">\n <h4>Description</h4>\n <p>{displayProduct.description}</p>\n </div>\n )}\n </div>\n )}\n\n {/* Similar Products */}\n <div className=\"hsk-sp-similar-section\">\n <h3>Similar Products</h3>\n <div className=\"hsk-sp-results\">\n {(() => {\n const similarProducts = results.filter(\n r => {\n const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());\n const isSameSlug = r.entity.slug && displayProduct?.slug && r.entity.slug.toLowerCase() === displayProduct.slug.toLowerCase();\n return !isSameName && !isSameSlug;\n }\n );\n\n if (!searchLoading && similarProducts.length === 0) {\n return <div className=\"hsk-sp-empty\">No similar products found.</div>;\n }\n\n return similarProducts.map((r, i) => {\n const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, '') || '0');\n const currency = r.entity.currency ?? 'KES';\n return (\n <div\n key={r.id}\n className={cn(\"hsk-sp-item\", classNames.item)}\n style={{ animationDelay: `${i * 55}ms`, cursor: 'pointer' }}\n onClick={() => handleNav(r)}\n >\n <div className=\"hsk-sp-img-wrap\">\n {r.entity.images?.[0] ? (\n <img src={r.entity.images[0]} alt={r.entity.name} />\n ) : (\n <span className=\"hsk-sp-img-placeholder\">ðŸ›</span>\n )}\n </div>\n <div className=\"hsk-sp-item-body\">\n <div>\n {r.entity.category && (\n <div className=\"hsk-sp-item-cat\">{r.entity.category}</div>\n )}\n <div className=\"hsk-sp-item-name\" title={r.entity.name}>{r.entity.name}</div>\n </div>\n <div className=\"hsk-sp-item-price-row\">\n <span className=\"hsk-sp-item-currency\">{currency}</span>\n <span className=\"hsk-sp-item-price\">{price.toLocaleString()}</span>\n </div>\n <div className=\"hsk-sp-actions\">\n <button\n className=\"hsk-sp-action hsk-sp-action-primary\"\n onClick={(e) => { e.stopPropagation(); handleNav(r); }}\n >\n View\n </button>\n </div>\n </div>\n </div>\n );\n });\n })()}\n </div>\n </div>\n </div>\n\n {/* Right Pane: AI Chat Assistant */}\n <div className=\"hsk-sp-chat-pane\">\n <div className=\"hsk-cb-msgs\">\n {displayMessages.map((msg, idx) => {\n const isUser = msg.role === 'user';\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\n </div>\n ) : (\n <div className=\"hsk-cb-ai-msg\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-ai-body\">\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\n </div>\n </div>\n )}\n </div>\n );\n })}\n\n {chatLoading && (\n <div className=\"hsk-cb-typing-row\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-typing\">\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n )}\n\n {chatError && <div className=\"hsk-cb-error\">{getFriendlyError(chatError)}</div>}\n <div ref={chatBottomRef} style={{ height: 1 }} />\n </div>\n\n <div className=\"hsk-cb-input-wrap\">\n <div className=\"hsk-cb-input-box\">\n <textarea\n ref={chatTextareaRef}\n className=\"hsk-cb-textarea\"\n value={chatInput}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder=\"Ask about this product, specs, or comparison...\"\n rows={1}\n disabled={chatLoading}\n />\n <button\n className=\"hsk-cb-send\"\n onClick={() => handleSend()}\n disabled={!chatInput.trim() || chatLoading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n <div className=\"hsk-cb-hint\">Akropolys · instant product knowledge</div>\n </div>\n </div>\n </div>\n\n <div className=\"hsk-sp-footer\">\n <span className=\"hsk-sp-esc\">Esc to close</span>\n </div>\n </div>\n </div>\n );\n}\n\n/* ── Exported component ───────────────────────────────────────────────────── */\nexport function Sparkle({ \n productName, \n limit = 8, \n onResult, \n backdropColor, \n backdropBlur, \n className, \n onNavigate,\n theme,\n classNames = {},\n product,\n children,\n}: SparkleProps) {\n const [open, setOpen] = useState(false);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => { setMounted(true); }, []);\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <>\n <button\n className={cn(\"hsk-sp-btn\", classNames.button, className)}\n onClick={() => setOpen(true)}\n style={customStyles}\n title=\"Find similar products\"\n aria-label=\"Find similar products\"\n >\n {children || <SparkleIcon />}\n </button>\n {open && mounted && createPortal(\n <SparkleModal\n productName={productName}\n limit={limit}\n onResult={onResult}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n onClose={() => setOpen(false)}\n onNavigate={onNavigate}\n theme={theme}\n classNames={classNames}\n product={product}\n />,\n document.body\n )}\n </>\n );\n}\n\r\n"],"mappings":"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","names":["useState","useRef","useEffect","Fragment","jsx","useState","useRef","jsx","jsxs","useRef","useState","useAkropolysContext","jsx","jsxs","jsx","jsxs","useState","useRef","useEffect","useState","useEffect","useRef","useCallback","useKiku","useAkropolysContext","jsx","jsxs","Fragment","jsx","jsxs","SparkleIcon","ArrowUpIcon","jsx","MicIcon","jsxs","SparkleIcon","useAkropolysContext","useRef","useState","useCallback","useEffect","Fragment","useKiku","ArrowUpIcon","useState","useEffect","useRef","createPortal","useSearch","useKiku","useAkropolysContext","Fragment","jsx","jsxs","SparkleIcon","CloseIcon","ArrowUpIcon","getFriendlyError","useAkropolysContext","useState","useSearch","useKiku","useRef","useEffect","createPortal"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/SearchBar.tsx","../src/utils/cn.ts","../src/components/ChatWidget.tsx","../src/utils/markdown.tsx","../src/components/VoiceButton.tsx","../src/components/VisualSearch.tsx","../src/components/KikuButton.tsx","../src/components/ComparisonMatrix.tsx","../src/components/Sparkle.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport { useSearch, SearchResult, AkropolysTheme, useAkropolysContext } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\n\nexport interface SearchBarProps {\n placeholder?: string;\n limit?: number;\n /** Debounce in ms — default 150 for instant type-ahead */\n debounceMs?: number;\n onSelect?: (result: SearchResult) => void;\n className?: string;\n inputClassName?: string;\n dropdownClassName?: string;\n renderResult?: (result: SearchResult) => React.ReactNode;\n theme?: AkropolysTheme;\n classNames?: {\n root?: string;\n input?: string;\n dropdown?: string;\n row?: string;\n };\n}\n\n/* SVG search glass — pure inline so no icon dependency */\nconst SearchIcon = () => (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\"/>\n <line x1=\"13\" y1=\"13\" x2=\"18\" y2=\"18\"/>\n </svg>\n);\n\nexport function SearchBar({\n placeholder = 'Search products…',\n limit = 10,\n debounceMs = 150,\n onSelect,\n className,\n inputClassName,\n dropdownClassName,\n renderResult,\n theme,\n classNames = {},\n}: SearchBarProps) {\n const [query, setQuery] = useState('');\n const [open, setOpen] = useState(false);\n const { results, loading, search, clear } = useSearch({ debounceMs });\n const client = useAkropolysContext();\n const wrap = useRef<HTMLDivElement>(null);\n const ignoreNextQueryChange = useRef(false);\n\n /* useSearch debounces internally — fire on every keystroke, keep stale results visible */\n useEffect(() => {\n if (ignoreNextQueryChange.current) {\n ignoreNextQueryChange.current = false;\n return;\n }\n if (!query.trim()) {\n clear();\n setOpen(false);\n return;\n }\n setOpen(true); // open immediately (stale results show while fetching)\n search(query, limit);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [query]);\n\n /* Click-outside to close */\n useEffect(() => {\n const h = (e: MouseEvent) => {\n if (wrap.current && !wrap.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', h);\n return () => document.removeEventListener('mousedown', h);\n }, []);\n\n const handleSelect = (r: SearchResult) => {\n if (query.trim()) {\n // keepalive: onSelect commonly navigates the page right after this call —\n // without it the browser aborts the in-flight log request mid-navigation.\n client.api.searchVector(query, 1, undefined, true).catch(() => {});\n }\n ignoreNextQueryChange.current = true;\n setOpen(false);\n setQuery(r.entity.title ?? r.entity.name ?? '');\n onSelect?.(r);\n };\n\n const handleCommitSearch = () => {\n if (!query.trim()) return;\n client.api.searchVector(query, 1, undefined, true).catch(() => {});\n if (results.length > 0) {\n handleSelect(results[0]);\n }\n };\n\n const showDrop = open && query.trim().length > 0;\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div className={cn(\"hsk-sb-wrap\", classNames.root, className)} ref={wrap} style={customStyles}>\n <span className=\"hsk-sb-icon\"><SearchIcon /></span>\n <input\n className={cn(\"hsk-sb-input\", classNames.input, inputClassName)}\n type=\"text\"\n value={query}\n placeholder={placeholder}\n onChange={e => setQuery(e.target.value)}\n onFocus={() => results.length > 0 && query.trim() && setOpen(true)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n handleCommitSearch();\n }\n }}\n autoComplete=\"off\"\n spellCheck={false}\n />\n {showDrop && (\n <div className={cn(\"hsk-sb-drop\", classNames.dropdown, dropdownClassName)} style={{ position: 'absolute' }}>\n {loading && <div className=\"hsk-sb-loading-bar\" />}\n\n {loading && results.length === 0 ? (\n <>\n <div className=\"hsk-sb-skeleton-row\">\n <span className=\"hsk-sb-skeleton-icon\" />\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-skeleton-text1\" />\n <div className=\"hsk-sb-skeleton-text2\" />\n </div>\n </div>\n <div className=\"hsk-sb-skeleton-row\">\n <span className=\"hsk-sb-skeleton-icon\" />\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-skeleton-text1\" style={{ width: '45%' }} />\n <div className=\"hsk-sb-skeleton-text2\" style={{ width: '25%' }} />\n </div>\n </div>\n </>\n ) : (\n <>\n {results.length === 0 && !loading && (\n <div className=\"hsk-sb-empty\">No results for “{query}”</div>\n )}\n\n {results.map((r, i) => {\n if (renderResult) {\n return (\n <div\n key={r.id}\n onClick={() => handleSelect(r)}\n className=\"hsk-sb-fade\"\n style={{ animationDelay: `${i * 18}ms` }}\n >\n {renderResult(r)}\n </div>\n );\n }\n const thumb = r.entity.image ?? r.entity.thumbnail ?? r.entity.images?.[0];\n return (\n <div\n key={r.id}\n className={cn(\"hsk-sb-row hsk-sb-fade\", classNames.row)}\n style={{ animationDelay: `${i * 18}ms` }}\n onClick={() => handleSelect(r)}\n >\n <span className=\"hsk-sb-row-thumb\">\n {thumb ? (\n <img\n src={thumb}\n alt=\"\"\n loading=\"lazy\"\n onError={e => { e.currentTarget.style.display = 'none'; }}\n />\n ) : (\n <SearchIcon />\n )}\n </span>\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-row-title\">{r.entity.title ?? r.entity.name}</div>\n {(r.entity.category || r.entity.brand) && (\n <div className=\"hsk-sb-row-sub\">\n {r.entity.category ?? r.entity.brand}\n </div>\n )}\n </div>\n </div>\n );\n })}\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merges Tailwind classes intelligently, allowing overrides.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import React, { useState, useRef, useEffect } from 'react';\nimport { useKiku, ChatMessage, ChatSource } from '@akropolys/sdk';\nimport { renderMarkdown } from '../utils/markdown';\nimport { AkropolysTheme } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\nimport { VoiceButton } from './VoiceButton';\nimport { VisualSearch } from './VisualSearch';\n\n// Better Prop Interface for SDKs\nexport interface ChatWidgetProps {\n title?: string;\n placeholder?: string;\n emptyStateText?: string;\n emptyStateSuggestions?: string;\n defaultCurrency?: string;\n className?: string;\n \n // Allow overriding styles via standard CSS variables\n theme?: AkropolysTheme;\n \n // Allow targeting specific elements with custom classes (e.g. Tailwind)\n classNames?: {\n root?: string;\n header?: string;\n messageBubble?: string;\n input?: string;\n };\n \n onSelectSource?: (source: ChatSource) => void;\n\n /** Enable 🎙️ voice input via browser Web Speech API (free) */\n enableVoice?: boolean;\n /** Enable 📷 visual style-match search via Gemini (requires backend GEMINI_API_KEY) */\n enableVision?: boolean;\n /** Optional category hint for visual search (e.g. 'dress', 'curtains') */\n visionCategoryHint?: string;\n}\n\n// Simple SVG Icons instead of text characters\nconst SparkleIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <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\"/>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\nfunction SourceCard({\n source,\n defaultCurrency,\n onSelect,\n isReferenced\n}: {\n source: ChatSource;\n defaultCurrency: string;\n onSelect?: (s: ChatSource) => void;\n isReferenced?: boolean;\n}) {\n return (\n <div\n className={cn(\"hsk-source-card\", isReferenced && \"hsk-source-card--referenced\")}\n onClick={() => onSelect?.(source)}\n >\n {source.image && <img src={source.image} alt={source.name} className=\"hsk-source-img\" />}\n <div style={{ flex: 1, minWidth: 0, position: 'relative' }}>\n {isReferenced && (\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\" style={{ top: '0', right: '0' }}>\n <SparkleIcon />\n </div>\n )}\n <div className=\"hsk-source-name\" style={{ paddingRight: isReferenced ? '20px' : undefined }}>{source.name}</div>\n {source.price && (\n <div className=\"hsk-source-price\">{source.currency ?? defaultCurrency} {source.price}</div>\n )}\n </div>\n </div>\n );\n}\n\ninterface ChatMessageWithVisual extends ChatMessage {\n imagePreview?: string;\n styleDNA?: any;\n visualSources?: ChatSource[];\n}\n\nexport function ChatWidget({ \n title = 'kiku',\n placeholder = 'Ask about anything in our store…', \n emptyStateText = 'Ask me anything about our products',\n emptyStateSuggestions = '\"Find me headphones under KSh 5,000\" · \"Gift ideas\"',\n defaultCurrency = 'KES',\n className,\n theme,\n classNames = {},\n onSelectSource,\n enableVoice = false,\n enableVision = false,\n visionCategoryHint\n}: ChatWidgetProps) {\n const { messages, sources, referencedIds, loading: chatLoading, streaming, error, send, reset } = useKiku();\n const [input, setInput] = useState('');\n const [visualLoading, setVisualLoading] = useState(false);\n const bottomRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const loading = chatLoading || visualLoading;\n\n const [chatHistory, setChatHistory] = useState<ChatMessageWithVisual[]>([]);\n const lastSyncedCount = useRef(0);\n\n useEffect(() => {\n if (messages.length === 0) {\n setChatHistory([]);\n lastSyncedCount.current = 0;\n return;\n }\n\n if (messages.length > lastSyncedCount.current) {\n const newMsgs = messages.slice(lastSyncedCount.current);\n setChatHistory(prev => [...prev, ...newMsgs]);\n lastSyncedCount.current = messages.length;\n } else if (messages.length < lastSyncedCount.current) {\n setChatHistory(messages);\n lastSyncedCount.current = messages.length;\n } else {\n setChatHistory(prev => {\n const next = [...prev];\n let hookIdx = messages.length - 1;\n let historyIdx = next.length - 1;\n while (hookIdx >= 0 && historyIdx >= 0) {\n if (next[historyIdx].role === messages[hookIdx].role) {\n next[historyIdx] = {\n ...next[historyIdx],\n content: messages[hookIdx].content,\n actionType: messages[hookIdx].actionType,\n };\n break;\n }\n historyIdx--;\n }\n return next;\n });\n }\n }, [messages]);\n\n useEffect(() => {\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [chatHistory, loading]);\n\n const handleSend = async () => {\n const q = input.trim();\n if (!q || loading) return;\n setInput('');\n if (textareaRef.current) textareaRef.current.style.height = 'auto';\n await send(q);\n };\n\n const handleKey = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = Math.min(t.scrollHeight, 120) + 'px';\n };\n\n const handleVisualResults = (res: any, preview: string) => {\n const userMsg: ChatMessageWithVisual = {\n role: 'user',\n content: 'Uploaded a photo for visual search',\n imagePreview: preview,\n };\n\n const dna = res.style_dna;\n let content = `I've analyzed your image! Here is the Style DNA I found:\\n`;\n if (dna) {\n if (dna.color_palette) content += `* **Palette:** ${dna.color_palette}\\n`;\n if (dna.dominant_colors && dna.dominant_colors.length > 0) {\n content += `* **Colors:** ${dna.dominant_colors.join(', ')}\\n`;\n }\n if (dna.aesthetic && dna.aesthetic.length > 0) {\n content += `* **Aesthetic:** ${dna.aesthetic.join(', ')}\\n`;\n }\n if (dna.texture) content += `* **Texture:** ${dna.texture}\\n`;\n if (dna.formality) content += `* **Formality:** ${dna.formality}\\n`;\n }\n\n const results = res.results || [];\n if (results.length > 0) {\n content += `\\nI found ${results.length} matching products in the store for you.`;\n } else {\n content += `\\nI couldn't find any matching products in the store.`;\n }\n\n const assistantMsg: ChatMessageWithVisual = {\n role: 'assistant',\n content,\n styleDNA: dna,\n visualSources: results.map((r: any) => ({\n id: r.id,\n name: r.product.name,\n price: r.product.price,\n currency: r.product.currency,\n category: r.product.category,\n url: r.product.url,\n image: r.product.images && r.product.images.length > 0 ? r.product.images[0] : undefined,\n brand: r.product.brand,\n })),\n };\n\n setChatHistory(prev => [...prev, userMsg, assistantMsg]);\n };\n\n // Apply custom CSS variables inline to the root wrapper\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div \n className={cn(\"hsk-chat-widget\", classNames.root, className)} \n style={customStyles}\n >\n <div className={cn(\"hsk-chat-header\", classNames.header)}>\n <span className=\"hsk-chat-header-icon\"><SparkleIcon /></span>\n <span className=\"hsk-chat-title\">{title}</span>\n <span className=\"hsk-chat-badge\">AI</span>\n {chatHistory.length > 0 && (\n <button className=\"hsk-chat-reset\" onClick={reset} style={{ marginLeft: 'auto' }}>Clear</button>\n )}\n </div>\n\n <div className=\"hsk-chat-messages\">\n {chatHistory.length === 0 ? (\n <div className=\"hsk-chat-empty\">\n <div className=\"hsk-chat-empty-icon\"><SparkleIcon /></div>\n <div>{emptyStateText}</div>\n <div className=\"hsk-chat-empty-suggestions\">{emptyStateSuggestions}</div>\n </div>\n ) : (\n chatHistory.map((msg, idx) => (\n <div key={idx}>\n <div className={`hsk-msg-row ${msg.role}`}>\n <div className={cn(\"hsk-msg-avatar\", msg.role === 'assistant' ? 'ai' : 'user')}>\n {msg.role === 'assistant' ? <SparkleIcon /> : 'U'}\n </div>\n <div className={cn(\"hsk-msg-bubble\", msg.role, classNames.messageBubble)}>\n {msg.imagePreview && (\n <div className=\"kiku-vs-preview-bubble\" style={{ marginBottom: '8px' }}>\n <img src={msg.imagePreview} alt=\"Uploaded Preview\" className=\"kiku-vs-preview-bubble-img\" style={{ maxWidth: '200px', borderRadius: '8px' }} />\n </div>\n )}\n {renderMarkdown(msg.content)}\n {msg.styleDNA && (\n <div className=\"kiku-vs-preview-banner\" style={{ marginTop: '10px' }}>\n {chatHistory[idx - 1]?.imagePreview && (\n <img src={chatHistory[idx - 1].imagePreview} alt=\"Visual Search Input\" className=\"kiku-vs-preview-img\" />\n )}\n <div className=\"kiku-vs-preview-info\">\n <div className=\"kiku-vs-preview-label\">Visual Match Palette</div>\n <div className=\"kiku-vs-preview-palette\">{msg.styleDNA.color_palette || 'Detected Style DNA'}</div>\n {msg.styleDNA.style_tags && msg.styleDNA.style_tags.length > 0 && (\n <div className=\"kiku-style-tags\">\n {msg.styleDNA.style_tags.map((tag: string, ti: number) => (\n <span key={ti} className=\"kiku-style-tag\">#{tag}</span>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n {msg.role === 'assistant' && msg.visualSources && msg.visualSources.length > 0 && (\n <div className=\"hsk-sources-container\">\n <div className=\"hsk-sources\">\n {msg.visualSources.map((src, si) => (\n <SourceCard key={si} source={src} defaultCurrency={defaultCurrency} onSelect={onSelectSource} />\n ))}\n </div>\n </div>\n )}\n {msg.role === 'assistant' && idx === chatHistory.length - 1 && !msg.visualSources && sources.length > 0 && (() => {\n const isStreamingActive = chatLoading || streaming;\n if (isStreamingActive) {\n return (\n <div className=\"hsk-sources-container\">\n <div className=\"hsk-sources\">\n {sources.map((src, si) => {\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\n return (\n <SourceCard\n key={si}\n source={src}\n defaultCurrency={defaultCurrency}\n onSelect={onSelectSource}\n isReferenced={isReferenced}\n />\n );\n })}\n </div>\n </div>\n );\n }\n\n // Streaming finished: show the products the answer actually\n // references. Only fall back to the full candidate list when the\n // answer referenced none — showing unrelated matches (a kids'\n // sandal for a \"heels to match my dress\" query) reads as a bug.\n const featured = sources.filter(src => src.id && referencedIds.includes(src.id));\n // Only fall back to the candidate list when the answer referenced\n // nothing at all. If it referenced specific items, show just those —\n // never dump unrelated matches (e.g. phones for a sofa question).\n const general = referencedIds.length > 0\n ? []\n : sources.filter(src => !src.id || !referencedIds.includes(src.id));\n\n return (\n <div className=\"hsk-sources-container\">\n {featured.length > 0 && (\n <div className=\"hsk-sources-group\" style={{ marginBottom: '10px' }}>\n <div className=\"hsk-sources-group-title\">⭐ Featured in response</div>\n <div className=\"hsk-sources\">\n {featured.map((src, si) => (\n <SourceCard\n key={`feat-${si}`}\n source={src}\n defaultCurrency={defaultCurrency}\n onSelect={onSelectSource}\n isReferenced={true}\n />\n ))}\n </div>\n </div>\n )}\n {general.length > 0 && (\n <div className=\"hsk-sources-group\">\n {featured.length > 0 && <div className=\"hsk-sources-group-title\">All matches</div>}\n <div className=\"hsk-sources\">\n {general.map((src, si) => (\n <SourceCard\n key={`gen-${si}`}\n source={src}\n defaultCurrency={defaultCurrency}\n onSelect={onSelectSource}\n isReferenced={false}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n );\n })()}\n </div>\n ))\n )}\n\n {loading && (\n <div className=\"hsk-msg-row\">\n <div className=\"hsk-msg-avatar ai\"><SparkleIcon /></div>\n <div className=\"hsk-pending\" role=\"status\" aria-live=\"polite\">\n <div className=\"hsk-pending-glyph\">\n <span className=\"hsk-pending-ring\" />\n <span className=\"hsk-pending-dot\" />\n </div>\n <div className=\"hsk-pending-text\">\n <span className=\"hsk-pending-step step-1\">Searching catalog</span>\n <span className=\"hsk-pending-step step-2\">Reasoning</span>\n <span className=\"hsk-pending-step step-3\">Composing</span>\n </div>\n </div>\n </div>\n )}\n\n {error && (\n <div className=\"hsk-chat-error\">\n {(() => {\n try {\n const parsed = JSON.parse(error);\n return parsed.error || parsed.message || error;\n } catch {\n return error;\n }\n })()}\n </div>\n )}\n <div ref={bottomRef} />\n </div>\n\n <div className=\"hsk-chat-input-area\" style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n {enableVision && (\n <VisualSearch\n onResults={handleVisualResults}\n onError={(err) => console.error('[VisualSearch] error:', err)}\n categoryHint={visionCategoryHint}\n disabled={loading}\n />\n )}\n <textarea\n ref={textareaRef}\n className={cn(\"hsk-chat-input\", classNames.input)}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKey}\n placeholder={placeholder}\n rows={1}\n disabled={loading}\n style={{ flex: 1 }}\n />\n {enableVoice && (\n <VoiceButton\n onTranscript={(text) => {\n setInput(text);\n send(text);\n setInput('');\n }}\n onInterim={(text) => setInput(text)}\n disabled={loading}\n />\n )}\n <button\n className=\"hsk-chat-send\"\n onClick={handleSend}\n disabled={!input.trim() || loading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n </div>\n );\n}\n\n\n","import React from 'react';\n\n// Helper to parse inline styles (bold, images, links, and inline code) safely into React nodes\nconst parseInline = (text: string, keyPrefix: string): React.ReactNode => {\n // Regex matches: images , links [text](url), bold **text**, inline code `code`\n const tokenRegex = /(!\\[[^\\]]*\\]\\([^)]+\\)|\\[[^\\]]+\\]\\([^)]+\\)|\\*\\*[^*]+\\*\\*|`[^`]+`)/g;\n const parts = text.split(tokenRegex);\n\n return parts.map((part, index) => {\n if (!part) return null;\n const key = `${keyPrefix}-inline-${index}`;\n\n // Handle Inline Code\n if (part.startsWith('`') && part.endsWith('`')) {\n return (\n <code key={key} className=\"hsk-markdown-code\">\n {part.slice(1, -1)}\n </code>\n );\n }\n\n // Handle Bold\n if (part.startsWith('**') && part.endsWith('**')) {\n return <strong key={key}>{parseInline(part.slice(2, -2), key)}</strong>;\n }\n\n // Handle Images: \n const imageMatch = part.match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\n if (imageMatch) {\n const alt = imageMatch[1];\n const url = imageMatch[2];\n const isSafeUrl = /^(https?|data:image):/i.test(url);\n if (isSafeUrl) {\n return (\n <img\n key={key}\n src={url}\n alt={alt || 'Product image'}\n className=\"hsk-markdown-img\"\n loading=\"lazy\"\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\n />\n );\n }\n return null;\n }\n\n // Handle Links: [text](url)\n const linkMatch = part.match(/^\\[([^\\]]+)\\]\\(([^)]+)\\)$/);\n if (linkMatch) {\n // Basic sanitization: ensure the URL doesn't contain javascript:\n const url = linkMatch[2];\n const isSafeUrl = /^(https?|mailto|tel):/i.test(url) || url.startsWith('/');\n if (isSafeUrl) {\n return (\n <a key={key} href={url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"hsk-markdown-link\">\n {parseInline(linkMatch[1], key)}\n </a>\n );\n }\n return <span key={key}>{parseInline(linkMatch[1], key)}</span>; // Fallback to plain text if unsafe\n }\n\n // Return standard text\n return part;\n });\n};\n\n// A table can only START on a line beginning with \"|\"; continuations just need a \"|\".\nfunction isTableLine(line: string, inTable: boolean): boolean {\n const t = line.trim();\n if (inTable) return t.includes('|');\n return t.startsWith('|');\n}\n\n// Strips at most one leading + one trailing pipe, so a missing closing pipe never drops the last cell.\nfunction splitTableCells(rowLine: string): string[] {\n let t = rowLine.trim();\n if (t.startsWith('|')) t = t.slice(1);\n if (t.endsWith('|')) t = t.slice(0, -1);\n return t.split('|').map(c => c.trim());\n}\n\nexport function renderMarkdown(content: string, streaming = false): React.ReactNode {\n const lines = content.split('\\n');\n // While streaming, hold back a trailing table row whose closing pipe hasn't arrived yet.\n if (streaming && lines.length > 0) {\n const last = lines[lines.length - 1];\n if (last.trim().startsWith('|') && !last.trim().endsWith('|')) {\n lines.pop();\n }\n }\n const elements: React.ReactNode[] = [];\n\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n const key = `md-line-${i}`;\n\n // 1. Empty lines (spacing)\n if (!line.trim()) {\n i++;\n continue;\n }\n\n // 2. Standalone image lines: \n const standaloneImageMatch = line.trim().match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\n if (standaloneImageMatch) {\n const alt = standaloneImageMatch[1];\n const url = standaloneImageMatch[2];\n const isSafeUrl = /^(https?|data:image):/i.test(url);\n if (isSafeUrl) {\n elements.push(\n <div key={key} className=\"hsk-markdown-img-block\">\n <img\n src={url}\n alt={alt || 'Product image'}\n className=\"hsk-markdown-img\"\n loading=\"lazy\"\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\n />\n </div>\n );\n }\n i++;\n continue;\n }\n\n // 3. Headers\n const headerMatch = line.match(/^(#{1,3})\\s+(.*)/);\n if (headerMatch) {\n const level = headerMatch[1].length;\n const Tag = `h${level + 3}` as keyof JSX.IntrinsicElements; // Maps # to h4, ## to h5 to avoid messing up host page hierarchy\n elements.push(<Tag key={key} className={`hsk-markdown-h${level}`}>{parseInline(headerMatch[2], key)}</Tag>);\n i++;\n continue;\n }\n\n // 4. Unordered Lists\n if (line.match(/^[-*]\\s+/)) {\n const listItems: React.ReactNode[] = [];\n while (i < lines.length && lines[i].match(/^[-*]\\s+/)) {\n const itemText = lines[i].replace(/^[-*]\\s+/, '');\n listItems.push(<li key={`li-${i}`}>{parseInline(itemText, `li-${i}`)}</li>);\n i++;\n }\n elements.push(<ul key={`ul-${key}`} className=\"hsk-markdown-list\">{listItems}</ul>);\n continue;\n }\n\n // 5. Ordered Lists\n if (line.match(/^\\d+[.)]\\s+/)) {\n const listItems: React.ReactNode[] = [];\n while (i < lines.length && lines[i].match(/^\\d+[.)]\\s+/)) {\n const itemText = lines[i].replace(/^\\d+[.)]\\s+/, '');\n listItems.push(<li key={`li-${i}`}>{parseInline(itemText, `li-${i}`)}</li>);\n i++;\n }\n elements.push(<ol key={`ol-${key}`} className=\"hsk-markdown-list\">{listItems}</ol>);\n continue;\n }\n\n // 6. Tables\n if (isTableLine(line, false)) {\n const tableRows: React.ReactNode[] = [];\n let isHeader = true;\n\n while (i < lines.length && isTableLine(lines[i], true)) {\n const rowLine = lines[i].trim();\n // Skip markdown table separator (e.g., |---|---| or |---|---)\n if (rowLine.match(/^\\|?[-:| ]+\\|?$/) && rowLine.includes('-')) {\n i++;\n isHeader = false;\n continue;\n }\n\n const cells = splitTableCells(rowLine);\n const Tag = isHeader ? 'th' : 'td';\n\n tableRows.push(\n <tr key={`tr-${i}`}>\n {cells.map((cell, cIdx) => (\n <Tag key={`td-${i}-${cIdx}`}>{parseInline(cell, `td-${i}-${cIdx}`)}</Tag>\n ))}\n </tr>\n );\n i++;\n }\n \n elements.push(\n <div key={`table-wrapper-${key}`} className=\"hsk-table-wrapper\">\n <table className=\"hsk-markdown-table\">\n <tbody>{tableRows}</tbody>\n </table>\n </div>\n );\n continue;\n }\n\n // 7. Default Paragraph\n elements.push(\n <p key={key} className=\"hsk-markdown-p\">\n {parseInline(line, key)}\n </p>\n );\n i++;\n }\n\n return <>{elements}</>;\n}\n","import React, { useState, useRef, useCallback } from 'react';\n\nexport interface VoiceButtonProps {\n onTranscript: (text: string) => void;\n onInterim?: (text: string) => void;\n /** BCP-47 language tag. Defaults to 'en-US'. */\n lang?: string;\n className?: string;\n disabled?: boolean;\n}\n\nconst MicIcon = ({ active }: { active: boolean }) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"9\" y=\"2\" width=\"6\" height=\"11\" rx=\"3\" fill={active ? 'currentColor' : 'none'} />\n <path d=\"M5 10a7 7 0 0 0 14 0\" />\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n </svg>\n);\n\n/**\n * VoiceButton — converts speech to text using the browser's free Web Speech API.\n * No API key, no backend call, no cost.\n *\n * @example\n * <VoiceButton onTranscript={(text) => setQuery(text)} />\n */\nexport function VoiceButton({\n onTranscript,\n onInterim,\n lang = 'en-US',\n className = '',\n disabled = false,\n}: VoiceButtonProps) {\n const [listening, setListening] = useState(false);\n const recognitionRef = useRef<any>(null);\n\n const isSupported =\n typeof window !== 'undefined' &&\n ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window);\n\n const start = useCallback(() => {\n if (!isSupported || listening) return;\n\n const SR: any =\n (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n const recognition = new SR();\n recognition.lang = lang;\n recognition.interimResults = true;\n recognition.maxAlternatives = 1;\n recognitionRef.current = recognition;\n\n recognition.onstart = () => setListening(true);\n recognition.onend = () => setListening(false);\n recognition.onerror = () => setListening(false);\n\n recognition.onresult = (e: any) => {\n const results = Array.from(e.results as any[]);\n const transcript = results.map((r: any) => r[0].transcript).join('');\n const isFinal = (e.results[e.results.length - 1] as any).isFinal;\n if (isFinal) {\n onTranscript(transcript);\n setListening(false);\n } else {\n onInterim?.(transcript);\n }\n };\n\n recognition.start();\n }, [isSupported, listening, lang, onTranscript, onInterim]);\n\n const stop = useCallback(() => {\n recognitionRef.current?.stop();\n setListening(false);\n }, []);\n\n // Silently render nothing if the browser doesn't support Web Speech API\n if (!isSupported) return null;\n\n return (\n <button\n type=\"button\"\n className={`kiku-voice-btn${listening ? ' kiku-voice-btn--active' : ''} ${className}`}\n onClick={listening ? stop : start}\n disabled={disabled}\n title={listening ? 'Stop listening' : 'Speak your search'}\n aria-label={listening ? 'Stop voice input' : 'Start voice input'}\n >\n <MicIcon active={listening} />\n {listening && <span className=\"kiku-voice-ripple\" aria-hidden=\"true\" />}\n </button>\n );\n}\n","import React, { useRef, useState } from 'react';\nimport { useAkropolysContext } from '@akropolys/sdk';\nimport type { VisualSearchResponse } from '@akropolys/sdk';\n\nexport interface VisualSearchProps {\n /** Called with search results + the base64 preview when Gemini responds. */\n onResults: (res: VisualSearchResponse, previewBase64: string) => void;\n onError?: (err: Error) => void;\n /**\n * Category hint sent to Gemini to sharpen the match_query.\n * e.g. \"dress\", \"curtains\", \"sofa\", \"shoes\"\n */\n categoryHint?: string;\n className?: string;\n disabled?: boolean;\n}\n\nconst CameraIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <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\" />\n <circle cx=\"12\" cy=\"13\" r=\"4\" />\n </svg>\n);\n\nconst SpinnerIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"kiku-vs-spin\">\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n\nfunction fileToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n}\n\n/**\n * VisualSearch — camera/image-upload button that powers style-match search.\n *\n * User picks a photo → it's base64-encoded in-browser → sent to POST /search/visual\n * → Gemini Flash extracts Style DNA → results returned via onResults().\n *\n * @example\n * <VisualSearch\n * categoryHint=\"dress\"\n * onResults={(res, preview) => setVisualResults(res)}\n * />\n */\nexport function VisualSearch({\n onResults,\n onError,\n categoryHint,\n className = '',\n disabled = false,\n}: VisualSearchProps) {\n const client = useAkropolysContext();\n const inputRef = useRef<HTMLInputElement>(null);\n const [loading, setLoading] = useState(false);\n\n const handleFile = async (file: File) => {\n if (!file.type.startsWith('image/')) return;\n setLoading(true);\n try {\n const base64 = await fileToBase64(file);\n const res = await (client.api as any).searchByImage(base64, categoryHint);\n onResults(res as VisualSearchResponse, base64);\n } catch (e: any) {\n onError?.(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n // Reset so the same file can be picked again\n if (inputRef.current) inputRef.current.value = '';\n }\n };\n\n return (\n <label\n className={`kiku-vs-btn${loading ? ' kiku-vs-btn--loading' : ''} ${className}`}\n title=\"Search by photo\"\n aria-label=\"Search by uploading a photo\"\n style={{ cursor: disabled || loading ? 'not-allowed' : 'pointer' }}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n onChange={e => e.target.files?.[0] && handleFile(e.target.files[0])}\n disabled={disabled || loading}\n hidden\n />\n {loading ? <SpinnerIcon /> : <CameraIcon />}\n </label>\n );\n}\n","'use client';\r\n\r\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { useKiku, ChatMessage, ChatSource } from '@akropolys/sdk';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport { renderMarkdown } from '../utils/markdown';\r\nimport { AkropolysTheme, ChatAttachment, CaptureTarget } from '@akropolys/sdk';\r\nimport { cn } from '../utils/cn';\r\nimport { ComparisonMatrix } from './ComparisonMatrix';\r\n\r\n\r\nexport interface KikuButtonProps {\r\n label?: string;\r\n title?: string;\r\n placeholder?: string;\r\n backdropColor?: string;\r\n backdropBlur?: string | number;\r\n className?: string;\r\n onSelectSource?: (source: ChatSource) => void;\r\n defaultCurrency?: string;\r\n chips?: string[];\r\n theme?: 'light' | 'dark' | AkropolysTheme;\r\n classNames?: {\r\n button?: string;\r\n overlay?: string;\r\n panel?: string;\r\n input?: string;\r\n sendButton?: string;\r\n };\r\n /** Enable 🎙️ voice input via browser Web Speech API (free) */\r\n enableVoice?: boolean;\r\n /** BCP-47 tag for voice transcription (e.g. 'sw-KE', 'fr-FR'). Defaults to\r\n the page's <html lang>, then the browser language. */\r\n voiceLang?: string;\r\n /** Enable 📷 visual style-match search via Gemini (requires backend GEMINI_API_KEY) */\r\n enableVision?: boolean;\r\n /** Optional category hint for visual search (e.g. 'dress', 'curtains') */\r\n visionCategoryHint?: string;\r\n}\r\n\r\n// ─── Icons ────────────────────────────────────────────────────────────────────\r\n\r\n// kiku brand mark — glyph extracted from public/brand/akropolys-icon.svg, fill\r\n// only (no background rect) so it drops into the existing colored circles/badges.\r\nconst KikuIcon = ({ className, size = 18 }: { className?: string; size?: number }) => (\r\n <svg\r\n className={cn(\"hsk-brand-mark\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 100 100\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-label=\"kiku\"\r\n >\r\n <g transform=\"translate(22.7 19) scale(0.62)\" fill=\"currentColor\" fillRule=\"evenodd\">\r\n <path d=\"M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z\" />\r\n <circle cx=\"55\" cy=\"82\" r=\"3.4\" />\r\n </g>\r\n </svg>\r\n);\r\n\r\nconst SparkleIcon = KikuIcon;\r\n\r\nconst ArrowUpIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m5 12 7-7 7 7\"/>\r\n <path d=\"M12 19V5\"/>\r\n </svg>\r\n);\r\n\r\nconst StopIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"5\" y=\"5\" width=\"14\" height=\"14\" rx=\"2\"/>\r\n </svg>\r\n);\r\n\r\nconst CloseIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nconst ChevronRightIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m9 18 6-6-6-6\"/>\r\n </svg>\r\n);\r\n\r\nconst HistoryIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/>\r\n <path d=\"M3 3v5h5\"/>\r\n <path d=\"M12 7v5l4 2\"/>\r\n </svg>\r\n);\r\n\r\nconst BookmarkIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M19 21 12 16l-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z\"/>\r\n </svg>\r\n);\r\n\r\nconst TrashIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M3 6h18\"/>\r\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/>\r\n </svg>\r\n);\r\n\r\nconst SecureShieldIcon = ({ className, size = 18 }: { className?: string; size?: number }) => (\r\n <svg\r\n className={className}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2.5\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n <path d=\"M12 11a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z\" />\r\n <path d=\"M12 11v4\" />\r\n </svg>\r\n);\r\n\r\nconst PaperclipIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <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\"/>\r\n </svg>\r\n);\r\n\r\nconst MicIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\"/>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\r\n </svg>\r\n);\r\n\r\nconst MicOffIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\"/>\r\n <path d=\"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2\"/>\r\n <path d=\"M5 10v2a7 7 0 0 0 12 5\"/>\r\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\"/>\r\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\r\n </svg>\r\n);\r\n\r\n// ─── Constants ────────────────────────────────────────────────────────────────\r\n\r\nconst DEFAULT_CHIPS = [\r\n 'Cheapest smartphone',\r\n 'Smart TV under KSh 20,000',\r\n 'Noise-cancelling headphones',\r\n 'Best laptop for students',\r\n];\r\n\r\n// ─── @kiku Mention System ─────────────────────────────────────────────────────\r\n\r\n/**\r\n * Parses the user's input for an @kiku mention prefix.\r\n * Returns the resolved intent + a cleaned query (product name only, no @kiku prefix)\r\n * that gets sent as the actual search text. Returns null if not an @kiku command.\r\n */\r\nfunction parseAtKiku(raw: string): { intent: string; cleanQuery: string } | null {\r\n const trimmed = raw.trim();\r\n if (!/^@kiku\\b/i.test(trimmed)) return null;\r\n\r\n const rest = trimmed.slice(5).trim(); // everything after \"@kiku\"\r\n\r\n if (rest === '' || /^(capture|save)\\b/i.test(rest)) {\r\n return {\r\n intent: 'capture',\r\n cleanQuery: rest.replace(/^(capture|save)\\s*/i, '').trim() || trimmed,\r\n };\r\n }\r\n if (/^(history|what have you|show my|my items|what did you|saved|captures|recall)\\b/i.test(rest)) {\r\n return { intent: 'view_history', cleanQuery: 'show my saved items' };\r\n }\r\n if (/^(delete|forget|remove|unsave)\\b/i.test(rest)) {\r\n return {\r\n intent: 'delete',\r\n cleanQuery: rest.replace(/^(delete|forget|remove|unsave)\\s*/i, '').trim() || trimmed,\r\n };\r\n }\r\n // Bare \"@kiku <text>\" defaults to capture\r\n return { intent: 'capture', cleanQuery: rest || trimmed };\r\n}\r\n\r\n// ─── @kiku Picker Menu ────────────────────────────────────────────────────────\r\n\r\ninterface KikuPickerMenuProps {\r\n sources: ChatSource[];\r\n referencedIds: string[];\r\n defaultCurrency: string;\r\n onCapture: (product: ChatSource) => void;\r\n onCaptureAll: (products: ChatSource[]) => void;\r\n onViewHistory: () => void;\r\n onDelete: () => void;\r\n onDismiss: () => void;\r\n}\r\n\r\nfunction KikuPickerMenu({\r\n sources,\r\n referencedIds,\r\n defaultCurrency,\r\n onCapture,\r\n onCaptureAll,\r\n onViewHistory,\r\n onDelete,\r\n onDismiss,\r\n}: KikuPickerMenuProps) {\r\n // Show products that were actually referenced in this conversation\r\n const discussed = sources.filter(s => s.id && referencedIds.includes(s.id));\r\n\r\n return (\r\n <div\r\n className=\"hsk-kiku-picker\"\r\n role=\"menu\"\r\n aria-label=\"@kiku commands\"\r\n onMouseDown={e => e.preventDefault()} // keep textarea focused\r\n >\r\n {discussed.map((src, i) => (\r\n <button\r\n key={src.id ?? i}\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onCapture(src); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\">\r\n {src.image ? <img src={src.image} alt=\"\" /> : <BookmarkIcon />}\r\n </span>\r\n <span className=\"hsk-kiku-picker-item-name\">{src.name}</span>\r\n {src.price && (\r\n <span className=\"hsk-kiku-picker-item-price\">\r\n {src.currency ?? defaultCurrency} {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </span>\r\n )}\r\n </button>\r\n ))}\r\n {discussed.length > 1 && (\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onCaptureAll(discussed); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\"><BookmarkIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">Capture all ({discussed.length})</span>\r\n </button>\r\n )}\r\n {discussed.length === 0 && (\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onCapture({ name: 'current page', id: undefined }); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\"><BookmarkIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">Capture current page</span>\r\n </button>\r\n )}\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onViewHistory(); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\"><HistoryIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">What have you saved?</span>\r\n </button>\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => { onDelete(); onDismiss(); }}\r\n >\r\n <span className=\"hsk-kiku-picker-icon\"><TrashIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">Delete this</span>\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\n// ─── @ Extension Picker Menu ──────────────────────────────────────────────────\r\n\r\ninterface AtPickerMenuProps {\r\n onSelect: (extension: string) => void;\r\n onDismiss: () => void;\r\n}\r\n\r\nfunction AtPickerMenu({ onSelect, onDismiss }: AtPickerMenuProps) {\r\n return (\r\n <div\r\n className=\"hsk-kiku-picker\"\r\n role=\"menu\"\r\n aria-label=\"Extensions\"\r\n onMouseDown={e => e.preventDefault()} // keep textarea focused\r\n >\r\n <button\r\n className=\"hsk-kiku-picker-item\"\r\n role=\"menuitem\"\r\n onClick={() => onSelect('@kiku')}\r\n >\r\n <span className=\"hsk-kiku-picker-icon hsk-kiku-picker-icon--accent\"><SparkleIcon /></span>\r\n <span className=\"hsk-kiku-picker-item-name\">kiku — capture & remember</span>\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\n// ─── Sources Carousel ──────────────────────────────────────────────────────────\r\n\r\ninterface SourcesCarouselProps {\r\n sources: ChatSource[];\r\n defaultCurrency: string;\r\n onSelectSource?: (src: ChatSource) => void;\r\n onImageClick?: (src: string) => void;\r\n referencedIds?: string[];\r\n compact?: boolean;\r\n}\r\n\r\nfunction SourceImg({ src, alt, onImageClick }: { src: string; alt?: string; onImageClick?: (src: string) => void }) {\r\n const [failed, setFailed] = useState(false);\r\n if (failed) {\r\n return (\r\n <div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--hsk-chat-source-bg, rgba(0,0,0,.04))', color: 'var(--hsk-chat-muted, #888)' }}>\r\n <SparkleIcon />\r\n </div>\r\n );\r\n }\r\n return (\r\n <img\r\n src={src}\r\n alt={alt ?? ''}\r\n onError={() => setFailed(true)}\r\n onClick={onImageClick ? (e) => { e.stopPropagation(); onImageClick(src); } : undefined}\r\n />\r\n );\r\n}\r\n\r\nfunction SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClick, referencedIds = [], compact = false }: SourcesCarouselProps) {\r\n const client = useAkropolysContext();\r\n const isProperty = client?.vertical === 'property';\r\n const railRef = useRef<HTMLDivElement>(null);\r\n const [showNext, setShowNext] = useState(false);\r\n\r\n const measure = useCallback(() => {\r\n const el = railRef.current;\r\n if (!el) return;\r\n const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;\r\n setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);\r\n }, []);\r\n\r\n useEffect(() => {\r\n measure();\r\n const el = railRef.current;\r\n if (!el) return;\r\n const ro = new ResizeObserver(measure);\r\n ro.observe(el);\r\n el.addEventListener('scroll', measure, { passive: true });\r\n return () => { ro.disconnect(); el.removeEventListener('scroll', measure); };\r\n }, [measure, sources]);\r\n\r\n const scrollNext = () => {\r\n railRef.current?.scrollBy({ left: 170, behavior: 'smooth' });\r\n };\r\n\r\n // Show only the products the answer referenced via <entity_ref>. If it\r\n // referenced none, show none — never dump raw retrieval candidates, which is\r\n // what surfaced product cards for questions nobody asked.\r\n const display = sources.filter(s => s.id && referencedIds.includes(s.id));\r\n if (display.length === 0) return null;\r\n\r\n return (\r\n <div className={cn(\"hsk-cb-sources-wrap\", compact && \"hsk-cb-sources-wrap--compact\")}>\r\n <div className=\"hsk-cb-sources\" ref={railRef}>\r\n {display.map((src, si) => {\r\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\r\n return (\r\n <div\r\n key={src.id ?? si}\r\n className={cn(\"hsk-cb-source\", isReferenced && \"hsk-cb-source--referenced\")}\r\n style={{ animationDelay: `${si * 50}ms` }}\r\n onClick={() => onSelectSource?.(src)}\r\n >\r\n {src.image ? (\r\n <div className=\"hsk-cb-src-imgwrap\" style={{ position: 'relative' }}>\r\n <SourceImg src={src.image} alt={src.name} onImageClick={onImageClick} />\r\n {isReferenced && (\r\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\">\r\n <SparkleIcon size={10} />\r\n </div>\r\n )}\r\n {isProperty && (\r\n <div style={{\r\n position: 'absolute',\r\n top: '6px',\r\n right: '6px',\r\n background: 'rgba(14, 14, 15, 0.75)',\r\n backdropFilter: 'blur(4px)',\r\n borderRadius: '50%',\r\n width: '24px',\r\n height: '24px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: '#fbbf24', // Gold sparkle badge\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)'\r\n }}>\r\n <SparkleIcon size={12} />\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"hsk-cb-src-imgwrap-empty\" style={{ position: 'relative' }}>\r\n <SparkleIcon />\r\n {isReferenced && (\r\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\">\r\n <SparkleIcon size={10} />\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n <div className=\"hsk-cb-src-info\">\r\n <div className=\"hsk-cb-src-name\">{src.name}</div>\r\n {src.price && (\r\n <div className=\"hsk-cb-src-price\">\r\n {src.currency ?? defaultCurrency}{' '}\r\n {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n {showNext && (\r\n <>\r\n <div\r\n className=\"hsk-cb-sources-fade\"\r\n style={{ background: 'linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))' }}\r\n />\r\n <button className=\"hsk-cb-sources-next\" onClick={scrollNext} aria-label=\"See more\">\r\n <ChevronRightIcon />\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ─── Strip markdown tables (used for compare view to avoid duplicate) ──────────\r\n\r\nfunction stripMarkdownTables(content: string): string {\r\n const lines = content.split('\\n');\r\n const out: string[] = [];\r\n for (const line of lines) {\r\n if (line.trim().startsWith('|')) continue; // table row or separator\r\n out.push(line);\r\n }\r\n // Collapse runs of 3+ blank lines down to 2\r\n return out.join('\\n').replace(/\\n{3,}/g, '\\n\\n').trim();\r\n}\r\n\r\n// ─── Smart context pills ──────────────────────────────────────────────────────\r\n// Shown after every assistant response (when there's no cart action).\r\n// Pills are generated from the current intent + sources so they're always relevant.\r\n\r\nfunction SmartContextPills({\r\n intent,\r\n sources,\r\n onSend,\r\n loading,\r\n}: {\r\n intent: string | null;\r\n sources: ChatSource[];\r\n onSend: (text: string) => void;\r\n loading: boolean;\r\n}) {\r\n const client = useAkropolysContext();\r\n const isProperty = client?.vertical === 'property';\r\n if (!intent) return null;\r\n\r\n const pills: { label: string; query: string; emoji: string }[] = [];\r\n\r\n // Find the cheapest product in the sources list\r\n const cheapest =\r\n sources.length > 0\r\n ? sources.reduce((min, s) => {\r\n const p = parseFloat(String(s.price ?? '').replace(/[^0-9.]/g, ''));\r\n const m = parseFloat(String(min.price ?? '').replace(/[^0-9.]/g, ''));\r\n return !isNaN(p) && (isNaN(m) || p < m) ? s : min;\r\n }, sources[0])\r\n : null;\r\n\r\n const firstName = sources[0]?.name ?? '';\r\n const firstTwo = sources.slice(0, 2).map(s => s.name);\r\n\r\n if (intent === 'search' && sources.length > 0) {\r\n if (firstTwo.length >= 2) {\r\n pills.push({\r\n emoji: '⚖️',\r\n label: 'Compare top 2',\r\n query: `Compare the ${firstTwo[0]} and ${firstTwo[1]}`,\r\n });\r\n }\r\n if (cheapest && !isProperty && cheapest.name) {\r\n const short = cheapest.name.split(' ').slice(0, 3).join(' ');\r\n pills.push({\r\n emoji: '💡',\r\n label: `More on ${short}`,\r\n query: `Tell me more about the ${cheapest.name}`,\r\n });\r\n }\r\n if (isProperty) {\r\n pills.push({ emoji: '💰', label: 'Under KSh 5M', query: 'Show me options under KSh 5,000,000' });\r\n } else {\r\n pills.push({ emoji: '💰', label: 'Under KSh 20K', query: 'Show me options under KSh 20,000' });\r\n }\r\n } else if (intent === 'compare' && sources.length > 0) {\r\n if (firstName) {\r\n pills.push({\r\n emoji: '🔍',\r\n label: 'Similar options',\r\n query: isProperty\r\n ? `Show me more properties similar to the ${firstName}`\r\n : `Show me more products similar to the ${firstName}`,\r\n });\r\n }\r\n pills.push({ emoji: '💡', label: 'Which is best?', query: 'Which one would you recommend and why?' });\r\n } else if (intent === 'specs' && sources.length > 0) {\r\n if (firstName) {\r\n pills.push({\r\n emoji: '🔄',\r\n label: 'Find alternatives',\r\n query: `What are good alternatives to the ${firstName}?`,\r\n });\r\n }\r\n } else if (intent === 'general') {\r\n if (isProperty) {\r\n pills.push({ emoji: '🔍', label: 'Show popular listings', query: 'What are your most popular properties?' });\r\n } else {\r\n pills.push({ emoji: '🔍', label: 'Show popular items', query: 'What are your most popular products?' });\r\n }\r\n pills.push({ emoji: '💡', label: 'Recommend something', query: 'What do you recommend for me?' });\r\n }\r\n\r\n if (pills.length === 0) return null;\r\n\r\n return (\r\n <div className=\"hsk-action-pills\">\r\n {pills.map(pill => (\r\n <button\r\n key={pill.query}\r\n className=\"hsk-action-pill\"\r\n onClick={() => onSend(pill.query)}\r\n disabled={loading}\r\n >\r\n <span className=\"hsk-pill-emoji\">{pill.emoji}</span>\r\n {pill.label}\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\n// ─── Error helper ──────────────────────────────────────────────────────────────\r\n\r\nconst getFriendlyError = (err: any) => {\r\n let str = '';\r\n if (typeof err === 'string') str = err;\r\n else if (err && typeof err === 'object' && err.message) str = err.message;\r\n else try { str = JSON.stringify(err); } catch { str = String(err); }\r\n\r\n const lower = str.toLowerCase();\r\n if (\r\n lower.includes('429') ||\r\n lower.includes('too many requests') ||\r\n lower.includes('requests per minute limit exceeded') ||\r\n lower.includes('too_many_requests_error') ||\r\n lower.includes('request_quota_exceeded') ||\r\n lower.includes('quota')\r\n ) {\r\n return 'The assistant is currently receiving too many requests. Please try again in a few moments.';\r\n }\r\n\r\n if (lower.includes('token limit')) {\r\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\r\n }\r\n\r\n // Never let a raw status or network failure reach a shopper.\r\n if (lower.includes('failed to fetch') || lower.includes('networkerror') || lower.includes('request failed')) {\r\n return \"The assistant couldn't respond just now — please try again in a moment.\";\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(str);\r\n return parsed.error || parsed.message || str;\r\n } catch {\r\n return str;\r\n }\r\n};\r\n\r\n// The kiku key is the shopper's portable, anonymous identity (kiku_<hex>) —\r\n// server-minted, shown exactly once. Entering the same key on any site (or\r\n// giving it to an AI agent) opens the same memory. Lost key = lost memory.\r\nconst KIKU_KEY_REVEAL_SECONDS = 60;\r\n\r\n// ─── ChatModal Props ───────────────────────────────────────────────────────────\r\n\r\ninterface ChatModalProps extends Pick<KikuButtonProps, 'title' | 'placeholder' | 'backdropColor' | 'backdropBlur' | 'onSelectSource' | 'defaultCurrency' | 'chips' | 'theme' | 'classNames' | 'enableVoice' | 'voiceLang' | 'enableVision' | 'visionCategoryHint'> {\r\n theme?: 'light' | 'dark' | AkropolysTheme;\r\n classNames?: any;\r\n onClose: () => void;\r\n}\r\n\r\n// ─── ChatModal ─────────────────────────────────────────────────────────────────\r\n\r\nfunction parseThinking(text: string): { thinking: string; content: string; isComplete: boolean } {\r\n const openMatch = text.match(/<\\s*thinking\\s*>/i);\r\n if (!openMatch) {\r\n return { thinking: '', content: text, isComplete: true };\r\n }\r\n\r\n const openIdx = openMatch.index ?? 0;\r\n const openTagLength = openMatch[0].length;\r\n const start = openIdx + openTagLength;\r\n \r\n const contentBefore = text.slice(0, openIdx);\r\n const textAfterOpen = text.slice(start);\r\n \r\n const closeMatch = textAfterOpen.match(/<\\/\\s*thinking\\s*>/i);\r\n if (!closeMatch) {\r\n return { \r\n thinking: textAfterOpen, \r\n content: contentBefore, \r\n isComplete: false \r\n };\r\n }\r\n\r\n const closeIdx = closeMatch.index ?? 0;\r\n const closeTagLength = closeMatch[0].length;\r\n \r\n return {\r\n thinking: textAfterOpen.slice(0, closeIdx),\r\n content: contentBefore + textAfterOpen.slice(closeIdx + closeTagLength),\r\n isComplete: true\r\n };\r\n}\r\n\r\nfunction ThinkingBlock({ text, isComplete }: { text: string; isComplete: boolean }) {\r\n const [isOpen, setIsOpen] = useState(true);\r\n\r\n // Auto-expand when streaming thinking content\r\n useEffect(() => {\r\n if (!isComplete) {\r\n setIsOpen(true);\r\n }\r\n }, [isComplete]);\r\n\r\n return (\r\n <div style={{\r\n marginBottom: '12px',\r\n borderLeft: '2px solid #e4e4e7',\r\n paddingLeft: '10px',\r\n fontSize: '0.825rem',\r\n backgroundColor: 'rgba(244, 244, 245, 0.4)',\r\n padding: '8px 10px',\r\n borderRadius: '0 6px 6px 0'\r\n }}>\r\n <div \r\n onClick={() => setIsOpen(!isOpen)} \r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n color: '#71717a',\r\n cursor: 'pointer',\r\n fontWeight: 500,\r\n userSelect: 'none'\r\n }}\r\n >\r\n <span style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ animation: !isComplete ? 'spin 3s linear infinite' : 'none' }}>\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <path d=\"M12 6v6l4 2\" />\r\n </svg>\r\n Thinking Process\r\n </span>\r\n {!isComplete && (\r\n <span style={{\r\n width: '6px',\r\n height: '6px',\r\n borderRadius: '50%',\r\n backgroundColor: '#3b82f6',\r\n display: 'inline-block',\r\n animation: 'hsk-pulse 1.2s infinite ease-in-out'\r\n }} />\r\n )}\r\n <span style={{ \r\n fontSize: '0.7rem', \r\n marginLeft: 'auto',\r\n transform: isOpen ? 'rotate(90deg)' : 'none', \r\n transition: 'transform 0.1s' \r\n }}>▶</span>\r\n </div>\r\n {isOpen && (\r\n <div style={{\r\n marginTop: '6px',\r\n color: '#52525b',\r\n whiteSpace: 'pre-wrap',\r\n lineHeight: '1.4',\r\n fontStyle: 'italic'\r\n }}>\r\n {text}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nconst PROPERTY_CHIPS = [\r\n '3 bedroom apartments',\r\n 'Houses under KSh 5,000,000',\r\n 'Properties in Palm Beach',\r\n 'Studio apartments with pool',\r\n];\r\n\r\nfunction ChatModal({\r\n title = 'kiku',\r\n placeholder = 'Ask me anything — gifts, budget, use case…',\r\n backdropColor,\r\n backdropBlur,\r\n onClose,\r\n onSelectSource,\r\n defaultCurrency = 'KES',\r\n chips = DEFAULT_CHIPS,\r\n theme,\r\n classNames = {},\r\n enableVoice = false,\r\n voiceLang,\r\n enableVision = false,\r\n visionCategoryHint,\r\n}: ChatModalProps) {\r\n const client = useAkropolysContext();\r\n const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, reset, referencedIds } = useKiku();\r\n const [input, setInput] = useState('');\r\n\r\n // ── Image attachments ────────────────────────────────────────────────────────\r\n const [attachments, setAttachments] = useState<ChatAttachment[]>([]);\r\n const imageInputRef = useRef<HTMLInputElement>(null);\r\n\r\n const handleImageFiles = (files: FileList | null) => {\r\n if (!files || files.length === 0) return;\r\n Array.from(files).forEach(file => {\r\n if (!file.type.startsWith('image/')) return;\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const dataUrl = e.target?.result as string;\r\n if (dataUrl) {\r\n setAttachments(prev => [...prev, { type: 'image', data: dataUrl }]);\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n };\r\n\r\n const removeAttachment = (idx: number) => {\r\n setAttachments(prev => prev.filter((_, i) => i !== idx));\r\n };\r\n\r\n // ── Voice mode (Web Speech API) ──────────────────────────────────────────────\r\n const [voiceState, setVoiceState] = useState<'idle' | 'listening' | 'processing'>('idle');\r\n const recognitionRef = useRef<any>(null);\r\n const pendingVoiceRef = useRef<string | null>(null); // transcript queued for auto-send\r\n const hasSpeechAPI = typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window);\r\n\r\n const startVoice = useCallback(() => {\r\n if (!hasSpeechAPI || voiceState !== 'idle') return;\r\n const SR = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\r\n const recognition = new SR();\r\n // Transcribe in the site's language, not a dictated one: developer override\r\n // → page <html lang> → browser language → English as last resort.\r\n recognition.lang = voiceLang || document.documentElement.lang || navigator.language || 'en-US';\r\n // Stream partial results so the user SEES words appear as they speak —\r\n // without this there's no feedback that anything was captured until the end.\r\n recognition.interimResults = true;\r\n recognition.maxAlternatives = 1;\r\n recognitionRef.current = recognition;\r\n\r\n recognition.onstart = () => setVoiceState('listening');\r\n recognition.onresult = (event: any) => {\r\n let finalText = '';\r\n let interimText = '';\r\n for (let i = 0; i < event.results.length; i++) {\r\n const seg = event.results[i][0].transcript;\r\n if (event.results[i].isFinal) finalText += seg;\r\n else interimText += seg;\r\n }\r\n // Live feedback: show the (final + in-progress) text in the input box.\r\n const live = (finalText + ' ' + interimText).trim();\r\n if (live) setInput(live);\r\n // Only auto-send once we have a finalized transcript.\r\n if (finalText.trim()) {\r\n pendingVoiceRef.current = finalText.trim();\r\n setVoiceState('processing');\r\n }\r\n };\r\n recognition.onerror = (event: any) => {\r\n // Surface the cause (most often denied mic permission or no speech) so the\r\n // user isn't left guessing whether it worked.\r\n const err = event?.error;\r\n if (err === 'not-allowed' || err === 'service-not-allowed') {\r\n setInput('Microphone access was blocked — enable it in your browser to use voice.');\r\n } else if (err === 'no-speech') {\r\n setInput(\"Didn't catch that — tap the mic and try again.\");\r\n }\r\n setVoiceState('idle');\r\n };\r\n recognition.onend = () => {\r\n // Only reset if we didn't already move to processing\r\n setVoiceState(prev => prev === 'listening' ? 'idle' : prev);\r\n };\r\n recognition.start();\r\n }, [hasSpeechAPI, voiceState, voiceLang]);\r\n\r\n const stopVoice = useCallback(() => {\r\n recognitionRef.current?.stop();\r\n setVoiceState('idle');\r\n }, []);\r\n\r\n // Clean up recognition on unmount\r\n useEffect(() => {\r\n return () => recognitionRef.current?.abort();\r\n }, []);\r\n\r\n const isProperty = client.vertical === 'property';\r\n const activeChips = chips === DEFAULT_CHIPS && isProperty ? PROPERTY_CHIPS : chips;\r\n const activeTitle = title;\r\n const activePlaceholder = placeholder === 'Ask me anything — gifts, budget, use case…' && isProperty\r\n ? 'Ask me anything — location, budget, bedrooms…'\r\n : placeholder;\r\n\r\n\r\n const [selectedProduct, setSelectedProduct] = useState<ChatSource | null>(null);\r\n const [lightboxSrc, setLightboxSrc] = useState<string | null>(null);\r\n const bottomRef = useRef<HTMLDivElement>(null);\r\n const textareaRef = useRef<HTMLTextAreaElement>(null);\r\n const [keyInput, setKeyInput] = useState('');\r\n const [keyPhase, setKeyPhase] = useState<'idle' | 'prompt_key'>('idle');\r\n const [mintedKey, setMintedKey] = useState<string | null>(null);\r\n const [keyCountdown, setKeyCountdown] = useState(KIKU_KEY_REVEAL_SECONDS);\r\n const [minting, setMinting] = useState(false);\r\n const [showKikuPicker, setShowKikuPicker] = useState(false);\r\n const [showAtPicker, setShowAtPicker] = useState(false);\r\n\r\n // React to lastAction from chat\r\n useEffect(() => {\r\n if (!lastAction) return;\r\n if (lastAction.type === 'request_kiku_key') {\r\n setKeyPhase('prompt_key');\r\n }\r\n }, [lastAction]);\r\n\r\n // Show-once countdown: the minted key is visible for a fixed window, then\r\n // gone for good — it stays active on this device, but is never shown again.\r\n useEffect(() => {\r\n if (!mintedKey) return;\r\n setKeyCountdown(KIKU_KEY_REVEAL_SECONDS);\r\n const t = setInterval(() => {\r\n setKeyCountdown(s => {\r\n if (s <= 1) {\r\n clearInterval(t);\r\n setMintedKey(null);\r\n return 0;\r\n }\r\n return s - 1;\r\n });\r\n }, 1000);\r\n return () => clearInterval(t);\r\n }, [mintedKey]);\r\n\r\n const isStringTheme = typeof theme === 'string';\r\n const hskThemeAttr = isStringTheme ? theme : undefined;\r\n\r\n const customStyles = (!isStringTheme && theme) ? {\r\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\r\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\r\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\r\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\r\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\r\n } as React.CSSProperties : undefined;\r\n\r\n // Retry the interrupted request (e.g. the capture) under the new identity.\r\n // Goes through handleSend so an \"@kiku …\" prefix is re-parsed back into a\r\n // forced intent instead of being sent as literal query text.\r\n const retryLastMessage = async () => {\r\n const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');\r\n if (lastUserMsg) await handleSend(lastUserMsg.content);\r\n };\r\n\r\n // Returning shopper: paste an existing kiku key.\r\n const handleUseExistingKey = async () => {\r\n const key = keyInput.trim();\r\n if (!key) return;\r\n client.setKikuKey(key);\r\n setKeyInput('');\r\n setKeyPhase('idle');\r\n await retryLastMessage();\r\n };\r\n\r\n // New shopper: mint a key server-side and reveal it exactly once.\r\n const handleCreateKey = async () => {\r\n if (minting) return;\r\n setMinting(true);\r\n try {\r\n const key = await client.mintKikuKey();\r\n setMintedKey(key);\r\n setKeyPhase('idle');\r\n await retryLastMessage();\r\n } catch {\r\n // mint failed — keep the prompt open so the shopper can try again\r\n } finally {\r\n setMinting(false);\r\n }\r\n };\r\n\r\n // Auto-scroll. A freshly sent user message is pinned to the top of the\r\n // view (like Claude) so the question and the start of the answer are both\r\n // visible without scrolling. While a response streams in, we only follow it\r\n // to the bottom if the user is already pinned there — this lets them freely\r\n // scroll up to re-read earlier messages.\r\n const msgsContainerRef = useRef<HTMLDivElement>(null);\r\n const messageRefs = useRef<(HTMLDivElement | null)[]>([]);\r\n useEffect(() => {\r\n const container = msgsContainerRef.current;\r\n if (!container) return;\r\n const lastMsg = messages[messages.length - 1];\r\n if (lastMsg?.role === 'user') {\r\n messageRefs.current[messages.length - 1]?.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n return;\r\n }\r\n const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;\r\n if (distanceFromBottom < 120) {\r\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }\r\n }, [messages, loading, selectedProduct]);\r\n\r\n // Lock the host page's own scroll while the panel is open, so only the\r\n // widget's internal message list scrolls — otherwise both scrollbars show.\r\n useEffect(() => {\r\n const prev = document.body.style.overflow;\r\n document.body.style.overflow = 'hidden';\r\n return () => { document.body.style.overflow = prev; };\r\n }, []);\r\n\r\n useEffect(() => {\r\n const h = (e: KeyboardEvent) => {\r\n if (e.key !== 'Escape') return;\r\n if (lightboxSrc) { setLightboxSrc(null); return; }\r\n onClose();\r\n };\r\n document.addEventListener('keydown', h);\r\n return () => document.removeEventListener('keydown', h);\r\n }, [lightboxSrc, onClose]);\r\n\r\n const handleReset = useCallback(() => {\r\n reset();\r\n setKeyPhase('idle');\r\n }, [reset]);\r\n\r\n const handleSourceClick = (src: ChatSource) => {\r\n setSelectedProduct(src);\r\n onSelectSource?.(src);\r\n const q = `Tell me more about the ${src.name}${src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : ''} — what are its key specs, who is it best for, and is it worth buying?`;\r\n send(q);\r\n };\r\n\r\n const handleSend = async (text?: string, extraAttachments?: ChatAttachment[], forcedIntent?: string, captureTargets?: CaptureTarget[]) => {\r\n const raw = (text ?? input).trim();\r\n if (!raw || loading) return;\r\n\r\n const kiku = parseAtKiku(raw);\r\n const q = kiku ? kiku.cleanQuery : raw;\r\n const resolvedForcedIntent = forcedIntent ?? kiku?.intent;\r\n\r\n setSelectedProduct(null);\r\n setShowKikuPicker(false);\r\n setShowAtPicker(false);\r\n setInput('');\r\n if (textareaRef.current) {\r\n textareaRef.current.style.height = 'auto';\r\n }\r\n const toSend = extraAttachments ?? attachments;\r\n setAttachments([]);\r\n await send(q, raw /* displayQuery */, toSend.length > 0 ? toSend : undefined, resolvedForcedIntent, captureTargets);\r\n };\r\n\r\n const handleSelectExtension = (ext: string) => {\r\n setInput(ext + ' ');\r\n setShowAtPicker(false);\r\n setShowKikuPicker(true);\r\n if (textareaRef.current) {\r\n textareaRef.current.focus();\r\n }\r\n };\r\n\r\n // Convenience wrappers for @kiku picker actions\r\n const handleKikuCapture = useCallback((product: ChatSource) => {\r\n const name = product.name || '';\r\n const display = `@kiku capture${name ? ' ' + name : ''}`;\r\n const q = name || 'capture current page';\r\n setInput('');\r\n setSelectedProduct(null);\r\n const toSend = attachments;\r\n setAttachments([]);\r\n send(q, display, toSend.length > 0 ? toSend : undefined, 'capture');\r\n }, [attachments, send]);\r\n\r\n const handleKikuCaptureAll = useCallback((products: ChatSource[]) => {\r\n const targets: CaptureTarget[] = products\r\n .filter(p => p.id)\r\n .map(p => ({\r\n name: p.name || '',\r\n url: (p as any).url || '',\r\n image: p.image || '',\r\n price: p.price ? String(p.price) : '',\r\n currency: p.currency || defaultCurrency,\r\n }));\r\n const names = products.map(p => p.name).filter(Boolean).join(', ');\r\n const display = `@kiku capture all (${products.length} items)`;\r\n setInput('');\r\n setSelectedProduct(null);\r\n setAttachments([]);\r\n send(names || 'capture all', display, undefined, 'capture_all', targets);\r\n }, [defaultCurrency, send]);\r\n\r\n const handleKikuViewHistory = useCallback(() => {\r\n const display = '@kiku what have you saved?';\r\n setInput('');\r\n setSelectedProduct(null);\r\n setAttachments([]);\r\n send('show my saved items', display, undefined, 'view_history');\r\n }, [send]);\r\n\r\n const handleKikuDelete = useCallback(() => {\r\n const display = '@kiku delete this';\r\n setInput('');\r\n setSelectedProduct(null);\r\n setAttachments([]);\r\n send('delete this', display, undefined, 'delete');\r\n }, [send]);\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\r\n if (e.key === 'Escape' && showKikuPicker) { e.preventDefault(); setShowKikuPicker(false); return; }\r\n if (e.key === 'Escape' && showAtPicker) { e.preventDefault(); setShowAtPicker(false); return; }\r\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }\r\n };\r\n\r\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n const val = e.target.value;\r\n setInput(val);\r\n const trimmed = val.trim();\r\n // Show @ picker when input is exactly '@'\r\n setShowAtPicker(trimmed === '@');\r\n // Show @kiku picker whenever the input starts with @kiku\r\n setShowKikuPicker(/^@kiku\\b/i.test(trimmed));\r\n const t = e.target;\r\n t.style.height = 'auto';\r\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\r\n };\r\n\r\n // Auto-send voice transcript once processing state is reached\r\n useEffect(() => {\r\n if (voiceState !== 'processing') return;\r\n const transcript = pendingVoiceRef.current;\r\n if (!transcript) { setVoiceState('idle'); return; }\r\n pendingVoiceRef.current = null;\r\n // Brief delay so user sees the transcript fill in before it fires\r\n const timer = setTimeout(() => {\r\n setVoiceState('idle');\r\n handleSend(transcript);\r\n }, 400);\r\n return () => clearTimeout(timer);\r\n }, [voiceState]);\r\n\r\n\r\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '20px');\r\n\r\n const displayMessages = messages;\r\n\r\n return (\r\n <div\r\n className={cn(\"hsk-cb-overlay\", classNames.overlay)}\r\n onClick={onClose}\r\n data-hsk-theme={hskThemeAttr}\r\n style={{\r\n backdropFilter: `blur(${blurVal})`,\r\n WebkitBackdropFilter: `blur(${blurVal})`,\r\n ...(backdropColor ? { background: backdropColor } : {}),\r\n ...customStyles,\r\n }}\r\n >\r\n <div\r\n className={cn(\"hsk-cb-panel\", classNames.panel)}\r\n onClick={e => {\r\n e.stopPropagation();\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === 'IMG' && (target.classList.contains('hsk-markdown-img') || target.classList.contains('hsk-cb-user-img-thumb'))) {\r\n const src = (target as HTMLImageElement).src;\r\n if (src) setLightboxSrc(src);\r\n }\r\n }}\r\n >\r\n {lightboxSrc && (\r\n <div className=\"hsk-lightbox\" onClick={() => setLightboxSrc(null)}>\r\n <button className=\"hsk-lightbox-close\" onClick={() => setLightboxSrc(null)} aria-label=\"Close image\">\r\n <CloseIcon />\r\n </button>\r\n <img src={lightboxSrc} alt=\"\" className=\"hsk-lightbox-img\" onClick={e => e.stopPropagation()} />\r\n </div>\r\n )}\r\n\r\n {/* ── Main Chat Area ── */}\r\n <div className=\"hsk-cb-main\">\r\n\r\n {/* Top bar */}\r\n <div className=\"hsk-cb-topbar\">\r\n <div className=\"hsk-cb-topbar-left\">\r\n <span className=\"hsk-cb-topbar-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </span>\r\n <div>\r\n <div className=\"hsk-cb-topbar-title\">{activeTitle}</div>\r\n </div>\r\n </div>\r\n <div className=\"hsk-cb-topbar-actions\">\r\n {messages.length > 0 && (\r\n <button className=\"hsk-cb-topbar-btn\" onClick={handleReset}>Clear chat</button>\r\n )}\r\n <button className=\"hsk-cb-close\" onClick={onClose} aria-label=\"Close\">\r\n <CloseIcon />\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Messages */}\r\n <div className=\"hsk-cb-msgs\" ref={msgsContainerRef}>\r\n {displayMessages.length === 0 ? (\r\n <div className=\"hsk-cb-empty\">\r\n <div className=\"hsk-cb-empty-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-empty-title\">Find exactly what you need</div>\r\n <div className=\"hsk-cb-chips\">\r\n {activeChips.map(chip => (\r\n <button\r\n key={chip}\r\n className=\"hsk-cb-chip\"\r\n onClick={() => handleSend(chip)}\r\n >\r\n {chip}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n ) : (\r\n displayMessages.map((msg: ChatMessage, idx: number) => {\r\n const isLast = idx === displayMessages.length - 1;\r\n const isUser = msg.role === 'user';\r\n // Strip the LLM's markdown table for compare so ComparisonMatrix isn't duplicated\r\n const displayContent =\r\n !isUser && isLast && lastIntent === 'compare' && sources.length >= 2\r\n ? stripMarkdownTables(msg.content)\r\n : msg.content;\r\n return (\r\n <div key={idx} className=\"hsk-cb-msg-group\" ref={(el) => { messageRefs.current[idx] = el; }}>\r\n {isUser ? (\r\n <div className=\"hsk-cb-user-msg\">\r\n {/* Image thumbnails in user bubble */}\r\n {msg.images && msg.images.length > 0 && (\r\n <div className=\"hsk-cb-user-imgs\">\r\n {msg.images.map((img, i) => (\r\n <img key={i} src={img} alt={`attachment ${i + 1}`} className=\"hsk-cb-user-img-thumb\" />\r\n ))}\r\n </div>\r\n )}\r\n {msg.content && (\r\n <div className=\"hsk-cb-user-bubble\">\r\n {/^@kiku\\b/i.test(msg.content) ? (\r\n <>\r\n <span className=\"hsk-kiku-badge\">@kiku</span>\r\n {msg.content.replace(/^@kiku\\s*/i, '')}\r\n </>\r\n ) : msg.content}\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n {(() => {\r\n const { thinking, content, isComplete } = parseThinking(displayContent);\r\n return (\r\n <>\r\n {thinking && (\r\n <ThinkingBlock text={thinking} isComplete={isComplete} />\r\n )}\r\n {content && (\r\n <div className=\"hsk-cb-ai-text\">\r\n {renderMarkdown(content, isLast && streaming)}\r\n {isLast && streaming && (\r\n <span style={{ display: 'inline-block', width: '0.5em', height: '1.05em', marginLeft: '2px', verticalAlign: 'text-bottom', background: 'currentColor', opacity: 0.55, borderRadius: '1px' }} />\r\n )}\r\n </div>\r\n )}\r\n </>\r\n );\r\n })()}\r\n\r\n {msg.visualizing && (\r\n <div className=\"hsk-cb-viz hsk-cb-viz--loading\">\r\n <span className=\"hsk-cb-viz-spinner\" />\r\n <span>Visualizing…</span>\r\n </div>\r\n )}\r\n {msg.visualization && (\r\n <div className=\"hsk-cb-viz\">\r\n <img\r\n src={msg.visualization}\r\n alt=\"Product visualized in your photo\"\r\n className=\"hsk-markdown-img\"\r\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Comparison matrix — replaces the markdown table when comparing products */}\r\n {isLast && lastIntent === 'compare' && sources.length >= 2 && (\r\n <ComparisonMatrix sources={sources} defaultCurrency={defaultCurrency} />\r\n )}\r\n\r\n {(() => {\r\n const msgReferencedIds = isLast ? referencedIds : (msg.referencedIds ?? []);\r\n const msgSources = isLast ? sources : (msg.sources ?? []);\r\n // Gate on this message's own intent — the live lastAction hid every earlier carousel.\r\n const msgIntent = isLast ? lastIntent : msg.intent;\r\n const hiddenIntent = msgIntent === 'compare' || msgIntent === 'capture' ||\r\n msgIntent === 'capture_all' || msgIntent === 'delete' || msgIntent === 'view_history';\r\n const showCarousel = msgReferencedIds.length > 0 && !hiddenIntent &&\r\n (!isLast || lastAction?.type !== 'request_kiku_key');\r\n return showCarousel && (\r\n <SourcesCarousel\r\n sources={msgSources}\r\n defaultCurrency={defaultCurrency}\r\n onSelectSource={handleSourceClick}\r\n onImageClick={setLightboxSrc}\r\n referencedIds={msgReferencedIds}\r\n compact={!!msg.visualization}\r\n />\r\n );\r\n })()}\r\n\r\n {/* Registered action link — the site executes; we just route */}\r\n {isLast && !loading && lastAction?.url && (\r\n <div className=\"hsk-action-pills\">\r\n <a className=\"hsk-action-pill\" href={lastAction.url}>\r\n {String(lastAction.type || 'continue').replace(/_/g, ' ')} →\r\n </a>\r\n </div>\r\n )}\r\n\r\n {/* Smart context pills — built only from products the answer referenced */}\r\n {isLast && !loading && (\r\n <SmartContextPills\r\n intent={lastIntent}\r\n sources={sources.filter(s => s.id && referencedIds.includes(s.id))}\r\n onSend={handleSend}\r\n loading={loading}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })\r\n )}\r\n\r\n {/* Selected product pinned card — shows while LLM fetches details */}\r\n {selectedProduct && loading && (\r\n <div\r\n className=\"hsk-cb-selected-product\"\r\n onClick={() => selectedProduct.url && window.open(selectedProduct.url, '_blank')}\r\n >\r\n {selectedProduct.image && (\r\n <img className=\"hsk-cb-selected-img\" src={selectedProduct.image} alt={selectedProduct.name} />\r\n )}\r\n <div className=\"hsk-cb-selected-info\">\r\n <div className=\"hsk-cb-selected-name\">{selectedProduct.name}</div>\r\n {selectedProduct.price && (\r\n <div className=\"hsk-cb-selected-price\">\r\n {selectedProduct.currency ?? defaultCurrency} {parseFloat(String(selectedProduct.price ?? '').replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Shown only while waiting for the server; stops the moment tokens start streaming in. */}\r\n {loading && !streaming && (\r\n <div className=\"hsk-cb-typing-row\" style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>\r\n <div className=\"hsk-cb-thinking-icon\">\r\n <svg className=\"hsk-brand-mark\" viewBox=\"0 0 100 100\" aria-hidden=\"true\">\r\n <path d=\"M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z\" transform=\"translate(22.7 19) scale(0.62)\" fillRule=\"evenodd\" />\r\n </svg>\r\n <svg className=\"hsk-brand-mark hsk-brand-mark--sheen\" viewBox=\"0 0 100 100\" aria-hidden=\"true\">\r\n <path d=\"M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z\" transform=\"translate(22.7 19) scale(0.62)\" fillRule=\"evenodd\" />\r\n </svg>\r\n <span className=\"hsk-handle-orbit\">\r\n <span className=\"hsk-handle-ring\">\r\n <span className=\"hsk-handle-ball\" />\r\n <span className=\"hsk-handle-ball\" />\r\n <span className=\"hsk-handle-ball\" />\r\n <span className=\"hsk-handle-ball\" />\r\n <span className=\"hsk-handle-ball\" />\r\n </span>\r\n </span>\r\n <span className=\"hsk-handle-rest\" />\r\n </div>\r\n <span className=\"hsk-cb-thinking-text\">Thinking…</span>\r\n </div>\r\n )}\r\n\r\n {error && <div className=\"hsk-cb-error\">{getFriendlyError(error)}</div>}\r\n\r\n {/* Carry-your-items prompt: paste an existing kiku key, or mint a\r\n new one (shown exactly once). No phone, no account. */}\r\n {keyPhase === 'prompt_key' && (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n <div className=\"hsk-cb-ai-text\">\r\n <div className=\"hsk-cb-phone-form\">\r\n <label className=\"hsk-cb-phone-label\">Paste your kiku key — or create one</label>\r\n <input\r\n type=\"text\"\r\n className=\"hsk-cb-phone-input\"\r\n placeholder=\"kiku_…\"\r\n value={keyInput}\r\n onChange={e => setKeyInput(e.target.value)}\r\n onKeyDown={e => e.key === 'Enter' && handleUseExistingKey()}\r\n autoFocus\r\n />\r\n <div style={{ display: 'flex', gap: 8 }}>\r\n <button className=\"hsk-cb-phone-submit\" onClick={handleUseExistingKey} disabled={!keyInput.trim()}>\r\n Use my key\r\n </button>\r\n <button className=\"hsk-cb-phone-submit\" onClick={handleCreateKey} disabled={minting}>\r\n {minting ? 'Creating…' : \"I'm new — create my key\"}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {mintedKey && (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n <div className=\"hsk-cb-ai-text\">\r\n <div style={{ padding: '10px 12px', border: '1px solid var(--hsk-border, #e5e5e5)', borderRadius: 8 }}>\r\n <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 4 }}>🔑 Your kiku key — shown only once</div>\r\n <code style={{ display: 'block', fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: 'break-all' }}>{mintedKey}</code>\r\n <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\r\n <button className=\"hsk-cb-phone-submit\" style={{ padding: '4px 10px' }} onClick={() => { try { navigator.clipboard?.writeText(mintedKey); } catch { /* ignore */ } }}>Copy</button>\r\n <span style={{ fontSize: 11, opacity: 0.7 }}>\r\n Disappears in {keyCountdown}s. Save it like a password — if lost, the memory it opens is lost with it.\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={bottomRef} style={{ height: 1 }} />\r\n </div>\r\n\r\n <div className=\"hsk-cb-input-wrap\">\r\n {/* @ extension picker — floats above the input area */}\r\n {showAtPicker && (\r\n <AtPickerMenu\r\n onSelect={handleSelectExtension}\r\n onDismiss={() => setShowAtPicker(false)}\r\n />\r\n )}\r\n {/* @kiku command picker — floats above the input area */}\r\n {showKikuPicker && (\r\n <KikuPickerMenu\r\n sources={sources}\r\n referencedIds={referencedIds}\r\n defaultCurrency={defaultCurrency}\r\n onCapture={handleKikuCapture}\r\n onCaptureAll={handleKikuCaptureAll}\r\n onViewHistory={handleKikuViewHistory}\r\n onDelete={handleKikuDelete}\r\n onDismiss={() => setShowKikuPicker(false)}\r\n />\r\n )}\r\n {/* Image attachment strip */}\r\n {attachments.length > 0 && (\r\n <div className=\"hsk-cb-img-strip\">\r\n {attachments.map((att, i) => (\r\n <div key={i} className=\"hsk-cb-img-thumb-wrap\">\r\n <img src={att.data} alt={`attachment ${i + 1}`} className=\"hsk-cb-img-thumb\" />\r\n <button\r\n className=\"hsk-cb-img-thumb-remove\"\r\n onClick={() => removeAttachment(i)}\r\n aria-label=\"Remove image\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n <div className=\"hsk-cb-input-box\">\r\n {/* Hidden file input */}\r\n <input\r\n ref={imageInputRef}\r\n type=\"file\"\r\n accept=\"image/*\"\r\n multiple\r\n style={{ display: 'none' }}\r\n onChange={e => handleImageFiles(e.target.files)}\r\n />\r\n {/* Attach button — only shown if vision is enabled */}\r\n {enableVision && (\r\n <button\r\n className=\"hsk-cb-attach-btn\"\r\n onClick={() => imageInputRef.current?.click()}\r\n disabled={loading}\r\n aria-label=\"Attach image\"\r\n title=\"Attach image\"\r\n >\r\n <PaperclipIcon />\r\n </button>\r\n )}\r\n <textarea\r\n ref={textareaRef}\r\n className={cn(\"hsk-cb-textarea\", classNames.input)}\r\n value={input}\r\n onChange={handleInput}\r\n onKeyDown={handleKeyDown}\r\n placeholder={\r\n voiceState === 'listening' ? '🎙️ Listening… tap the mic to stop'\r\n : voiceState === 'processing' ? 'Got it — sending…'\r\n : activePlaceholder\r\n }\r\n rows={1}\r\n disabled={loading}\r\n autoFocus\r\n />\r\n {/* Voice button — only shown if SpeechRecognition is supported and enabled */}\r\n {hasSpeechAPI && enableVoice && (\r\n <button\r\n className={cn(\r\n \"hsk-cb-mic-btn\",\r\n voiceState === 'listening' && \"hsk-cb-mic-btn--listening\",\r\n voiceState === 'processing' && \"hsk-cb-mic-btn--processing\"\r\n )}\r\n onClick={voiceState === 'idle' ? startVoice : stopVoice}\r\n disabled={loading}\r\n aria-label={voiceState === 'idle' ? 'Start voice input' : 'Stop recording'}\r\n title={voiceState === 'idle' ? 'Voice input' : 'Stop'}\r\n >\r\n {voiceState === 'listening' ? <MicOffIcon /> : <MicIcon />}\r\n {voiceState === 'listening' && <span className=\"hsk-cb-mic-pulse\" />}\r\n </button>\r\n )}\r\n {(loading || streaming) ? (\r\n <button\r\n className={cn(\"hsk-cb-send\", \"hsk-cb-send--stop\", classNames.sendButton)}\r\n onClick={stop}\r\n aria-label=\"Stop generating\"\r\n title=\"Stop generating\"\r\n >\r\n <StopIcon />\r\n </button>\r\n ) : (\r\n <button\r\n className={cn(\"hsk-cb-send\", classNames.sendButton)}\r\n onClick={() => handleSend()}\r\n disabled={!input.trim() && attachments.length === 0}\r\n aria-label=\"Send message\"\r\n >\r\n <ArrowUpIcon />\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"hsk-cb-hint\">kiku · searches the whole catalogue in real time</div>\r\n </div>\r\n\r\n </div>{/* end .hsk-cb-main */}\r\n\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n// ─── KikuButton (public export) ─────────────────────────────────────────────\r\n\r\nexport function KikuButton({\r\n label,\r\n title,\r\n placeholder,\r\n backdropColor,\r\n backdropBlur,\r\n className,\r\n onSelectSource,\r\n defaultCurrency,\r\n chips,\r\n theme,\r\n classNames = {},\r\n enableVoice = false,\r\n voiceLang,\r\n enableVision = false,\r\n visionCategoryHint,\r\n}: KikuButtonProps) {\r\n const [open, setOpen] = useState(false);\r\n const [mounted, setMounted] = useState(false);\r\n\r\n useEffect(() => {\r\n setMounted(true);\r\n\r\n if (typeof window !== 'undefined' && !(window as any).__akropolys_nav_patched) {\r\n (window as any).__akropolys_nav_patched = true;\r\n const originalPush = window.history.pushState;\r\n const originalReplace = window.history.replaceState;\r\n\r\n window.history.pushState = function(...args) {\r\n originalPush.apply(this, args);\r\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\r\n };\r\n\r\n window.history.replaceState = function(...args) {\r\n originalReplace.apply(this, args);\r\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\r\n };\r\n }\r\n\r\n const handleNavigation = () => {\r\n setOpen(false);\r\n };\r\n\r\n window.addEventListener('popstate', handleNavigation);\r\n window.addEventListener('akropolys:navigation', handleNavigation);\r\n\r\n return () => {\r\n window.removeEventListener('popstate', handleNavigation);\r\n window.removeEventListener('akropolys:navigation', handleNavigation);\r\n };\r\n }, []);\r\n\r\n const isStringTheme = typeof theme === 'string';\r\n const hskThemeAttr = isStringTheme ? theme : undefined;\r\n\r\n const customStyles = (!isStringTheme && theme) ? {\r\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\r\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\r\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\r\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\r\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\r\n } as React.CSSProperties : undefined;\r\n\r\n return (\r\n <>\r\n <button\r\n className={cn(\"hsk-cb-btn\", classNames.button, className)}\r\n onClick={() => setOpen(true)}\r\n style={customStyles}\r\n data-hsk-theme={hskThemeAttr}\r\n aria-label=\"Open AI chat\"\r\n >\r\n <span className=\"hsk-cb-btn-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </span>\r\n {label !== undefined ? label : null}\r\n </button>\r\n {open && mounted && createPortal(\r\n <ChatModal\r\n title={title}\r\n placeholder={placeholder}\r\n backdropColor={backdropColor}\r\n backdropBlur={backdropBlur}\r\n onClose={() => setOpen(false)}\r\n onSelectSource={onSelectSource}\r\n defaultCurrency={defaultCurrency}\r\n chips={chips}\r\n theme={theme}\r\n classNames={classNames}\r\n enableVoice={enableVoice}\r\n voiceLang={voiceLang}\r\n enableVision={enableVision}\r\n visionCategoryHint={visionCategoryHint}\r\n />,\r\n document.body\r\n )}\r\n </>\r\n );\r\n}\r\n","import React from 'react';\nimport type { ChatSource } from '@akropolys/sdk';\nimport { resolveDisplayFields } from '@akropolys/sdk';\n\nexport interface ComparisonMatrixProps {\n sources: ChatSource[];\n defaultCurrency?: string;\n displayConfig?: Record<string, string>;\n}\n\ninterface Row {\n label: string;\n values: (string | null)[];\n type?: 'image' | 'price' | 'availability' | 'text';\n bestIdx?: number;\n}\n\nfunction normalizeKey(key: string): string {\n let s = key.replace(/[_-]+/g, ' ');\n s = s.replace(/([a-z])([A-Z])/g, '$1 $2');\n return s.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');\n}\n\nfunction getBaseGroup(normalized: string): string {\n const norm = normalized.toLowerCase().trim();\n if (norm.startsWith('salary') || norm.startsWith('pay') || norm.startsWith('wage')) {\n return 'Salary';\n }\n if (norm.startsWith('price') || norm.startsWith('cost') || norm.startsWith('rate')) {\n return 'Price';\n }\n if (norm.startsWith('location') || norm.startsWith('address') || norm.startsWith('city')) {\n return 'Location';\n }\n if (norm.startsWith('image') || norm.startsWith('photo') || norm.startsWith('pic') || norm.startsWith('thumb')) {\n return 'Image';\n }\n if (norm.startsWith('title') || norm.startsWith('name') || norm.startsWith('label') || norm.startsWith('heading')) {\n return 'Title';\n }\n return normalized;\n}\n\nfunction buildRows(products: ChatSource[], displayConfig?: Record<string, string>, defaultCurrency = 'KES'): Row[] {\n const rows: Row[] = [];\n const resolved = products.map(p => resolveDisplayFields(p.fields || p, displayConfig));\n\n rows.push({\n label: 'Product Preview',\n values: resolved.map(r => r.image || null),\n type: 'image',\n });\n\n const prices = resolved.map(r => {\n const n = parseFloat(String(r.price ?? '').replace(/[^0-9.]/g, ''));\n return isNaN(n) ? null : n;\n });\n\n const priceLabels = products.map((p, i) => {\n const c = p.fields?.currency || p.currency || defaultCurrency;\n const n = prices[i];\n return n !== null\n ? `${c} ${n.toLocaleString('en-KE', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`\n : null;\n });\n\n const validPrices = prices.filter((p): p is number => p !== null);\n const minPrice = validPrices.length ? Math.min(...validPrices) : null;\n rows.push({\n label: 'Price',\n values: priceLabels,\n type: 'price',\n bestIdx: minPrice !== null ? prices.indexOf(minPrice) : undefined,\n });\n\n const keysToExclude = new Set<string>([\n 'url', 'fields', 'id', 'score', 'currency', 'status', 'indexed_at', 'indexedAt'\n ]);\n \n if (displayConfig) {\n Object.values(displayConfig).forEach(v => {\n if (v) keysToExclude.add(v);\n });\n }\n\n const commonKeys = [\n 'title', 'name', 'label', 'headline', 'subject', 'job_title', 'listing_title', 'common_name', 'product_name',\n 'image', 'images', 'thumbnail', 'photo', 'cover', 'featured_image', 'hero_image', 'listing_image', 'logo',\n 'price', 'cost', 'listingPrice', 'rate', 'fee', 'startingFrom',\n 'brand', 'category', 'location', 'type', 'variety', 'make'\n ];\n commonKeys.forEach(k => keysToExclude.add(k));\n\n const allFieldKeys = new Set<string>();\n products.forEach(p => {\n const f = p.fields || p;\n if (f) {\n Object.keys(f).forEach(k => {\n if (!keysToExclude.has(k)) {\n allFieldKeys.add(k);\n }\n });\n }\n });\n\n const groupedKeys = new Map<string, string[]>();\n allFieldKeys.forEach(k => {\n const norm = normalizeKey(k);\n const base = getBaseGroup(norm);\n if (!groupedKeys.has(base)) {\n groupedKeys.set(base, []);\n }\n groupedKeys.get(base)!.push(k);\n });\n\n const sortedGroups = Array.from(groupedKeys.keys()).sort();\n\n sortedGroups.forEach(group => {\n const originalKeys = groupedKeys.get(group)!;\n const values = products.map(p => {\n const f = (p.fields || p) as Record<string, any>;\n if (!f) return null;\n for (const k of originalKeys) {\n if (f[k] !== undefined && f[k] !== null) {\n if (typeof f[k] === 'object') {\n return JSON.stringify(f[k]);\n }\n return String(f[k]);\n }\n }\n return null;\n });\n\n if (values.some(v => v !== null)) {\n rows.push({\n label: group,\n values,\n type: 'text',\n });\n }\n });\n\n const avail = products.map(s => {\n const f = s.fields || s;\n const a = (f.availability as string) || '';\n if (!a) return null;\n if (/in.?stock/i.test(a)) return 'In-Stock';\n if (/out.?of.?stock/i.test(a)) return 'Out of Stock';\n return a;\n });\n if (avail.some(Boolean)) {\n rows.push({ label: 'Availability', values: avail, type: 'availability' });\n }\n\n const cats = products.map(s => {\n const f = s.fields || s;\n return (f.category as string) || null;\n });\n if (cats.some(Boolean)) rows.push({ label: 'Category', values: cats });\n\n return rows;\n}\n\nfunction ImageCell({ value, name }: { value: string | null; name: string }) {\n if (!value) {\n return <div style={{ fontSize: 28, textAlign: 'center' }}>📦</div>;\n }\n return (\n <img\n src={value}\n alt={name}\n style={{\n width: 72,\n height: 72,\n objectFit: 'contain',\n borderRadius: 8,\n background: '#f5f5f5',\n display: 'block',\n }}\n />\n );\n}\n\n// Custom green pulsing ring on availability dot to match design guidelines\nfunction AvailabilityCell({ value }: { value: string | null }) {\n if (!value) return <span style={{ color: '#9ca3af' }}>—</span>;\n const inStock = /in.?stock/i.test(value);\n return (\n <span style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 13, color: 'var(--hsk-text, #111827)' }}>\n <span style={{\n width: 8, height: 8, borderRadius: '50%', flexShrink: 0,\n background: inStock ? '#22c55e' : '#ef4444',\n boxShadow: inStock ? '0 0 0 3px rgba(34,197,94,0.2)' : '0 0 0 3px rgba(239,68,68,0.2)',\n display: 'inline-block',\n }} />\n {value}\n </span>\n );\n}\n\nexport function ComparisonMatrix({ sources, defaultCurrency = 'KES', displayConfig }: ComparisonMatrixProps) {\n if (!sources || sources.length < 2) return null;\n\n const products = sources.slice(0, 3);\n const rows = buildRows(products, displayConfig, defaultCurrency);\n const colTemplate = `140px repeat(${products.length}, 1fr)`;\n\n const labelStyle: React.CSSProperties = {\n padding: '10px 12px',\n fontSize: 11,\n fontWeight: 700,\n color: 'var(--hsk-text-muted, #4b5563)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n borderBottom: '1px solid var(--hsk-border, rgba(0,0,0,0.07))',\n verticalAlign: 'middle',\n whiteSpace: 'nowrap',\n display: 'flex',\n alignItems: 'center',\n };\n\n const cellBase: React.CSSProperties = {\n padding: '10px 14px',\n fontSize: 13,\n color: 'var(--hsk-text, #111827)',\n borderBottom: '1px solid var(--hsk-border, rgba(0,0,0,0.07))',\n verticalAlign: 'middle',\n display: 'flex',\n alignItems: 'center',\n };\n\n return (\n <div\n className=\"hsk-compare-matrix\"\n style={{\n marginTop: 10,\n borderRadius: 12,\n overflow: 'hidden',\n border: '1px solid var(--hsk-border, rgba(0,0,0,0.09))',\n background: 'var(--hsk-surface, #fff)',\n fontSize: 13,\n }}\n >\n <div style={{ display: 'grid', gridTemplateColumns: colTemplate, background: 'var(--hsk-surface2, #f9fafb)', borderBottom: '2px solid var(--hsk-border, rgba(0,0,0,0.09))' }}>\n <div style={{ ...labelStyle, borderBottom: 'none', color: 'var(--hsk-text, #111)', fontSize: 12 }}>Feature</div>\n {products.map((p, i) => {\n const { title } = resolveDisplayFields(p.fields || p, displayConfig);\n return (\n <a\n key={i}\n href={p.url || '#'}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{\n display: 'flex',\n alignItems: 'center',\n padding: '10px 14px',\n fontSize: 12,\n fontWeight: 700,\n color: 'var(--hsk-primary, #16a34a)',\n textDecoration: 'none',\n lineHeight: 1.3,\n borderLeft: i > 0 ? '1px solid var(--hsk-border, rgba(0,0,0,0.07))' : 'none',\n }}\n >\n {title}\n </a>\n );\n })}\n </div>\n\n {rows.map((row, rowIdx) => (\n <div\n key={rowIdx}\n style={{\n display: 'grid',\n gridTemplateColumns: colTemplate,\n background: rowIdx % 2 === 1 ? 'var(--hsk-surface2, rgba(0,0,0,0.015))' : 'transparent',\n }}\n >\n <div style={labelStyle}>{row.label}</div>\n\n {products.map((p, i) => {\n const val = row.values[i];\n const isBest = row.bestIdx === i && row.values.filter(Boolean).length > 1;\n const { title } = resolveDisplayFields(p.fields || p, displayConfig);\n\n if (row.type === 'image') {\n return (\n <div key={i} style={{ ...cellBase, justifyContent: 'center', padding: '12px', borderLeft: i > 0 ? '1px solid var(--hsk-border, rgba(0,0,0,0.07))' : 'none' }}>\n <ImageCell value={val} name={title} />\n </div>\n );\n }\n if (row.type === 'availability') {\n return (\n <div key={i} style={{ ...cellBase, borderLeft: i > 0 ? '1px solid var(--hsk-border, rgba(0,0,0,0.07))' : 'none' }}>\n <AvailabilityCell value={val} />\n </div>\n );\n }\n return (\n <div\n key={i}\n style={{\n ...cellBase,\n fontWeight: isBest ? 700 : 400,\n color: isBest\n ? 'var(--hsk-primary, #ea580c)'\n : row.type === 'price'\n ? 'var(--hsk-text, #374151)'\n : 'var(--hsk-text, #111827)',\n borderLeft: i > 0 ? '1px solid var(--hsk-border, rgba(0,0,0,0.07))' : 'none',\n }}\n >\n {val ?? <span style={{ color: '#9ca3af' }}>—</span>}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n );\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useSearch, useKiku, useAkropolysContext } from '@akropolys/sdk';\nimport { renderMarkdown } from '../utils/markdown';\nimport { SearchResult, Product, AkropolysTheme } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\n\nexport interface SparkleProps {\n productName: string;\n limit?: number;\n onResult?: (results: SearchResult[]) => void;\n /** Override the backdrop colour (any CSS colour/gradient) */\n backdropColor?: string;\n /** Override backdrop blur — e.g. \"8px\" or 8 */\n backdropBlur?: string | number;\n /** Extra classes on the trigger button */\n className?: string;\n /** Called when user clicks a result — return false to prevent default navigation */\n onNavigate?: (result: SearchResult) => boolean | void;\n theme?: AkropolysTheme;\n classNames?: {\n button?: string;\n backdrop?: string;\n card?: string;\n item?: string;\n };\n product?: Product;\n children?: React.ReactNode;\n}\n\n/* ── Modal ────────────────────────────────────────────────────────────────── */\ninterface ModalProps extends Pick<SparkleProps, 'productName' | 'limit' | 'backdropColor' | 'backdropBlur' | 'onNavigate' | 'onResult' | 'theme' | 'classNames' | 'product'> {\n onClose: () => void;\n}\n\nconst SparkleIcon = ({ className, size = 16 }: { className?: string; size?: number }) => (\n <svg\n className={cn(\"hsk-brand-mark\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 100 100\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-label=\"kiku\"\n >\n <g transform=\"translate(22.7 19) scale(0.62)\" fill=\"currentColor\" fillRule=\"evenodd\">\n <path d=\"M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z\" />\n <circle cx=\"55\" cy=\"82\" r=\"3.4\" />\n </g>\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\n/* ── Modal ────────────────────────────────────────────────────────────────── */\ninterface ModalProps extends Pick<SparkleProps, 'productName' | 'limit' | 'backdropColor' | 'backdropBlur' | 'onNavigate' | 'onResult' | 'theme' | 'classNames' | 'product'> {\n onClose: () => void;\n}\n\nconst getFriendlyError = (err: any) => {\n let str = '';\n if (typeof err === 'string') str = err;\n else if (err && typeof err === 'object' && err.message) str = err.message;\n else try { str = JSON.stringify(err); } catch { str = String(err); }\n\n if (str.toLowerCase().includes('token limit')) {\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\n }\n\n try {\n const parsed = JSON.parse(str);\n return parsed.error || parsed.message || str;\n } catch {\n return str;\n }\n};\n\nfunction SparkleModal({ \n productName, \n limit, \n backdropColor, \n backdropBlur, \n onClose, \n onNavigate, \n onResult,\n theme,\n classNames = {},\n product: initialProduct,\n}: ModalProps) {\n const client = useAkropolysContext();\n const [fetchedProduct, setFetchedProduct] = useState<Product | null>(null);\n const displayProduct = initialProduct || fetchedProduct;\n const { results, loading: searchLoading, search } = useSearch({ type: 'vector' });\n const { messages, sources, loading: chatLoading, error: chatError, send } = useKiku();\n const [chatInput, setChatInput] = useState('');\n const [isMobile, setIsMobile] = useState(false);\n const [showSpecs, setShowSpecs] = useState(false);\n const [collapseSimilar, setCollapseSimilar] = useState(false);\n const chatBottomRef = useRef<HTMLDivElement>(null);\n const chatTextareaRef = useRef<HTMLTextAreaElement>(null);\n\n /* auto-search and product fetching on open */\n useEffect(() => {\n if (!initialProduct && !fetchedProduct) {\n client.api.searchVector(productName, 1)\n .then(res => {\n if (res.results && res.results.length > 0) {\n setFetchedProduct(res.results[0].entity);\n }\n })\n .catch(err => console.error('[Akropolys] Failed to fetch product details', err));\n }\n search(productName, limit);\n }, [productName, initialProduct, fetchedProduct, client, limit, search]);\n\n /* handle window resize for mobile check */\n useEffect(() => {\n const handleResize = () => setIsMobile(window.innerWidth <= 768);\n handleResize();\n if (typeof window !== 'undefined') {\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }\n }, []);\n\n /* fire callback */\n useEffect(() => { if (results.length > 0) onResult?.(results); }, [results, onResult]);\n\n /* Escape key */\n useEffect(() => {\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, [onClose]);\n\n /* Scroll chat to bottom */\n useEffect(() => {\n chatBottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages, chatLoading]);\n\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '16px');\n const bg = backdropColor ?? undefined;\n\n const handleNav = (r: SearchResult) => {\n const prevent = onNavigate?.(r);\n if (prevent !== false) {\n onClose();\n if (r.entity.url) window.location.href = r.entity.url;\n }\n };\n\n const handleSend = async (text?: string) => {\n const q = (text ?? chatInput).trim();\n if (!q || chatLoading) return;\n setChatInput('');\n if (chatTextareaRef.current) {\n chatTextareaRef.current.style.height = 'auto';\n }\n\n if (messages.length === 0 && displayProduct) {\n const contextQuery = `[Context: Shopper is viewing \"${displayProduct.name}\". Price: ${displayProduct.price}. Description: ${displayProduct.description || ''}]\\n\\nQuestion: ${q}`;\n await send(contextQuery, q);\n } else {\n await send(q);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setChatInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\n };\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n const displayMessages = messages.length === 0 && displayProduct\n ? [\n {\n role: 'assistant' as const,\n content: `Hi! I can help you with **${displayProduct.name}**. Ask me about its specifications, features, compare it with other options, or find alternatives!`,\n },\n ]\n : messages;\n\n if (isMobile) {\n return (\n <div\n className={cn(\"hsk-sp-backdrop hsk-sp-mobile-view\", classNames.backdrop)}\n onClick={onClose}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n background: bg ?? undefined,\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-sp-card hsk-sp-fullscreen hsk-sp-mobile-card\", classNames.card)} onClick={e => e.stopPropagation()}>\n {/* Header */}\n <div className=\"hsk-sp-header\">\n <span className=\"hsk-sp-header-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div className=\"hsk-sp-header-body\">\n <div className=\"hsk-sp-header-title-row\">\n <div className=\"hsk-sp-header-title\">{displayProduct?.name || productName}</div>\n {displayProduct && (\n <button \n type=\"button\" \n className=\"hsk-sp-header-specs-btn\"\n onClick={() => setShowSpecs(true)}\n >\n Specs\n </button>\n )}\n </div>\n <div className=\"hsk-sp-header-sub\">kiku</div>\n </div>\n <button className=\"hsk-sp-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n\n {searchLoading && <div className=\"hsk-sp-bar\" />}\n\n {/* Chat Assistant */}\n <div className=\"hsk-sp-mobile-chat-container\">\n <div className=\"hsk-cb-msgs\">\n {displayMessages.map((msg, idx) => {\n const isUser = msg.role === 'user';\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\n </div>\n ) : (\n <div className=\"hsk-cb-ai-msg\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-ai-body\">\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\n \n {/* Inline Claude-like attachments under the first assistant message */}\n {idx === 0 && displayProduct && (\n <div className=\"hsk-sp-mobile-attachment-deck\">\n {/* Main Product Card */}\n <div className=\"hsk-sp-mobile-main-card\">\n <div className=\"hsk-sp-mobile-main-card-img\">\n {displayProduct.images?.[0] ? (\n <img src={displayProduct.images[0]} alt={displayProduct.name} />\n ) : (\n <span>ðŸ›</span>\n )}\n </div>\n <div className=\"hsk-sp-mobile-main-card-info\">\n <div className=\"hsk-sp-mobile-main-card-brand\">\n {displayProduct.brand || displayProduct.category || 'Product'}\n </div>\n <div className=\"hsk-sp-mobile-main-card-name\">{displayProduct.name}</div>\n <div className=\"hsk-sp-mobile-main-card-price\">\n {displayProduct.currency ?? 'KES'} {parseFloat(displayProduct.price?.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n </div>\n {((displayProduct.specs && Object.keys(displayProduct.specs).length > 0) || displayProduct.description) && (\n <button \n type=\"button\"\n className=\"hsk-sp-mobile-main-card-specs-btn\"\n onClick={() => setShowSpecs(true)}\n >\n Specs\n </button>\n )}\n </div>\n\n {/* Similar Products Carousel */}\n {(() => {\n const similarProducts = results.filter(\n r => {\n const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());\n const isSameSlug = r.entity.slug && displayProduct?.slug && r.entity.slug.toLowerCase() === displayProduct.slug.toLowerCase();\n return !isSameName && !isSameSlug;\n }\n );\n\n if (similarProducts.length === 0) return null;\n\n return (\n <div className=\"hsk-sp-mobile-similar-carousel-inline\">\n <div className=\"hsk-sp-mobile-similar-carousel-title\">Similar Products</div>\n <div className=\"hsk-sp-mobile-similar-carousel-list\">\n {similarProducts.map((r) => {\n const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, '') || '0');\n const currency = r.entity.currency ?? 'KES';\n return (\n <div\n key={r.id}\n className=\"hsk-sp-mobile-similar-carousel-item\"\n onClick={() => handleNav(r)}\n >\n <div className=\"hsk-sp-mobile-similar-carousel-img\">\n {r.entity.images?.[0] ? (\n <img src={r.entity.images[0]} alt={r.entity.name} />\n ) : (\n <span>ðŸ›</span>\n )}\n </div>\n <div className=\"hsk-sp-mobile-similar-carousel-meta\">\n <div className=\"hsk-sp-mobile-similar-carousel-name\" title={r.entity.name}>\n {r.entity.name}\n </div>\n <div className=\"hsk-sp-mobile-similar-carousel-price\">\n {currency} {price.toLocaleString()}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n })()}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n })}\n\n {chatLoading && (\n <div className=\"hsk-cb-typing-row\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-typing\">\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n )}\n\n {chatError && <div className=\"hsk-cb-error\">{getFriendlyError(chatError)}</div>}\n <div ref={chatBottomRef} style={{ height: 1 }} />\n </div>\n\n <div className=\"hsk-cb-input-wrap\">\n <div className=\"hsk-cb-input-box\">\n <textarea\n ref={chatTextareaRef}\n className=\"hsk-cb-textarea\"\n value={chatInput}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder=\"Ask about this product, specs, or comparison...\"\n rows={1}\n disabled={chatLoading}\n />\n <button\n className=\"hsk-cb-send\"\n onClick={() => handleSend()}\n disabled={!chatInput.trim() || chatLoading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n </div>\n </div>\n\n {/* Specs Sheet Drawer Overlay */}\n {showSpecs && displayProduct && (\n <div className=\"hsk-sp-mobile-specs-overlay\" onClick={() => setShowSpecs(false)}>\n <div className=\"hsk-sp-mobile-specs-drawer\" onClick={e => e.stopPropagation()}>\n <div className=\"hsk-sp-mobile-specs-header\">\n <h3>Specifications</h3>\n <button type=\"button\" onClick={() => setShowSpecs(false)}>Close</button>\n </div>\n <div className=\"hsk-sp-mobile-specs-body\">\n <h4 className=\"hsk-sp-mobile-specs-title\">{displayProduct.name}</h4>\n {displayProduct.description && (\n <div className=\"hsk-sp-mobile-specs-desc\">\n <h5>Description</h5>\n <p>{displayProduct.description}</p>\n </div>\n )}\n {displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && (\n <div className=\"hsk-sp-mobile-specs-list\">\n <h5>Details</h5>\n {Object.entries(displayProduct.specs).map(([key, val]) => (\n <div key={key} className=\"hsk-sp-mobile-spec-row\">\n <span className=\"hsk-sp-mobile-spec-label\">{key}</span>\n <span className=\"hsk-sp-mobile-spec-value\">{val}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"hsk-sp-backdrop\", classNames.backdrop)}\n onClick={onClose}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n background: bg ?? undefined,\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-sp-card hsk-sp-fullscreen\", classNames.card)} onClick={e => e.stopPropagation()}>\n <div className=\"hsk-sp-header\">\n <span className=\"hsk-sp-header-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div className=\"hsk-sp-header-body\">\n <div className=\"hsk-sp-header-title\">{displayProduct?.name || productName}</div>\n <div className=\"hsk-sp-header-sub\">Ask questions, compare specs, or check similar products</div>\n </div>\n <button className=\"hsk-sp-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n\n {searchLoading && <div className=\"hsk-sp-bar\" />}\n\n {/* Split pane body */}\n <div className=\"hsk-sp-body\">\n {/* Left Pane: Product Profile */}\n <div className=\"hsk-sp-details-pane\">\n {displayProduct && (\n <div className=\"hsk-sp-product-profile-container\">\n <div className=\"hsk-sp-product-profile\">\n <div className=\"hsk-sp-details-imgwrap\">\n {displayProduct.images?.[0] ? (\n <img src={displayProduct.images[0]} alt={displayProduct.name} />\n ) : (\n <span className=\"hsk-sp-img-placeholder\">ðŸ›</span>\n )}\n </div>\n <div className=\"hsk-sp-details-meta\">\n {displayProduct.brand && <span className=\"hsk-sp-item-brand\">{displayProduct.brand}</span>}\n {displayProduct.category && <span className=\"hsk-sp-item-cat\">{displayProduct.category}</span>}\n <h2 className=\"hsk-sp-details-name\">{displayProduct.name}</h2>\n <div className=\"hsk-sp-item-price-row\">\n <span className=\"hsk-sp-item-currency\">{displayProduct.currency ?? 'KES'}</span>\n <span className=\"hsk-sp-item-price\">{parseFloat(displayProduct.price?.replace(/[^0-9.]/g, '') || '0').toLocaleString()}</span>\n {displayProduct.originalPrice && (\n <span className=\"hsk-sp-item-original-price\">\n {parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </span>\n )}\n {displayProduct.discount && (\n <span className=\"hsk-sp-item-discount\">({displayProduct.discount})</span>\n )}\n </div>\n \n <div className=\"hsk-sp-item-meta-badges\">\n {displayProduct.rating && (\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-rating\">\n ★ {parseFloat(displayProduct.rating.toString()).toFixed(1)} {displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ''}\n </span>\n )}\n {displayProduct.availability && (\n <span className={`hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes('in') ? 'in-stock' : 'out-stock'}`}>\n {displayProduct.availability}\n </span>\n )}\n {displayProduct.stock && !displayProduct.availability && (\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-stock\">\n Stock: {displayProduct.stock}\n </span>\n )}\n </div>\n </div>\n </div>\n\n {displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && (\n <div className=\"hsk-sp-specs-horizontal\">\n {Object.entries(displayProduct.specs).map(([key, val]) => (\n <div key={key} className=\"hsk-sp-spec-item-horizontal\">\n <span className=\"hsk-sp-spec-label-horizontal\">{key}:</span>\n <span className=\"hsk-sp-spec-value-horizontal\" title={val}>{val}</span>\n </div>\n ))}\n </div>\n )}\n\n {displayProduct.description && (\n <div className=\"hsk-sp-details-desc\">\n <h4>Description</h4>\n <p>{displayProduct.description}</p>\n </div>\n )}\n </div>\n )}\n\n {/* Similar Products */}\n <div className=\"hsk-sp-similar-section\">\n <h3>Similar Products</h3>\n <div className=\"hsk-sp-results\">\n {(() => {\n const similarProducts = results.filter(\n r => {\n const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());\n const isSameSlug = r.entity.slug && displayProduct?.slug && r.entity.slug.toLowerCase() === displayProduct.slug.toLowerCase();\n return !isSameName && !isSameSlug;\n }\n );\n\n if (!searchLoading && similarProducts.length === 0) {\n return <div className=\"hsk-sp-empty\">No similar products found.</div>;\n }\n\n return similarProducts.map((r, i) => {\n const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, '') || '0');\n const currency = r.entity.currency ?? 'KES';\n return (\n <div\n key={r.id}\n className={cn(\"hsk-sp-item\", classNames.item)}\n style={{ animationDelay: `${i * 55}ms`, cursor: 'pointer' }}\n onClick={() => handleNav(r)}\n >\n <div className=\"hsk-sp-img-wrap\">\n {r.entity.images?.[0] ? (\n <img src={r.entity.images[0]} alt={r.entity.name} />\n ) : (\n <span className=\"hsk-sp-img-placeholder\">ðŸ›</span>\n )}\n </div>\n <div className=\"hsk-sp-item-body\">\n <div>\n {r.entity.category && (\n <div className=\"hsk-sp-item-cat\">{r.entity.category}</div>\n )}\n <div className=\"hsk-sp-item-name\" title={r.entity.name}>{r.entity.name}</div>\n </div>\n <div className=\"hsk-sp-item-price-row\">\n <span className=\"hsk-sp-item-currency\">{currency}</span>\n <span className=\"hsk-sp-item-price\">{price.toLocaleString()}</span>\n </div>\n <div className=\"hsk-sp-actions\">\n <button\n className=\"hsk-sp-action hsk-sp-action-primary\"\n onClick={(e) => { e.stopPropagation(); handleNav(r); }}\n >\n View\n </button>\n </div>\n </div>\n </div>\n );\n });\n })()}\n </div>\n </div>\n </div>\n\n {/* Right Pane: AI Chat Assistant */}\n <div className=\"hsk-sp-chat-pane\">\n <div className=\"hsk-cb-msgs\">\n {displayMessages.map((msg, idx) => {\n const isUser = msg.role === 'user';\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\n </div>\n ) : (\n <div className=\"hsk-cb-ai-msg\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-ai-body\">\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\n </div>\n </div>\n )}\n </div>\n );\n })}\n\n {chatLoading && (\n <div className=\"hsk-cb-typing-row\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-typing\">\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n )}\n\n {chatError && <div className=\"hsk-cb-error\">{getFriendlyError(chatError)}</div>}\n <div ref={chatBottomRef} style={{ height: 1 }} />\n </div>\n\n <div className=\"hsk-cb-input-wrap\">\n <div className=\"hsk-cb-input-box\">\n <textarea\n ref={chatTextareaRef}\n className=\"hsk-cb-textarea\"\n value={chatInput}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder=\"Ask about this product, specs, or comparison...\"\n rows={1}\n disabled={chatLoading}\n />\n <button\n className=\"hsk-cb-send\"\n onClick={() => handleSend()}\n disabled={!chatInput.trim() || chatLoading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n <div className=\"hsk-cb-hint\">Akropolys · instant product knowledge</div>\n </div>\n </div>\n </div>\n\n <div className=\"hsk-sp-footer\">\n <span className=\"hsk-sp-esc\">Esc to close</span>\n </div>\n </div>\n </div>\n );\n}\n\n/* ── Exported component ───────────────────────────────────────────────────── */\nexport function Sparkle({ \n productName, \n limit = 8, \n onResult, \n backdropColor, \n backdropBlur, \n className, \n onNavigate,\n theme,\n classNames = {},\n product,\n children,\n}: SparkleProps) {\n const [open, setOpen] = useState(false);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => { setMounted(true); }, []);\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <>\n <button\n className={cn(\"hsk-sp-btn\", classNames.button, className)}\n onClick={() => setOpen(true)}\n style={customStyles}\n title=\"Find similar products\"\n aria-label=\"Find similar products\"\n >\n {children || <SparkleIcon />}\n </button>\n {open && mounted && createPortal(\n <SparkleModal\n productName={productName}\n limit={limit}\n onResult={onResult}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n onClose={() => setOpen(false)}\n onNavigate={onNavigate}\n theme={theme}\n classNames={classNames}\n product={product}\n />,\n document.body\n )}\n </>\n );\n}\n\n"],"mappings":"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","names":["useState","useRef","useEffect","Fragment","jsx","useState","useRef","jsx","jsxs","useRef","useState","useAkropolysContext","jsx","jsxs","jsx","jsxs","useState","useRef","useEffect","useState","useEffect","useRef","useCallback","useKiku","useAkropolysContext","jsx","jsxs","Fragment","jsx","jsxs","SparkleIcon","ArrowUpIcon","jsx","MicIcon","jsxs","SparkleIcon","useState","useAkropolysContext","useRef","useCallback","useEffect","Fragment","useKiku","ArrowUpIcon","useState","useEffect","useRef","createPortal","useSearch","useKiku","useAkropolysContext","Fragment","jsx","jsxs","SparkleIcon","CloseIcon","ArrowUpIcon","getFriendlyError","useAkropolysContext","useState","useSearch","useKiku","useRef","useEffect","createPortal"]}
|