@akropolys/kiku 1.6.1 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../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":["// @akropolys/kiku — Plug-and-play UI components for Akropolys\n// Developers must explicitly import '@akropolys/kiku/styles.css' in their entry file.\n\nexport { SearchBar } from './components/SearchBar';\nexport type { SearchBarProps } from './components/SearchBar';\nexport { ChatWidget, ChatWidget as KikuChat } from './components/ChatWidget';\nexport type { ChatWidgetProps, ChatWidgetProps as KikuChatProps } from './components/ChatWidget';\nexport { KikuButton } from './components/KikuButton';\nexport type { KikuButtonProps } from './components/KikuButton';\nexport { Sparkle } from './components/Sparkle';\nexport { ComparisonMatrix } from './components/ComparisonMatrix';\n\n// Voice & Vision — free AI input modalities\nexport { VoiceButton } from './components/VoiceButton';\nexport type { VoiceButtonProps } from './components/VoiceButton';\nexport { VisualSearch } from './components/VisualSearch';\nexport type { VisualSearchProps } from './components/VisualSearch';\n\n","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 300 for smooth 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 = 300,\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 [isDebouncing, setIsDebouncing] = useState(false);\n const { results, loading, search, clear } = useSearch();\n const client = useAkropolysContext();\n const timer = useRef<ReturnType<typeof setTimeout>>();\n const wrap = useRef<HTMLDivElement>(null);\n const ignoreNextQueryChange = useRef(false);\n\n /* Debounce search — but keep stale results visible between calls */\n useEffect(() => {\n if (ignoreNextQueryChange.current) {\n ignoreNextQueryChange.current = false;\n return;\n }\n clearTimeout(timer.current);\n if (!query.trim()) {\n clear();\n setOpen(false);\n setIsDebouncing(false);\n return;\n }\n setOpen(true); // open immediately (stale results show while fetching)\n setIsDebouncing(true);\n timer.current = setTimeout(() => {\n setIsDebouncing(false);\n search(query, limit);\n }, debounceMs);\n return () => clearTimeout(timer.current);\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 client.api.searchVector(query, 1).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).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 || isDebouncing) && <div className=\"hsk-sb-loading-bar\" />}\n\n {(loading || isDebouncing) && 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 && !isDebouncing && (\n <div className=\"hsk-sb-empty\">No results for &ldquo;{query}&rdquo;</div>\n )}\n\n {results.map((r, i) => (\n renderResult ? (\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 <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-icon\"><SearchIcon /></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 cartSnapshot: messages[hookIdx].cartSnapshot,\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 ![alt](url), 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: ![alt](url)\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: ![alt](url)\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';\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useKiku, ChatMessage, ChatSource } from '@akropolys/sdk';\nimport { useAkropolysContext } from '@akropolys/sdk';\nimport { renderMarkdown } from '../utils/markdown';\nimport { AkropolysTheme, CartPayload, CartItem, ChatAttachment } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\nimport { ComparisonMatrix } from './ComparisonMatrix';\n\n\nexport interface KikuButtonProps {\n label?: string;\n title?: string;\n placeholder?: string;\n backdropColor?: string;\n backdropBlur?: string | number;\n className?: string;\n onSelectSource?: (source: ChatSource) => void;\n defaultCurrency?: string;\n chips?: string[];\n theme?: 'light' | 'dark' | AkropolysTheme;\n classNames?: {\n button?: string;\n overlay?: string;\n panel?: string;\n input?: string;\n sendButton?: string;\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// ─── Icons ────────────────────────────────────────────────────────────────────\n\n/**\n * Akropolys brand mark — an ancient serif capital Alpha (Α)\n * with an animated smooth breathing mark (spiritus lenis ʻ) at top-left.\n * The mark pulses gently, like a breath.\n */\nconst AkropolysAIcon = ({ className, size = 18 }: { 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\n/** Keep a tiny sparkle alias for places that still want the star (sources, etc.) */\nconst SparkleIcon = AkropolysAIcon;\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\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 ChevronRightIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\"/>\n </svg>\n);\n\nconst HistoryIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/>\n <path d=\"M3 3v5h5\"/>\n <path d=\"M12 7v5l4 2\"/>\n </svg>\n);\n\nconst NewChatIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 5v14M5 12h14\"/>\n </svg>\n);\n\nconst ShoppingBagIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z\"/>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/>\n <path d=\"M16 10a4 4 0 0 1-8 0\"/>\n </svg>\n);\n\nconst SecureShieldIcon = ({ className, size = 18 }: { className?: string; size?: number }) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n <path d=\"M12 11a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z\" />\n <path d=\"M12 11v4\" />\n </svg>\n);\n\nconst PaperclipIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\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\"/>\n </svg>\n);\n\nconst MicIcon = () => (\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 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\"/>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\n </svg>\n);\n\nconst MicOffIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\"/>\n <path d=\"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2\"/>\n <path d=\"M5 10v2a7 7 0 0 0 12 5\"/>\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\"/>\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\n </svg>\n);\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst DEFAULT_CHIPS = [\n 'Cheapest smartphone',\n 'Smart TV under KSh 20,000',\n 'Noise-cancelling headphones',\n 'Best laptop for students',\n];\n\nconst SESSIONS_KEY = 'akropolys_chat_sessions';\nconst MAX_SESSIONS = 20;\n\n// ─── Session types ─────────────────────────────────────────────────────────────\n\ninterface ChatSession {\n id: string;\n title: string;\n messages: ChatMessage[];\n ts: number;\n}\n\nfunction loadSessions(): ChatSession[] {\n try {\n if (typeof window === 'undefined') return [];\n const raw = localStorage.getItem(SESSIONS_KEY);\n return raw ? JSON.parse(raw) : [];\n } catch {\n return [];\n }\n}\n\nfunction saveSessions(sessions: ChatSession[]) {\n try {\n if (typeof window === 'undefined') return;\n localStorage.setItem(SESSIONS_KEY, JSON.stringify(sessions.slice(0, MAX_SESSIONS)));\n } catch {}\n}\n\nfunction relativeTime(ts: number): string {\n const diff = Date.now() - ts;\n const mins = Math.floor(diff / 60000);\n if (mins < 1) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n const hrs = Math.floor(mins / 60);\n if (hrs < 24) return `${hrs}h ago`;\n const days = Math.floor(hrs / 24);\n return `${days}d ago`;\n}\n\n// ─── Cart Context Card ─────────────────────────────────────────────────────────\n\ninterface CartContextCardProps {\n cart: CartPayload;\n defaultCurrency: string;\n}\n\nfunction CartContextCard({ cart, defaultCurrency }: CartContextCardProps) {\n if (!cart.items || cart.items.length === 0) return null;\n\n const currency = cart.currency || defaultCurrency;\n const total = cart.total ?? cart.items.reduce((s: number, i: CartItem) => s + i.price_numeric * i.quantity, 0);\n\n return (\n <div className=\"hsk-cart-card\">\n <div className=\"hsk-cart-card-header\">\n <ShoppingBagIcon />\n <span>Your cart · {cart.item_count ?? cart.items.length} item{(cart.item_count ?? cart.items.length) !== 1 ? 's' : ''}</span>\n </div>\n <div className=\"hsk-cart-items\">\n {cart.items.map((item: CartItem) => (\n\n <div key={item.id} className=\"hsk-cart-item\">\n <div className=\"hsk-cart-item-img-wrap\">\n {item.image ? (\n <img className=\"hsk-cart-item-img\" src={item.image} alt={item.name} loading=\"lazy\" />\n ) : (\n <div className=\"hsk-cart-item-img-placeholder\">\n <ShoppingBagIcon />\n </div>\n )}\n {item.quantity > 1 && (\n <span className=\"hsk-cart-item-qty\">{item.quantity}</span>\n )}\n </div>\n <div className=\"hsk-cart-item-info\">\n <div className=\"hsk-cart-item-name\">{item.name}</div>\n <div className=\"hsk-cart-item-price\">\n {item.quantity > 1 && <span className=\"hsk-cart-item-qty-label\">{item.quantity}× </span>}\n {currency} {(item.price_numeric * item.quantity).toLocaleString()}\n </div>\n </div>\n </div>\n ))}\n </div>\n <div className=\"hsk-cart-total\">\n <span>Total</span>\n <span className=\"hsk-cart-total-amount\">{currency} {total.toLocaleString()}</span>\n </div>\n </div>\n );\n}\n\n// ─── Action Pills ──────────────────────────────────────────────────────────────\n\ninterface ActionPillsProps {\n cart: CartPayload;\n actionType?: string;\n onSend: (text: string) => void;\n loading: boolean;\n}\n\nfunction ActionPills({ cart, actionType, onSend, loading }: ActionPillsProps) {\n const hasItems = cart.items && cart.items.length > 0;\n const lastItem = hasItems ? cart.items[cart.items.length - 1] : null;\n\n const pills: { label: string; query: string; emoji: string }[] = [];\n\n if (hasItems && lastItem) {\n if (actionType === 'add_to_cart') {\n const name = lastItem.name || 'item';\n const shortName = name.split(' ')[0] || 'item';\n pills.push({ emoji: '➕', label: 'Add 1 more', query: `Add one more ${name} to my cart` });\n pills.push({ emoji: '🗑️', label: `Remove ${shortName}`, query: `Remove the ${name} from my cart` });\n }\n if (cart.items.length > 1) {\n pills.push({ emoji: '🛒', label: 'View cart', query: 'Show me my cart' });\n }\n pills.push({ emoji: '💳', label: 'Checkout', query: 'Proceed to checkout' });\n pills.push({ emoji: '🛍️', label: 'Keep shopping', query: 'What else do you recommend?' });\n } else if (actionType === 'clear_cart' || actionType === 'remove_from_cart') {\n pills.push({ emoji: '🛍️', label: 'Continue shopping', query: 'Show me popular products' });\n pills.push({ emoji: '🔍', label: 'Search again', query: 'Help me find something' });\n } else if (actionType === 'view_cart') {\n if (hasItems) {\n pills.push({ emoji: '💳', label: 'Checkout', query: 'Proceed to checkout' });\n pills.push({ emoji: '🗑️', label: 'Clear cart', query: 'Clear my cart' });\n }\n }\n\n if (pills.length === 0) return null;\n\n return (\n <div className=\"hsk-action-pills\">\n {pills.map((pill) => (\n <button\n key={pill.query}\n className=\"hsk-action-pill\"\n onClick={() => onSend(pill.query)}\n disabled={loading}\n >\n <span className=\"hsk-pill-emoji\">{pill.emoji}</span>\n {pill.label}\n </button>\n ))}\n </div>\n );\n}\n\n// ─── Sources Carousel ──────────────────────────────────────────────────────────\n\ninterface SourcesCarouselProps {\n sources: ChatSource[];\n defaultCurrency: string;\n onSelectSource?: (src: ChatSource) => void;\n referencedIds?: string[];\n}\n\nfunction SourcesCarousel({ sources, defaultCurrency, onSelectSource, referencedIds = [] }: SourcesCarouselProps) {\n const client = useAkropolysContext();\n const isProperty = client?.vertical === 'property';\n const railRef = useRef<HTMLDivElement>(null);\n const [showNext, setShowNext] = useState(false);\n\n const measure = useCallback(() => {\n const el = railRef.current;\n if (!el) return;\n const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;\n setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);\n }, []);\n\n useEffect(() => {\n measure();\n const el = railRef.current;\n if (!el) return;\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n el.addEventListener('scroll', measure, { passive: true });\n return () => { ro.disconnect(); el.removeEventListener('scroll', measure); };\n }, [measure, sources]);\n\n const scrollNext = () => {\n railRef.current?.scrollBy({ left: 170, behavior: 'smooth' });\n };\n\n // Show only the products the answer referenced via <entity_ref>. If it\n // referenced none, show none — never dump raw retrieval candidates, which is\n // what surfaced product cards for questions nobody asked.\n const display = sources.filter(s => s.id && referencedIds.includes(s.id));\n if (display.length === 0) return null;\n\n return (\n <div className=\"hsk-cb-sources-wrap\">\n <div className=\"hsk-cb-sources\" ref={railRef}>\n {display.map((src, si) => {\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\n return (\n <div\n key={si}\n className={cn(\"hsk-cb-source\", isReferenced && \"hsk-cb-source--referenced\")}\n style={{ animationDelay: `${si * 50}ms` }}\n onClick={() => onSelectSource?.(src)}\n >\n {src.image ? (\n <div className=\"hsk-cb-src-imgwrap\" style={{ position: 'relative' }}>\n <img src={src.image} alt={src.name} loading=\"lazy\" />\n {isReferenced && (\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\">\n <SparkleIcon size={10} />\n </div>\n )}\n {isProperty && (\n <div style={{\n position: 'absolute',\n top: '6px',\n right: '6px',\n background: 'rgba(14, 14, 15, 0.75)',\n backdropFilter: 'blur(4px)',\n borderRadius: '50%',\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fbbf24', // Gold sparkle badge\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)'\n }}>\n <SparkleIcon size={12} />\n </div>\n )}\n </div>\n ) : (\n <div className=\"hsk-cb-src-imgwrap-empty\" style={{ position: 'relative' }}>\n <SparkleIcon />\n {isReferenced && (\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\">\n <SparkleIcon size={10} />\n </div>\n )}\n </div>\n )}\n <div className=\"hsk-cb-src-info\">\n <div className=\"hsk-cb-src-name\">{src.name}</div>\n {src.price && (\n <div className=\"hsk-cb-src-price\">\n {src.currency ?? defaultCurrency}{' '}\n {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n )}\n </div>\n </div>\n );\n })}\n </div>\n {showNext && (\n <>\n <div\n className=\"hsk-cb-sources-fade\"\n style={{ background: 'linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))' }}\n />\n <button className=\"hsk-cb-sources-next\" onClick={scrollNext} aria-label=\"See more\">\n <ChevronRightIcon />\n </button>\n </>\n )}\n </div>\n );\n}\n\n// ─── Strip markdown tables (used for compare view to avoid duplicate) ──────────\n\nfunction stripMarkdownTables(content: string): string {\n const lines = content.split('\\n');\n const out: string[] = [];\n for (const line of lines) {\n if (line.trim().startsWith('|')) continue; // table row or separator\n out.push(line);\n }\n // Collapse runs of 3+ blank lines down to 2\n return out.join('\\n').replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\n// ─── Smart context pills ──────────────────────────────────────────────────────\n// Shown after every assistant response (when there's no cart action).\n// Pills are generated from the current intent + sources so they're always relevant.\n\nfunction SmartContextPills({\n intent,\n sources,\n onSend,\n loading,\n}: {\n intent: string | null;\n sources: ChatSource[];\n onSend: (text: string) => void;\n loading: boolean;\n}) {\n const client = useAkropolysContext();\n const isProperty = client?.vertical === 'property';\n if (!intent) return null;\n\n const pills: { label: string; query: string; emoji: string }[] = [];\n\n // Find the cheapest product in the sources list\n const cheapest =\n sources.length > 0\n ? sources.reduce((min, s) => {\n const p = parseFloat(String(s.price ?? '').replace(/[^0-9.]/g, ''));\n const m = parseFloat(String(min.price ?? '').replace(/[^0-9.]/g, ''));\n return !isNaN(p) && (isNaN(m) || p < m) ? s : min;\n }, sources[0])\n : null;\n\n const firstName = sources[0]?.name ?? '';\n const firstTwo = sources.slice(0, 2).map(s => s.name);\n\n if (intent === 'search' && sources.length > 0) {\n if (firstTwo.length >= 2) {\n pills.push({\n emoji: '⚖️',\n label: 'Compare top 2',\n query: `Compare the ${firstTwo[0]} and ${firstTwo[1]}`,\n });\n }\n if (cheapest && !isProperty) {\n const name = cheapest.name || '';\n const short = name.split(' ').slice(0, 3).join(' ');\n pills.push({\n emoji: '🛒',\n label: `Add ${short}`,\n query: `Add the ${name} to my cart`,\n });\n }\n if (isProperty) {\n pills.push({ emoji: '💰', label: 'Under KSh 5M', query: 'Show me options under KSh 5,000,000' });\n } else {\n pills.push({ emoji: '💰', label: 'Under KSh 20K', query: 'Show me options under KSh 20,000' });\n }\n } else if (intent === 'compare' && sources.length > 0) {\n if (cheapest && !isProperty) {\n const name = cheapest.name || '';\n const short = name.split(' ').slice(0, 3).join(' ');\n pills.push({\n emoji: '🛒',\n label: `Add ${short}`,\n query: `Add the ${name} to my cart`,\n });\n }\n if (firstName) {\n pills.push({\n emoji: '🔍',\n label: 'Similar options',\n query: isProperty\n ? `Show me more properties similar to the ${firstName}`\n : `Show me more products similar to the ${firstName}`,\n });\n }\n pills.push({ emoji: '💡', label: 'Which is best?', query: 'Which one would you recommend and why?' });\n } else if (intent === 'specs' && sources.length > 0) {\n if (firstName) {\n if (!isProperty) {\n pills.push({ emoji: '🛒', label: 'Add to cart', query: `Add the ${firstName} to my cart` });\n }\n pills.push({\n emoji: '🔄',\n label: 'Find alternatives',\n query: `What are good alternatives to the ${firstName}?`,\n });\n }\n } else if (intent === 'general') {\n if (isProperty) {\n pills.push({ emoji: '🔍', label: 'Show popular listings', query: 'What are your most popular properties?' });\n } else {\n pills.push({ emoji: '🔍', label: 'Show popular items', query: 'What are your most popular products?' });\n }\n pills.push({ emoji: '💡', label: 'Recommend something', query: 'What do you recommend for me?' });\n }\n\n if (pills.length === 0) return null;\n\n return (\n <div className=\"hsk-action-pills\">\n {pills.map(pill => (\n <button\n key={pill.query}\n className=\"hsk-action-pill\"\n onClick={() => onSend(pill.query)}\n disabled={loading}\n >\n <span className=\"hsk-pill-emoji\">{pill.emoji}</span>\n {pill.label}\n </button>\n ))}\n </div>\n );\n}\n\n// ─── Error helper ──────────────────────────────────────────────────────────────\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 const lower = str.toLowerCase();\n if (\n lower.includes('429') ||\n lower.includes('too many requests') ||\n lower.includes('requests per minute limit exceeded') ||\n lower.includes('too_many_requests_error') ||\n lower.includes('request_quota_exceeded') ||\n lower.includes('quota')\n ) {\n return 'The assistant is currently receiving too many requests. Please try again in a few moments.';\n }\n\n if (lower.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\n// Memory-key helper: a phone + an auto-generated word = the shopper's portable\n// identity (e.g. \"0111466235flyingthunder\"). parseMemoryKey accepts either a\n// bare phone (new user → we generate the word) or a full key (returning user).\nconst MK_ADJ = ['flying', 'silent', 'golden', 'lucky', 'brave', 'swift', 'royal', 'cosmic'];\nconst MK_NOUN = ['thunder', 'falcon', 'river', 'ember', 'tiger', 'comet', 'willow', 'onyx'];\nfunction generateMagicWord(): string {\n return MK_ADJ[Math.floor(Math.random() * MK_ADJ.length)] + MK_NOUN[Math.floor(Math.random() * MK_NOUN.length)];\n}\nfunction parseMemoryKey(raw: string): { phone: string; word: string } {\n const cleaned = raw.trim().replace(/\\s+/g, '');\n const m = cleaned.match(/^(\\d{6,})([a-zA-Z].*)?$/);\n const phone = m?.[1] || cleaned.replace(/\\D/g, '');\n const word = (m?.[2] || '').toLowerCase() || generateMagicWord();\n return { phone, word };\n}\n\n// ─── ChatModal Props ───────────────────────────────────────────────────────────\n\ninterface ChatModalProps extends Pick<KikuButtonProps, 'title' | 'placeholder' | 'backdropColor' | 'backdropBlur' | 'onSelectSource' | 'defaultCurrency' | 'chips' | 'theme' | 'classNames' | 'enableVoice' | 'enableVision' | 'visionCategoryHint'> {\n theme?: 'light' | 'dark' | AkropolysTheme;\n classNames?: any;\n onClose: () => void;\n}\n\n// ─── ChatModal ─────────────────────────────────────────────────────────────────\n\nfunction parseThinking(text: string): { thinking: string; content: string; isComplete: boolean } {\n const openMatch = text.match(/<\\s*thinking\\s*>/i);\n if (!openMatch) {\n return { thinking: '', content: text, isComplete: true };\n }\n\n const openIdx = openMatch.index ?? 0;\n const openTagLength = openMatch[0].length;\n const start = openIdx + openTagLength;\n \n const contentBefore = text.slice(0, openIdx);\n const textAfterOpen = text.slice(start);\n \n const closeMatch = textAfterOpen.match(/<\\/\\s*thinking\\s*>/i);\n if (!closeMatch) {\n return { \n thinking: textAfterOpen, \n content: contentBefore, \n isComplete: false \n };\n }\n\n const closeIdx = closeMatch.index ?? 0;\n const closeTagLength = closeMatch[0].length;\n \n return {\n thinking: textAfterOpen.slice(0, closeIdx),\n content: contentBefore + textAfterOpen.slice(closeIdx + closeTagLength),\n isComplete: true\n };\n}\n\nfunction ThinkingBlock({ text, isComplete }: { text: string; isComplete: boolean }) {\n const [isOpen, setIsOpen] = useState(true);\n\n // Auto-expand when streaming thinking content\n useEffect(() => {\n if (!isComplete) {\n setIsOpen(true);\n }\n }, [isComplete]);\n\n return (\n <div style={{\n marginBottom: '12px',\n borderLeft: '2px solid #e4e4e7',\n paddingLeft: '10px',\n fontSize: '0.825rem',\n backgroundColor: 'rgba(244, 244, 245, 0.4)',\n padding: '8px 10px',\n borderRadius: '0 6px 6px 0'\n }}>\n <div \n onClick={() => setIsOpen(!isOpen)} \n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n color: '#71717a',\n cursor: 'pointer',\n fontWeight: 500,\n userSelect: 'none'\n }}\n >\n <span style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\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' }}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n </svg>\n Thinking Process\n </span>\n {!isComplete && (\n <span style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: '#3b82f6',\n display: 'inline-block',\n animation: 'hsk-pulse 1.2s infinite ease-in-out'\n }} />\n )}\n <span style={{ \n fontSize: '0.7rem', \n marginLeft: 'auto',\n transform: isOpen ? 'rotate(90deg)' : 'none', \n transition: 'transform 0.1s' \n }}>▶</span>\n </div>\n {isOpen && (\n <div style={{\n marginTop: '6px',\n color: '#52525b',\n whiteSpace: 'pre-wrap',\n lineHeight: '1.4',\n fontStyle: 'italic'\n }}>\n {text}\n </div>\n )}\n </div>\n );\n}\n\nconst PROPERTY_CHIPS = [\n '3 bedroom apartments',\n 'Houses under KSh 5,000,000',\n 'Properties in Palm Beach',\n 'Studio apartments with pool',\n];\n\nfunction ChatModal({\n title = 'Shopping Assistant',\n placeholder = 'Ask me anything — gifts, budget, use case…',\n backdropColor,\n backdropBlur,\n onClose,\n onSelectSource,\n defaultCurrency = 'KES',\n chips = DEFAULT_CHIPS,\n theme,\n classNames = {},\n enableVoice = false,\n enableVision = false,\n visionCategoryHint,\n}: ChatModalProps) {\n const client = useAkropolysContext();\n const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, reset, referencedIds } = useKiku();\n const [input, setInput] = useState('');\n\n // ── Image attachments ────────────────────────────────────────────────────────\n const [attachments, setAttachments] = useState<ChatAttachment[]>([]);\n const imageInputRef = useRef<HTMLInputElement>(null);\n\n const handleImageFiles = (files: FileList | null) => {\n if (!files || files.length === 0) return;\n Array.from(files).forEach(file => {\n if (!file.type.startsWith('image/')) return;\n const reader = new FileReader();\n reader.onload = (e) => {\n const dataUrl = e.target?.result as string;\n if (dataUrl) {\n setAttachments(prev => [...prev, { type: 'image', data: dataUrl }]);\n }\n };\n reader.readAsDataURL(file);\n });\n };\n\n const removeAttachment = (idx: number) => {\n setAttachments(prev => prev.filter((_, i) => i !== idx));\n };\n\n // ── Voice mode (Web Speech API) ──────────────────────────────────────────────\n const [voiceState, setVoiceState] = useState<'idle' | 'listening' | 'processing'>('idle');\n const recognitionRef = useRef<any>(null);\n const pendingVoiceRef = useRef<string | null>(null); // transcript queued for auto-send\n const hasSpeechAPI = typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window);\n\n const startVoice = useCallback(() => {\n if (!hasSpeechAPI || voiceState !== 'idle') return;\n const SR = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n const recognition = new SR();\n recognition.lang = 'en-US';\n // Stream partial results so the user SEES words appear as they speak —\n // without this there's no feedback that anything was captured until the end.\n recognition.interimResults = true;\n recognition.maxAlternatives = 1;\n recognitionRef.current = recognition;\n\n recognition.onstart = () => setVoiceState('listening');\n recognition.onresult = (event: any) => {\n let finalText = '';\n let interimText = '';\n for (let i = 0; i < event.results.length; i++) {\n const seg = event.results[i][0].transcript;\n if (event.results[i].isFinal) finalText += seg;\n else interimText += seg;\n }\n // Live feedback: show the (final + in-progress) text in the input box.\n const live = (finalText + ' ' + interimText).trim();\n if (live) setInput(live);\n // Only auto-send once we have a finalized transcript.\n if (finalText.trim()) {\n pendingVoiceRef.current = finalText.trim();\n setVoiceState('processing');\n }\n };\n recognition.onerror = (event: any) => {\n // Surface the cause (most often denied mic permission or no speech) so the\n // user isn't left guessing whether it worked.\n const err = event?.error;\n if (err === 'not-allowed' || err === 'service-not-allowed') {\n setInput('Microphone access was blocked — enable it in your browser to use voice.');\n } else if (err === 'no-speech') {\n setInput(\"Didn't catch that — tap the mic and try again.\");\n }\n setVoiceState('idle');\n };\n recognition.onend = () => {\n // Only reset if we didn't already move to processing\n setVoiceState(prev => prev === 'listening' ? 'idle' : prev);\n };\n recognition.start();\n }, [hasSpeechAPI, voiceState]);\n\n const stopVoice = useCallback(() => {\n recognitionRef.current?.stop();\n setVoiceState('idle');\n }, []);\n\n // Clean up recognition on unmount\n useEffect(() => {\n return () => recognitionRef.current?.abort();\n }, []);\n\n const isProperty = client.vertical === 'property';\n const activeChips = chips === DEFAULT_CHIPS && isProperty ? PROPERTY_CHIPS : chips;\n const activeTitle = title === 'Shopping Assistant' && isProperty ? 'Property Assistant' : title;\n const activePlaceholder = placeholder === 'Ask me anything — gifts, budget, use case…' && isProperty\n ? 'Ask me anything — location, budget, bedrooms…'\n : placeholder;\n\n\n const [selectedProduct, setSelectedProduct] = useState<ChatSource | null>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const [phoneInput, setPhoneInput] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem('akropolys_user_phone') || '';\n }\n return '';\n });\n const [paymentPhase, setPaymentPhase] = useState<'idle' | 'prompt_phone'>('idle');\n const [memoryKey, setMemoryKey] = useState<string | null>(null); // shown after first capture sign-up\n\n // ── History sidebar ──────────────────────────────────────────────────────────\n const [sessions, setSessions] = useState<ChatSession[]>(() => loadSessions());\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [replayMessages, setReplayMessages] = useState<ChatMessage[] | null>(null); // null = live session\n\n // React to lastAction from chat\n useEffect(() => {\n if (!lastAction) return;\n if (lastAction.type === 'request_phone') {\n setPaymentPhase('prompt_phone');\n }\n }, [lastAction]);\n\n const isStringTheme = typeof theme === 'string';\n const hskThemeAttr = isStringTheme ? theme : undefined;\n\n const customStyles = (!isStringTheme && theme) ? {\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 : undefined;\n\n const handlePhoneSubmit = async () => {\n if (!phoneInput.trim()) return;\n // request_phone is only the capture/memory flow now (payments were removed),\n // so this NEVER triggers M-Pesa. Phone (new user → we generate a word) or a\n // full memory key (returning user) → store identity, show the key, retry.\n const { phone, word } = parseMemoryKey(phoneInput);\n if (!phone) return;\n if (typeof window !== 'undefined') localStorage.setItem('akropolys_user_phone', phone);\n client.setShopperIdentity(phone, word);\n setMemoryKey(phone + word);\n setPaymentPhase('idle');\n const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');\n if (lastUserMsg) await send(lastUserMsg.content); // retry under the new identity\n };\n\n // Auto-scroll: only when the user is already pinned near the bottom (within 120px).\n // This lets them freely scroll up to re-read earlier messages while streaming continues.\n const msgsContainerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const container = msgsContainerRef.current;\n if (!container) return;\n const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;\n if (distanceFromBottom < 120) {\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }\n }, [messages, loading, selectedProduct]);\n\n useEffect(() => {\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, []);\n\n // ── Save session on reset or close ───────────────────────────────────────────\n const saveCurrentSession = useCallback(() => {\n if (messages.length < 2) return; // Nothing worth saving\n const firstUser = messages.find(m => m.role === 'user');\n const session: ChatSession = {\n id: `session_${Date.now()}`,\n title: firstUser ? firstUser.content.slice(0, 60) : 'Chat session',\n messages: messages,\n ts: Date.now(),\n };\n const updated = [session, ...sessions].slice(0, MAX_SESSIONS);\n setSessions(updated);\n saveSessions(updated);\n }, [messages, sessions]);\n\n const handleReset = useCallback(() => {\n saveCurrentSession();\n reset();\n setReplayMessages(null);\n setPaymentPhase('idle');\n }, [reset, saveCurrentSession]);\n\n const handleSourceClick = (src: ChatSource) => {\n setSelectedProduct(src);\n onSelectSource?.(src);\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?`;\n send(q);\n };\n\n const handleSend = async (text?: string, extraAttachments?: ChatAttachment[]) => {\n const q = (text ?? input).trim();\n if (!q || loading) return;\n // If we're in replay mode, exit replay and continue live\n setReplayMessages(null);\n setSelectedProduct(null);\n setInput('');\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n }\n const toSend = extraAttachments ?? attachments;\n setAttachments([]);\n await send(q, undefined, toSend.length > 0 ? toSend : undefined);\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 setInput(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 // Auto-send voice transcript once processing state is reached\n useEffect(() => {\n if (voiceState !== 'processing') return;\n const transcript = pendingVoiceRef.current;\n if (!transcript) { setVoiceState('idle'); return; }\n pendingVoiceRef.current = null;\n // Brief delay so user sees the transcript fill in before it fires\n const timer = setTimeout(() => {\n setVoiceState('idle');\n handleSend(transcript);\n }, 400);\n return () => clearTimeout(timer);\n }, [voiceState]);\n\n\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '20px');\n\n // The messages to display: replay or live\n const displayMessages = replayMessages ?? messages;\n\n // ── Load a historical session ─────────────────────────────────────────────────\n const loadSession = (session: ChatSession) => {\n setReplayMessages(session.messages);\n setSidebarOpen(false);\n };\n\n // ── Delete a session ──────────────────────────────────────────────────────────\n const deleteSession = (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const updated = sessions.filter(s => s.id !== id);\n setSessions(updated);\n saveSessions(updated);\n };\n\n return (\n <div\n className={cn(\"hsk-cb-overlay\", classNames.overlay)}\n onClick={onClose}\n data-hsk-theme={hskThemeAttr}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n ...(backdropColor ? { background: backdropColor } : {}),\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-cb-panel hsk-cb-panel--with-sidebar\", classNames.panel)} onClick={e => e.stopPropagation()}>\n\n {/* ── History Sidebar ── */}\n <div className={cn(\"hsk-cb-sidebar\", sidebarOpen && \"hsk-cb-sidebar--open\")}>\n <div className=\"hsk-cb-sidebar-header\">\n <span className=\"hsk-cb-sidebar-title\">History</span>\n <button\n className=\"hsk-cb-sidebar-new\"\n onClick={handleReset}\n title=\"New chat\"\n >\n <NewChatIcon />\n <span>New chat</span>\n </button>\n </div>\n <div className=\"hsk-cb-sidebar-list\">\n {sessions.length === 0 ? (\n <div className=\"hsk-cb-sidebar-empty\">\n <HistoryIcon />\n <span>No history yet</span>\n </div>\n ) : (\n sessions.map(session => (\n <div\n key={session.id}\n className={cn(\n \"hsk-cb-sidebar-session\",\n replayMessages === session.messages && \"hsk-cb-sidebar-session--active\"\n )}\n onClick={() => loadSession(session)}\n >\n <div className=\"hsk-cb-sidebar-session-title\">{session.title}</div>\n <div className=\"hsk-cb-sidebar-session-meta\">{relativeTime(session.ts)}</div>\n <button\n className=\"hsk-cb-sidebar-session-del\"\n onClick={(e) => deleteSession(session.id, e)}\n title=\"Delete\"\n >\n ×\n </button>\n </div>\n ))\n )}\n </div>\n </div>\n\n {/* ── Main Chat Area ── */}\n <div className=\"hsk-cb-main\">\n\n {/* Top bar */}\n <div className=\"hsk-cb-topbar\">\n <div className=\"hsk-cb-topbar-left\">\n {/* Sidebar toggle (always visible) */}\n <button\n className={cn(\"hsk-cb-sidebar-toggle\", sidebarOpen && \"hsk-cb-sidebar-toggle--active\")}\n onClick={(e) => { e.stopPropagation(); setSidebarOpen(v => !v); }}\n aria-label=\"Toggle history\"\n >\n <HistoryIcon />\n </button>\n <span className=\"hsk-cb-topbar-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div>\n <div className=\"hsk-cb-topbar-title\">{activeTitle}</div>\n </div>\n </div>\n <div className=\"hsk-cb-topbar-actions\">\n {replayMessages ? (\n <button className=\"hsk-cb-topbar-btn\" onClick={() => { setReplayMessages(null); }}>← Live chat</button>\n ) : (\n messages.length > 0 && (\n <button className=\"hsk-cb-topbar-btn\" onClick={handleReset}>Clear chat</button>\n )\n )}\n <button className=\"hsk-cb-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Replay banner */}\n {replayMessages && (\n <div className=\"hsk-cb-replay-banner\">\n <HistoryIcon />\n <span>You're viewing a past conversation.</span>\n <button onClick={() => setReplayMessages(null)}>Back to chat →</button>\n </div>\n )}\n\n {/* Messages */}\n <div className=\"hsk-cb-msgs\" ref={msgsContainerRef}>\n {displayMessages.length === 0 ? (\n <div className=\"hsk-cb-empty\">\n <div className=\"hsk-cb-empty-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-empty-title\">Find exactly what you need</div>\n <div className=\"hsk-cb-chips\">\n {activeChips.map(chip => (\n <button\n key={chip}\n className=\"hsk-cb-chip\"\n onClick={() => handleSend(chip)}\n >\n {chip}\n </button>\n ))}\n </div>\n </div>\n ) : (\n displayMessages.map((msg: ChatMessage, idx: number) => {\n const isLast = idx === displayMessages.length - 1 && !replayMessages;\n const isUser = msg.role === 'user';\n // Strip the LLM's markdown table for compare so ComparisonMatrix isn't duplicated\n const displayContent =\n !isUser && isLast && lastIntent === 'compare' && sources.length >= 2 && !replayMessages\n ? stripMarkdownTables(msg.content)\n : msg.content;\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n {/* Image thumbnails in user bubble */}\n {msg.images && msg.images.length > 0 && (\n <div className=\"hsk-cb-user-imgs\">\n {msg.images.map((img, i) => (\n <img key={i} src={img} alt={`attachment ${i + 1}`} className=\"hsk-cb-user-img-thumb\" />\n ))}\n </div>\n )}\n {msg.content && <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 {(() => {\n const { thinking, content, isComplete } = parseThinking(displayContent);\n return (\n <>\n {thinking && (\n <ThinkingBlock text={thinking} isComplete={isComplete} />\n )}\n {content && (\n <div className=\"hsk-cb-ai-text\">\n {renderMarkdown(content)}\n {isLast && streaming && (\n <span style={{ display: 'inline-block', width: '0.5em', height: '1.05em', marginLeft: '2px', verticalAlign: 'text-bottom', background: 'currentColor', opacity: 0.55, borderRadius: '1px' }} />\n )}\n </div>\n )}\n </>\n );\n })()}\n\n {/* Comparison matrix — replaces the markdown table when comparing products */}\n {isLast && lastIntent === 'compare' && sources.length >= 2 && !replayMessages && (\n <ComparisonMatrix sources={sources} defaultCurrency={defaultCurrency} />\n )}\n\n {/* Sources carousel — only for products the answer referenced, non-cart, non-compare */}\n {isLast && referencedIds.length > 0 && lastIntent !== 'compare' && lastAction?.type !== 'request_phone' && lastAction?.type !== 'awaiting_payment' && lastAction?.type !== 'checkout' && !msg.cartSnapshot && (\n <SourcesCarousel\n sources={sources}\n defaultCurrency={defaultCurrency}\n onSelectSource={handleSourceClick}\n referencedIds={referencedIds}\n />\n )}\n\n {/* Cart context card — shown when the message has a cart snapshot */}\n {msg.cartSnapshot && msg.cartSnapshot.items?.length > 0 && (\n <CartContextCard\n cart={msg.cartSnapshot}\n defaultCurrency={defaultCurrency}\n />\n )}\n\n {/* Action pills — for cart-mutating responses */}\n {isLast && msg.cartSnapshot && !loading && (\n <ActionPills\n cart={msg.cartSnapshot}\n actionType={msg.actionType}\n onSend={handleSend}\n loading={loading}\n />\n )}\n\n {/* Smart context pills — built only from products the answer referenced */}\n {isLast && !loading && !msg.cartSnapshot && !replayMessages && (\n <SmartContextPills\n intent={lastIntent}\n sources={sources.filter(s => s.id && referencedIds.includes(s.id))}\n onSend={handleSend}\n loading={loading}\n />\n )}\n </div>\n </div>\n )}\n </div>\n );\n })\n )}\n\n {/* Selected product pinned card — shows while LLM fetches details */}\n {selectedProduct && loading && (\n <div\n className=\"hsk-cb-selected-product\"\n onClick={() => selectedProduct.url && window.open(selectedProduct.url, '_blank')}\n >\n {selectedProduct.image && (\n <img className=\"hsk-cb-selected-img\" src={selectedProduct.image} alt={selectedProduct.name} />\n )}\n <div className=\"hsk-cb-selected-info\">\n <div className=\"hsk-cb-selected-name\">{selectedProduct.name}</div>\n {selectedProduct.price && (\n <div className=\"hsk-cb-selected-price\">\n {selectedProduct.currency ?? defaultCurrency} {parseFloat(String(selectedProduct.price ?? '').replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Typing dots — shown ONLY while waiting for the server (loading).\n Once the response arrives and token streaming begins (!loading && streaming)\n the text animates in directly with no dots visible. */}\n {loading && !streaming && (\n <div className=\"hsk-cb-typing-row\" style={{ display: 'flex', alignItems: 'flex-start', gap: '10px' }}>\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center', marginTop: '4px' }}>\n <SparkleIcon />\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\n <style>{`\n @keyframes hsk-pulse {\n 0%, 100% { opacity: 0.6; }\n 50% { opacity: 1; }\n }\n `}</style>\n <div style={{ fontSize: '0.85rem', color: '#6b7280', fontStyle: 'italic', animation: 'hsk-pulse 1.5s infinite ease-in-out' }}>\n Thinking…\n </div>\n <div className=\"hsk-cb-typing\" style={{ margin: 0, alignSelf: 'flex-start' }}>\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n </div>\n )}\n\n {error && <div className=\"hsk-cb-error\">{getFriendlyError(error)}</div>}\n\n {/* Carry-your-items prompt: one field takes a phone (new user → we\n auto-make the word) OR a full memory key (returning user). This is\n the ONLY thing request_phone does now — no payments. */}\n {!replayMessages && paymentPhase === 'prompt_phone' && (\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\">\n <div className=\"hsk-cb-phone-form\">\n <label className=\"hsk-cb-phone-label\">Your phone number — or paste your memory key</label>\n <input\n type=\"text\"\n className=\"hsk-cb-phone-input\"\n placeholder=\"0712345678 or 0712345678flyingthunder\"\n value={phoneInput}\n onChange={e => setPhoneInput(e.target.value.replace(/[^0-9a-zA-Z]/g, ''))}\n onKeyDown={e => e.key === 'Enter' && handlePhoneSubmit()}\n autoFocus\n />\n <button className=\"hsk-cb-phone-submit\" onClick={handlePhoneSubmit}>\n Save &amp; sync my items\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {!replayMessages && memoryKey && (\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\">\n <div style={{ padding: '10px 12px', border: '1px solid var(--hsk-border, #e5e5e5)', borderRadius: 8 }}>\n <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 4 }}>🔑 Your memory key</div>\n <code style={{ display: 'block', fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: 'break-all' }}>{memoryKey}</code>\n <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\n <button className=\"hsk-cb-phone-submit\" style={{ padding: '4px 10px' }} onClick={() => { try { navigator.clipboard?.writeText(memoryKey); } catch { /* ignore */ } }}>Copy</button>\n <span style={{ fontSize: 11, opacity: 0.7 }}>Save it — enter it on any site to get your items back.</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n )}\n\n <div ref={bottomRef} style={{ height: 1 }} />\n </div>\n\n {/* Input — disabled in replay mode */}\n {!replayMessages && (\n <div className=\"hsk-cb-input-wrap\">\n {/* Image attachment strip */}\n {attachments.length > 0 && (\n <div className=\"hsk-cb-img-strip\">\n {attachments.map((att, i) => (\n <div key={i} className=\"hsk-cb-img-thumb-wrap\">\n <img src={att.data} alt={`attachment ${i + 1}`} className=\"hsk-cb-img-thumb\" />\n <button\n className=\"hsk-cb-img-thumb-remove\"\n onClick={() => removeAttachment(i)}\n aria-label=\"Remove image\"\n >\n ×\n </button>\n </div>\n ))}\n </div>\n )}\n <div className=\"hsk-cb-input-box\">\n {/* Hidden file input */}\n <input\n ref={imageInputRef}\n type=\"file\"\n accept=\"image/*\"\n multiple\n style={{ display: 'none' }}\n onChange={e => handleImageFiles(e.target.files)}\n />\n {/* Attach button — only shown if vision is enabled */}\n {enableVision && (\n <button\n className=\"hsk-cb-attach-btn\"\n onClick={() => imageInputRef.current?.click()}\n disabled={loading}\n aria-label=\"Attach image\"\n title=\"Attach image\"\n >\n <PaperclipIcon />\n </button>\n )}\n <textarea\n ref={textareaRef}\n className={cn(\"hsk-cb-textarea\", classNames.input)}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={\n voiceState === 'listening' ? '🎙️ Listening… tap the mic to stop'\n : voiceState === 'processing' ? 'Got it — sending…'\n : activePlaceholder\n }\n rows={1}\n disabled={loading}\n autoFocus\n />\n {/* Voice button — only shown if SpeechRecognition is supported and enabled */}\n {hasSpeechAPI && enableVoice && (\n <button\n className={cn(\n \"hsk-cb-mic-btn\",\n voiceState === 'listening' && \"hsk-cb-mic-btn--listening\",\n voiceState === 'processing' && \"hsk-cb-mic-btn--processing\"\n )}\n onClick={voiceState === 'idle' ? startVoice : stopVoice}\n disabled={loading}\n aria-label={voiceState === 'idle' ? 'Start voice input' : 'Stop recording'}\n title={voiceState === 'idle' ? 'Voice input' : 'Stop'}\n >\n {voiceState === 'listening' ? <MicOffIcon /> : <MicIcon />}\n {voiceState === 'listening' && <span className=\"hsk-cb-mic-pulse\" />}\n </button>\n )}\n <button\n className={cn(\"hsk-cb-send\", classNames.sendButton)}\n onClick={() => handleSend()}\n disabled={(!input.trim() && attachments.length === 0) || loading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n <div className=\"hsk-cb-hint\">Akropolys AI · searches the whole catalogue in real time</div>\n </div>\n )}\n\n </div>{/* end .hsk-cb-main */}\n\n </div>\n </div>\n );\n}\n\n// ─── KikuButton (public export) ─────────────────────────────────────────────\n\nexport function KikuButton({\n label,\n title,\n placeholder,\n backdropColor,\n backdropBlur,\n className,\n onSelectSource,\n defaultCurrency,\n chips,\n theme,\n classNames = {},\n enableVoice = false,\n enableVision = false,\n visionCategoryHint,\n}: KikuButtonProps) {\n const [open, setOpen] = useState(false);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n\n if (typeof window !== 'undefined' && !(window as any).__akropolys_nav_patched) {\n (window as any).__akropolys_nav_patched = true;\n const originalPush = window.history.pushState;\n const originalReplace = window.history.replaceState;\n\n window.history.pushState = function(...args) {\n originalPush.apply(this, args);\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\n };\n\n window.history.replaceState = function(...args) {\n originalReplace.apply(this, args);\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\n };\n }\n\n const handleNavigation = () => {\n setOpen(false);\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('akropolys:navigation', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('akropolys:navigation', handleNavigation);\n };\n }, []);\n\n const isStringTheme = typeof theme === 'string';\n const hskThemeAttr = isStringTheme ? theme : undefined;\n\n const customStyles = (!isStringTheme && theme) ? {\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 : undefined;\n\n return (\n <>\n <button\n className={cn(\"hsk-cb-btn\", classNames.button, className)}\n onClick={() => setOpen(true)}\n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n aria-label=\"Open AI chat\"\n >\n <span className=\"hsk-cb-btn-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n {label !== undefined ? label : null}\n </button>\n {open && mounted && createPortal(\n <ChatModal\n title={title}\n placeholder={placeholder}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n onClose={() => setOpen(false)}\n onSelectSource={onSelectSource}\n defaultCurrency={defaultCurrency}\n chips={chips}\n theme={theme}\n classNames={classNames}\n enableVoice={enableVoice}\n enableVision={enableVision}\n visionCategoryHint={visionCategoryHint}\n />,\n document.body\n )}\n </>\n );\n}\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 &middot; 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":["import_react","import_sdk","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_sdk","import_jsx_runtime","import_jsx_runtime","import_react","import_sdk","import_sdk","import_jsx_runtime","import_jsx_runtime","SparkleIcon","ArrowUpIcon","MicIcon","SparkleIcon","ArrowUpIcon","import_react","import_react_dom","import_sdk","import_jsx_runtime","SparkleIcon","CloseIcon","ArrowUpIcon","getFriendlyError"]}
1
+ {"version":3,"sources":["../src/index.ts","../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":["// @akropolys/kiku — Plug-and-play UI components for Akropolys\n// Developers must explicitly import '@akropolys/kiku/styles.css' in their entry file.\n\nexport { SearchBar } from './components/SearchBar';\nexport type { SearchBarProps } from './components/SearchBar';\nexport { ChatWidget, ChatWidget as KikuChat } from './components/ChatWidget';\nexport type { ChatWidgetProps, ChatWidgetProps as KikuChatProps } from './components/ChatWidget';\nexport { KikuButton } from './components/KikuButton';\nexport type { KikuButtonProps } from './components/KikuButton';\nexport { Sparkle } from './components/Sparkle';\nexport { ComparisonMatrix } from './components/ComparisonMatrix';\n\n// Voice & Vision — free AI input modalities\nexport { VoiceButton } from './components/VoiceButton';\nexport type { VoiceButtonProps } from './components/VoiceButton';\nexport { VisualSearch } from './components/VisualSearch';\nexport type { VisualSearchProps } from './components/VisualSearch';\n\n","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 300 for smooth 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 = 300,\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 [isDebouncing, setIsDebouncing] = useState(false);\n const { results, loading, search, clear } = useSearch();\n const client = useAkropolysContext();\n const timer = useRef<ReturnType<typeof setTimeout>>();\n const wrap = useRef<HTMLDivElement>(null);\n const ignoreNextQueryChange = useRef(false);\n\n /* Debounce search — but keep stale results visible between calls */\n useEffect(() => {\n if (ignoreNextQueryChange.current) {\n ignoreNextQueryChange.current = false;\n return;\n }\n clearTimeout(timer.current);\n if (!query.trim()) {\n clear();\n setOpen(false);\n setIsDebouncing(false);\n return;\n }\n setOpen(true); // open immediately (stale results show while fetching)\n setIsDebouncing(true);\n timer.current = setTimeout(() => {\n setIsDebouncing(false);\n search(query, limit);\n }, debounceMs);\n return () => clearTimeout(timer.current);\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 client.api.searchVector(query, 1).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).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 || isDebouncing) && <div className=\"hsk-sb-loading-bar\" />}\n\n {(loading || isDebouncing) && 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 && !isDebouncing && (\n <div className=\"hsk-sb-empty\">No results for &ldquo;{query}&rdquo;</div>\n )}\n\n {results.map((r, i) => (\n renderResult ? (\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 <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-icon\"><SearchIcon /></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 cartSnapshot: messages[hookIdx].cartSnapshot,\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 ![alt](url), 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: ![alt](url)\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: ![alt](url)\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';\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useKiku, ChatMessage, ChatSource } from '@akropolys/sdk';\nimport { useAkropolysContext } from '@akropolys/sdk';\nimport { renderMarkdown } from '../utils/markdown';\nimport { AkropolysTheme, CartPayload, CartItem, ChatAttachment } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\nimport { ComparisonMatrix } from './ComparisonMatrix';\n\n\nexport interface KikuButtonProps {\n label?: string;\n title?: string;\n placeholder?: string;\n backdropColor?: string;\n backdropBlur?: string | number;\n className?: string;\n onSelectSource?: (source: ChatSource) => void;\n defaultCurrency?: string;\n chips?: string[];\n theme?: 'light' | 'dark' | AkropolysTheme;\n classNames?: {\n button?: string;\n overlay?: string;\n panel?: string;\n input?: string;\n sendButton?: string;\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// ─── Icons ────────────────────────────────────────────────────────────────────\n\n/**\n * Akropolys brand mark — an ancient serif capital Alpha (Α)\n * with an animated smooth breathing mark (spiritus lenis ʻ) at top-left.\n * The mark pulses gently, like a breath.\n */\nconst AkropolysAIcon = ({ className, size = 18 }: { 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\n/** Keep a tiny sparkle alias for places that still want the star (sources, etc.) */\nconst SparkleIcon = AkropolysAIcon;\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\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 ChevronRightIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\"/>\n </svg>\n);\n\nconst HistoryIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/>\n <path d=\"M3 3v5h5\"/>\n <path d=\"M12 7v5l4 2\"/>\n </svg>\n);\n\nconst NewChatIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 5v14M5 12h14\"/>\n </svg>\n);\n\nconst ShoppingBagIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z\"/>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/>\n <path d=\"M16 10a4 4 0 0 1-8 0\"/>\n </svg>\n);\n\nconst SecureShieldIcon = ({ className, size = 18 }: { className?: string; size?: number }) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n <path d=\"M12 11a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z\" />\n <path d=\"M12 11v4\" />\n </svg>\n);\n\nconst PaperclipIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\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\"/>\n </svg>\n);\n\nconst MicIcon = () => (\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 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\"/>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\n </svg>\n);\n\nconst MicOffIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\"/>\n <path d=\"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2\"/>\n <path d=\"M5 10v2a7 7 0 0 0 12 5\"/>\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\"/>\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\n </svg>\n);\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst DEFAULT_CHIPS = [\n 'Cheapest smartphone',\n 'Smart TV under KSh 20,000',\n 'Noise-cancelling headphones',\n 'Best laptop for students',\n];\n\nconst SESSIONS_KEY = 'akropolys_chat_sessions';\nconst MAX_SESSIONS = 20;\n\n// ─── Session types ─────────────────────────────────────────────────────────────\n\ninterface ChatSession {\n id: string;\n title: string;\n messages: ChatMessage[];\n ts: number;\n}\n\nfunction loadSessions(): ChatSession[] {\n try {\n if (typeof window === 'undefined') return [];\n const raw = localStorage.getItem(SESSIONS_KEY);\n return raw ? JSON.parse(raw) : [];\n } catch {\n return [];\n }\n}\n\nfunction saveSessions(sessions: ChatSession[]) {\n try {\n if (typeof window === 'undefined') return;\n localStorage.setItem(SESSIONS_KEY, JSON.stringify(sessions.slice(0, MAX_SESSIONS)));\n } catch {}\n}\n\nfunction relativeTime(ts: number): string {\n const diff = Date.now() - ts;\n const mins = Math.floor(diff / 60000);\n if (mins < 1) return 'just now';\n if (mins < 60) return `${mins}m ago`;\n const hrs = Math.floor(mins / 60);\n if (hrs < 24) return `${hrs}h ago`;\n const days = Math.floor(hrs / 24);\n return `${days}d ago`;\n}\n\n// ─── Cart Context Card ─────────────────────────────────────────────────────────\n\ninterface CartContextCardProps {\n cart: CartPayload;\n defaultCurrency: string;\n}\n\nfunction CartContextCard({ cart, defaultCurrency }: CartContextCardProps) {\n if (!cart.items || cart.items.length === 0) return null;\n\n const currency = cart.currency || defaultCurrency;\n const total = cart.total ?? cart.items.reduce((s: number, i: CartItem) => s + i.price_numeric * i.quantity, 0);\n\n return (\n <div className=\"hsk-cart-card\">\n <div className=\"hsk-cart-card-header\">\n <ShoppingBagIcon />\n <span>Your cart · {cart.item_count ?? cart.items.length} item{(cart.item_count ?? cart.items.length) !== 1 ? 's' : ''}</span>\n </div>\n <div className=\"hsk-cart-items\">\n {cart.items.map((item: CartItem) => (\n\n <div key={item.id} className=\"hsk-cart-item\">\n <div className=\"hsk-cart-item-img-wrap\">\n {item.image ? (\n <img className=\"hsk-cart-item-img\" src={item.image} alt={item.name} loading=\"lazy\" />\n ) : (\n <div className=\"hsk-cart-item-img-placeholder\">\n <ShoppingBagIcon />\n </div>\n )}\n {item.quantity > 1 && (\n <span className=\"hsk-cart-item-qty\">{item.quantity}</span>\n )}\n </div>\n <div className=\"hsk-cart-item-info\">\n <div className=\"hsk-cart-item-name\">{item.name}</div>\n <div className=\"hsk-cart-item-price\">\n {item.quantity > 1 && <span className=\"hsk-cart-item-qty-label\">{item.quantity}× </span>}\n {currency} {(item.price_numeric * item.quantity).toLocaleString()}\n </div>\n </div>\n </div>\n ))}\n </div>\n <div className=\"hsk-cart-total\">\n <span>Total</span>\n <span className=\"hsk-cart-total-amount\">{currency} {total.toLocaleString()}</span>\n </div>\n </div>\n );\n}\n\n// ─── Action Pills ──────────────────────────────────────────────────────────────\n\ninterface ActionPillsProps {\n cart: CartPayload;\n actionType?: string;\n onSend: (text: string) => void;\n loading: boolean;\n}\n\nfunction ActionPills({ cart, actionType, onSend, loading }: ActionPillsProps) {\n const hasItems = cart.items && cart.items.length > 0;\n const lastItem = hasItems ? cart.items[cart.items.length - 1] : null;\n\n const pills: { label: string; query: string; emoji: string }[] = [];\n\n if (hasItems && lastItem) {\n if (actionType === 'add_to_cart') {\n const name = lastItem.name || 'item';\n const shortName = name.split(' ')[0] || 'item';\n pills.push({ emoji: '➕', label: 'Add 1 more', query: `Add one more ${name} to my cart` });\n pills.push({ emoji: '🗑️', label: `Remove ${shortName}`, query: `Remove the ${name} from my cart` });\n }\n if (cart.items.length > 1) {\n pills.push({ emoji: '🛒', label: 'View cart', query: 'Show me my cart' });\n }\n pills.push({ emoji: '💳', label: 'Checkout', query: 'Proceed to checkout' });\n pills.push({ emoji: '🛍️', label: 'Keep shopping', query: 'What else do you recommend?' });\n } else if (actionType === 'clear_cart' || actionType === 'remove_from_cart') {\n pills.push({ emoji: '🛍️', label: 'Continue shopping', query: 'Show me popular products' });\n pills.push({ emoji: '🔍', label: 'Search again', query: 'Help me find something' });\n } else if (actionType === 'view_cart') {\n if (hasItems) {\n pills.push({ emoji: '💳', label: 'Checkout', query: 'Proceed to checkout' });\n pills.push({ emoji: '🗑️', label: 'Clear cart', query: 'Clear my cart' });\n }\n }\n\n if (pills.length === 0) return null;\n\n return (\n <div className=\"hsk-action-pills\">\n {pills.map((pill) => (\n <button\n key={pill.query}\n className=\"hsk-action-pill\"\n onClick={() => onSend(pill.query)}\n disabled={loading}\n >\n <span className=\"hsk-pill-emoji\">{pill.emoji}</span>\n {pill.label}\n </button>\n ))}\n </div>\n );\n}\n\n// ─── Sources Carousel ──────────────────────────────────────────────────────────\n\ninterface SourcesCarouselProps {\n sources: ChatSource[];\n defaultCurrency: string;\n onSelectSource?: (src: ChatSource) => void;\n referencedIds?: string[];\n}\n\nfunction SourcesCarousel({ sources, defaultCurrency, onSelectSource, referencedIds = [] }: SourcesCarouselProps) {\n const client = useAkropolysContext();\n const isProperty = client?.vertical === 'property';\n const railRef = useRef<HTMLDivElement>(null);\n const [showNext, setShowNext] = useState(false);\n\n const measure = useCallback(() => {\n const el = railRef.current;\n if (!el) return;\n const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;\n setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);\n }, []);\n\n useEffect(() => {\n measure();\n const el = railRef.current;\n if (!el) return;\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n el.addEventListener('scroll', measure, { passive: true });\n return () => { ro.disconnect(); el.removeEventListener('scroll', measure); };\n }, [measure, sources]);\n\n const scrollNext = () => {\n railRef.current?.scrollBy({ left: 170, behavior: 'smooth' });\n };\n\n // Show only the products the answer referenced via <entity_ref>. If it\n // referenced none, show none — never dump raw retrieval candidates, which is\n // what surfaced product cards for questions nobody asked.\n const display = sources.filter(s => s.id && referencedIds.includes(s.id));\n if (display.length === 0) return null;\n\n return (\n <div className=\"hsk-cb-sources-wrap\">\n <div className=\"hsk-cb-sources\" ref={railRef}>\n {display.map((src, si) => {\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\n return (\n <div\n key={si}\n className={cn(\"hsk-cb-source\", isReferenced && \"hsk-cb-source--referenced\")}\n style={{ animationDelay: `${si * 50}ms` }}\n onClick={() => onSelectSource?.(src)}\n >\n {src.image ? (\n <div className=\"hsk-cb-src-imgwrap\" style={{ position: 'relative' }}>\n <img src={src.image} alt={src.name} loading=\"lazy\" />\n {isReferenced && (\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\">\n <SparkleIcon size={10} />\n </div>\n )}\n {isProperty && (\n <div style={{\n position: 'absolute',\n top: '6px',\n right: '6px',\n background: 'rgba(14, 14, 15, 0.75)',\n backdropFilter: 'blur(4px)',\n borderRadius: '50%',\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fbbf24', // Gold sparkle badge\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)'\n }}>\n <SparkleIcon size={12} />\n </div>\n )}\n </div>\n ) : (\n <div className=\"hsk-cb-src-imgwrap-empty\" style={{ position: 'relative' }}>\n <SparkleIcon />\n {isReferenced && (\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\">\n <SparkleIcon size={10} />\n </div>\n )}\n </div>\n )}\n <div className=\"hsk-cb-src-info\">\n <div className=\"hsk-cb-src-name\">{src.name}</div>\n {src.price && (\n <div className=\"hsk-cb-src-price\">\n {src.currency ?? defaultCurrency}{' '}\n {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n )}\n </div>\n </div>\n );\n })}\n </div>\n {showNext && (\n <>\n <div\n className=\"hsk-cb-sources-fade\"\n style={{ background: 'linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))' }}\n />\n <button className=\"hsk-cb-sources-next\" onClick={scrollNext} aria-label=\"See more\">\n <ChevronRightIcon />\n </button>\n </>\n )}\n </div>\n );\n}\n\n// ─── Strip markdown tables (used for compare view to avoid duplicate) ──────────\n\nfunction stripMarkdownTables(content: string): string {\n const lines = content.split('\\n');\n const out: string[] = [];\n for (const line of lines) {\n if (line.trim().startsWith('|')) continue; // table row or separator\n out.push(line);\n }\n // Collapse runs of 3+ blank lines down to 2\n return out.join('\\n').replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\n// ─── Smart context pills ──────────────────────────────────────────────────────\n// Shown after every assistant response (when there's no cart action).\n// Pills are generated from the current intent + sources so they're always relevant.\n\nfunction SmartContextPills({\n intent,\n sources,\n onSend,\n loading,\n}: {\n intent: string | null;\n sources: ChatSource[];\n onSend: (text: string) => void;\n loading: boolean;\n}) {\n const client = useAkropolysContext();\n const isProperty = client?.vertical === 'property';\n if (!intent) return null;\n\n const pills: { label: string; query: string; emoji: string }[] = [];\n\n // Find the cheapest product in the sources list\n const cheapest =\n sources.length > 0\n ? sources.reduce((min, s) => {\n const p = parseFloat(String(s.price ?? '').replace(/[^0-9.]/g, ''));\n const m = parseFloat(String(min.price ?? '').replace(/[^0-9.]/g, ''));\n return !isNaN(p) && (isNaN(m) || p < m) ? s : min;\n }, sources[0])\n : null;\n\n const firstName = sources[0]?.name ?? '';\n const firstTwo = sources.slice(0, 2).map(s => s.name);\n\n if (intent === 'search' && sources.length > 0) {\n if (firstTwo.length >= 2) {\n pills.push({\n emoji: '⚖️',\n label: 'Compare top 2',\n query: `Compare the ${firstTwo[0]} and ${firstTwo[1]}`,\n });\n }\n if (cheapest && !isProperty) {\n const name = cheapest.name || '';\n const short = name.split(' ').slice(0, 3).join(' ');\n pills.push({\n emoji: '🛒',\n label: `Add ${short}`,\n query: `Add the ${name} to my cart`,\n });\n }\n if (isProperty) {\n pills.push({ emoji: '💰', label: 'Under KSh 5M', query: 'Show me options under KSh 5,000,000' });\n } else {\n pills.push({ emoji: '💰', label: 'Under KSh 20K', query: 'Show me options under KSh 20,000' });\n }\n } else if (intent === 'compare' && sources.length > 0) {\n if (cheapest && !isProperty) {\n const name = cheapest.name || '';\n const short = name.split(' ').slice(0, 3).join(' ');\n pills.push({\n emoji: '🛒',\n label: `Add ${short}`,\n query: `Add the ${name} to my cart`,\n });\n }\n if (firstName) {\n pills.push({\n emoji: '🔍',\n label: 'Similar options',\n query: isProperty\n ? `Show me more properties similar to the ${firstName}`\n : `Show me more products similar to the ${firstName}`,\n });\n }\n pills.push({ emoji: '💡', label: 'Which is best?', query: 'Which one would you recommend and why?' });\n } else if (intent === 'specs' && sources.length > 0) {\n if (firstName) {\n if (!isProperty) {\n pills.push({ emoji: '🛒', label: 'Add to cart', query: `Add the ${firstName} to my cart` });\n }\n pills.push({\n emoji: '🔄',\n label: 'Find alternatives',\n query: `What are good alternatives to the ${firstName}?`,\n });\n }\n } else if (intent === 'general') {\n if (isProperty) {\n pills.push({ emoji: '🔍', label: 'Show popular listings', query: 'What are your most popular properties?' });\n } else {\n pills.push({ emoji: '🔍', label: 'Show popular items', query: 'What are your most popular products?' });\n }\n pills.push({ emoji: '💡', label: 'Recommend something', query: 'What do you recommend for me?' });\n }\n\n if (pills.length === 0) return null;\n\n return (\n <div className=\"hsk-action-pills\">\n {pills.map(pill => (\n <button\n key={pill.query}\n className=\"hsk-action-pill\"\n onClick={() => onSend(pill.query)}\n disabled={loading}\n >\n <span className=\"hsk-pill-emoji\">{pill.emoji}</span>\n {pill.label}\n </button>\n ))}\n </div>\n );\n}\n\n// ─── Error helper ──────────────────────────────────────────────────────────────\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 const lower = str.toLowerCase();\n if (\n lower.includes('429') ||\n lower.includes('too many requests') ||\n lower.includes('requests per minute limit exceeded') ||\n lower.includes('too_many_requests_error') ||\n lower.includes('request_quota_exceeded') ||\n lower.includes('quota')\n ) {\n return 'The assistant is currently receiving too many requests. Please try again in a few moments.';\n }\n\n if (lower.includes('token limit')) {\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\n }\n\n // Never let a raw status or network failure reach a shopper.\n if (lower.includes('failed to fetch') || lower.includes('networkerror') || lower.includes('request failed')) {\n return \"The assistant couldn't respond just now — please try again in a moment.\";\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\n// Memory-key helper: a phone + an auto-generated word = the shopper's portable\n// identity (e.g. \"0111466235flyingthunder\"). parseMemoryKey accepts either a\n// bare phone (new user → we generate the word) or a full key (returning user).\nconst MK_ADJ = ['flying', 'silent', 'golden', 'lucky', 'brave', 'swift', 'royal', 'cosmic'];\nconst MK_NOUN = ['thunder', 'falcon', 'river', 'ember', 'tiger', 'comet', 'willow', 'onyx'];\nfunction generateMagicWord(): string {\n return MK_ADJ[Math.floor(Math.random() * MK_ADJ.length)] + MK_NOUN[Math.floor(Math.random() * MK_NOUN.length)];\n}\nfunction parseMemoryKey(raw: string): { phone: string; word: string } {\n const cleaned = raw.trim().replace(/\\s+/g, '');\n const m = cleaned.match(/^(\\d{6,})([a-zA-Z].*)?$/);\n const phone = m?.[1] || cleaned.replace(/\\D/g, '');\n const word = (m?.[2] || '').toLowerCase() || generateMagicWord();\n return { phone, word };\n}\n\n// ─── ChatModal Props ───────────────────────────────────────────────────────────\n\ninterface ChatModalProps extends Pick<KikuButtonProps, 'title' | 'placeholder' | 'backdropColor' | 'backdropBlur' | 'onSelectSource' | 'defaultCurrency' | 'chips' | 'theme' | 'classNames' | 'enableVoice' | 'enableVision' | 'visionCategoryHint'> {\n theme?: 'light' | 'dark' | AkropolysTheme;\n classNames?: any;\n onClose: () => void;\n}\n\n// ─── ChatModal ─────────────────────────────────────────────────────────────────\n\nfunction parseThinking(text: string): { thinking: string; content: string; isComplete: boolean } {\n const openMatch = text.match(/<\\s*thinking\\s*>/i);\n if (!openMatch) {\n return { thinking: '', content: text, isComplete: true };\n }\n\n const openIdx = openMatch.index ?? 0;\n const openTagLength = openMatch[0].length;\n const start = openIdx + openTagLength;\n \n const contentBefore = text.slice(0, openIdx);\n const textAfterOpen = text.slice(start);\n \n const closeMatch = textAfterOpen.match(/<\\/\\s*thinking\\s*>/i);\n if (!closeMatch) {\n return { \n thinking: textAfterOpen, \n content: contentBefore, \n isComplete: false \n };\n }\n\n const closeIdx = closeMatch.index ?? 0;\n const closeTagLength = closeMatch[0].length;\n \n return {\n thinking: textAfterOpen.slice(0, closeIdx),\n content: contentBefore + textAfterOpen.slice(closeIdx + closeTagLength),\n isComplete: true\n };\n}\n\nfunction ThinkingBlock({ text, isComplete }: { text: string; isComplete: boolean }) {\n const [isOpen, setIsOpen] = useState(true);\n\n // Auto-expand when streaming thinking content\n useEffect(() => {\n if (!isComplete) {\n setIsOpen(true);\n }\n }, [isComplete]);\n\n return (\n <div style={{\n marginBottom: '12px',\n borderLeft: '2px solid #e4e4e7',\n paddingLeft: '10px',\n fontSize: '0.825rem',\n backgroundColor: 'rgba(244, 244, 245, 0.4)',\n padding: '8px 10px',\n borderRadius: '0 6px 6px 0'\n }}>\n <div \n onClick={() => setIsOpen(!isOpen)} \n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n color: '#71717a',\n cursor: 'pointer',\n fontWeight: 500,\n userSelect: 'none'\n }}\n >\n <span style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\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' }}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n </svg>\n Thinking Process\n </span>\n {!isComplete && (\n <span style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: '#3b82f6',\n display: 'inline-block',\n animation: 'hsk-pulse 1.2s infinite ease-in-out'\n }} />\n )}\n <span style={{ \n fontSize: '0.7rem', \n marginLeft: 'auto',\n transform: isOpen ? 'rotate(90deg)' : 'none', \n transition: 'transform 0.1s' \n }}>▶</span>\n </div>\n {isOpen && (\n <div style={{\n marginTop: '6px',\n color: '#52525b',\n whiteSpace: 'pre-wrap',\n lineHeight: '1.4',\n fontStyle: 'italic'\n }}>\n {text}\n </div>\n )}\n </div>\n );\n}\n\nconst PROPERTY_CHIPS = [\n '3 bedroom apartments',\n 'Houses under KSh 5,000,000',\n 'Properties in Palm Beach',\n 'Studio apartments with pool',\n];\n\nfunction ChatModal({\n title = 'Shopping Assistant',\n placeholder = 'Ask me anything — gifts, budget, use case…',\n backdropColor,\n backdropBlur,\n onClose,\n onSelectSource,\n defaultCurrency = 'KES',\n chips = DEFAULT_CHIPS,\n theme,\n classNames = {},\n enableVoice = false,\n enableVision = false,\n visionCategoryHint,\n}: ChatModalProps) {\n const client = useAkropolysContext();\n const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, reset, referencedIds } = useKiku();\n const [input, setInput] = useState('');\n\n // ── Image attachments ────────────────────────────────────────────────────────\n const [attachments, setAttachments] = useState<ChatAttachment[]>([]);\n const imageInputRef = useRef<HTMLInputElement>(null);\n\n const handleImageFiles = (files: FileList | null) => {\n if (!files || files.length === 0) return;\n Array.from(files).forEach(file => {\n if (!file.type.startsWith('image/')) return;\n const reader = new FileReader();\n reader.onload = (e) => {\n const dataUrl = e.target?.result as string;\n if (dataUrl) {\n setAttachments(prev => [...prev, { type: 'image', data: dataUrl }]);\n }\n };\n reader.readAsDataURL(file);\n });\n };\n\n const removeAttachment = (idx: number) => {\n setAttachments(prev => prev.filter((_, i) => i !== idx));\n };\n\n // ── Voice mode (Web Speech API) ──────────────────────────────────────────────\n const [voiceState, setVoiceState] = useState<'idle' | 'listening' | 'processing'>('idle');\n const recognitionRef = useRef<any>(null);\n const pendingVoiceRef = useRef<string | null>(null); // transcript queued for auto-send\n const hasSpeechAPI = typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window);\n\n const startVoice = useCallback(() => {\n if (!hasSpeechAPI || voiceState !== 'idle') return;\n const SR = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n const recognition = new SR();\n recognition.lang = 'en-US';\n // Stream partial results so the user SEES words appear as they speak —\n // without this there's no feedback that anything was captured until the end.\n recognition.interimResults = true;\n recognition.maxAlternatives = 1;\n recognitionRef.current = recognition;\n\n recognition.onstart = () => setVoiceState('listening');\n recognition.onresult = (event: any) => {\n let finalText = '';\n let interimText = '';\n for (let i = 0; i < event.results.length; i++) {\n const seg = event.results[i][0].transcript;\n if (event.results[i].isFinal) finalText += seg;\n else interimText += seg;\n }\n // Live feedback: show the (final + in-progress) text in the input box.\n const live = (finalText + ' ' + interimText).trim();\n if (live) setInput(live);\n // Only auto-send once we have a finalized transcript.\n if (finalText.trim()) {\n pendingVoiceRef.current = finalText.trim();\n setVoiceState('processing');\n }\n };\n recognition.onerror = (event: any) => {\n // Surface the cause (most often denied mic permission or no speech) so the\n // user isn't left guessing whether it worked.\n const err = event?.error;\n if (err === 'not-allowed' || err === 'service-not-allowed') {\n setInput('Microphone access was blocked — enable it in your browser to use voice.');\n } else if (err === 'no-speech') {\n setInput(\"Didn't catch that — tap the mic and try again.\");\n }\n setVoiceState('idle');\n };\n recognition.onend = () => {\n // Only reset if we didn't already move to processing\n setVoiceState(prev => prev === 'listening' ? 'idle' : prev);\n };\n recognition.start();\n }, [hasSpeechAPI, voiceState]);\n\n const stopVoice = useCallback(() => {\n recognitionRef.current?.stop();\n setVoiceState('idle');\n }, []);\n\n // Clean up recognition on unmount\n useEffect(() => {\n return () => recognitionRef.current?.abort();\n }, []);\n\n const isProperty = client.vertical === 'property';\n const activeChips = chips === DEFAULT_CHIPS && isProperty ? PROPERTY_CHIPS : chips;\n const activeTitle = title === 'Shopping Assistant' && isProperty ? 'Property Assistant' : title;\n const activePlaceholder = placeholder === 'Ask me anything — gifts, budget, use case…' && isProperty\n ? 'Ask me anything — location, budget, bedrooms…'\n : placeholder;\n\n\n const [selectedProduct, setSelectedProduct] = useState<ChatSource | null>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const [phoneInput, setPhoneInput] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem('akropolys_user_phone') || '';\n }\n return '';\n });\n const [paymentPhase, setPaymentPhase] = useState<'idle' | 'prompt_phone'>('idle');\n const [memoryKey, setMemoryKey] = useState<string | null>(null); // shown after first capture sign-up\n\n // ── History sidebar ──────────────────────────────────────────────────────────\n const [sessions, setSessions] = useState<ChatSession[]>(() => loadSessions());\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [replayMessages, setReplayMessages] = useState<ChatMessage[] | null>(null); // null = live session\n\n // React to lastAction from chat\n useEffect(() => {\n if (!lastAction) return;\n if (lastAction.type === 'request_phone') {\n setPaymentPhase('prompt_phone');\n }\n }, [lastAction]);\n\n const isStringTheme = typeof theme === 'string';\n const hskThemeAttr = isStringTheme ? theme : undefined;\n\n const customStyles = (!isStringTheme && theme) ? {\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 : undefined;\n\n const handlePhoneSubmit = async () => {\n if (!phoneInput.trim()) return;\n // request_phone is only the capture/memory flow now (payments were removed),\n // so this NEVER triggers M-Pesa. Phone (new user → we generate a word) or a\n // full memory key (returning user) → store identity, show the key, retry.\n const { phone, word } = parseMemoryKey(phoneInput);\n if (!phone) return;\n if (typeof window !== 'undefined') localStorage.setItem('akropolys_user_phone', phone);\n client.setShopperIdentity(phone, word);\n setMemoryKey(phone + word);\n setPaymentPhase('idle');\n const lastUserMsg = [...messages].reverse().find(m => m.role === 'user');\n if (lastUserMsg) await send(lastUserMsg.content); // retry under the new identity\n };\n\n // Auto-scroll: only when the user is already pinned near the bottom (within 120px).\n // This lets them freely scroll up to re-read earlier messages while streaming continues.\n const msgsContainerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const container = msgsContainerRef.current;\n if (!container) return;\n const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;\n if (distanceFromBottom < 120) {\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }\n }, [messages, loading, selectedProduct]);\n\n useEffect(() => {\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, []);\n\n // ── Save session on reset or close ───────────────────────────────────────────\n const saveCurrentSession = useCallback(() => {\n if (messages.length < 2) return; // Nothing worth saving\n const firstUser = messages.find(m => m.role === 'user');\n const session: ChatSession = {\n id: `session_${Date.now()}`,\n title: firstUser ? firstUser.content.slice(0, 60) : 'Chat session',\n messages: messages,\n ts: Date.now(),\n };\n const updated = [session, ...sessions].slice(0, MAX_SESSIONS);\n setSessions(updated);\n saveSessions(updated);\n }, [messages, sessions]);\n\n const handleReset = useCallback(() => {\n saveCurrentSession();\n reset();\n setReplayMessages(null);\n setPaymentPhase('idle');\n }, [reset, saveCurrentSession]);\n\n const handleSourceClick = (src: ChatSource) => {\n setSelectedProduct(src);\n onSelectSource?.(src);\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?`;\n send(q);\n };\n\n const handleSend = async (text?: string, extraAttachments?: ChatAttachment[]) => {\n const q = (text ?? input).trim();\n if (!q || loading) return;\n // If we're in replay mode, exit replay and continue live\n setReplayMessages(null);\n setSelectedProduct(null);\n setInput('');\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n }\n const toSend = extraAttachments ?? attachments;\n setAttachments([]);\n await send(q, undefined, toSend.length > 0 ? toSend : undefined);\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 setInput(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 // Auto-send voice transcript once processing state is reached\n useEffect(() => {\n if (voiceState !== 'processing') return;\n const transcript = pendingVoiceRef.current;\n if (!transcript) { setVoiceState('idle'); return; }\n pendingVoiceRef.current = null;\n // Brief delay so user sees the transcript fill in before it fires\n const timer = setTimeout(() => {\n setVoiceState('idle');\n handleSend(transcript);\n }, 400);\n return () => clearTimeout(timer);\n }, [voiceState]);\n\n\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '20px');\n\n // The messages to display: replay or live\n const displayMessages = replayMessages ?? messages;\n\n // ── Load a historical session ─────────────────────────────────────────────────\n const loadSession = (session: ChatSession) => {\n setReplayMessages(session.messages);\n setSidebarOpen(false);\n };\n\n // ── Delete a session ──────────────────────────────────────────────────────────\n const deleteSession = (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const updated = sessions.filter(s => s.id !== id);\n setSessions(updated);\n saveSessions(updated);\n };\n\n return (\n <div\n className={cn(\"hsk-cb-overlay\", classNames.overlay)}\n onClick={onClose}\n data-hsk-theme={hskThemeAttr}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n ...(backdropColor ? { background: backdropColor } : {}),\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-cb-panel hsk-cb-panel--with-sidebar\", classNames.panel)} onClick={e => e.stopPropagation()}>\n\n {/* ── History Sidebar ── */}\n <div className={cn(\"hsk-cb-sidebar\", sidebarOpen && \"hsk-cb-sidebar--open\")}>\n <div className=\"hsk-cb-sidebar-header\">\n <span className=\"hsk-cb-sidebar-title\">History</span>\n <button\n className=\"hsk-cb-sidebar-new\"\n onClick={handleReset}\n title=\"New chat\"\n >\n <NewChatIcon />\n <span>New chat</span>\n </button>\n </div>\n <div className=\"hsk-cb-sidebar-list\">\n {sessions.length === 0 ? (\n <div className=\"hsk-cb-sidebar-empty\">\n <HistoryIcon />\n <span>No history yet</span>\n </div>\n ) : (\n sessions.map(session => (\n <div\n key={session.id}\n className={cn(\n \"hsk-cb-sidebar-session\",\n replayMessages === session.messages && \"hsk-cb-sidebar-session--active\"\n )}\n onClick={() => loadSession(session)}\n >\n <div className=\"hsk-cb-sidebar-session-title\">{session.title}</div>\n <div className=\"hsk-cb-sidebar-session-meta\">{relativeTime(session.ts)}</div>\n <button\n className=\"hsk-cb-sidebar-session-del\"\n onClick={(e) => deleteSession(session.id, e)}\n title=\"Delete\"\n >\n ×\n </button>\n </div>\n ))\n )}\n </div>\n </div>\n\n {/* ── Main Chat Area ── */}\n <div className=\"hsk-cb-main\">\n\n {/* Top bar */}\n <div className=\"hsk-cb-topbar\">\n <div className=\"hsk-cb-topbar-left\">\n {/* Sidebar toggle (always visible) */}\n <button\n className={cn(\"hsk-cb-sidebar-toggle\", sidebarOpen && \"hsk-cb-sidebar-toggle--active\")}\n onClick={(e) => { e.stopPropagation(); setSidebarOpen(v => !v); }}\n aria-label=\"Toggle history\"\n >\n <HistoryIcon />\n </button>\n <span className=\"hsk-cb-topbar-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div>\n <div className=\"hsk-cb-topbar-title\">{activeTitle}</div>\n </div>\n </div>\n <div className=\"hsk-cb-topbar-actions\">\n {replayMessages ? (\n <button className=\"hsk-cb-topbar-btn\" onClick={() => { setReplayMessages(null); }}>← Live chat</button>\n ) : (\n messages.length > 0 && (\n <button className=\"hsk-cb-topbar-btn\" onClick={handleReset}>Clear chat</button>\n )\n )}\n <button className=\"hsk-cb-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Replay banner */}\n {replayMessages && (\n <div className=\"hsk-cb-replay-banner\">\n <HistoryIcon />\n <span>You're viewing a past conversation.</span>\n <button onClick={() => setReplayMessages(null)}>Back to chat →</button>\n </div>\n )}\n\n {/* Messages */}\n <div className=\"hsk-cb-msgs\" ref={msgsContainerRef}>\n {displayMessages.length === 0 ? (\n <div className=\"hsk-cb-empty\">\n <div className=\"hsk-cb-empty-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-empty-title\">Find exactly what you need</div>\n <div className=\"hsk-cb-chips\">\n {activeChips.map(chip => (\n <button\n key={chip}\n className=\"hsk-cb-chip\"\n onClick={() => handleSend(chip)}\n >\n {chip}\n </button>\n ))}\n </div>\n </div>\n ) : (\n displayMessages.map((msg: ChatMessage, idx: number) => {\n const isLast = idx === displayMessages.length - 1 && !replayMessages;\n const isUser = msg.role === 'user';\n // Strip the LLM's markdown table for compare so ComparisonMatrix isn't duplicated\n const displayContent =\n !isUser && isLast && lastIntent === 'compare' && sources.length >= 2 && !replayMessages\n ? stripMarkdownTables(msg.content)\n : msg.content;\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n {/* Image thumbnails in user bubble */}\n {msg.images && msg.images.length > 0 && (\n <div className=\"hsk-cb-user-imgs\">\n {msg.images.map((img, i) => (\n <img key={i} src={img} alt={`attachment ${i + 1}`} className=\"hsk-cb-user-img-thumb\" />\n ))}\n </div>\n )}\n {msg.content && <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 {(() => {\n const { thinking, content, isComplete } = parseThinking(displayContent);\n return (\n <>\n {thinking && (\n <ThinkingBlock text={thinking} isComplete={isComplete} />\n )}\n {content && (\n <div className=\"hsk-cb-ai-text\">\n {renderMarkdown(content)}\n {isLast && streaming && (\n <span style={{ display: 'inline-block', width: '0.5em', height: '1.05em', marginLeft: '2px', verticalAlign: 'text-bottom', background: 'currentColor', opacity: 0.55, borderRadius: '1px' }} />\n )}\n </div>\n )}\n </>\n );\n })()}\n\n {/* Comparison matrix — replaces the markdown table when comparing products */}\n {isLast && lastIntent === 'compare' && sources.length >= 2 && !replayMessages && (\n <ComparisonMatrix sources={sources} defaultCurrency={defaultCurrency} />\n )}\n\n {/* Sources carousel — only for products the answer referenced, non-cart, non-compare */}\n {isLast && referencedIds.length > 0 && lastIntent !== 'compare' && lastAction?.type !== 'request_phone' && lastAction?.type !== 'awaiting_payment' && lastAction?.type !== 'checkout' && !msg.cartSnapshot && (\n <SourcesCarousel\n sources={sources}\n defaultCurrency={defaultCurrency}\n onSelectSource={handleSourceClick}\n referencedIds={referencedIds}\n />\n )}\n\n {/* Cart context card — shown when the message has a cart snapshot */}\n {msg.cartSnapshot && msg.cartSnapshot.items?.length > 0 && (\n <CartContextCard\n cart={msg.cartSnapshot}\n defaultCurrency={defaultCurrency}\n />\n )}\n\n {/* Action pills — for cart-mutating responses */}\n {isLast && msg.cartSnapshot && !loading && (\n <ActionPills\n cart={msg.cartSnapshot}\n actionType={msg.actionType}\n onSend={handleSend}\n loading={loading}\n />\n )}\n\n {/* Smart context pills — built only from products the answer referenced */}\n {isLast && !loading && !msg.cartSnapshot && !replayMessages && (\n <SmartContextPills\n intent={lastIntent}\n sources={sources.filter(s => s.id && referencedIds.includes(s.id))}\n onSend={handleSend}\n loading={loading}\n />\n )}\n </div>\n </div>\n )}\n </div>\n );\n })\n )}\n\n {/* Selected product pinned card — shows while LLM fetches details */}\n {selectedProduct && loading && (\n <div\n className=\"hsk-cb-selected-product\"\n onClick={() => selectedProduct.url && window.open(selectedProduct.url, '_blank')}\n >\n {selectedProduct.image && (\n <img className=\"hsk-cb-selected-img\" src={selectedProduct.image} alt={selectedProduct.name} />\n )}\n <div className=\"hsk-cb-selected-info\">\n <div className=\"hsk-cb-selected-name\">{selectedProduct.name}</div>\n {selectedProduct.price && (\n <div className=\"hsk-cb-selected-price\">\n {selectedProduct.currency ?? defaultCurrency} {parseFloat(String(selectedProduct.price ?? '').replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Typing dots — shown ONLY while waiting for the server (loading).\n Once the response arrives and token streaming begins (!loading && streaming)\n the text animates in directly with no dots visible. */}\n {loading && !streaming && (\n <div className=\"hsk-cb-typing-row\" style={{ display: 'flex', alignItems: 'flex-start', gap: '10px' }}>\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center', marginTop: '4px' }}>\n <SparkleIcon />\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\n <style>{`\n @keyframes hsk-pulse {\n 0%, 100% { opacity: 0.6; }\n 50% { opacity: 1; }\n }\n `}</style>\n <div style={{ fontSize: '0.85rem', color: '#6b7280', fontStyle: 'italic', animation: 'hsk-pulse 1.5s infinite ease-in-out' }}>\n Thinking…\n </div>\n <div className=\"hsk-cb-typing\" style={{ margin: 0, alignSelf: 'flex-start' }}>\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n </div>\n )}\n\n {error && <div className=\"hsk-cb-error\">{getFriendlyError(error)}</div>}\n\n {/* Carry-your-items prompt: one field takes a phone (new user → we\n auto-make the word) OR a full memory key (returning user). This is\n the ONLY thing request_phone does now — no payments. */}\n {!replayMessages && paymentPhase === 'prompt_phone' && (\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\">\n <div className=\"hsk-cb-phone-form\">\n <label className=\"hsk-cb-phone-label\">Your phone number — or paste your memory key</label>\n <input\n type=\"text\"\n className=\"hsk-cb-phone-input\"\n placeholder=\"0712345678 or 0712345678flyingthunder\"\n value={phoneInput}\n onChange={e => setPhoneInput(e.target.value.replace(/[^0-9a-zA-Z]/g, ''))}\n onKeyDown={e => e.key === 'Enter' && handlePhoneSubmit()}\n autoFocus\n />\n <button className=\"hsk-cb-phone-submit\" onClick={handlePhoneSubmit}>\n Save &amp; sync my items\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n\n {!replayMessages && memoryKey && (\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\">\n <div style={{ padding: '10px 12px', border: '1px solid var(--hsk-border, #e5e5e5)', borderRadius: 8 }}>\n <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 4 }}>🔑 Your memory key</div>\n <code style={{ display: 'block', fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: 'break-all' }}>{memoryKey}</code>\n <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\n <button className=\"hsk-cb-phone-submit\" style={{ padding: '4px 10px' }} onClick={() => { try { navigator.clipboard?.writeText(memoryKey); } catch { /* ignore */ } }}>Copy</button>\n <span style={{ fontSize: 11, opacity: 0.7 }}>Save it — enter it on any site to get your items back.</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n )}\n\n <div ref={bottomRef} style={{ height: 1 }} />\n </div>\n\n {/* Input — disabled in replay mode */}\n {!replayMessages && (\n <div className=\"hsk-cb-input-wrap\">\n {/* Image attachment strip */}\n {attachments.length > 0 && (\n <div className=\"hsk-cb-img-strip\">\n {attachments.map((att, i) => (\n <div key={i} className=\"hsk-cb-img-thumb-wrap\">\n <img src={att.data} alt={`attachment ${i + 1}`} className=\"hsk-cb-img-thumb\" />\n <button\n className=\"hsk-cb-img-thumb-remove\"\n onClick={() => removeAttachment(i)}\n aria-label=\"Remove image\"\n >\n ×\n </button>\n </div>\n ))}\n </div>\n )}\n <div className=\"hsk-cb-input-box\">\n {/* Hidden file input */}\n <input\n ref={imageInputRef}\n type=\"file\"\n accept=\"image/*\"\n multiple\n style={{ display: 'none' }}\n onChange={e => handleImageFiles(e.target.files)}\n />\n {/* Attach button — only shown if vision is enabled */}\n {enableVision && (\n <button\n className=\"hsk-cb-attach-btn\"\n onClick={() => imageInputRef.current?.click()}\n disabled={loading}\n aria-label=\"Attach image\"\n title=\"Attach image\"\n >\n <PaperclipIcon />\n </button>\n )}\n <textarea\n ref={textareaRef}\n className={cn(\"hsk-cb-textarea\", classNames.input)}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={\n voiceState === 'listening' ? '🎙️ Listening… tap the mic to stop'\n : voiceState === 'processing' ? 'Got it — sending…'\n : activePlaceholder\n }\n rows={1}\n disabled={loading}\n autoFocus\n />\n {/* Voice button — only shown if SpeechRecognition is supported and enabled */}\n {hasSpeechAPI && enableVoice && (\n <button\n className={cn(\n \"hsk-cb-mic-btn\",\n voiceState === 'listening' && \"hsk-cb-mic-btn--listening\",\n voiceState === 'processing' && \"hsk-cb-mic-btn--processing\"\n )}\n onClick={voiceState === 'idle' ? startVoice : stopVoice}\n disabled={loading}\n aria-label={voiceState === 'idle' ? 'Start voice input' : 'Stop recording'}\n title={voiceState === 'idle' ? 'Voice input' : 'Stop'}\n >\n {voiceState === 'listening' ? <MicOffIcon /> : <MicIcon />}\n {voiceState === 'listening' && <span className=\"hsk-cb-mic-pulse\" />}\n </button>\n )}\n <button\n className={cn(\"hsk-cb-send\", classNames.sendButton)}\n onClick={() => handleSend()}\n disabled={(!input.trim() && attachments.length === 0) || loading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n <div className=\"hsk-cb-hint\">Akropolys AI · searches the whole catalogue in real time</div>\n </div>\n )}\n\n </div>{/* end .hsk-cb-main */}\n\n </div>\n </div>\n );\n}\n\n// ─── KikuButton (public export) ─────────────────────────────────────────────\n\nexport function KikuButton({\n label,\n title,\n placeholder,\n backdropColor,\n backdropBlur,\n className,\n onSelectSource,\n defaultCurrency,\n chips,\n theme,\n classNames = {},\n enableVoice = false,\n enableVision = false,\n visionCategoryHint,\n}: KikuButtonProps) {\n const [open, setOpen] = useState(false);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n\n if (typeof window !== 'undefined' && !(window as any).__akropolys_nav_patched) {\n (window as any).__akropolys_nav_patched = true;\n const originalPush = window.history.pushState;\n const originalReplace = window.history.replaceState;\n\n window.history.pushState = function(...args) {\n originalPush.apply(this, args);\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\n };\n\n window.history.replaceState = function(...args) {\n originalReplace.apply(this, args);\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\n };\n }\n\n const handleNavigation = () => {\n setOpen(false);\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('akropolys:navigation', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('akropolys:navigation', handleNavigation);\n };\n }, []);\n\n const isStringTheme = typeof theme === 'string';\n const hskThemeAttr = isStringTheme ? theme : undefined;\n\n const customStyles = (!isStringTheme && theme) ? {\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 : undefined;\n\n return (\n <>\n <button\n className={cn(\"hsk-cb-btn\", classNames.button, className)}\n onClick={() => setOpen(true)}\n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n aria-label=\"Open AI chat\"\n >\n <span className=\"hsk-cb-btn-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n {label !== undefined ? label : null}\n </button>\n {open && mounted && createPortal(\n <ChatModal\n title={title}\n placeholder={placeholder}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n onClose={() => setOpen(false)}\n onSelectSource={onSelectSource}\n defaultCurrency={defaultCurrency}\n chips={chips}\n theme={theme}\n classNames={classNames}\n enableVoice={enableVoice}\n enableVision={enableVision}\n visionCategoryHint={visionCategoryHint}\n />,\n document.body\n )}\n </>\n );\n}\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 &middot; 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":["import_react","import_sdk","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_sdk","import_jsx_runtime","import_jsx_runtime","import_react","import_sdk","import_sdk","import_jsx_runtime","import_jsx_runtime","SparkleIcon","ArrowUpIcon","MicIcon","SparkleIcon","ArrowUpIcon","import_react","import_react_dom","import_sdk","import_jsx_runtime","SparkleIcon","CloseIcon","ArrowUpIcon","getFriendlyError"]}