@akropolys/kiku 1.8.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -64
- package/dist/chunk-RWGHGIF7.mjs +3 -0
- package/dist/chunk-RWGHGIF7.mjs.map +1 -0
- package/dist/index.d.mts +5 -196
- package/dist/index.d.ts +5 -196
- package/dist/index.js +7 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -46
- package/dist/index.mjs.map +1 -1
- package/dist/lazy-UZ2LZJOA.mjs +39 -0
- package/dist/lazy-UZ2LZJOA.mjs.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +7 -9
- package/dist/kiku.iife.global.js +0 -111
- package/dist/kiku.iife.global.js.map +0 -1
- package/dist/kiku.iife.js +0 -111
- package/dist/kiku.iife.js.map +0 -1
- package/dist/shopify.global.js +0 -111
- package/dist/shopify.global.js.map +0 -1
- package/dist/shopify.js +0 -111
- package/dist/shopify.js.map +0 -1
- package/shopify/README.md +0 -71
- package/shopify/blocks/kiku-button.liquid +0 -121
- package/shopify/snippets/kiku-embed.liquid +0 -45
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/SearchBar.tsx","../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/utils/cn.ts","../src/components/ChatWidget.tsx","../src/utils/markdown.tsx","../src/utils/icons.tsx","../src/utils/theme.ts","../src/components/VoiceButton.tsx","../src/utils/voiceSession.ts","../src/utils/tts.ts","../src/components/VisualSearch.tsx","../src/utils/downscaleImage.ts","../src/components/KikuButton.tsx","../src/generated/cssText.ts","../src/utils/shadowRoot.ts","../src/utils/chromeWarm.ts","../src/utils/hostFont.ts","../src/components/ChatModal/types.ts","../src/components/ChatModal/ChatModal.tsx","../src/components/ChatModal/icons.tsx","../src/components/ChatModal/themes.ts","../src/utils/sheetGesture.ts","../src/components/MarkupEditor.tsx","../src/utils/markRegions.ts","../src/components/Scouts/ScoutRail.tsx","../src/components/Scouts/ScoutCharacter.tsx","../src/components/Scouts/AnimatedNumber.tsx","../src/components/Scouts/ScoutPin.tsx","../src/components/KikuDoodles.tsx","../src/components/ChatModal/hooks/useScriptFont.tsx","../src/components/ChatModal/locales.json","../src/components/ChatModal/hooks/useChatScroll.ts","../src/components/ChatModal/hooks/useKikuKey.ts","../src/components/ChatModal/hooks/useChatCommands.ts","../src/components/ChatModal/hooks/useVoiceController.ts","../src/utils/liveVoice.ts","../src/components/ChatModal/ChatTopbar.tsx","../src/components/KikuAvatar.tsx","../src/components/ChatModal/OnboardingView.tsx","../src/components/ChatModal/components/CascadeText.tsx","../src/components/ChatModal/components/InkBloomSkeleton.tsx","../src/components/ChatModal/components/AnimatedPlaceholder.tsx","../src/components/ChatModal/components/MessageItem.tsx","../src/components/LiveTable.tsx","../src/components/ChatModal/components/ThinkingBlock.tsx","../src/components/ChatModal/components/SourcesCarousel.tsx","../src/components/ChatModal/components/SmartContextPills.tsx","../src/components/ChatModal/components/MemoryKeyCards.tsx","../src/components/ChatModal/ChatMessages.tsx","../src/components/ChatModal/ChatComposer.tsx","../src/components/VoiceCanvas.tsx","../src/components/ChatModal/VoiceOverlay.tsx","../src/components/ChatModal/components/LightboxModal.tsx","../src/components/ChatModal/components/ConversationTimeline.tsx","../src/components/ChatModal/components/TapbackMenu.tsx","../src/components/Sparkle.tsx","../src/shopify.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\r\nimport { useSearch, SearchResult, AkropolysTheme, useAkropolysContext } from '@akropolys/sdk';\r\nimport { cn } from '../utils/cn';\r\n\r\nexport interface SearchBarProps {\r\n placeholder?: string;\r\n limit?: number;\r\n debounceMs?: number;\r\n onSelect?: (result: SearchResult) => void;\r\n className?: string;\r\n inputClassName?: string;\r\n dropdownClassName?: string;\r\n renderResult?: (result: SearchResult) => React.ReactNode;\r\n theme?: AkropolysTheme;\r\n classNames?: {\r\n root?: string;\r\n input?: string;\r\n dropdown?: string;\r\n row?: string;\r\n };\r\n}\r\n\r\nconst SearchIcon = () => (\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\r\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\"/>\r\n <line x1=\"13\" y1=\"13\" x2=\"18\" y2=\"18\"/>\r\n </svg>\r\n);\r\n\r\nexport function SearchBar({\r\n placeholder = 'Search products…',\r\n limit = 10,\r\n debounceMs = 150,\r\n onSelect,\r\n className,\r\n inputClassName,\r\n dropdownClassName,\r\n renderResult,\r\n theme,\r\n classNames = {},\r\n}: SearchBarProps) {\r\n const [query, setQuery] = useState('');\r\n const [open, setOpen] = useState(false);\r\n const { results, loading, search, clear } = useSearch({ debounceMs });\r\n const client = useAkropolysContext();\r\n const wrap = useRef<HTMLDivElement>(null);\r\n const ignoreNextQueryChange = useRef(false);\r\n\r\n useEffect(() => {\r\n if (ignoreNextQueryChange.current) {\r\n ignoreNextQueryChange.current = false;\r\n return;\r\n }\r\n if (!query.trim()) {\r\n clear();\r\n setOpen(false);\r\n return;\r\n }\r\n setOpen(true); // open immediately (stale results show while fetching)\r\n search(query, limit);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [query]);\r\n\r\n useEffect(() => {\r\n const h = (e: MouseEvent) => {\r\n if (wrap.current && !wrap.current.contains(e.target as Node)) setOpen(false);\r\n };\r\n document.addEventListener('mousedown', h);\r\n return () => document.removeEventListener('mousedown', h);\r\n }, []);\r\n\r\n const handleSelect = (r: SearchResult) => {\r\n if (query.trim()) {\r\n client.api.searchVector(query, 1, undefined, true).catch(() => {});\r\n }\r\n ignoreNextQueryChange.current = true;\r\n setOpen(false);\r\n setQuery(r.entity.title ?? r.entity.name ?? '');\r\n onSelect?.(r);\r\n };\r\n\r\n const handleCommitSearch = () => {\r\n if (!query.trim()) return;\r\n client.api.searchVector(query, 1, undefined, true).catch(() => {});\r\n if (results.length > 0) {\r\n handleSelect(results[0]);\r\n }\r\n };\r\n\r\n const showDrop = open && query.trim().length > 0;\r\n\r\n const customStyles = {\r\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\r\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\r\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\r\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\r\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\r\n } as React.CSSProperties;\r\n\r\n return (\r\n <div className={cn(\"hsk-sb-wrap\", classNames.root, className)} ref={wrap} style={customStyles}>\r\n <span className=\"hsk-sb-icon\"><SearchIcon /></span>\r\n <input\r\n className={cn(\"hsk-sb-input\", classNames.input, inputClassName)}\r\n type=\"text\"\r\n value={query}\r\n placeholder={placeholder}\r\n onChange={e => setQuery(e.target.value)}\r\n onFocus={() => results.length > 0 && query.trim() && setOpen(true)}\r\n onKeyDown={e => {\r\n if (e.key === 'Enter') {\r\n handleCommitSearch();\r\n }\r\n }}\r\n autoComplete=\"off\"\r\n spellCheck={false}\r\n />\r\n {showDrop && (\r\n <div className={cn(\"hsk-sb-drop\", classNames.dropdown, dropdownClassName)} style={{ position: 'absolute' }}>\r\n {loading && <div className=\"hsk-sb-loading-bar\" />}\r\n\r\n {loading && results.length === 0 ? (\r\n <>\r\n <div className=\"hsk-sb-skeleton-row\">\r\n <span className=\"hsk-sb-skeleton-icon\" />\r\n <div className=\"hsk-sb-row-body\">\r\n <div className=\"hsk-sb-skeleton-text1\" />\r\n <div className=\"hsk-sb-skeleton-text2\" />\r\n </div>\r\n </div>\r\n <div className=\"hsk-sb-skeleton-row\">\r\n <span className=\"hsk-sb-skeleton-icon\" />\r\n <div className=\"hsk-sb-row-body\">\r\n <div className=\"hsk-sb-skeleton-text1\" style={{ width: '45%' }} />\r\n <div className=\"hsk-sb-skeleton-text2\" style={{ width: '25%' }} />\r\n </div>\r\n </div>\r\n </>\r\n ) : (\r\n <>\r\n {results.length === 0 && !loading && (\r\n <div className=\"hsk-sb-empty\">No results for “{query}”</div>\r\n )}\r\n\r\n {results.map((r, i) => {\r\n if (renderResult) {\r\n return (\r\n <div\r\n key={r.id}\r\n onClick={() => handleSelect(r)}\r\n className=\"hsk-sb-fade\"\r\n style={{ animationDelay: `${i * 18}ms` }}\r\n >\r\n {renderResult(r)}\r\n </div>\r\n );\r\n }\r\n const thumb = r.entity.image ?? r.entity.thumbnail ?? r.entity.images?.[0];\r\n return (\r\n <div\r\n key={r.id}\r\n className={cn(\"hsk-sb-row hsk-sb-fade\", classNames.row)}\r\n style={{ animationDelay: `${i * 18}ms` }}\r\n onClick={() => handleSelect(r)}\r\n >\r\n <span className=\"hsk-sb-row-thumb\">\r\n {thumb ? (\r\n <img\r\n src={thumb}\r\n alt=\"\"\r\n loading=\"lazy\"\r\n onError={e => { e.currentTarget.style.display = 'none'; }}\r\n />\r\n ) : (\r\n <SearchIcon />\r\n )}\r\n </span>\r\n <div className=\"hsk-sb-row-body\">\r\n <div className=\"hsk-sb-row-title\">{r.entity.title ?? r.entity.name}</div>\r\n {(r.entity.category || r.entity.brand) && (\r\n <div className=\"hsk-sb-row-sub\">\r\n {r.entity.category ?? r.entity.brand}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { clsx, type ClassValue } from \"clsx\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return clsx(inputs);\r\n}\r\n","import React, { useState, useRef, useEffect } from 'react';\r\nimport { useKiku, useAkropolysContext, resolveDisplayFields, ChatMessage, ChatSource } from '@akropolys/sdk';\r\nimport { renderMarkdown } from '../utils/markdown';\r\nimport { AkropolysTheme } from '@akropolys/sdk';\r\nimport { cn } from '../utils/cn';\r\nimport { ArrowUpIcon } from '../utils/icons';\r\nimport { resolveTheme } from '../utils/theme';\r\nimport { VoiceButton } from './VoiceButton';\r\nimport { VisualSearch } from './VisualSearch';\r\nimport { speak, stopSpeech } from '../utils/tts';\r\n\r\nexport interface ChatWidgetProps {\r\n title?: string;\r\n placeholder?: string;\r\n emptyStateText?: string;\r\n emptyStateSuggestions?: string;\r\n defaultCurrency?: string;\r\n className?: string;\r\n\r\n theme?: AkropolysTheme;\r\n\r\n classNames?: {\r\n root?: string;\r\n header?: string;\r\n messageBubble?: string;\r\n input?: string;\r\n };\r\n\r\n onSelectSource?: (source: ChatSource) => void;\r\n\r\n enableVoice?: boolean;\r\n /** Enable 📷 visual style-match search */\r\n enableVision?: boolean;\r\n\r\n visionCategoryHint?: string;\r\n\r\n /** Enable 🔊 TTS voice audio responses from AI */\r\n enableAudioResponse?: boolean;\r\n /** Optional AI voice preset */\r\n ttsVoice?: string;\r\n\r\n autoSpeakResponses?: boolean;\r\n}\r\n\r\nconst SparkleIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m12 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\"/>\r\n </svg>\r\n);\r\n\r\nconst SpeakerIcon = ({ active }: { active: boolean }) => (\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" fill={active ? 'currentColor' : 'none'} />\r\n {active ? (\r\n <>\r\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\r\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\r\n </>\r\n ) : (\r\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\r\n )}\r\n </svg>\r\n);\r\n\r\nfunction SourceCard({\r\n source,\r\n defaultCurrency,\r\n onSelect,\r\n isReferenced\r\n}: {\r\n source: ChatSource;\r\n defaultCurrency: string;\r\n onSelect?: (s: ChatSource) => void;\r\n isReferenced?: boolean;\r\n}) {\r\n return (\r\n <div\r\n className={cn(\"hsk-source-card\", isReferenced && \"hsk-source-card--referenced\")}\r\n onClick={() => onSelect?.(source)}\r\n >\r\n {source.image && <img src={source.image} alt={source.name} className=\"hsk-source-img\" />}\r\n <div style={{ flex: 1, minWidth: 0, position: 'relative' }}>\r\n {isReferenced && (\r\n <div className=\"hsk-cb-source-ref-badge\" title=\"Featured in response\" style={{ top: '0', right: '0' }}>\r\n <SparkleIcon />\r\n </div>\r\n )}\r\n <div className=\"hsk-source-name\" style={{ paddingRight: isReferenced ? '20px' : undefined }}>{source.name}</div>\r\n {source.price && (\r\n <div className=\"hsk-source-price\">{source.currency ?? defaultCurrency} {source.price}</div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\ninterface ChatMessageWithVisual extends ChatMessage {\r\n imagePreview?: string;\r\n styleDNA?: any;\r\n visualSources?: ChatSource[];\r\n}\r\n\r\nexport function ChatWidget({\r\n title = 'kiku',\r\n placeholder = 'Ask about anything in our store…',\r\n emptyStateText = 'Ask me anything about our products',\r\n emptyStateSuggestions = '\"Find me headphones under KSh 5,000\" · \"Gift ideas\"',\r\n defaultCurrency = 'KES',\r\n className,\r\n theme,\r\n classNames = {},\r\n onSelectSource,\r\n enableVoice = false,\r\n enableVision = false,\r\n visionCategoryHint,\r\n enableAudioResponse = true,\r\n ttsVoice,\r\n autoSpeakResponses = true\r\n}: ChatWidgetProps) {\r\n const client = useAkropolysContext();\r\n const { messages, sources, referencedIds, loading: chatLoading, streaming, error, send, reset } = useKiku();\r\n const [input, setInput] = useState('');\r\n const [visualLoading, setVisualLoading] = useState(false);\r\n const bottomRef = useRef<HTMLDivElement>(null);\r\n const textareaRef = useRef<HTMLTextAreaElement>(null);\r\n\r\n const [audioEnabled, setAudioEnabled] = useState(enableAudioResponse);\r\n const [speakingMsgIndex, setSpeakingMsgIndex] = useState<number | null>(null);\r\n const prevStreamingRef = useRef(streaming);\r\n const userInitiatedVoiceRef = useRef(false);\r\n\r\n const loading = chatLoading || visualLoading;\r\n\r\n const [chatHistory, setChatHistory] = useState<ChatMessageWithVisual[]>([]);\r\n const lastSyncedCount = useRef(0);\r\n\r\n useEffect(() => {\r\n if (messages.length === 0) {\r\n setChatHistory([]);\r\n lastSyncedCount.current = 0;\r\n return;\r\n }\r\n\r\n if (messages.length > lastSyncedCount.current) {\r\n const newMsgs = messages.slice(lastSyncedCount.current);\r\n setChatHistory(prev => [...prev, ...newMsgs]);\r\n lastSyncedCount.current = messages.length;\r\n } else if (messages.length < lastSyncedCount.current) {\r\n setChatHistory(messages);\r\n lastSyncedCount.current = messages.length;\r\n } else {\r\n setChatHistory(prev => {\r\n const next = [...prev];\r\n let hookIdx = messages.length - 1;\r\n let historyIdx = next.length - 1;\r\n while (hookIdx >= 0 && historyIdx >= 0) {\r\n if (next[historyIdx].role === messages[hookIdx].role) {\r\n next[historyIdx] = {\r\n ...next[historyIdx],\r\n content: messages[hookIdx].content,\r\n actionType: messages[hookIdx].actionType,\r\n thinking: messages[hookIdx].thinking,\r\n thoughtForSeconds: messages[hookIdx].thoughtForSeconds,\r\n statusMessage: messages[hookIdx].statusMessage,\r\n };\r\n break;\r\n }\r\n historyIdx--;\r\n }\r\n return next;\r\n });\r\n }\r\n }, [messages]);\r\n\r\n useEffect(() => {\r\n const wasStreaming = prevStreamingRef.current;\r\n prevStreamingRef.current = streaming;\r\n\r\n const spoken = userInitiatedVoiceRef.current;\r\n userInitiatedVoiceRef.current = false;\r\n if (wasStreaming && !streaming && spoken && audioEnabled && autoSpeakResponses) {\r\n const lastMsgIndex = chatHistory.length - 1;\r\n const lastMsg = chatHistory[lastMsgIndex];\r\n if (lastMsg && lastMsg.role === 'assistant' && lastMsg.content) {\r\n setSpeakingMsgIndex(lastMsgIndex);\r\n void speak({\r\n client: client as any,\r\n text: lastMsg.content,\r\n voice: ttsVoice,\r\n language: client.getShopperLanguage?.(),\r\n onEnd: () => setSpeakingMsgIndex(null),\r\n onError: () => setSpeakingMsgIndex(null),\r\n });\r\n }\r\n }\r\n }, [streaming, audioEnabled, autoSpeakResponses, chatHistory, ttsVoice, client]);\r\n\r\n useEffect(() => {\r\n bottomRef.current?.scrollIntoView({ behavior: loading ? 'auto' : 'smooth' });\r\n }, [chatHistory, loading]);\r\n\r\n const handleSend = async () => {\r\n const q = input.trim();\r\n if (!q || loading) return;\r\n stopSpeech();\r\n setSpeakingMsgIndex(null);\r\n setInput('');\r\n if (textareaRef.current) textareaRef.current.style.height = 'auto';\r\n await send(q);\r\n };\r\n\r\n const handleKey = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\r\n if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n setInput(e.target.value);\r\n const t = e.target;\r\n t.style.height = 'auto';\r\n t.style.height = Math.min(t.scrollHeight, 120) + 'px';\r\n };\r\n\r\n const handleSpeakToggle = (idx: number, text: string) => {\r\n if (speakingMsgIndex === idx) {\r\n stopSpeech();\r\n setSpeakingMsgIndex(null);\r\n } else {\r\n setSpeakingMsgIndex(idx);\r\n void speak({\r\n client: client as any,\r\n text,\r\n voice: ttsVoice,\r\n language: client.getShopperLanguage?.(),\r\n onEnd: () => setSpeakingMsgIndex(null),\r\n onError: () => setSpeakingMsgIndex(null),\r\n });\r\n }\r\n };\r\n\r\n const handleVisualResults = (res: any, preview: string) => {\r\n const userMsg: ChatMessageWithVisual = {\r\n role: 'user',\r\n content: 'Uploaded a photo for visual search',\r\n imagePreview: preview,\r\n };\r\n\r\n const dna = res.style_dna;\r\n let content = `I've analyzed your image! Here is the Style DNA I found:\\n`;\r\n if (dna) {\r\n if (dna.color_palette) content += `* **Palette:** ${dna.color_palette}\\n`;\r\n if (dna.dominant_colors && dna.dominant_colors.length > 0) {\r\n content += `* **Colors:** ${dna.dominant_colors.join(', ')}\\n`;\r\n }\r\n if (dna.aesthetic && dna.aesthetic.length > 0) {\r\n content += `* **Aesthetic:** ${dna.aesthetic.join(', ')}\\n`;\r\n }\r\n if (dna.texture) content += `* **Texture:** ${dna.texture}\\n`;\r\n if (dna.formality) content += `* **Formality:** ${dna.formality}\\n`;\r\n }\r\n\r\n const results = res.results || [];\r\n if (results.length > 0) {\r\n content += `\\nI found ${results.length} matching products in the store for you.`;\r\n } else {\r\n content += `\\nI couldn't find any matching products in the store.`;\r\n }\r\n\r\n const assistantMsg: ChatMessageWithVisual = {\r\n role: 'assistant',\r\n content,\r\n styleDNA: dna,\r\n visualSources: results.map((r: any) => {\r\n const fields = r.entity ?? {};\r\n const d = resolveDisplayFields(fields, undefined);\r\n return {\r\n id: r.id,\r\n url: r.url ?? fields.url,\r\n fields,\r\n name: d.title,\r\n price: d.price,\r\n image: d.image,\r\n brand: d.subtitle,\r\n currency: typeof fields.currency === 'string' ? fields.currency : undefined,\r\n };\r\n }),\r\n };\r\n\r\n setChatHistory(prev => [...prev, userMsg, assistantMsg]);\r\n };\r\n\r\n const { vars: customStyles } = resolveTheme(theme);\r\n\r\n return (\r\n <div\r\n className={cn(\"hsk-chat-widget\", classNames.root, className)}\r\n style={customStyles}\r\n >\r\n <div className={cn(\"hsk-chat-header\", classNames.header)}>\r\n <span className=\"hsk-chat-header-icon\"><SparkleIcon /></span>\r\n <span className=\"hsk-chat-title\">{title}</span>\r\n <span className=\"hsk-chat-badge\">AI</span>\r\n <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: '8px' }}>\r\n {enableAudioResponse && (\r\n <button\r\n type=\"button\"\r\n className={cn(\"hsk-audio-toggle-btn\", audioEnabled && \"hsk-audio-toggle-btn--active\")}\r\n onClick={() => {\r\n const next = !audioEnabled;\r\n setAudioEnabled(next);\r\n if (!next) {\r\n stopSpeech();\r\n setSpeakingMsgIndex(null);\r\n }\r\n }}\r\n title={audioEnabled ? \"Mute AI audio response\" : \"Enable AI audio response\"}\r\n aria-label={audioEnabled ? \"Mute voice\" : \"Enable voice\"}\r\n >\r\n <SpeakerIcon active={audioEnabled} />\r\n </button>\r\n )}\r\n {chatHistory.length > 0 && (\r\n <button className=\"hsk-chat-reset\" onClick={() => { stopSpeech(); reset(); }}>Clear</button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <div className=\"hsk-chat-messages\">\r\n {chatHistory.length === 0 ? (\r\n <div className=\"hsk-chat-empty\">\r\n <div className=\"hsk-chat-empty-icon\"><SparkleIcon /></div>\r\n <div>{emptyStateText}</div>\r\n <div className=\"hsk-chat-empty-suggestions\">{emptyStateSuggestions}</div>\r\n </div>\r\n ) : (\r\n chatHistory.map((msg, idx) => (\r\n <div key={idx}>\r\n <div className={`hsk-msg-row ${msg.role}`}>\r\n <div className={cn(\"hsk-msg-avatar\", msg.role === 'assistant' ? 'ai' : 'user')}>\r\n {msg.role === 'assistant' ? <SparkleIcon /> : 'U'}\r\n </div>\r\n <div className={cn(\"hsk-msg-bubble\", msg.role, classNames.messageBubble)}>\r\n {msg.imagePreview && (\r\n <div className=\"kiku-vs-preview-bubble\" style={{ marginBottom: '8px' }}>\r\n <img src={msg.imagePreview} alt=\"Uploaded Preview\" className=\"kiku-vs-preview-bubble-img\" style={{ maxWidth: '200px', borderRadius: '8px' }} />\r\n </div>\r\n )}\r\n {msg.thinking && (\r\n <details className=\"hsk-thinking-details\" open={streaming && idx === chatHistory.length - 1 && !msg.content}>\r\n <summary className=\"hsk-thinking-summary\">\r\n Thought for {msg.thoughtForSeconds ?? 1}s\r\n </summary>\r\n <div className=\"hsk-thinking-text\">{msg.thinking}</div>\r\n </details>\r\n )}\r\n {(!msg.content && !msg.thinking && msg.role === 'assistant' && idx === chatHistory.length - 1) && (\r\n <div className=\"hsk-status-live\">\r\n <span className=\"hsk-status-dot\" />\r\n <span>{msg.statusMessage || 'Thinking...'}</span>\r\n </div>\r\n )}\r\n {renderMarkdown(msg.content)}\r\n {msg.role === 'assistant' && msg.content && !streaming && (\r\n <button\r\n type=\"button\"\r\n className={cn(\"hsk-msg-audio-btn\", speakingMsgIndex === idx && \"hsk-msg-audio-btn--active\")}\r\n onClick={() => handleSpeakToggle(idx, msg.content)}\r\n title={speakingMsgIndex === idx ? \"Stop speaking\" : \"Listen to response\"}\r\n aria-label=\"Toggle speech\"\r\n >\r\n <SpeakerIcon active={speakingMsgIndex === idx} />\r\n </button>\r\n )}\r\n {streaming && idx === chatHistory.length - 1 && msg.role === 'assistant' && (\r\n <span className=\"hsk-streaming-cursor\" />\r\n )}\r\n {msg.styleDNA && (\r\n <div className=\"kiku-vs-preview-banner\" style={{ marginTop: '10px' }}>\r\n {chatHistory[idx - 1]?.imagePreview && (\r\n <img src={chatHistory[idx - 1].imagePreview} alt=\"Visual Search Input\" className=\"kiku-vs-preview-img\" />\r\n )}\r\n <div className=\"kiku-vs-preview-info\">\r\n <div className=\"kiku-vs-preview-label\">Visual Match Palette</div>\r\n <div className=\"kiku-vs-preview-palette\">{msg.styleDNA.color_palette || 'Detected Style DNA'}</div>\r\n {msg.styleDNA.style_tags && msg.styleDNA.style_tags.length > 0 && (\r\n <div className=\"kiku-style-tags\">\r\n {msg.styleDNA.style_tags.map((tag: string, ti: number) => (\r\n <span key={ti} className=\"kiku-style-tag\">#{tag}</span>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n {msg.role === 'assistant' && msg.visualSources && msg.visualSources.length > 0 && (\r\n <div className=\"hsk-sources-container\">\r\n <div className=\"hsk-sources\">\r\n {msg.visualSources.map((src, si) => (\r\n <SourceCard key={si} source={src} defaultCurrency={defaultCurrency} onSelect={onSelectSource} />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n {msg.role === 'assistant' && idx === chatHistory.length - 1 && !msg.visualSources && sources.length > 0 && (() => {\r\n const isStreamingActive = chatLoading || streaming;\r\n if (isStreamingActive) {\r\n return (\r\n <div className=\"hsk-sources-container\">\r\n <div className=\"hsk-sources\">\r\n {sources.map((src, si) => {\r\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\r\n return (\r\n <SourceCard\r\n key={si}\r\n source={src}\r\n defaultCurrency={defaultCurrency}\r\n onSelect={onSelectSource}\r\n isReferenced={isReferenced}\r\n />\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const featured = sources.filter(src => src.id && referencedIds.includes(src.id));\r\n const general = referencedIds.length > 0\r\n ? []\r\n : sources.filter(src => !src.id || !referencedIds.includes(src.id));\r\n\r\n return (\r\n <div className=\"hsk-sources-container\">\r\n {featured.length > 0 && (\r\n <div className=\"hsk-sources-group\" style={{ marginBottom: '10px' }}>\r\n <div className=\"hsk-sources-group-title\">⭐ Featured in response</div>\r\n <div className=\"hsk-sources\">\r\n {featured.map((src, si) => (\r\n <SourceCard\r\n key={`feat-${si}`}\r\n source={src}\r\n defaultCurrency={defaultCurrency}\r\n onSelect={onSelectSource}\r\n isReferenced={true}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n {general.length > 0 && (\r\n <div className=\"hsk-sources-group\">\r\n {featured.length > 0 && <div className=\"hsk-sources-group-title\">All matches</div>}\r\n <div className=\"hsk-sources\">\r\n {general.map((src, si) => (\r\n <SourceCard\r\n key={`gen-${si}`}\r\n source={src}\r\n defaultCurrency={defaultCurrency}\r\n onSelect={onSelectSource}\r\n isReferenced={false}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })()}\r\n </div>\r\n ))\r\n )}\r\n\r\n {loading && (\r\n <div className=\"hsk-msg-row\">\r\n <div className=\"hsk-msg-avatar ai\"><SparkleIcon /></div>\r\n <div className=\"hsk-pending\" role=\"status\" aria-live=\"polite\">\r\n <div className=\"hsk-pending-glyph\">\r\n <span className=\"hsk-pending-ring\" />\r\n <span className=\"hsk-pending-dot\" />\r\n </div>\r\n <div className=\"hsk-pending-text\">\r\n <span className=\"hsk-pending-step step-1\">Searching catalog</span>\r\n <span className=\"hsk-pending-step step-2\">Reasoning</span>\r\n <span className=\"hsk-pending-step step-3\">Composing</span>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {error && (\r\n <div className=\"hsk-chat-error\">\r\n {(() => {\r\n try {\r\n const parsed = JSON.parse(error);\r\n return parsed.error || parsed.message || error;\r\n } catch {\r\n return error;\r\n }\r\n })()}\r\n </div>\r\n )}\r\n <div ref={bottomRef} />\r\n </div>\r\n\r\n <div className=\"hsk-chat-input-area\" style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\r\n {enableVision && (\r\n <VisualSearch\r\n onResults={handleVisualResults}\r\n onError={(err) => console.error('[VisualSearch] error:', err)}\r\n categoryHint={visionCategoryHint}\r\n disabled={loading}\r\n />\r\n )}\r\n <textarea\r\n ref={textareaRef}\r\n className={cn(\"hsk-chat-input\", classNames.input)}\r\n value={input}\r\n onChange={handleInput}\r\n onKeyDown={handleKey}\r\n placeholder={placeholder}\r\n rows={1}\r\n disabled={loading}\r\n style={{ flex: 1 }}\r\n />\r\n {enableVoice && (\r\n <VoiceButton\r\n onTranscript={(text) => {\r\n userInitiatedVoiceRef.current = true;\r\n stopSpeech();\r\n setSpeakingMsgIndex(null);\r\n setInput(text);\r\n send(text);\r\n setInput('');\r\n }}\r\n onInterim={(text) => setInput(text)}\r\n disabled={loading}\r\n />\r\n )}\r\n <button\r\n className=\"hsk-chat-send\"\r\n onClick={handleSend}\r\n disabled={!input.trim() || loading}\r\n aria-label=\"Send message\"\r\n >\r\n <ArrowUpIcon />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n","import React from 'react';\r\n\r\nconst SPACING_DOUBLE_REGEX = /[ \\t]{2,}/g;\r\nconst SPACING_PUNCT_REGEX = / ([.,!?:;])/g;\r\nconst SPACING_OPEN_PAREN_REGEX = /\\(([ \\t]+)/g;\r\nconst SPACING_CLOSE_PAREN_REGEX = /([ \\t]+)\\)/g;\r\nconst SPACING_UNIT_REGEX = /(\\d+)\\s+(MP|mAh|W|GB|MB|KHz|Hz|KSh|KES|USD|EUR)\\b/gi;\r\n\r\nconst TOKEN_SPLIT_REGEX = /(!\\[[^\\]]*\\]\\([^)]+\\)|\\[[^\\]]+\\]\\([^)]+\\)|\\*\\*[^*]+\\*\\*|`[^`]+`)/g;\r\nconst IMAGE_PARSE_REGEX = /^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/;\r\nconst LINK_PARSE_REGEX = /^\\[([^\\]]+)\\]\\(([^)]+)\\)$/;\r\nconst SAFE_IMG_REGEX = /^(https?|data:image|blob):/i;\r\nconst SAFE_LINK_REGEX = /^(https?|mailto|tel):/i;\r\nconst MEMORY_LINK_FILTER_REGEX = /memory|mimi/i;\r\nconst MEMORY_URL_FILTER_REGEX = /mimi\\.akropolys/i;\r\n\r\nconst normalizeSpacing = (text: string): string => {\r\n if (!text) return text;\r\n return text\r\n .replace(SPACING_DOUBLE_REGEX, ' ')\r\n .replace(SPACING_PUNCT_REGEX, '$1')\r\n .replace(SPACING_OPEN_PAREN_REGEX, '(')\r\n .replace(SPACING_CLOSE_PAREN_REGEX, ')')\r\n .replace(SPACING_UNIT_REGEX, '$1 $2');\r\n};\r\n\r\nconst parseInline = (text: string, keyPrefix: string): React.ReactNode => {\r\n const normalizedText = normalizeSpacing(text);\r\n const parts = normalizedText.split(TOKEN_SPLIT_REGEX);\r\n\r\n return parts.map((part, index) => {\r\n if (!part) return null;\r\n const key = `${keyPrefix}-inline-${index}`;\r\n\r\n if (part.startsWith('`') && part.endsWith('`')) {\r\n return (\r\n <code key={key} className=\"hsk-markdown-code\">\r\n {part.slice(1, -1)}\r\n </code>\r\n );\r\n }\r\n\r\n if (part.startsWith('**') && part.endsWith('**')) {\r\n return <strong key={key}>{parseInline(part.slice(2, -2), key)}</strong>;\r\n }\r\n\r\n const imageMatch = part.match(IMAGE_PARSE_REGEX);\r\n if (imageMatch) {\r\n const alt = imageMatch[1];\r\n const url = imageMatch[2];\r\n const isSafeUrl = SAFE_IMG_REGEX.test(url) || url.startsWith('/');\r\n if (isSafeUrl) {\r\n return (\r\n <img\r\n key={key}\r\n src={url}\r\n alt={alt || 'Product image'}\r\n className=\"hsk-markdown-img\"\r\n loading=\"lazy\"\r\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\r\n />\r\n );\r\n }\r\n return null;\r\n }\r\n\r\n const linkMatch = part.match(LINK_PARSE_REGEX);\r\n if (linkMatch) {\r\n const linkText = linkMatch[1];\r\n const url = linkMatch[2];\r\n if (MEMORY_LINK_FILTER_REGEX.test(linkText) || MEMORY_URL_FILTER_REGEX.test(url)) {\r\n return null;\r\n }\r\n const isSafeUrl = SAFE_LINK_REGEX.test(url) || url.startsWith('/');\r\n if (isSafeUrl) {\r\n return (\r\n <a key={key} href={url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"hsk-markdown-link\">\r\n {parseInline(linkText, key)}\r\n </a>\r\n );\r\n }\r\n return <span key={key}>{parseInline(linkText, key)}</span>;\r\n }\r\n\r\n return part;\r\n });\r\n};\r\n\r\nfunction isTableLine(line: string, inTable: boolean): boolean {\r\n const t = line.trim();\r\n if (inTable) return t.includes('|');\r\n return t.startsWith('|');\r\n}\r\n\r\nfunction splitTableCells(rowLine: string): string[] {\r\n let t = rowLine.trim();\r\n if (t.startsWith('|')) t = t.slice(1);\r\n if (t.endsWith('|')) t = t.slice(0, -1);\r\n return t.split('|').map(c => c.trim());\r\n}\r\n\r\nexport function TableWrapper({ children }: { children: React.ReactNode }) {\r\n const ref = React.useRef<HTMLDivElement>(null);\r\n const [scrollState, setScrollState] = React.useState<'left' | 'middle' | 'right' | 'none'>('none');\r\n const [isDragging, setIsDragging] = React.useState(false);\r\n const dragRef = React.useRef({ startX: 0, scrollLeft: 0, isDown: false, hasMoved: false });\r\n\r\n const checkScroll = React.useCallback(() => {\r\n const el = ref.current;\r\n if (!el) return;\r\n const canScroll = el.scrollWidth > el.clientWidth + 2;\r\n if (!canScroll) {\r\n setScrollState('none');\r\n return;\r\n }\r\n const rtl = getComputedStyle(el).direction === 'rtl';\r\n const travelled = Math.abs(el.scrollLeft);\r\n const atStart = travelled <= 4;\r\n const atEnd = travelled + el.clientWidth >= el.scrollWidth - 4;\r\n if (atStart) setScrollState(rtl ? 'right' : 'left');\r\n else if (atEnd) setScrollState(rtl ? 'left' : 'right');\r\n else setScrollState('middle');\r\n }, []);\r\n\r\n React.useEffect(() => {\r\n checkScroll();\r\n const el = ref.current;\r\n if (!el) return;\r\n const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(checkScroll) : null;\r\n ro?.observe(el);\r\n return () => ro?.disconnect();\r\n }, [checkScroll]);\r\n\r\n const onMouseDown = (e: React.MouseEvent) => {\r\n const el = ref.current;\r\n if (!el || el.scrollWidth <= el.clientWidth) return;\r\n if ((e.target as HTMLElement).closest('a, button, input')) return;\r\n dragRef.current = { startX: e.pageX - el.offsetLeft, scrollLeft: el.scrollLeft, isDown: true, hasMoved: false };\r\n setIsDragging(true);\r\n };\r\n\r\n const onMouseMove = (e: React.MouseEvent) => {\r\n if (!dragRef.current.isDown) return;\r\n const el = ref.current;\r\n if (!el) return;\r\n const x = e.pageX - el.offsetLeft;\r\n const walk = (x - dragRef.current.startX) * 1.5;\r\n if (Math.abs(walk) > 3) {\r\n dragRef.current.hasMoved = true;\r\n e.preventDefault();\r\n el.scrollLeft = dragRef.current.scrollLeft - walk;\r\n }\r\n };\r\n\r\n const onMouseUp = () => {\r\n dragRef.current.isDown = false;\r\n setIsDragging(false);\r\n };\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n className={`hsk-table-wrapper hsk-table-wrapper--${scrollState}${isDragging ? ' is-dragging' : ''}`}\r\n onScroll={checkScroll}\r\n onMouseDown={onMouseDown}\r\n onMouseMove={onMouseMove}\r\n onMouseUp={onMouseUp}\r\n onMouseLeave={onMouseUp}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function renderMarkdown(content: string, streaming = false): React.ReactNode {\r\n return buildMarkdown(content, streaming);\r\n}\r\n\r\nfunction buildMarkdown(content: string, streaming: boolean): React.ReactNode {\r\n const lines = content.split('\\n');\r\n if (streaming && lines.length > 0) {\r\n const last = lines[lines.length - 1];\r\n if (last.trim().startsWith('|') && !last.trim().endsWith('|')) {\r\n lines.pop();\r\n }\r\n }\r\n\r\n const blocks: React.ReactNode[] = [];\r\n let currentTextNodes: React.ReactNode[] = [];\r\n let bubbleIndex = 0;\r\n\r\n const flushTextBubble = () => {\r\n if (currentTextNodes.length > 0) {\r\n blocks.push(\r\n <div key={`text-bubble-${bubbleIndex++}`} className=\"hsk-cb-ai-text\">\r\n {currentTextNodes}\r\n </div>\r\n );\r\n currentTextNodes = [];\r\n }\r\n };\r\n\r\n let i = 0;\r\n while (i < lines.length) {\r\n const line = lines[i];\r\n const key = `md-line-${i}`;\r\n\r\n if (!line.trim()) {\r\n i++;\r\n continue;\r\n }\r\n\r\n const standaloneImageMatch = line.trim().match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\r\n if (standaloneImageMatch) {\r\n flushTextBubble();\r\n const alt = standaloneImageMatch[1];\r\n const url = standaloneImageMatch[2];\r\n const isSafeUrl = /^(https?|data:image|blob):/i.test(url) || url.startsWith('/');\r\n if (isSafeUrl) {\r\n blocks.push(\r\n <div key={key} className=\"hsk-markdown-img-block\">\r\n <img\r\n src={url}\r\n alt={alt || 'Product image'}\r\n className=\"hsk-markdown-img\"\r\n loading=\"lazy\"\r\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\r\n />\r\n </div>\r\n );\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n const headerMatch = line.match(/^(#{1,3})\\s+(.*)/);\r\n if (headerMatch) {\r\n const level = headerMatch[1].length;\r\n const Tag = `h${level + 3}` as keyof JSX.IntrinsicElements; // Maps # to h4, ## to h5 to avoid messing up host page hierarchy\r\n currentTextNodes.push(<Tag key={key} className={`hsk-markdown-h${level}`}>{parseInline(headerMatch[2], key)}</Tag>);\r\n i++;\r\n continue;\r\n }\r\n\r\n if (line.match(/^[\\s]*[-*+•]\\s+/)) {\r\n const listItems: React.ReactNode[] = [];\r\n while (i < lines.length && lines[i].match(/^[\\s]*[-*+•]\\s+/)) {\r\n const itemText = lines[i].replace(/^[\\s]*[-*+•]\\s+/, '');\r\n listItems.push(<li key={`li-${i}`}>{parseInline(itemText, `li-${i}`)}</li>);\r\n i++;\r\n }\r\n currentTextNodes.push(<ul key={`ul-${key}`} className=\"hsk-markdown-list hsk-markdown-ul\">{listItems}</ul>);\r\n continue;\r\n }\r\n\r\n if (line.match(/^[\\s]*\\d+[\\.\\)]\\s+/)) {\r\n const listItems: React.ReactNode[] = [];\r\n while (i < lines.length && lines[i].match(/^[\\s]*\\d+[\\.\\)]\\s+/)) {\r\n const itemText = lines[i].replace(/^[\\s]*\\d+[\\.\\)]\\s+/, '');\r\n listItems.push(<li key={`li-${i}`}>{parseInline(itemText, `li-${i}`)}</li>);\r\n i++;\r\n }\r\n currentTextNodes.push(<ol key={`ol-${key}`} className=\"hsk-markdown-list hsk-markdown-ol\">{listItems}</ol>);\r\n continue;\r\n }\r\n\r\n if (isTableLine(line, false)) {\r\n flushTextBubble();\r\n\r\n let headerCells: string[] = [];\r\n const rawBodyRows: string[][] = [];\r\n let alignments: ('start' | 'center' | 'end')[] = [];\r\n let isHeader = true;\r\n\r\n while (i < lines.length && isTableLine(lines[i], true)) {\r\n const rowLine = lines[i].trim();\r\n if (rowLine.match(/^\\|?[-:| ]+\\|?$/) && rowLine.includes('-')) {\r\n const sepCells = splitTableCells(rowLine);\r\n alignments = sepCells.map(cell => {\r\n const trimmed = cell.trim();\r\n const startColon = trimmed.startsWith(':');\r\n const endColon = trimmed.endsWith(':');\r\n if (startColon && endColon) return 'center';\r\n if (endColon) return 'end';\r\n return 'start';\r\n });\r\n i++;\r\n isHeader = false;\r\n continue;\r\n }\r\n\r\n const cells = splitTableCells(rowLine);\r\n\r\n if (isHeader && headerCells.length === 0) {\r\n headerCells = cells;\r\n } else {\r\n rawBodyRows.push(cells);\r\n }\r\n i++;\r\n }\r\n\r\n const colCount = Math.max(headerCells.length, ...rawBodyRows.map(r => r.length));\r\n const finalAlignments: ('start' | 'center' | 'end')[] = [];\r\n for (let c = 0; c < colCount; c++) {\r\n if (alignments[c]) {\r\n finalAlignments[c] = alignments[c];\r\n } else if (c === 0) {\r\n finalAlignments[c] = 'start';\r\n } else {\r\n const numericCount = rawBodyRows.filter(r => {\r\n const val = (r[c] || '').trim();\r\n return /^[\\$€£¥+-]?\\d+([.,]\\d+)?%?$/.test(val) || /^[\\$€£¥+-]?\\d+([.,]\\d+)?\\s*(bps|M|K|B)?$/i.test(val);\r\n }).length;\r\n finalAlignments[c] = numericCount >= Math.ceil(rawBodyRows.length / 2) ? 'end' : 'start';\r\n }\r\n }\r\n\r\n const headerRow = headerCells.length > 0 ? (\r\n <tr key={`tr-head-${key}`}>\r\n {headerCells.map((cell, cIdx) => (\r\n <th\r\n key={`th-${key}-${cIdx}`}\r\n style={{ textAlign: finalAlignments[cIdx] || 'start' }}\r\n >\r\n {}\r\n <bdi>{parseInline(cell, `th-${key}-${cIdx}`)}</bdi>\r\n </th>\r\n ))}\r\n </tr>\r\n ) : null;\r\n\r\n const bodyRows = rawBodyRows.map((cells, rIdx) => (\r\n <tr key={`tr-body-${key}-${rIdx}`}>\r\n {cells.map((cell, cIdx) => (\r\n <td\r\n key={`td-${key}-${rIdx}-${cIdx}`}\r\n style={{ textAlign: finalAlignments[cIdx] || 'start' }}\r\n >\r\n <bdi>{parseInline(cell, `td-${key}-${rIdx}-${cIdx}`)}</bdi>\r\n </td>\r\n ))}\r\n </tr>\r\n ));\r\n\r\n blocks.push(\r\n <TableWrapper key={`table-wrapper-${key}`}>\r\n <table className=\"hsk-markdown-table\">\r\n {headerRow && <thead>{headerRow}</thead>}\r\n <tbody>{bodyRows}</tbody>\r\n </table>\r\n </TableWrapper>\r\n );\r\n continue;\r\n }\r\n\r\n currentTextNodes.push(\r\n <p key={key} className=\"hsk-markdown-p\">\r\n {parseInline(line, key)}\r\n </p>\r\n );\r\n i++;\r\n }\r\n\r\n flushTextBubble();\r\n\r\n return <>{blocks}</>;\r\n}\r\n","import React from 'react';\r\n\r\nexport const ArrowUpIcon = () => (\r\n <svg\r\n className=\"hsk-telegram-icon\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\r\n </svg>\r\n);\r\n\r\nexport const TelegramSendIcon = ArrowUpIcon;\r\n\r\n","import type { CSSProperties } from 'react';\r\nimport type { AkropolysTheme } from '@akropolys/sdk';\r\n\r\nexport type ThemeProp = string | AkropolysTheme | undefined;\r\n\r\nexport function resolveTheme(theme: ThemeProp): {\r\n themeAttr: string | undefined;\r\n vars: CSSProperties | undefined;\r\n} {\r\n if (typeof theme === 'string') {\r\n return { themeAttr: theme as any, vars: undefined };\r\n }\r\n if (!theme) {\r\n return { themeAttr: undefined, vars: undefined };\r\n }\r\n const vars: Record<string, string> = {};\r\n if (theme.primaryColor) vars['--hsk-primary'] = theme.primaryColor;\r\n if (theme.backgroundColor) {\r\n vars['--hsk-bg'] = theme.backgroundColor;\r\n vars['--hsk-chat-bg'] = theme.backgroundColor;\r\n }\r\n if (theme.textColor) {\r\n vars['--hsk-text'] = theme.textColor;\r\n vars['--hsk-chat-text'] = theme.textColor;\r\n }\r\n if (theme.fontFamily) vars['--hsk-font'] = theme.fontFamily;\r\n if (theme.fontSize) vars['--hsk-font-size'] = theme.fontSize;\r\n if (theme.mobileFontSize) vars['--hsk-mobile-font-size'] = theme.mobileFontSize;\r\n if (theme.borderRadius) vars['--hsk-border-radius'] = theme.borderRadius;\r\n return { themeAttr: undefined, vars: vars as CSSProperties };\r\n}\r\n","import React, { useCallback, useEffect, useRef } from 'react';\r\nimport { useVoiceSession } from '../utils/voiceSession';\r\n\r\nexport interface VoiceButtonProps {\r\n onTranscript: (text: string) => void;\r\n onInterim?: (text: string) => void;\r\n /** BCP-47 tag. Defaults to the page's <html lang>, then the browser language. */\r\n lang?: string;\r\n className?: string;\r\n disabled?: boolean;\r\n /** Raw SpeechRecognition error code — 'not-allowed', 'audio-capture', etc. */\r\n onError?: (code: string) => void;\r\n}\r\n\r\nconst MicIcon = ({ active }: { active: boolean }) => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <rect x=\"9\" y=\"2\" width=\"6\" height=\"11\" rx=\"3\" fill={active ? 'currentColor' : 'none'} />\r\n <path d=\"M5 10a7 7 0 0 0 14 0\" />\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\r\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\r\n </svg>\r\n);\r\n\r\n/**\r\n * VoiceButton — speech to text input with pause-based utterance detection.\r\n */\r\nexport function VoiceButton({\r\n onTranscript,\r\n onInterim,\r\n lang,\r\n className = '',\r\n disabled = false,\r\n onError,\r\n}: VoiceButtonProps) {\r\n const onTranscriptRef = useRef(onTranscript);\r\n useEffect(() => { onTranscriptRef.current = onTranscript; }, [onTranscript]);\r\n\r\n const stopRef = useRef<() => void>(() => {});\r\n const handleUtterance = useCallback((text: string) => {\r\n stopRef.current();\r\n onTranscriptRef.current(text);\r\n }, []);\r\n\r\n const voice = useVoiceSession({ lang, onUtterance: handleUtterance, onError });\r\n useEffect(() => { stopRef.current = voice.stop; }, [voice.stop]);\r\n\r\n useEffect(() => {\r\n if (voice.interim) onInterim?.(voice.interim);\r\n }, [voice.interim, onInterim]);\r\n\r\n if (!voice.supported) return null;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className={`kiku-voice-btn${voice.active ? ' kiku-voice-btn--active' : ''} ${className}`}\r\n onClick={() => (voice.active ? voice.stop() : void voice.start())}\r\n disabled={disabled}\r\n title={voice.active ? 'Stop listening' : 'Speak your search'}\r\n aria-label={voice.active ? 'Stop voice input' : 'Start voice input'}\r\n >\r\n <MicIcon active={voice.active} />\r\n {voice.active && <span className=\"kiku-voice-ripple\" aria-hidden=\"true\" />}\r\n </button>\r\n );\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from 'react';\r\nimport { speechLevel, duckSpeech } from './tts';\r\n\r\nexport type VoicePhase = 'idle' | 'listening' | 'thinking' | 'speaking';\r\n\r\nexport interface VoiceSessionOptions {\r\n /** BCP-47 tag for recognition. */\r\n lang?: string;\r\n\r\n onUtterance: (text: string) => void;\r\n /** Raw SpeechRecognition error code. */\r\n onError?: (code: string) => void;\r\n\r\n onBargeIn?: () => void;\r\n /** Silence, in ms, that ends an utterance. */\r\n silenceMs?: number;\r\n\r\n paused?: boolean;\r\n}\r\n\r\nconst DEFAULT_SILENCE_MS = 1100;\r\nconst SPEECH_MARGIN = 0.012;\r\nconst BARGE_IN_MS = 320;\r\nconst ECHO_REJECT = 0.09;\r\n\r\nconst DUCK_LEVEL = 0.25;\r\nconst DUCK_FADE_MS = 130;\r\nconst CONFIRM_MS = 700;\r\nconst CONFIRM_FRAMES = 12;\r\n\r\nconst MOD_WINDOW = 48; // ~0.8s of envelope history at 60fps\r\n\r\nconst W_ENERGY = 0.45;\r\nconst W_MODULATION = 0.35;\r\nconst W_BAND = 0.20;\r\nconst DUCK_SCORE = 0.55;\r\n\r\nexport function useVoiceSession({\r\n lang,\r\n onUtterance,\r\n onError,\r\n onBargeIn,\r\n silenceMs = DEFAULT_SILENCE_MS,\r\n paused = false,\r\n}: VoiceSessionOptions) {\r\n const [active, setActive] = useState(false);\r\n const [hearing, setHearing] = useState(false);\r\n const [interim, setInterim] = useState('');\r\n const [supported, setSupported] = useState(false);\r\n\r\n const recognitionRef = useRef<any>(null);\r\n const streamRef = useRef<MediaStream | null>(null);\r\n const audioCtxRef = useRef<AudioContext | null>(null);\r\n const analyserRef = useRef<AnalyserNode | null>(null);\r\n const rafRef = useRef<number | null>(null);\r\n const dataRef = useRef<Uint8Array | null>(null);\r\n\r\n const levelRef = useRef(0);\r\n const floorRef = useRef(0.008);\r\n const lastLoudRef = useRef(0);\r\n const loudSinceRef = useRef(0);\r\n const transcriptRef = useRef('');\r\n const consumedRef = useRef(0);\r\n const resultLenRef = useRef(0);\r\n const activeRef = useRef(false);\r\n const pausedRef = useRef(paused);\r\n const wantRestartRef = useRef(false);\r\n const stoppingRef = useRef(false);\r\n\r\n const onUtteranceRef = useRef(onUtterance);\r\n const onErrorRef = useRef(onError);\r\n const onBargeInRef = useRef(onBargeIn);\r\n useEffect(() => { onUtteranceRef.current = onUtterance; }, [onUtterance]);\r\n useEffect(() => { onErrorRef.current = onError; }, [onError]);\r\n useEffect(() => { onBargeInRef.current = onBargeIn; }, [onBargeIn]);\r\n useEffect(() => { pausedRef.current = paused; }, [paused]);\r\n\r\n useEffect(() => {\r\n setSupported(\r\n typeof window !== 'undefined' &&\r\n ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) &&\r\n !!navigator.mediaDevices?.getUserMedia\r\n );\r\n }, []);\r\n\r\n const micLevel = useCallback(() => levelRef.current, []);\r\n\r\n const micSpectrum = useCallback((out: Uint8Array) => {\r\n const a = analyserRef.current;\r\n if (!a || out.length !== a.frequencyBinCount) return false;\r\n a.getByteFrequencyData(out as any);\r\n return true;\r\n }, []);\r\n\r\n const spectrumBins = useCallback(() => analyserRef.current?.frequencyBinCount ?? 0, []);\r\n\r\n const envRef = useRef<number[]>([]);\r\n const freqRef = useRef<Uint8Array | null>(null);\r\n const duckedRef = useRef(false);\r\n const duckAtRef = useRef(0);\r\n const bargeEvidenceRef = useRef(0);\r\n\r\n const voiceLikeness = useCallback((rms: number): number => {\r\n const analyser = analyserRef.current;\r\n if (!analyser) return 0;\r\n\r\n const env = envRef.current;\r\n env.push(rms);\r\n if (env.length > MOD_WINDOW) env.shift();\r\n\r\n let modulation = 0;\r\n if (env.length >= 12) {\r\n let mean = 0;\r\n for (const v of env) mean += v;\r\n mean /= env.length;\r\n if (mean > 0.0001) {\r\n let variance = 0;\r\n for (const v of env) variance += (v - mean) * (v - mean);\r\n modulation = Math.min(1, Math.sqrt(variance / env.length) / mean / 0.6);\r\n }\r\n }\r\n\r\n let band = 0;\r\n if (!freqRef.current || freqRef.current.length !== analyser.frequencyBinCount) {\r\n freqRef.current = new Uint8Array(analyser.frequencyBinCount);\r\n }\r\n const freq = freqRef.current;\r\n analyser.getByteFrequencyData(freq as any);\r\n const nyquist = (audioCtxRef.current?.sampleRate ?? 48000) / 2;\r\n const per = nyquist / freq.length;\r\n const lo = Math.floor(300 / per);\r\n const hi = Math.min(freq.length - 1, Math.ceil(3400 / per));\r\n let inBand = 0, total = 0;\r\n for (let i = 0; i < freq.length; i++) {\r\n total += freq[i];\r\n if (i >= lo && i <= hi) inBand += freq[i];\r\n }\r\n if (total > 0) band = inBand / total;\r\n\r\n const energy = Math.min(1, rms / (floorRef.current + SPEECH_MARGIN * 3));\r\n return W_ENERGY * energy + W_MODULATION * modulation + W_BAND * band;\r\n }, []);\r\n\r\n const commit = useCallback(() => {\r\n const text = transcriptRef.current.trim();\r\n transcriptRef.current = '';\r\n consumedRef.current = resultLenRef.current;\r\n setInterim('');\r\n setHearing(false);\r\n if (text) {\r\n wantRestartRef.current = false;\r\n const r = recognitionRef.current;\r\n recognitionRef.current = null;\r\n try { r?.stop(); } catch { }\r\n onUtteranceRef.current(text);\r\n }\r\n }, []);\r\n\r\n const monitor = useCallback(() => {\r\n const analyser = analyserRef.current;\r\n const data = dataRef.current;\r\n if (!analyser || !data) return;\r\n\r\n analyser.getByteTimeDomainData(data as any);\r\n let sum = 0;\r\n for (let i = 0; i < data.length; i++) {\r\n const v = (data[i] - 128) / 128;\r\n sum += v * v;\r\n }\r\n const rms = Math.sqrt(sum / data.length);\r\n const lvl = Math.min(1, rms * 4);\r\n levelRef.current += (lvl - levelRef.current) * (lvl > levelRef.current ? 0.6 : 0.12);\r\n\r\n const now = Date.now();\r\n const echo = pausedRef.current ? speechLevel() * ECHO_REJECT : 0;\r\n const speech = rms > floorRef.current + SPEECH_MARGIN + echo;\r\n if (speech) {\r\n lastLoudRef.current = now;\r\n if (!loudSinceRef.current) loudSinceRef.current = now;\r\n } else {\r\n loudSinceRef.current = 0;\r\n floorRef.current = Math.min(floorRef.current * 1.02 + 0.00002, Math.max(0.004, rms));\r\n }\r\n\r\n if (pausedRef.current) {\r\n if (!duckedRef.current) {\r\n if (loudSinceRef.current && now - loudSinceRef.current > BARGE_IN_MS &&\r\n voiceLikeness(rms) > DUCK_SCORE) {\r\n loudSinceRef.current = 0;\r\n duckedRef.current = true;\r\n duckAtRef.current = now;\r\n bargeEvidenceRef.current = 0;\r\n duckSpeech(DUCK_LEVEL, DUCK_FADE_MS);\r\n }\r\n } else {\r\n if (voiceLikeness(rms) > DUCK_SCORE) bargeEvidenceRef.current += 1;\r\n else bargeEvidenceRef.current = Math.max(0, bargeEvidenceRef.current - 2);\r\n\r\n if (bargeEvidenceRef.current >= CONFIRM_FRAMES) {\r\n duckedRef.current = false;\r\n bargeEvidenceRef.current = 0;\r\n duckSpeech(1, 0);\r\n onBargeInRef.current?.();\r\n } else if (now - duckAtRef.current > CONFIRM_MS) {\r\n duckedRef.current = false;\r\n bargeEvidenceRef.current = 0;\r\n duckSpeech(1, DUCK_FADE_MS * 2);\r\n }\r\n }\r\n } else if (transcriptRef.current.trim() && now - lastLoudRef.current > silenceMs) {\r\n commit();\r\n }\r\n\r\n rafRef.current = requestAnimationFrame(monitor);\r\n }, [commit, silenceMs, voiceLikeness]);\r\n\r\n const startRecognition = useCallback(() => {\r\n if (recognitionRef.current || !activeRef.current) return;\r\n const SR: any = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\r\n const recognition = new SR();\r\n consumedRef.current = 0;\r\n resultLenRef.current = 0;\r\n recognition.lang = lang || document.documentElement.lang || navigator.language || 'en-US';\r\n recognition.interimResults = true;\r\n recognition.maxAlternatives = 1;\r\n recognition.continuous = true;\r\n\r\n recognition.onresult = (event: any) => {\r\n let text = '';\r\n for (let i = consumedRef.current; i < event.results.length; i++) {\r\n text += event.results[i][0].transcript;\r\n }\r\n resultLenRef.current = event.results.length;\r\n text = text.trim();\r\n if (!text) return;\r\n transcriptRef.current = text;\r\n setInterim(text);\r\n setHearing(true);\r\n };\r\n\r\n recognition.onerror = (event: any) => {\r\n const code = event?.error || '';\r\n if (code === 'no-speech' || code === 'aborted') return;\r\n onErrorRef.current?.(code);\r\n };\r\n\r\n recognition.onend = () => {\r\n recognitionRef.current = null;\r\n if (activeRef.current && wantRestartRef.current) {\r\n setTimeout(() => {\r\n startRecognition();\r\n }, 120);\r\n }\r\n };\r\n\r\n recognitionRef.current = recognition;\r\n try {\r\n recognition.start();\r\n } catch (e: any) {\r\n recognitionRef.current = null;\r\n onErrorRef.current?.('failed-to-start');\r\n }\r\n }, [lang]);\r\n\r\n const stopRecognition = useCallback(() => {\r\n wantRestartRef.current = false;\r\n const r = recognitionRef.current;\r\n recognitionRef.current = null;\r\n try { r?.stop(); } catch { }\r\n }, []);\r\n\r\n const stop = useCallback(() => {\r\n activeRef.current = false;\r\n duckedRef.current = false;\r\n bargeEvidenceRef.current = 0;\r\n envRef.current = [];\r\n duckSpeech(1, 0);\r\n wantRestartRef.current = false;\r\n setActive(false);\r\n setHearing(false);\r\n setInterim('');\r\n transcriptRef.current = '';\r\n levelRef.current = 0;\r\n const r = recognitionRef.current;\r\n recognitionRef.current = null;\r\n try { r?.abort(); } catch { }\r\n if (rafRef.current !== null) { cancelAnimationFrame(rafRef.current); rafRef.current = null; }\r\n streamRef.current?.getTracks().forEach(t => t.stop());\r\n streamRef.current = null;\r\n analyserRef.current = null;\r\n audioCtxRef.current?.close().catch(() => { });\r\n audioCtxRef.current = null;\r\n }, []);\r\n\r\n const start = useCallback(async () => {\r\n if (activeRef.current || !supported) return;\r\n activeRef.current = true;\r\n setActive(true);\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n autoGainControl: true,\r\n },\r\n });\r\n streamRef.current = stream;\r\n const AC = (window as any).AudioContext || (window as any).webkitAudioContext;\r\n const ctx: AudioContext = new AC();\r\n audioCtxRef.current = ctx;\r\n const analyser = ctx.createAnalyser();\r\n analyser.fftSize = 1024;\r\n analyser.smoothingTimeConstant = 0.25;\r\n ctx.createMediaStreamSource(stream).connect(analyser);\r\n analyserRef.current = analyser;\r\n dataRef.current = new Uint8Array(analyser.fftSize);\r\n floorRef.current = 0.008;\r\n lastLoudRef.current = Date.now();\r\n rafRef.current = requestAnimationFrame(monitor);\r\n } catch (e: any) {\r\n activeRef.current = false;\r\n setActive(false);\r\n onErrorRef.current?.(e?.name === 'NotAllowedError' ? 'not-allowed' : 'audio-capture');\r\n return;\r\n }\r\n wantRestartRef.current = true;\r\n startRecognition();\r\n }, [supported, monitor, startRecognition]);\r\n\r\n useEffect(() => {\r\n if (!active) return;\r\n if (paused) {\r\n transcriptRef.current = '';\r\n setInterim('');\r\n duckedRef.current = false;\r\n bargeEvidenceRef.current = 0;\r\n envRef.current = [];\r\n stopRecognition();\r\n } else {\r\n duckedRef.current = false;\r\n lastLoudRef.current = Date.now();\r\n wantRestartRef.current = true;\r\n startRecognition();\r\n }\r\n }, [paused, active, startRecognition, stopRecognition]);\r\n\r\n useEffect(() => {\r\n if (!active || paused) return;\r\n const id = setInterval(() => {\r\n const alive = !!recognitionRef.current;\r\n const hearingSomething = levelRef.current > floorRef.current + SPEECH_MARGIN;\r\n if (!alive) {\r\n } else if (hearingSomething && !transcriptRef.current) {\r\n }\r\n }, 2000);\r\n return () => clearInterval(id);\r\n }, [active, paused]);\r\n\r\n useEffect(() => () => { stop(); }, [stop]);\r\n\r\n return { supported, active, hearing, interim, micLevel, micSpectrum, spectrumBins, start, stop };\r\n}\r\n","import type { SpeechResult, VoiceRefusal } from '@akropolys/sdk';\r\n\r\nexport interface SpeakOptions {\r\n\r\n client: { synthesizeSpeech: (text: string, voice?: string, language?: string, signal?: AbortSignal) => Promise<SpeechResult | null> };\r\n text: string;\r\n voice?: string;\r\n\r\n language?: string;\r\n\r\n bcp47?: string;\r\n onStart?: () => void;\r\n onEnd?: () => void;\r\n onError?: (err: any) => void;\r\n\r\n onRefused?: (reason: VoiceRefusal) => void;\r\n\r\n onSecondsLeft?: (seconds: number) => void;\r\n}\r\n\r\nlet ctx: AudioContext | null = null;\r\nlet analyser: AnalyserNode | null = null;\r\nlet duckGain: GainNode | null = null;\r\nlet timeData: Uint8Array | null = null;\r\nlet generation = 0;\r\nlet speaking = false;\r\nlet smoothed = 0;\r\nlet usingFallback = false;\r\n\r\nfunction audio(): { ctx: AudioContext; analyser: AnalyserNode } | null {\r\n if (typeof window === 'undefined') return null;\r\n const AC = (window as any).AudioContext || (window as any).webkitAudioContext;\r\n if (!AC) return null;\r\n if (!ctx) {\r\n ctx = new AC();\r\n analyser = ctx!.createAnalyser();\r\n analyser.fftSize = 1024;\r\n analyser.smoothingTimeConstant = 0.25;\r\n duckGain = ctx!.createGain();\r\n duckGain.gain.value = 1;\r\n analyser.connect(duckGain);\r\n duckGain.connect(ctx!.destination);\r\n timeData = new Uint8Array(analyser.fftSize);\r\n }\r\n return { ctx: ctx!, analyser: analyser! };\r\n}\r\n\r\nexport function duckSpeech(level: number, fadeMs = 130): void {\r\n const g = duckGain;\r\n if (!g || !ctx) return;\r\n const now = ctx.currentTime;\r\n g.gain.cancelScheduledValues(now);\r\n g.gain.setValueAtTime(g.gain.value, now);\r\n g.gain.linearRampToValueAtTime(Math.max(0, Math.min(1, level)), now + fadeMs / 1000);\r\n}\r\n\r\nexport function speechLevel(): number {\r\n if (!speaking) {\r\n smoothed *= 0.85;\r\n return smoothed;\r\n }\r\n if (usingFallback || !analyser || !timeData) {\r\n const t = Date.now() / 1000;\r\n return 0.35 + 0.18 * Math.sin(t * 7.1) + 0.1 * Math.sin(t * 3.3);\r\n }\r\n analyser.getByteTimeDomainData(timeData as any);\r\n let sum = 0;\r\n for (let i = 0; i < timeData.length; i++) {\r\n const v = (timeData[i] - 128) / 128;\r\n sum += v * v;\r\n }\r\n const rms = Math.sqrt(sum / timeData.length);\r\n const level = Math.min(1, rms * 3.2);\r\n smoothed += (level - smoothed) * (level > smoothed ? 0.6 : 0.12);\r\n return smoothed;\r\n}\r\n\r\nexport function speechSpectrum(out: Uint8Array): boolean {\r\n if (!speaking || usingFallback || !analyser) return false;\r\n if (out.length !== analyser.frequencyBinCount) return false;\r\n analyser.getByteFrequencyData(out as any);\r\n return true;\r\n}\r\n\r\nexport function spectrumBins(): number {\r\n return analyser ? analyser.frequencyBinCount : 0;\r\n}\r\n\r\nexport function isSpeaking(): boolean {\r\n return speaking;\r\n}\r\n\r\nexport function stopSpeech() {\r\n generation++;\r\n speaking = false;\r\n if (duckGain && ctx) {\r\n duckGain.gain.cancelScheduledValues(ctx.currentTime);\r\n duckGain.gain.value = 1;\r\n }\r\n if (typeof window !== 'undefined' && 'speechSynthesis' in window) {\r\n try { window.speechSynthesis.cancel(); } catch { }\r\n }\r\n}\r\n\r\nexport function cleanTextForSpeech(text: string): string {\r\n return text\r\n .replace(/```[\\s\\S]*?```/g, ' ')\r\n .replace(/`([^`]+)`/g, '$1')\r\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, ' ')\r\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\r\n .replace(/https?:\\/\\/\\S+/g, ' ')\r\n .replace(/^\\s{0,3}#{1,6}\\s+/gm, '')\r\n .replace(/^\\s*[-*+]\\s+/gm, '')\r\n .replace(/[*_~>|]/g, '')\r\n .replace(/\\s*\\n\\s*\\n\\s*/g, '. ')\r\n .replace(/\\s*\\n\\s*/g, ' ')\r\n .replace(/\\s+/g, ' ')\r\n .replace(/\\s+([.,!?;:])/g, '$1')\r\n .trim();\r\n}\r\n\r\nconst SENTENCE_END = /([.!?…。!?؟۔।]+[\"'”’)\\]]*\\s+)/;\r\nconst CHUNK_TARGET = 240;\r\n\r\nexport function chunkForSpeech(text: string, target = CHUNK_TARGET): string[] {\r\n const pieces = text.split(SENTENCE_END).filter(Boolean);\r\n const chunks: string[] = [];\r\n let buf = '';\r\n for (const piece of pieces) {\r\n if (buf && (buf + piece).length > target) {\r\n chunks.push(buf.trim());\r\n buf = '';\r\n }\r\n buf += piece;\r\n while (buf.length > target * 2) {\r\n const cut = buf.lastIndexOf(' ', target * 2);\r\n chunks.push(buf.slice(0, cut > target ? cut : target * 2).trim());\r\n buf = buf.slice(cut > target ? cut : target * 2);\r\n }\r\n }\r\n if (buf.trim()) chunks.push(buf.trim());\r\n return chunks.filter(c => /\\S/.test(c));\r\n}\r\n\r\nfunction playBuffer(a: { ctx: AudioContext; analyser: AnalyserNode }, buf: AudioBuffer, gen: number): Promise<void> {\r\n return new Promise(resolve => {\r\n if (gen !== generation) return resolve();\r\n const src = a.ctx.createBufferSource();\r\n src.buffer = buf;\r\n src.connect(a.analyser);\r\n src.onended = () => resolve();\r\n src.start();\r\n const watchdog = setInterval(() => {\r\n if (gen !== generation) {\r\n clearInterval(watchdog);\r\n try { src.stop(); } catch { }\r\n resolve();\r\n }\r\n }, 100);\r\n src.onended = () => { clearInterval(watchdog); resolve(); };\r\n });\r\n}\r\n\r\nexport async function speak({\r\n client,\r\n text,\r\n voice,\r\n language,\r\n bcp47,\r\n onStart,\r\n onEnd,\r\n onError,\r\n onRefused,\r\n onSecondsLeft,\r\n}: SpeakOptions): Promise<void> {\r\n stopSpeech();\r\n const gen = ++generation;\r\n usingFallback = false;\r\n\r\n const clean = cleanTextForSpeech(text);\r\n if (!clean) { onEnd?.(); return; }\r\n\r\n const a = audio();\r\n if (!a) { fallbackWebSpeech(clean, bcp47, onStart, onEnd, onError); return; }\r\n if (a.ctx.state === 'suspended') { try { await a.ctx.resume(); } catch { } }\r\n\r\n const chunks = chunkForSpeech(clean);\r\n const synth = (t: string) => client.synthesizeSpeech(t, voice, language).catch(() => null);\r\n\r\n let started = false;\r\n let pending = synth(chunks[0]);\r\n\r\n for (let i = 0; i < chunks.length; i++) {\r\n if (gen !== generation) break;\r\n const result = await pending;\r\n pending = i + 1 < chunks.length ? synth(chunks[i + 1]) : Promise.resolve(null);\r\n\r\n if (result && 'refused' in result && result.refused) {\r\n onRefused?.(result.refused);\r\n onEnd?.();\r\n return;\r\n }\r\n if (!result) {\r\n if (!started) {\r\n fallbackWebSpeech(chunks.slice(i).join(' '), bcp47, onStart, onEnd, onError);\r\n return;\r\n }\r\n continue;\r\n }\r\n if (result.secondsLeft !== undefined) onSecondsLeft?.(result.secondsLeft);\r\n if (gen !== generation) break;\r\n\r\n let decoded: AudioBuffer;\r\n try {\r\n decoded = await a.ctx.decodeAudioData(result.audio.slice(0));\r\n } catch (e) {\r\n onError?.(e);\r\n continue;\r\n }\r\n if (gen !== generation) break;\r\n\r\n if (!started) { started = true; speaking = true; onStart?.(); }\r\n await playBuffer(a, decoded, gen);\r\n }\r\n\r\n if (gen === generation) {\r\n speaking = false;\r\n onEnd?.();\r\n }\r\n}\r\n\r\nfunction pickVoice(tag: string): SpeechSynthesisVoice | undefined {\r\n const voices = window.speechSynthesis.getVoices?.() ?? [];\r\n if (!voices.length || !tag) return undefined;\r\n const want = tag.toLowerCase();\r\n const base = want.split('-')[0];\r\n const candidates = voices.filter(v => v.lang?.toLowerCase().replace('_', '-') === want);\r\n const loose = candidates.length\r\n ? candidates\r\n : voices.filter(v => v.lang?.toLowerCase().split(/[-_]/)[0] === base);\r\n if (!loose.length) return undefined;\r\n return loose.find(v => v.localService === false) ?? loose[0];\r\n}\r\n\r\nfunction fallbackWebSpeech(\r\n text: string,\r\n bcp47?: string,\r\n onStart?: () => void,\r\n onEnd?: () => void,\r\n onError?: (err: any) => void\r\n) {\r\n if (typeof window === 'undefined' || !('speechSynthesis' in window)) {\r\n onError?.('speech-unavailable');\r\n onEnd?.();\r\n return;\r\n }\r\n const gen = generation;\r\n usingFallback = true;\r\n try {\r\n window.speechSynthesis.cancel();\r\n const utterance = new SpeechSynthesisUtterance(text);\r\n const tag = bcp47 || document.documentElement.lang || navigator.language || '';\r\n if (tag) utterance.lang = tag;\r\n const v = pickVoice(tag);\r\n if (v) utterance.voice = v;\r\n utterance.rate = 1.0;\r\n utterance.pitch = 1.0;\r\n\r\n utterance.onstart = () => { speaking = true; onStart?.(); };\r\n utterance.onend = () => {\r\n if (gen !== generation) return;\r\n speaking = false;\r\n onEnd?.();\r\n };\r\n utterance.onerror = (e) => {\r\n speaking = false;\r\n onError?.(e);\r\n onEnd?.();\r\n };\r\n window.speechSynthesis.speak(utterance);\r\n } catch (e) {\r\n speaking = false;\r\n onError?.(e);\r\n onEnd?.();\r\n }\r\n}\r\n","import React, { useRef, useState } from 'react';\r\nimport { downscaleImage } from '../utils/downscaleImage';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport type { VisualSearchResponse } from '@akropolys/sdk';\r\n\r\nexport interface VisualSearchProps {\r\n /** Called with search results + the base64 preview when Gemini responds. */\r\n onResults: (res: VisualSearchResponse, previewBase64: string) => void;\r\n onError?: (err: Error) => void;\r\n /**\r\n * Category hint sent to Gemini to sharpen the match_query.\r\n * e.g. \"dress\", \"curtains\", \"sofa\", \"shoes\"\r\n */\r\n categoryHint?: string;\r\n className?: string;\r\n disabled?: boolean;\r\n}\r\n\r\nconst CameraIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"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\" />\r\n <circle cx=\"12\" cy=\"13\" r=\"4\" />\r\n </svg>\r\n);\r\n\r\nconst SpinnerIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"kiku-vs-spin\">\r\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\r\n </svg>\r\n);\r\n\r\nfunction fileToBase64(file: File): Promise<string> {\r\n return downscaleImage(file);\r\n}\r\n\r\n/**\r\n * VisualSearch — camera/image-upload button for style-match search.\r\n */\r\nexport function VisualSearch({\r\n onResults,\r\n onError,\r\n categoryHint,\r\n className = '',\r\n disabled = false,\r\n}: VisualSearchProps) {\r\n const client = useAkropolysContext();\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleFile = async (file: File) => {\r\n if (!file.type.startsWith('image/')) return;\r\n setLoading(true);\r\n try {\r\n const base64 = await fileToBase64(file);\r\n const res = await (client.api as any).searchByImage(base64, categoryHint);\r\n onResults(res as VisualSearchResponse, base64);\r\n } catch (e: any) {\r\n onError?.(e instanceof Error ? e : new Error(String(e)));\r\n } finally {\r\n setLoading(false);\r\n if (inputRef.current) inputRef.current.value = '';\r\n }\r\n };\r\n\r\n return (\r\n <label\r\n className={`kiku-vs-btn${loading ? ' kiku-vs-btn--loading' : ''} ${className}`}\r\n title=\"Search by photo\"\r\n aria-label=\"Search by uploading a photo\"\r\n style={{ cursor: disabled || loading ? 'not-allowed' : 'pointer' }}\r\n >\r\n <input\r\n ref={inputRef}\r\n type=\"file\"\r\n accept=\"image/*\"\r\n capture=\"environment\"\r\n onChange={e => e.target.files?.[0] && handleFile(e.target.files[0])}\r\n disabled={disabled || loading}\r\n hidden\r\n />\r\n {loading ? <SpinnerIcon /> : <CameraIcon />}\r\n </label>\r\n );\r\n}\r\n","const MAX_EDGE = 1536;\r\nconst QUALITY = 0.85;\r\n\r\nconst SKIP_UNDER_BYTES = 300 * 1024;\r\n\r\nfunction approxBytesOfDataURL(dataURL: string): number {\r\n const i = dataURL.indexOf(',');\r\n const b64 = i === -1 ? dataURL : dataURL.slice(i + 1);\r\n return Math.floor(b64.length * 0.75);\r\n}\r\n\r\nexport async function downscaleImage(file: File): Promise<string> {\r\n const original = await new Promise<string>((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onload = () => resolve(reader.result as string);\r\n reader.onerror = () => reject(reader.error ?? new Error('read failed'));\r\n reader.readAsDataURL(file);\r\n });\r\n\r\n if (file.type === 'image/gif' || file.type === 'image/svg+xml') return original;\r\n if (approxBytesOfDataURL(original) <= SKIP_UNDER_BYTES) return original;\r\n\r\n try {\r\n const bitmap = await createImageBitmap(file);\r\n try {\r\n const scale = Math.min(1, MAX_EDGE / Math.max(bitmap.width, bitmap.height));\r\n const w = Math.max(1, Math.round(bitmap.width * scale));\r\n const h = Math.max(1, Math.round(bitmap.height * scale));\r\n\r\n const canvas = document.createElement('canvas');\r\n canvas.width = w;\r\n canvas.height = h;\r\n const cx = canvas.getContext('2d');\r\n if (!cx) return original;\r\n cx.drawImage(bitmap, 0, 0, w, h);\r\n\r\n const keepPNG = file.type === 'image/png';\r\n const out = canvas.toDataURL(keepPNG ? 'image/png' : 'image/jpeg', QUALITY);\r\n\r\n return approxBytesOfDataURL(out) < approxBytesOfDataURL(original) ? out : original;\r\n } finally {\r\n bitmap.close?.();\r\n }\r\n } catch {\r\n return original;\r\n }\r\n}\r\n","'use client';\r\n\r\nimport React, { useState, useEffect, useCallback } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { getShadowContainer } from '../utils/shadowRoot';\r\nimport type { AkropolysTheme, ChatSource } from '@akropolys/sdk';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport { cn } from '../utils/cn';\r\nimport { resolveTheme } from '../utils/theme';\r\nimport { warmChrome } from '../utils/chromeWarm';\r\nimport { useHostFontFace } from '../utils/hostFont';\r\nimport { DEFAULT_CHIPS, DEFAULT_UI_STRINGS } from './ChatModal/types';\r\nimport { ChatModal } from './ChatModal';\r\n\r\nexport interface KikuButtonProps {\r\n label?: React.ReactNode;\r\n children?: React.ReactNode;\r\n icon?: React.ReactNode;\r\n title?: string;\r\n placeholder?: string;\r\n backdropColor?: string;\r\n backdropBlur?: string | number;\r\n className?: string;\r\n onSelectSource?: (source: ChatSource) => void;\r\n defaultCurrency?: string;\r\n chips?: string[];\r\n theme?: 'light' | 'dark' | AkropolysTheme;\r\n classNames?: {\r\n button?: string;\r\n overlay?: string;\r\n panel?: string;\r\n input?: string;\r\n sendButton?: string;\r\n };\r\n\r\n enableVoice?: boolean;\r\n\r\n voiceLang?: string;\r\n\r\n enableVision?: boolean;\r\n\r\n visionCategoryHint?: string;\r\n\r\n /** Enable 🔊 TTS voice audio responses from AI */\r\n enableAudioResponse?: boolean;\r\n\r\n ttsVoice?: string;\r\n\r\n autoSpeakResponses?: boolean;\r\n}\r\n\r\nexport function KikuButton({\r\n label = 'Ask AI',\r\n children,\r\n icon,\r\n title,\r\n placeholder,\r\n backdropColor,\r\n backdropBlur,\r\n className,\r\n onSelectSource,\r\n defaultCurrency = '$',\r\n chips = DEFAULT_CHIPS,\r\n theme,\r\n classNames = {},\r\n enableVoice = false,\r\n voiceLang,\r\n enableVision = false,\r\n visionCategoryHint,\r\n enableAudioResponse,\r\n ttsVoice,\r\n autoSpeakResponses,\r\n}: KikuButtonProps) {\r\n const client = useAkropolysContext();\r\n const [open, setOpen] = useState(false);\r\n const [mounted, setMounted] = useState(false);\r\n const [origin, setOrigin] = useState<import('./ChatModal/types').ModalOrigin | null>(null);\r\n\r\n // The open path otherwise pays for ~190KB of CSS parsing plus the ui-strings and\r\n // base-font round trips. Pulling both forward means the click only mounts React.\r\n const warmShadow = useCallback(() => {\r\n getShadowContainer();\r\n try {\r\n warmChrome(client, client?.getShopperLanguage?.() ?? '', DEFAULT_UI_STRINGS);\r\n } catch { }\r\n }, [client]);\r\n\r\n const openFrom = useCallback((el: HTMLElement) => {\r\n warmShadow();\r\n const b = el.getBoundingClientRect();\r\n const style = window.getComputedStyle(el);\r\n const br = parseFloat(style.borderRadius) || 12;\r\n const x = b.left + b.width / 2;\r\n const y = b.top + b.height / 2;\r\n const w = window.innerWidth, h = window.innerHeight;\r\n const r = Math.max(\r\n Math.hypot(x, y), Math.hypot(w - x, y),\r\n Math.hypot(x, h - y), Math.hypot(w - x, h - y),\r\n );\r\n setOrigin({\r\n x,\r\n y,\r\n r,\r\n top: b.top,\r\n left: b.left,\r\n width: b.width,\r\n height: b.height,\r\n borderRadius: br,\r\n });\r\n setOpen(true);\r\n }, [warmShadow]);\r\n\r\n useEffect(() => {\r\n setMounted(true);\r\n warmShadow(); // Eager warm immediately on mount so first click has 0ms CSS lag\r\n\r\n // backstop for the first click when it arrives without a prior hover (touch, programmatic)\r\n const ric = (window as any).requestIdleCallback;\r\n const warmId = ric ? ric(warmShadow, { timeout: 2000 }) : setTimeout(warmShadow, 300);\r\n\r\n if (typeof window !== 'undefined' && !(window as any).__akropolys_nav_patched) {\r\n (window as any).__akropolys_nav_patched = true;\r\n let lastPath = window.location.pathname;\r\n const originalPush = window.history.pushState;\r\n const originalReplace = window.history.replaceState;\r\n\r\n window.history.pushState = function(...args) {\r\n originalPush.apply(this, args);\r\n if (window.location.pathname !== lastPath) {\r\n lastPath = window.location.pathname;\r\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\r\n }\r\n };\r\n\r\n window.history.replaceState = function(...args) {\r\n originalReplace.apply(this, args);\r\n if (window.location.pathname !== lastPath) {\r\n lastPath = window.location.pathname;\r\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\r\n }\r\n };\r\n }\r\n\r\n const handleNavigation = () => {\r\n setOpen(false);\r\n };\r\n\r\n window.addEventListener('popstate', handleNavigation);\r\n window.addEventListener('akropolys:navigation', handleNavigation);\r\n\r\n return () => {\r\n const cic = (window as any).cancelIdleCallback;\r\n if (ric && cic) cic(warmId); else clearTimeout(warmId as any);\r\n window.removeEventListener('popstate', handleNavigation);\r\n window.removeEventListener('akropolys:navigation', handleNavigation);\r\n };\r\n }, [warmShadow]);\r\n\r\n const { themeAttr: hskThemeAttr, vars: customStyles } = resolveTheme(theme);\r\n useHostFontFace(theme);\r\n\r\n return (\r\n <>\r\n <button\r\n className={cn(\"hsk-cb-btn\", classNames.button, className)}\r\n onClick={e => openFrom(e.currentTarget)}\r\n onPointerEnter={warmShadow}\r\n onPointerDown={warmShadow}\r\n style={customStyles}\r\n data-hsk-theme={hskThemeAttr}\r\n aria-label=\"Open AI chat\"\r\n >\r\n {children !== undefined ? (\r\n children\r\n ) : (\r\n <>\r\n {icon ? (\r\n <span className=\"hsk-cb-btn-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n {icon}\r\n </span>\r\n ) : null}\r\n {label}\r\n </>\r\n )}\r\n </button>\r\n {open && mounted && createPortal(\r\n <ChatModal\r\n title={title}\r\n placeholder={placeholder}\r\n backdropColor={backdropColor}\r\n backdropBlur={backdropBlur}\r\n origin={origin}\r\n onClose={() => setOpen(false)}\r\n onSelectSource={onSelectSource}\r\n defaultCurrency={defaultCurrency}\r\n chips={chips}\r\n theme={theme}\r\n classNames={classNames}\r\n enableVoice={enableVoice}\r\n voiceLang={voiceLang}\r\n enableVision={enableVision}\r\n visionCategoryHint={visionCategoryHint}\r\n enableAudioResponse={enableAudioResponse}\r\n ttsVoice={ttsVoice}\r\n autoSpeakResponses={autoSpeakResponses}\r\n />,\r\n getShadowContainer() ?? document.body\r\n )}\r\n </>\r\n );\r\n}\r\n","// AUTO-GENERATED by scripts/gen-css.mjs — do not edit.\nexport default \"@property --hsk-chat-bg{syntax:'<color>';inherits:true;initial-value:#0a0a0a}@property --hsk-chat-text{syntax:'<color>';inherits:true;initial-value:#f0efed}@property --hsk-chat-muted{syntax:'<color>';inherits:true;initial-value:#888888}@property --hsk-chat-divide{syntax:'<color>';inherits:true;initial-value:rgba(255,255,255,.08)}@property --hsk-chat-input-bg{syntax:'<color>';inherits:true;initial-value:#191919}@property --hsk-chat-source-bg{syntax:'<color>';inherits:true;initial-value:rgba(255,255,255,.04)}@property --hsk-fade-bg{syntax:'<color>';inherits:true;initial-value:#0a0a0a}@property --hsk-surface-1{syntax:'<color>';inherits:true;initial-value:rgba(255,255,255,.06)}@property --hsk-surface-2{syntax:'<color>';inherits:true;initial-value:#1f1f22}@property --hsk-bubble-bg{syntax:'<color>';inherits:true;initial-value:#1f1f22}@property --hsk-think-text{syntax:'<color>';inherits:true;initial-value:#a6a6a6}@property --hsk-placeholder{syntax:'<color>';inherits:true;initial-value:#555555}@property --hsk-grid-bg{syntax:'<color>';inherits:true;initial-value:#1a1a1c}@property --hsk-active-bg{syntax:'<color>';inherits:true;initial-value:#f0efed}@property --hsk-on-active{syntax:'<color>';inherits:true;initial-value:#0a0a0a}@property --hsk-src-title{syntax:'<color>';inherits:true;initial-value:#f9fafb}@property --hsk-src-desc{syntax:'<color>';inherits:true;initial-value:#9ca3af}@property --hsk-price-bg{syntax:'<color>';inherits:true;initial-value:rgba(255,255,255,.08)}@property --hsk-price-text{syntax:'<color>';inherits:true;initial-value:#ff7a45}@property --hsk-sheet-bg{syntax:'<color>';inherits:true;initial-value:#1f1f22}@property --hsk-primary{syntax:'<color>';inherits:true;initial-value:#ff6a33}:host,:root{--hsk-border-radius:0;--hsk-brand-green:#2D7A4B;--hsk-font:\\\"Geist\\\",\\\"Inter\\\",-apple-system,BlinkMacSystemFont,\\\"SF Pro Text\\\",\\\"SF Pro Display\\\",\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif;--hsk-default-font-size:15px}.hsk-cb-btn,.hsk-cb-close,.hsk-cb-topbar-btn,.hsk-cb-chip,.hsk-cb-source,.hsk-cb-sources-next,.hsk-action-pill,.hsk-chat-send,.hsk-chat-reset,.hsk-close-btn,.hsk-cb-overlay{--hsk-font-size:16px;touch-action:manipulation;-webkit-tap-highlight-color:transparent;font-family:var(--hsk-font)}.hsk-cb-overlay{transition:--hsk-chat-bg .45s cubic-bezier(.16,1,.3,1),--hsk-chat-text .45s cubic-bezier(.16,1,.3,1),--hsk-chat-muted .45s cubic-bezier(.16,1,.3,1),--hsk-chat-divide .45s cubic-bezier(.16,1,.3,1),--hsk-chat-input-bg .45s cubic-bezier(.16,1,.3,1),--hsk-surface-1 .45s cubic-bezier(.16,1,.3,1),--hsk-surface-2 .45s cubic-bezier(.16,1,.3,1),--hsk-bubble-bg .45s cubic-bezier(.16,1,.3,1),--hsk-primary .45s cubic-bezier(.16,1,.3,1),--hsk-grid-bg .45s cubic-bezier(.16,1,.3,1),--hsk-active-bg .45s cubic-bezier(.16,1,.3,1),--hsk-on-active .45s cubic-bezier(.16,1,.3,1),--hsk-src-title .45s cubic-bezier(.16,1,.3,1),--hsk-src-desc .45s cubic-bezier(.16,1,.3,1),--hsk-price-bg .45s cubic-bezier(.16,1,.3,1),--hsk-price-text .45s cubic-bezier(.16,1,.3,1),--hsk-sheet-bg .45s cubic-bezier(.16,1,.3,1),background-color .45s cubic-bezier(.16,1,.3,1),border-color .45s cubic-bezier(.16,1,.3,1),color .45s cubic-bezier(.16,1,.3,1),fill .45s cubic-bezier(.16,1,.3,1),stroke .45s cubic-bezier(.16,1,.3,1),box-shadow .45s cubic-bezier(.16,1,.3,1)}.hsk-kiku-avatar,.hsk-kiku-avatar *{transition:none}@media (prefers-reduced-motion:reduce){.hsk-cb-overlay,.hsk-cb-overlay *,.hsk-cb-overlay *::before,.hsk-cb-overlay *::after{transition:none}}.hsk-cb-overlay button,.hsk-cb-overlay [role=\\\"button\\\"],.hsk-cb-overlay input,.hsk-cb-overlay textarea,.hsk-cb-overlay select,.hsk-chat button,.hsk-chat [role=\\\"button\\\"],.hsk-chat input,.hsk-chat textarea,.hsk-chat select,.hsk-cb-btn,.hsk-search button,.hsk-search [role=\\\"button\\\"],.hsk-search input,.hsk-search textarea,.hsk-search select{touch-action:manipulation;-webkit-tap-highlight-color:transparent;font-family:var(--hsk-font)}:host,:root,.hsk-cb-btn,.hsk-cb-overlay,.hsk-chat-widget{--hsk-marble-1:color-mix(in srgb,var(--hsk-primary,#ff6a33) 12%,#fffaf4);--hsk-marble-2:color-mix(in srgb,var(--hsk-primary,#ff6a33) 30%,#fdf0e4);--hsk-marble-3:color-mix(in srgb,var(--hsk-primary,#ff6a33) 62%,#e8cbb0);--hsk-marble-4:color-mix(in srgb,var(--hsk-primary,#ff6a33) 85%,#6d3a1c);--hsk-marble-sheen:.5}@media (prefers-color-scheme:dark){:host,:root,.hsk-cb-btn,.hsk-cb-overlay,.hsk-chat-widget{--hsk-marble-1:#FFFDF6;--hsk-marble-2:#FBF3E2;--hsk-marble-3:color-mix(in srgb,var(--hsk-primary,#ff6a33) 20%,#EDDFC4);--hsk-marble-4:color-mix(in srgb,var(--hsk-primary,#ff6a33) 42%,#D8C39C);--hsk-marble-sheen:.9}}.hsk-chat-widget{--hsk-bg:var(--chat-bg-color,#ffffff);--hsk-text:var(--chat-text-color,#1f1f1f);--hsk-primary:var(--chat-primary-color,#ff6a33);--hsk-font:var(--chat-font-family,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif);--hsk-font-size:var(--chat-font-size,16px);display:flex;flex-direction:column;height:100%;min-height:320px;font-family:var(--hsk-font);letter-spacing:normal;word-spacing:normal;text-transform:none;background:var(--hsk-bg);border:1px solid #f1f3f4;border-radius:var(--hsk-border-radius,0);overflow:hidden}@media (prefers-color-scheme:dark){.hsk-chat-widget{--hsk-bg:var(--chat-bg-color,#0a0a0a);--hsk-text:var(--chat-text-color,#e8eaed);border-color:#202124}}.hsk-chat-header{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid #f1f3f4;background:var(--hsk-bg);flex-shrink:0}@media (prefers-color-scheme:dark){.hsk-chat-header{border-bottom-color:#202124}}.hsk-chat-header-icon{color:var(--hsk-primary);display:flex;align-items:center}.hsk-chat-title{font-size:14px;font-weight:600;color:var(--hsk-text)}.hsk-chat-badge{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--hsk-primary);background:rgba(255,106,51,.09);border:1px solid rgba(255,106,51,.18);padding:2px 8px;border-radius:var(--hsk-border-radius,0)}.hsk-chat-messages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px;overscroll-behavior:contain}.hsk-chat-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:8px;color:#555;font-size:13px;text-align:center;padding:24px}.hsk-chat-empty-icon{font-size:28px;margin-bottom:4px;color:var(--hsk-primary);display:flex;align-items:center;justify-content:center}.hsk-chat-empty-suggestions{font-size:12px;color:#666;margin-top:4px}.hsk-msg-row{display:flex;gap:8px;align-items:flex-start}.hsk-msg-row.user{flex-direction:row-reverse}.hsk-msg-avatar{width:28px;height:28px;border-radius:var(--hsk-border-radius,0);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700}.hsk-msg-avatar.ai{background:rgba(255,106,51,.12);border:1px solid rgba(255,106,51,.25);color:var(--hsk-primary);display:flex;align-items:center;justify-content:center}.hsk-msg-avatar.user{background:#f1f3f4;color:#5f6368}@media (prefers-color-scheme:dark){.hsk-msg-avatar.user{background:#202124;color:#888}}.hsk-msg-bubble{max-width:78%;padding:10px 14px;border-radius:var(--hsk-border-radius,0);font-size:var(--hsk-font-size,13px);line-height:1.6}.hsk-msg-bubble.ai{background:var(--hsk-bg);border:1px solid #f1f3f4;color:var(--hsk-text)}@media (prefers-color-scheme:dark){.hsk-msg-bubble.ai{border-color:#202124}}.hsk-msg-bubble.user{background:var(--hsk-primary);color:#fff}.hsk-streaming-cursor{display:inline-block;width:6px;height:1.1em;margin-inline-start:3px;vertical-align:-2px;background-color:var(--hsk-primary);animation:hsk-cursor-blink .9s infinite}@keyframes hsk-cursor-blink{0%,100%{opacity:1}50%{opacity:0}}.hsk-status-live{display:flex;align-items:center;gap:8px;font-size:12px;color:#666;padding:4px 0 8px 0;font-weight:500}.hsk-status-dot{width:8px;height:8px;border-radius:50%;background-color:var(--hsk-primary);animation:hsk-pulse 1.4s infinite ease-in-out}@keyframes hsk-pulse{0%,100%{transform:scale(.8);opacity:.5}50%{transform:scale(1.2);opacity:1}}.hsk-thinking-details{margin-bottom:10px;padding:8px 12px;background:rgba(0,0,0,.03);border:1px solid rgba(0,0,0,.06);border-radius:8px;font-size:12px}.hsk-thinking-summary{cursor:pointer;font-weight:600;color:#666;user-select:none}.hsk-thinking-text{margin-top:8px;white-space:pre-wrap;color:#555;font-family:monospace;font-size:11px;line-height:1.4;max-height:200px;overflow-y:auto}.hsk-sources-container{margin-inline-start:36px}.hsk-sources{margin-top:10px;display:flex;flex-direction:column;gap:6px}.hsk-source-card{display:flex;align-items:center;gap:10px;padding:8px 10px;background:#f8f9fa;border:1px solid #f1f3f4;border-radius:var(--hsk-border-radius,0);cursor:pointer;transition:border-color .15s}@media (prefers-color-scheme:dark){.hsk-source-card{background:#1a1a1b;border-color:#202124}}.hsk-source-card:hover{border-color:rgba(255,106,51,.37)}.hsk-source-img{width:36px;height:36px;object-fit:cover;border-radius:var(--hsk-border-radius,0);background:#fff}.hsk-source-name{font-size:12px;font-weight:500;color:var(--hsk-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hsk-source-price{font-size:11px;color:var(--hsk-primary);font-weight:700;margin-top:2px}.hsk-typing{display:flex;gap:4px;align-items:center;padding:10px 14px;background:var(--hsk-bg);border:1px solid #f1f3f4;border-radius:var(--hsk-border-radius,0);width:fit-content}@media (prefers-color-scheme:dark){.hsk-typing{border-color:#202124}}.hsk-typing-dot{width:6px;height:6px;background:var(--hsk-primary);border-radius:50%;animation:hsk-chat-bounce 1.2s infinite}.hsk-typing-dot:nth-child(2){animation-delay:.2s}.hsk-typing-dot:nth-child(3){animation-delay:.4s}@keyframes hsk-chat-bounce{0%,100%{opacity:.3;transform:translateY(0)}50%{opacity:1;transform:translateY(-4px)}}.hsk-pending{display:inline-flex;align-items:center;gap:10px;padding:10px 14px;background:var(--hsk-bg);border:1px solid #f1f3f4;border-radius:var(--hsk-border-radius,0);position:relative}@media (prefers-color-scheme:dark){.hsk-pending{border-color:#202124}}.hsk-pending-glyph{width:18px;height:18px;position:relative;display:inline-flex;align-items:center;justify-content:center}.hsk-pending-ring{width:18px;height:18px;border-radius:50%;border:2px solid rgba(255,106,51,.25);border-top-color:var(--hsk-primary);animation:hsk-pending-spin 1.1s linear infinite}.hsk-pending-dot{position:absolute;width:6px;height:6px;border-radius:50%;background:var(--hsk-primary);box-shadow:0 0 8px rgba(255,106,51,.45);animation:hsk-pending-pulse 1.4s ease-in-out infinite}.hsk-pending-text{position:relative;min-width:140px;height:16px;font-size:12px;color:var(--hsk-text);letter-spacing:.01em}.hsk-pending-step{position:absolute;left:0;top:0;opacity:0;animation:hsk-pending-cycle 6s infinite}.hsk-pending-step.step-1{animation-delay:0s}.hsk-pending-step.step-2{animation-delay:2s}.hsk-pending-step.step-3{animation-delay:4s}@keyframes hsk-pending-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes hsk-pending-pulse{0%,100%{transform:scale(.75);opacity:.6}50%{transform:scale(1);opacity:1}}@keyframes hsk-pending-cycle{0%,10%{opacity:0;transform:translateY(2px)}20%,45%{opacity:1;transform:translateY(0)}55%,100%{opacity:0;transform:translateY(-2px)}}.hsk-chat-input-area{display:flex;align-items:center;gap:8px;padding:12px 14px;border-top:1px solid #f1f3f4;background:var(--hsk-bg);flex-shrink:0}@media (prefers-color-scheme:dark){.hsk-chat-input-area{border-top-color:#202124}}.hsk-chat-input{flex:1;background:#f1f3f4;border:1px solid #f1f3f4;border-radius:var(--hsk-border-radius,0);padding:9px 14px;font-size:13px;color:var(--hsk-text);outline:none;font-family:inherit;transition:border-color .2s;resize:none;min-height:38px;max-height:120px;line-height:1.5}@media (prefers-color-scheme:dark){.hsk-chat-input{background:#1a1a1b;border-color:#202124}}.hsk-chat-input::placeholder{color:#888}.hsk-chat-input:focus{border-color:var(--hsk-primary)}.hsk-chat-send{width:34px;height:34px;border-radius:var(--hsk-border-radius,0);background:var(--hsk-primary);border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:16px;transition:opacity .15s,transform .1s}.hsk-chat-send:hover{opacity:.88}.hsk-chat-send:active{transform:scale(.93)}.hsk-chat-send:disabled{opacity:.4;cursor:not-allowed}.hsk-chat-reset{font-size:11px;color:#555;cursor:pointer;padding:0 4px;transition:color .15s;background:none;border:none;font-family:inherit}.hsk-chat-reset:hover{color:var(--hsk-primary)}.hsk-chat-error{font-size:12px;color:#ef4444;text-align:center;padding:8px}.hsk-cb-btn{--hsk-primary:var(--chat-primary-color,#ff6a33);display:inline-flex;align-items:center;gap:7px;padding:8px 16px;border-radius:var(--hsk-border-radius,0);border:1px solid rgba(255,106,51,.4);background:rgba(255,106,51,.1);color:var(--hsk-primary);font-size:13px;font-weight:600;cursor:pointer;transition:background .15s,border-color .15s,transform .16s cubic-bezier(.34,1.56,.64,1),box-shadow .15s;will-change:transform}.hsk-cb-btn:hover{background:rgba(255,106,51,.18);border-color:rgba(255,106,51,.7);box-shadow:0 4px 16px rgba(255,106,51,.2)}.hsk-cb-btn:active{transform:scale(.98)}.hsk-cb-btn-icon{font-size:15px;line-height:1;display:flex;align-items:center}.hsk-cb-overlay{--hsk-primary:var(--chat-primary-color,#ff6a33);--hsk-font:var(--chat-font-family,\\\"Geist\\\",ui-sans-serif,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif);letter-spacing:normal;word-spacing:normal;font-kerning:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--hsk-font-size:var(--hsk-desktop-font-size,15px);--hsk-mobile-font-size:14px;position:fixed !important;inset:0 !important;width:100vw !important;height:100vh !important;height:100dvh !important;z-index:2147483647 !important;display:flex !important;flex-direction:column !important;overflow:hidden !important;animation:hsk-overlay-in .2s ease-out;background:var(--hsk-chat-bg,#ffffff) !important;box-sizing:border-box !important;margin:0 !important;padding:0 !important}@keyframes hsk-overlay-in{from{opacity:0}to{opacity:1}}.hsk-cb-overlay.hsk-cb-overlay--grows{animation:hsk-overlay-in .18s cubic-bezier(.16,1,.3,1) both !important}.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-panel{transform-origin:var(--hsk-ox,50%) var(--hsk-oy,50%);animation:hsk-panel-float-in .22s cubic-bezier(.16,1,.3,1) both !important}@keyframes hsk-panel-float-in{0%{opacity:0;transform:translateY(8px) scale(.985)}100%{opacity:1;transform:translateY(0) scale(1)}}.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-msgs{animation:hsk-content-fade .2s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-content-fade{0%{opacity:0;transform:translateY(4px)}100%{opacity:1;transform:translateY(0)}}.hsk-cb-lang-chip,.hsk-cb-chip{animation:hsk-pill-wave .22s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(.04s+var(--hsk-pill-idx,0) * .012s)}.hsk-cb-lang-chips-hint{animation:hsk-content-fade .22s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(.04s+var(--hsk-pill-idx,0) * .012s)}@keyframes hsk-pill-wave{0%{opacity:0;transform:translateY(6px) scale(.96)}100%{opacity:1;transform:translateY(0) scale(1)}}.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-input-wrap{animation:hsk-input-dock .22s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-input-dock{0%{opacity:0;transform:translateY(10px)}100%{opacity:1;transform:translateY(0)}}.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-hello-avatar{animation:hsk-avatar-spring .22s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-avatar-spring{0%{opacity:0;transform:scale(.92)}100%{opacity:1;transform:scale(1)}}.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-hello-wrap{animation:hsk-hello-spring .2s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-hello-spring{0%{opacity:0;transform:translateY(6px)}100%{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){.hsk-cb-overlay.hsk-cb-overlay--grows{animation:none !important;-webkit-clip-path:none !important;clip-path:none !important}.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-panel,.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-msgs,.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-lang-chip,.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-chip,.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-input-wrap,.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-hello-avatar,.hsk-cb-overlay.hsk-cb-overlay--grows .hsk-cb-hello-wrap{animation:none !important}}.hsk-cb-panel{position:relative;display:flex;flex-direction:column;height:100%;max-width:720px;width:100%;margin:0 auto;animation:hsk-panel-in .28s cubic-bezier(.34,1.2,.64,1)}.hsk-cb-main{flex:1;min-width:0;display:flex;flex-direction:column;height:100%;overflow:hidden}@keyframes hsk-panel-in{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:translateY(0)}}.hsk-cb-topbar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:14px var(--hsk-gutter,24px) 10px;flex-shrink:0;position:relative;z-index:10;background:transparent !important;backdrop-filter:none !important;-webkit-backdrop-filter:none !important}.hsk-cb-topbar::after{display:none !important}.hsk-cb-topbar-left{display:flex;align-items:center;gap:10px;justify-self:start;min-width:0}.hsk-cb-topbar-mark{justify-self:center;display:flex;flex-direction:column;align-items:center;line-height:0;cursor:pointer;user-select:none;touch-action:manipulation;transition:transform .22s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-topbar-mark:hover{transform:translateY(-1px)}.hsk-cb-topbar-mark[data-unread=\\\"true\\\"] .hsk-cb-topbar-name{background:var(--hsk-primary,#ff6a33);color:#fff;box-shadow:0 0 0 3px var(--hsk-chat-bg,#ffffff);animation:hsk-unread-pill .9s cubic-bezier(.34,1.56,.64,1) infinite}@keyframes hsk-unread-pill{0%,100%{transform:scale(1,1)}38%{transform:scale(1.08,.92)}62%{transform:scale(.97,1.03)}}@media (prefers-reduced-motion:reduce){.hsk-cb-topbar-mark[data-unread=\\\"true\\\"] .hsk-cb-topbar-name{animation:none}}.hsk-cb-topbar-name{margin-top:-5px;padding:3px 13px;white-space:nowrap;border-radius:999px;background:var(--hsk-surface-2);box-shadow:0 0 0 3px var(--hsk-chat-bg),0 1px 3px rgba(0,0,0,.12);font-size:12px;font-weight:700;line-height:18px;letter-spacing:-.01em;color:var(--hsk-name-text,var(--hsk-chat-text));transform-origin:50% 0;transition:transform .18s cubic-bezier(.34,1.8,.64,1)}.hsk-cb-topbar-mark{position:relative;z-index:100}.hsk-cb-topbar-ooze-menu{position:absolute;top:calc(100%+12px) !important;left:50%;transform:translateX(-50%);width:216px !important;max-width:calc(100vw - 32px);padding:6px !important;border-radius:18px;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 68%,transparent) !important;backdrop-filter:blur(28px) saturate(190%) contrast(102%) !important;-webkit-backdrop-filter:blur(28px) saturate(190%) contrast(102%) !important;border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.35)) 35%,transparent) !important;border-top:1px solid rgba(255,255,255,.7) !important;border-bottom:1px solid color-mix(in srgb,#000 6%,transparent) !important;box-shadow:0 16px 38px -6px color-mix(in srgb,var(--hsk-chat-text,#000) 10%,transparent),0 0 0 1px rgba(255,255,255,.25) inset,0 1px 0 0 rgba(255,255,255,.5) inset !important;z-index:1000;animation:hsk-topbar-ooze .25s cubic-bezier(.16,1,.3,1) both}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-2x2-grid{display:grid !important;grid-template-columns:repeat(2,1fr) !important;gap:4px !important;width:100% !important;box-shadow:none !important;margin-top:6px !important;padding:0 !important;background:transparent !important}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-grid-item{width:100%;height:30px;display:inline-flex;align-items:center;justify-content:flex-start;gap:6px;padding:6px 10px;border-radius:12px;border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.4)) 25%,transparent) !important;border-top:1px solid rgba(255,255,255,.6) !important;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 62%,transparent) !important;backdrop-filter:blur(14px) !important;-webkit-backdrop-filter:blur(14px) !important;color:var(--hsk-chat-muted,#71717a);font-size:11px;font-weight:550;box-sizing:border-box;white-space:nowrap;box-shadow:0 1px 3px rgba(0,0,0,.04),0 1px 0 0 rgba(255,255,255,.35) inset !important;cursor:pointer;transition:all .16s cubic-bezier(.16,1,.3,1)}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-grid-item:hover{background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 80%,transparent) !important;color:var(--hsk-chat-text,currentColor) !important;transform:translateY(-1px)}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-grid-item.is-active{background:var(--hsk-primary,#ff6a33) !important;color:#ffffff !important;border-color:var(--hsk-primary,#ff6a33) !important;box-shadow:0 3px 12px color-mix(in srgb,var(--hsk-primary,#ff6a33) 35%,transparent),0 1px 0 0 rgba(255,255,255,.4) inset !important}@keyframes hsk-topbar-ooze{0%{opacity:0;transform:translateX(-50%) translateY(-6px) scale(.94)}100%{opacity:1;transform:translateX(-50%) translateY(0) scale(1)}}.hsk-cb-topbar-mark[data-impacting=\\\"true\\\"] .hsk-cb-topbar-name{transform:translateY(1.5px) scale(1.09,.91);box-shadow:0 0 0 3px var(--hsk-chat-bg,#ffffff),0 2px 10px var(--hsk-contact-glow,rgba(19,78,61,.45))}.hsk-cb-back{width:34px;height:34px;border-radius:999px;border:none;padding:0;display:flex;align-items:center;justify-content:center;background:var(--hsk-surface-1);color:var(--hsk-chat-muted);cursor:pointer;transition:transform .18s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-back:hover{background:var(--hsk-chat-divide,rgba(0,0,0,.09))}.hsk-cb-back:active{transform:scale(.94)}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-back-icon{display:inline-flex;transform:scaleX(-1)}.hsk-cb-topbar-actions{justify-self:end}.hsk-cb-topbar-title{font-size:16px;font-weight:500;color:var(--hsk-chat-text,#1f1f1f);letter-spacing:-.01em}.hsk-cb-topbar-sub{font-size:12px;color:var(--hsk-chat-muted,#5f6368);margin-top:2px}.hsk-cb-kiku-id-rail{display:none}@media (min-width:900px){.hsk-cb-kiku-id-rail.hsk-cb-kiku-id-rail--left{display:flex;position:absolute;left:auto !important;right:100% !important;margin-right:28px !important;transform:none !important;top:auto !important;bottom:48px !important;flex-direction:column;justify-content:flex-end;align-items:flex-start;gap:8px;width:200px;max-width:200px;min-width:200px;padding:0;border:0;background:none;font-family:inherit;z-index:10}.hsk-cb-kiku-id-rail.hsk-cb-kiku-id-rail--right{display:flex;position:absolute;left:100% !important;right:auto !important;margin-left:28px !important;transform:none !important;top:auto !important;bottom:48px !important;flex-direction:column;justify-content:flex-end;align-items:flex-start;gap:8px;width:200px;max-width:200px;min-width:200px;padding:0;border:0;background:none;font-family:inherit;z-index:10}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-kiku-id-rail{bottom:50px !important}.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-kiku-id-rail{bottom:58px !important}.hsk-cb-kiku-id-pill{display:inline-flex;align-items:center;gap:6px;max-width:100%;height:28px;padding:0 11px;border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 62%,transparent);backdrop-filter:blur(22px) saturate(180%);-webkit-backdrop-filter:blur(22px) saturate(180%);border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.35)) 30%,transparent) !important;border-top:1px solid rgba(255,255,255,.6) !important;border-bottom:1px solid color-mix(in srgb,#000 6%,transparent) !important;box-shadow:0 4px 14px -2px color-mix(in srgb,var(--hsk-chat-text,#000) 6%,transparent),0 1px 0 0 rgba(255,255,255,.4) inset;color:var(--hsk-chat-muted,#71717a);cursor:pointer;font-family:inherit;transition:all .22s cubic-bezier(.16,1,.3,1)}.hsk-cb-kiku-id-pill:hover{color:var(--hsk-primary,#ff6a33);background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 80%,transparent);border-top-color:rgba(255,255,255,.75) !important;transform:translateY(-1px);box-shadow:0 6px 18px -2px color-mix(in srgb,var(--hsk-chat-text,#000) 9%,transparent),0 1px 0 0 rgba(255,255,255,.55) inset}.hsk-cb-kiku-id-rail-val{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;letter-spacing:-.01em;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hsk-cb-kiku-id-pill svg{flex:none;opacity:.8}.hsk-cb-theme-squircle-wrap{position:relative;display:flex;flex-direction:column;align-items:flex-start;padding:0;margin:0;border:none !important;box-shadow:none !important;background:transparent !important}.hsk-cb-theme-squircle-trigger{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 12px;border-radius:16px;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 65%,transparent) !important;backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.35)) 30%,transparent) !important;border-top:1px solid rgba(255,255,255,.6) !important;border-bottom:1px solid color-mix(in srgb,#000 6%,transparent) !important;box-shadow:0 4px 16px -2px color-mix(in srgb,var(--hsk-chat-text,#000) 6%,transparent),0 1px 0 0 rgba(255,255,255,.4) inset !important;color:var(--hsk-chat-text) !important;font-size:11.5px;font-weight:600;cursor:pointer;font-family:inherit;transition:all .2s cubic-bezier(.16,1,.3,1)}.hsk-cb-theme-squircle-trigger:hover{background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 80%,transparent) !important;color:var(--hsk-primary,#ff6a33) !important;border-top-color:rgba(255,255,255,.8) !important;transform:translateY(-1px);box-shadow:0 6px 20px -2px color-mix(in srgb,var(--hsk-chat-text,#000) 10%,transparent),0 1px 0 0 rgba(255,255,255,.55) inset !important}.hsk-cb-theme-trigger-icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.hsk-cb-theme-trigger-icon svg{width:13px;height:13px}.hsk-cb-theme-trigger-label{letter-spacing:-0.01em}.hsk-cb-scout-rail-wrap{position:relative;display:flex;flex-direction:column;align-items:flex-start;padding:0;margin:0;border:none !important;box-shadow:none !important;background:transparent !important}.hsk-cb-scout-rail-trigger{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 12px;border-radius:16px;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 65%,transparent) !important;backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.35)) 30%,transparent) !important;border-top:1px solid rgba(255,255,255,.6) !important;border-bottom:1px solid color-mix(in srgb,#000 6%,transparent) !important;box-shadow:0 4px 16px -2px color-mix(in srgb,var(--hsk-chat-text,#000) 6%,transparent),0 1px 0 0 rgba(255,255,255,.4) inset !important;color:var(--hsk-chat-text) !important;font-size:11.5px;font-weight:600;cursor:pointer;font-family:inherit;transition:all .2s cubic-bezier(.16,1,.3,1)}.hsk-cb-scout-rail-trigger:hover{background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 80%,transparent) !important;color:var(--hsk-primary,#ff6a33) !important;border-top-color:rgba(255,255,255,.8) !important;transform:translateY(-1px);box-shadow:0 6px 20px -2px color-mix(in srgb,var(--hsk-chat-text,#000) 10%,transparent),0 1px 0 0 rgba(255,255,255,.55) inset !important}.hsk-cb-scout-rail-card{width:200px;max-width:200px;min-width:200px;box-sizing:border-box;border-radius:18px;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 70%,transparent);backdrop-filter:blur(28px) saturate(190%) contrast(102%);-webkit-backdrop-filter:blur(28px) saturate(190%) contrast(102%);border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.4)) 35%,transparent);border-top:1px solid rgba(255,255,255,.65);border-bottom:1px solid color-mix(in srgb,#000 6%,transparent);box-shadow:0 16px 38px -6px color-mix(in srgb,var(--hsk-chat-text,#000) 10%,transparent),0 0 0 1px rgba(255,255,255,.2) inset,0 1px 0 0 rgba(255,255,255,.5) inset;padding:7px;z-index:100;transform-origin:bottom center;will-change:opacity;animation:hsk-scout-card-in .26s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-scout-card-in{from{opacity:0;translate:0 6px}to{opacity:1;translate:none}}.hsk-cb-theme-2x2-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:5px;padding:6px;width:200px;max-width:200px;min-width:200px;box-sizing:border-box;border-radius:18px;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 70%,transparent);backdrop-filter:blur(28px) saturate(190%) contrast(102%);-webkit-backdrop-filter:blur(28px) saturate(190%) contrast(102%);border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.4)) 35%,transparent);border-top:1px solid rgba(255,255,255,.65);border-bottom:1px solid color-mix(in srgb,#000 6%,transparent);box-shadow:0 16px 38px -6px color-mix(in srgb,var(--hsk-chat-text,#000) 10%,transparent),0 0 0 1px rgba(255,255,255,.2) inset,0 1px 0 0 rgba(255,255,255,.5) inset;transform-origin:bottom center;animation:hsk-theme-morph-in .26s cubic-bezier(.16,1,.3,1) both}.hsk-cb-theme-squircle-wrap.is-closing .hsk-cb-theme-2x2-grid{animation:hsk-theme-morph-out .2s cubic-bezier(.4,0,.9,.4) both}.hsk-cb-theme-grid-item{display:inline-flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:6px;height:30px;padding:0 10px;border-radius:12px;border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.3)) 25%,transparent) !important;border-top:1px solid rgba(255,255,255,.45) !important;outline:none !important;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 65%,transparent);color:var(--hsk-chat-text,currentColor);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);font-size:11px;font-weight:550;cursor:pointer;font-family:inherit;transition:all .18s cubic-bezier(.16,1,.3,1);box-shadow:0 1px 3px rgba(0,0,0,.04),0 1px 0 0 rgba(255,255,255,.3) inset !important;box-sizing:border-box;white-space:nowrap}.hsk-cb-theme-grid-item svg{flex-shrink:0;width:12px;height:12px}.hsk-cb-theme-grid-item:hover{background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 85%,transparent);color:var(--hsk-chat-text,currentColor);border-top-color:rgba(255,255,255,.7) !important;transform:translateY(-1px);box-shadow:0 3px 8px rgba(0,0,0,.08),0 1px 0 0 rgba(255,255,255,.45) inset !important}.hsk-cb-theme-grid-item.is-active{background:var(--hsk-primary,#ff6a33) !important;border-color:var(--hsk-primary,#ff6a33) !important;color:#ffffff !important;box-shadow:0 2px 10px color-mix(in srgb,var(--hsk-primary,#ff6a33) 38%,transparent),0 1px 0 0 rgba(255,255,255,.4) inset !important}}@keyframes hsk-ooze-in{0%{opacity:0;transform:translateX(-50%) translateY(-16px) scale(.88);filter:blur(6px)}65%{transform:translateX(-50%) translateY(3px) scale(1.02);filter:blur(0)}100%{opacity:1;transform:translateX(-50%) translateY(0) scale(1);filter:blur(0)}}.hsk-cb-topbar-actions{display:flex;align-items:center;gap:8px}.hsk-cb-topbar-btn{height:34px;padding:0 14px;border-radius:var(--hsk-control-radius,999px);border:1px solid transparent;background:var(--hsk-chat-subtle,rgba(0,0,0,.045));color:var(--hsk-chat-muted,#5f6368);font-size:12px;font-weight:500;cursor:pointer;transition:all .15s;font-family:inherit}.hsk-cb-topbar-btn:hover{background:color-mix(in srgb,var(--hsk-primary) 12%,transparent);color:var(--hsk-primary)}.hsk-cb-close{width:34px;height:34px;border-radius:var(--hsk-control-radius,999px);border:1px solid transparent;background:var(--hsk-chat-subtle,rgba(0,0,0,.045));color:var(--hsk-chat-muted,#5f6368);cursor:pointer;font-size:20px;display:flex;align-items:center;justify-content:center;transition:all .15s;flex-shrink:0;font-family:inherit;line-height:1}.hsk-cb-close:hover{background:color-mix(in srgb,var(--hsk-primary) 12%,transparent);color:var(--hsk-primary)}.hsk-cb-squircle-btn{width:34px;height:34px;border-radius:11px;background:color-mix(in srgb,var(--hsk-surface-1,currentColor) 35%,transparent);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid color-mix(in srgb,var(--hsk-chat-border,currentColor) 16%,transparent);border-top:1px solid rgba(255,255,255,.35);border-bottom:1px solid color-mix(in srgb,#000 6%,transparent);box-shadow:0 2px 6px color-mix(in srgb,var(--hsk-chat-text,#000) 6%,transparent),0 1px 0 0 rgba(255,255,255,.25) inset;color:var(--hsk-chat-muted,currentColor);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;transition:all .18s cubic-bezier(.16,1,.3,1);position:relative;flex-shrink:0}.hsk-cb-squircle-btn:hover{background:color-mix(in srgb,var(--hsk-surface-2,currentColor) 50%,transparent);color:var(--hsk-chat-text,currentColor);border-top-color:rgba(255,255,255,.55);box-shadow:0 3px 10px color-mix(in srgb,var(--hsk-chat-text,#000) 8%,transparent),0 1px 0 0 rgba(255,255,255,.35) inset;transform:translateY(-1px)}.hsk-cb-squircle-btn:active{transform:scale(.95)}.hsk-cb-squircle-btn.is-active{background:color-mix(in srgb,var(--hsk-primary,#ff6a33) 16%,transparent);border-color:var(--hsk-primary,#ff6a33);color:var(--hsk-primary,#ff6a33);box-shadow:0 0 12px color-mix(in srgb,var(--hsk-primary,#ff6a33) 30%,transparent),0 1px 0 0 rgba(255,255,255,.3) inset}.hsk-cb-squircle-btn--dashed{border-style:dashed;border-color:color-mix(in srgb,var(--hsk-chat-text,currentColor) 28%,transparent)}.hsk-cb-squircle-btn--dashed:hover{border-color:var(--hsk-primary,#ff6a33);color:var(--hsk-primary,#ff6a33)}.hsk-cb-exit-btn:hover{background:rgba(239,68,68,.12);border-color:rgba(239,68,68,.3);border-top-color:rgba(239,68,68,.5);color:#ef4444}.hsk-cb-desktop-scout-dropdown{position:absolute;top:calc(100%+10px);right:0;width:320px;border-radius:20px;background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 65%,transparent);backdrop-filter:blur(28px) saturate(190%) contrast(102%);-webkit-backdrop-filter:blur(28px) saturate(190%) contrast(102%);border:1px solid color-mix(in srgb,var(--hsk-chat-border,rgba(255,255,255,.3)) 40%,transparent);border-top:1px solid rgba(255,255,255,.5);border-bottom:1px solid color-mix(in srgb,#000 6%,transparent);box-shadow:0 12px 34px -4px color-mix(in srgb,var(--hsk-chat-text,#000) 10%,transparent),0 0 0 1px rgba(255,255,255,.25) inset,0 1px 0 0 rgba(255,255,255,.45) inset;padding:12px;z-index:1000;animation:hsk-desktop-scout-enter .2s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-desktop-scout-enter{0%{opacity:0;transform:translateY(-8px) scale(.96)}100%{opacity:1;transform:translateY(0) scale(1)}}.hsk-cb-msgs{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;touch-action:pan-y;overscroll-behavior-y:none;overflow-anchor:none;padding:16px var(--hsk-gutter,24px) 16px;display:flex;flex-direction:column;gap:0;scrollbar-width:none;-ms-overflow-style:none;mask-image:linear-gradient(to bottom,transparent 0,#000000 8px,#000000 100%);-webkit-mask-image:linear-gradient(to bottom,transparent 0,#000000 8px,#000000 100%)}.hsk-cb-msgs>:first-child{margin-top:auto}.hsk-cb-msgs.hsk-scrolling>*{pointer-events:none}.hsk-cb-msgs::-webkit-scrollbar{display:none !important;width:0 !important;height:0 !important}.hsk-cb-empty{flex:1;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:14px;padding:24px 0 32px;width:100%;text-align:start}.hsk-cb-onboarding-card{display:flex;flex-direction:column;align-items:flex-start;width:100%;gap:10px}.hsk-cb-onboarding-head{display:flex;align-items:center;justify-content:flex-end;width:100%;margin-bottom:8px}.hsk-cb-step-badge{font-size:11px;font-weight:600;letter-spacing:.05em;color:var(--hsk-chat-muted,#71717a);background:var(--hsk-chat-source-bg,rgba(255,255,255,.06));border:1px solid var(--hsk-chat-border,rgba(255,255,255,.08));padding:4px 10px;border-radius:999px;line-height:1}.hsk-cb-hello-wrap{display:flex;flex-direction:column;align-items:flex-start;text-align:start;gap:6px;padding:0;width:100%}.hsk-cb-hello-avatar{--hsk-avatar-size:80px;display:flex;align-items:center;justify-content:flex-start;width:auto;margin-inline-start:calc(var(--hsk-avatar-size,80px) * -0.25);margin-inline-end:0;margin-top:0;margin-bottom:0;animation:hsk-avatar-spring .42s cubic-bezier(.16,1,.3,1) both}.hsk-cb-hello{margin:0;font-size:clamp(24px,4.5vw,34px);font-weight:500;line-height:1.2;letter-spacing:-0.02em;color:color-mix(in srgb,var(--hsk-chat-text,#111) 55%,var(--hsk-chat-muted,#8b8b8f));text-align:start}.hsk-cb-hello b{font-weight:700;color:var(--hsk-primary,#ff6a33)}.hsk-cb-hello-lead{margin:0;font-size:15px;line-height:22px;color:var(--hsk-chat-muted,#5f6368);max-width:42ch;text-align:start}.hsk-cb-hello-ask{margin:2px 0 2px;font-size:16px;font-weight:500;color:var(--hsk-chat-text,#111);text-align:start}.hsk-cb-step{font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--hsk-chat-muted,#9aa0a6)}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-msgs{direction:ltr}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-msgs>*{direction:rtl}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-user-imgs{margin-left:0;margin-right:auto}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-user-bubble,.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-ai-text{word-break:normal;overflow-wrap:break-word;letter-spacing:normal}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-hello{line-height:1.6;letter-spacing:normal}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-entlang-cards{justify-content:end}.hsk-cb-lang-chips{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 4px}.hsk-cb-lang-chip{display:inline-flex;align-items:center;justify-content:center;min-height:36px;padding:6px 16px;font-size:14px;font-weight:500;line-height:1;color:var(--hsk-chat-text,#111);background:var(--hsk-chat-source-bg,rgba(0,0,0,.04));border:1px solid var(--hsk-chat-border,rgba(0,0,0,.09));border-radius:999px;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.03);transition:all .18s cubic-bezier(.16,1,.3,1);user-select:none;-webkit-font-smoothing:antialiased}.hsk-cb-lang-chip:hover{background:var(--hsk-primary,#ff6a33);color:#ffffff;border-color:var(--hsk-primary,#ff6a33);transform:translateY(-1px);box-shadow:0 4px 12px color-mix(in srgb,var(--hsk-primary,#ff6a33) 25%,transparent)}.hsk-cb-lang-chip:active{transform:scale(.96)}@media (prefers-color-scheme:dark){.hsk-cb-lang-chip{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.1);color:#f4f4f5}}[data-hsk-theme=\\\"dark\\\"] .hsk-cb-lang-chip{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.1);color:#f4f4f5}.hsk-cb-lang-chips-hint{display:inline-flex;align-items:center;font-size:13px;color:var(--hsk-chat-muted,#71717a);padding:0 6px;margin-inline-start:4px;user-select:none;align-self:center}.hsk-cb-chrome-loading{display:flex;flex-direction:column;align-items:flex-start;text-align:start;gap:12px;width:100%;max-width:480px;margin:4px 0 2px;animation:hsk-content-fade .3s ease-out both}.hsk-cb-chrome-loading-header{display:flex;flex-direction:column;align-items:flex-start;text-align:start;gap:6px;width:100%}.hsk-cb-chrome-loading-sub{margin:0;font-size:15px;color:var(--hsk-chat-muted,#71717a);line-height:1.45;text-align:start}.hsk-cb-chrome-loading-sub b{color:var(--hsk-chat-text,#f4f4f5);font-weight:600}.hsk-cb-chrome-progress{height:3px;width:100%;border-radius:3px;background:var(--hsk-chat-source-bg,rgba(255,255,255,.08));overflow:hidden;margin-top:4px}.hsk-cb-chrome-progress-track{height:100%;width:100%;border-radius:3px;background:linear-gradient( 90deg,#ff6a33,#f7b733,#43c59e,#3d8bfd,#9b5de5,#ff5d8f,#ff6a33 );background-size:300% 100%;animation:hsk-chrome-rainbow 2.6s linear infinite}.hsk-cb-chrome-progress{position:relative;overflow:hidden}.hsk-cb-chrome-progress::after{content:'';position:absolute;inset:0;background:linear-gradient( 100deg,transparent 20%,rgba(255,255,255,.55) 50%,transparent 80% );transform:translateX(-100%);animation:hsk-chrome-sheen 1.9s cubic-bezier(.55,0,.45,1) infinite;pointer-events:none}@keyframes hsk-chrome-rainbow{0%{background-position:0 0}100%{background-position:-300% 0}}@keyframes hsk-chrome-sheen{0%{transform:translateX(-100%)}100%{transform:translateX(200%)}}@media (prefers-reduced-motion:reduce){.hsk-cb-chrome-progress-track{animation:none;opacity:.5}.hsk-cb-chrome-progress::after{animation:none;opacity:0}}.hsk-cb-chrome-back-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;margin-top:6px;font-size:13px;font-weight:500;color:var(--hsk-chat-muted,#a1a1aa);background:var(--hsk-chat-source-bg,rgba(255,255,255,.05));border:1px solid var(--hsk-chat-border,rgba(255,255,255,.09));border-radius:999px;cursor:pointer;transition:all .15s ease;user-select:none}.hsk-cb-chrome-back-btn:hover{background:var(--hsk-chat-source-bg,rgba(255,255,255,.12));color:var(--hsk-chat-text,#ffffff);border-color:var(--hsk-chat-border,rgba(255,255,255,.18))}.hsk-cb-chrome-notice{display:flex;flex-direction:column;gap:6px;max-width:48ch;margin:24px 0 0;padding:14px 16px;border-radius:14px;background:var(--hsk-chat-source-bg,rgba(255,255,255,.04));border:1px solid var(--hsk-chat-border,rgba(255,255,255,.09));text-align:start;font-family:var(--hsk-font,system-ui,sans-serif);animation:hsk-content-fade .4s ease-out both}.hsk-cb-chrome-notice-header{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.hsk-cb-chrome-notice-pill{display:inline-flex;align-items:center;padding:2px 7px;border-radius:6px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;background:rgba(255,106,51,.15);color:var(--hsk-primary,#ff6a33);border:1px solid rgba(255,106,51,.28)}.hsk-cb-chrome-notice-title{font-size:12px;font-weight:600;letter-spacing:.01em;color:var(--hsk-chat-text,#ffffff)}.hsk-cb-chrome-notice-body{font-size:12px;line-height:1.55;color:var(--hsk-chat-muted,#a1a1aa)}.hsk-cb-chrome-notice-body b{color:var(--hsk-chat-text,#ffffff)}@media (prefers-color-scheme:light){.hsk-cb-chrome-loading-sub b{color:var(--hsk-chat-text,#18181b)}.hsk-cb-chrome-progress{background:var(--hsk-chat-source-bg,rgba(0,0,0,.06))}.hsk-cb-chrome-back-btn{color:#52525b;background:rgba(0,0,0,.04);border-color:rgba(0,0,0,.08)}.hsk-cb-chrome-back-btn:hover{background:rgba(0,0,0,.08);color:#09090b;border-color:rgba(0,0,0,.14)}}.hsk-cb-input-box--waiting{opacity:.45;pointer-events:none}.hsk-cb-entlang-opts{display:flex;flex-direction:column;gap:10px;width:100%;max-width:440px;margin-top:6px}.hsk-cb-entlang-opt{position:relative;display:flex;flex-direction:row;align-items:center;width:100%;padding:16px 20px;text-align:start;background:transparent !important;border:none !important;outline:none !important;border-radius:16px;cursor:pointer;user-select:none;overflow:hidden;box-shadow:none !important;animation:hsk-entlang-opt-in .22s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(.04s+var(--hsk-opt-idx,0) * .02s)}@media (prefers-color-scheme:light){.hsk-cb-entlang-opt{background:transparent !important}}[data-hsk-theme=\\\"light\\\"] .hsk-cb-entlang-opt{background:transparent !important}@keyframes hsk-entlang-opt-in{0%{opacity:0;transform:translateY(6px)}100%{opacity:1;transform:translateY(0)}}.hsk-cb-entlang-opt:hover{background:transparent !important;border:none !important;box-shadow:none !important}.hsk-cb-entlang-opt:active{opacity:.8}.hsk-cb-entlang-radio{position:relative;display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;min-width:18px;min-height:18px;border-radius:999px;border:1.5px solid var(--hsk-chat-divide,rgba(255,255,255,.22));flex-shrink:0;margin-inline-end:14px;box-sizing:border-box;transform:none !important;transition:border-color .2s cubic-bezier(.16,1,.3,1),background-color .2s ease}.hsk-cb-entlang-radio-dot{width:9px;height:9px;border-radius:999px;background:var(--hsk-primary,#ff6a33);opacity:0;transition:opacity .15s ease;pointer-events:none}.hsk-cb-entlang-opt:hover .hsk-cb-entlang-radio,.hsk-cb-entlang-opt.is-selected .hsk-cb-entlang-radio{border-color:var(--hsk-primary,#ff6a33)}.hsk-cb-entlang-opt.is-selected .hsk-cb-entlang-radio-dot{opacity:1}.hsk-cb-entlang-opt-text{display:flex;flex-direction:column;gap:3px;width:100%}.hsk-cb-entlang-opt-title{font-size:15px;font-weight:600;color:var(--hsk-chat-text,#1f1f1f);letter-spacing:-0.01em}.hsk-cb-entlang-opt-note{font-size:12.5px;color:var(--hsk-chat-muted,#71717a);line-height:1.45}.hsk-cb-shimmer-char{display:inline;color:inherit;font-family:inherit}.hsk-cb-entlang-opt:hover .hsk-cb-entlang-opt-title .hsk-cb-shimmer-char{animation:hsk-entlang-char-shimmer-title .5s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--hsk-char-idx,0) * 16ms)}.hsk-cb-entlang-opt:hover .hsk-cb-entlang-opt-note .hsk-cb-shimmer-char{animation:hsk-entlang-char-shimmer-note .5s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--hsk-char-idx,0) * 16ms)}@keyframes hsk-entlang-char-shimmer-title{0%{color:var(--hsk-chat-text,#1f1f1f)}45%{color:hsl(var(--hsk-ph-hue,0) 80% 60%)}100%{color:var(--hsk-primary,#ff6a33)}}@keyframes hsk-entlang-char-shimmer-note{0%{color:var(--hsk-chat-muted,#71717a)}45%{color:hsl(var(--hsk-ph-hue,0) 75% 55%)}100%{color:var(--hsk-chat-muted,#71717a)}}.hsk-cb-entlang-opt-note{font-size:12.5px;color:var(--hsk-chat-muted,#71717a);line-height:1.45}.hsk-cb-ink-skeleton{display:flex;flex-direction:column;align-items:flex-start;width:100%;gap:12px;animation:hsk-ink-bloom-in .22s cubic-bezier(.16,1,.3,1) both}.hsk-cb-ink-line{position:relative;border-radius:999px;overflow:hidden;background:color-mix(in srgb,var(--hsk-chat-text,#ffffff) 6%,transparent)}.hsk-cb-ink-line::after{content:'';position:absolute;inset:0;background:linear-gradient( 90deg,transparent 0,color-mix(in srgb,var(--hsk-primary,#ff6a33) 12%,transparent) 35%,color-mix(in srgb,var(--hsk-chat-text,#ffffff) 14%,transparent) 50%,color-mix(in srgb,var(--hsk-primary,#ff6a33) 12%,transparent) 65%,transparent 100% );transform:translateX(-100%);animation:hsk-ink-sheen 2.2s cubic-bezier(.4,0,.2,1) infinite}.hsk-cb-ink-line--title{height:30px;width:50%;max-width:220px;border-radius:14px;margin-bottom:2px}.hsk-cb-ink-line--lead1{height:14px;width:78%;max-width:340px}.hsk-cb-ink-line--lead2{height:14px;width:60%;max-width:260px}.hsk-cb-ink-line--ask{height:15px;width:40%;max-width:170px;margin-top:3px}@keyframes hsk-ink-sheen{0%{transform:translateX(-100%)}100%{transform:translateX(200%)}}@keyframes hsk-ink-bloom-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes hsk-hello-rise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}.hsk-cb-hello,.hsk-cb-hello-lead,.hsk-cb-hello-ask,.hsk-cb-hello-skip{opacity:0;animation:hsk-hello-rise .9s cubic-bezier(.22,1,.36,1) both}.hsk-cb-hello{animation-delay:.06s}.hsk-cb-hello-lead{animation-delay:.26s}.hsk-cb-hello-ask{animation-delay:.44s}.hsk-cb-hello-skip{animation-delay:.60s}.hsk-cb-hello.hsk-cascade,.hsk-cb-hello-lead.hsk-cascade,.hsk-cb-hello-ask.hsk-cascade{opacity:1;animation:none;filter:none}.hsk-cascade__w{display:inline-block;white-space:nowrap;opacity:0;animation:hsk-cascade-rise .44s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-cascade-rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){.hsk-cb-hello,.hsk-cb-hello-lead,.hsk-cb-hello-ask,.hsk-cb-hello-skip,.hsk-cascade__w{animation:none;opacity:1;transform:none;filter:none}}.hsk-cb-chips{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-start;margin-top:4px}.hsk-cb-chip{padding:8px 16px;border-radius:var(--hsk-border-radius,0);border:1px solid var(--hsk-chat-divide,rgba(0,0,0,.1));background:var(--hsk-chat-source-bg,rgba(0,0,0,.03));color:var(--hsk-chat-text,#333);font-size:13px;cursor:pointer;transition:all .15s;font-family:inherit}.hsk-cb-chip:hover{border-color:var(--hsk-primary);color:var(--hsk-primary);background:rgba(255,106,51,.06)}.hsk-cb-msg-group{padding:16px 0;border-bottom:none;animation:hsk-msg-in .22s ease-out both}.hsk-cb-spoken-mark{position:absolute;top:50%;margin-top:-5px;inset-inline-start:-17px;opacity:.4;pointer-events:none}.hsk-cb-msg-group--run-mid{padding-bottom:0}.hsk-cb-msg-group--run-mid .hsk-cb-user-msg{margin-bottom:0}.hsk-cb-msg-group--run-cont{padding-top:2px}.hsk-cb-msg-group:last-child{border-bottom:none}@keyframes hsk-msg-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.hsk-cb-user-msg{display:flex;flex-direction:column;align-items:flex-end;align-self:flex-end;max-width:min(75%,420px);margin-inline-start:auto;margin-inline-end:0;gap:6px;margin-bottom:20px}@media (max-width:640px){.hsk-cb-user-msg{max-width:84%}}.hsk-cb-user-msg.hsk-sent{transform-origin:bottom right;animation:hsk-send-in .42s cubic-bezier(.2,.9,.3,1.2) both}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-user-msg.hsk-sent{transform-origin:bottom left}@keyframes hsk-send-in{0%{opacity:0;transform:translateY(28px) scale(.55)}55%{opacity:1}75%{transform:translateY(-2px) scale(1.02)}100%{opacity:1;transform:translateY(0) scale(1)}}@media (prefers-reduced-motion:reduce){.hsk-cb-user-msg.hsk-sent{animation:none}}.hsk-cb-user-bubble{background:var(--hsk-user-bubble-bg,#007aff);color:#ffffff;padding:10px 18px;border-radius:20px;position:relative;font-size:var(--hsk-font-size,15.5px);font-family:var(--hsk-font);line-height:1.45;max-width:100%;font-weight:500;word-break:break-word;overflow-wrap:anywhere;letter-spacing:-0.01em}.hsk-cb-user-bubble--tail::before,.hsk-cb-user-bubble--tail::after{content:'';position:absolute;bottom:0;height:25px;pointer-events:none}.hsk-cb-user-bubble--tail::before{right:-7px;width:20px;background:var(--hsk-user-bubble-bg,#007aff);border-bottom-left-radius:16px 14px}.hsk-cb-user-bubble--tail::after{right:-26px;width:26px;background:var(--hsk-chat-bg,#ffffff);border-bottom-left-radius:10px}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-user-bubble--tail::before{right:auto;left:-7px;border-bottom-left-radius:0;border-bottom-right-radius:16px 14px}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-user-bubble--tail::after{right:auto;left:-26px;border-bottom-left-radius:0;border-bottom-right-radius:10px}.hsk-cb-ai-msg{display:block}.hsk-cb-ai-icon{width:32px;height:32px;border-radius:0;background:transparent !important;border:none !important;color:var(--hsk-primary,#ff6a33);display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:-2px}.hsk-cb-ai-icon>svg{width:30px !important;height:30px !important}.hsk-cb-ai-icon>.hsk-cb-ai-mark{width:40px !important;height:40px !important}.hsk-cb-ai-body{flex:1;min-width:0}.hsk-cb-ai-content{display:flex;flex-direction:column;gap:10px;align-items:flex-start;width:100%}.hsk-cb-think+.hsk-cb-ai-content>.hsk-cb-ai-text:first-child{padding-top:20px}.hsk-cb-ai-text{font-size:var(--hsk-font-size,14.5px);font-family:var(--hsk-font);line-height:1.48;color:var(--hsk-chat-text,#111827);background:var(--hsk-chat-ai-bg,#eeeef0);padding:11px 15px;border-radius:18px;position:relative;display:inline-block;width:fit-content;box-sizing:border-box;max-width:min(88%,560px);word-break:break-word;overflow-wrap:anywhere;margin-top:4px}.hsk-cb-ai-text:not(:has(~.hsk-cb-ai-text))::before,.hsk-cb-ai-text:not(:has(~.hsk-cb-ai-text))::after{content:'';position:absolute;bottom:0;height:25px;pointer-events:none}.hsk-cb-ai-text:not(:has(~.hsk-cb-ai-text))::before{left:-7px;width:20px;background:var(--hsk-chat-ai-bg,#eeeef0);border-bottom-right-radius:16px 14px}.hsk-cb-ai-text:not(:has(~.hsk-cb-ai-text))::after{left:-26px;width:26px;background:var(--hsk-chat-bg,#ffffff);border-bottom-right-radius:10px}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-ai-text:not(:has(~.hsk-cb-ai-text))::before{left:auto;right:-7px;border-bottom-right-radius:0;border-bottom-left-radius:16px 14px}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-ai-text:not(:has(~.hsk-cb-ai-text))::after{left:auto;right:-26px;border-bottom-right-radius:0;border-bottom-left-radius:10px}.hsk-cb-user-footer{display:flex;flex-direction:row;align-items:center;justify-content:flex-end;gap:6px;width:100%;margin-top:2px;min-height:16px;line-height:1}.hsk-cb-ai-footer{display:flex;align-items:center;gap:4px;margin-top:4px;min-height:16px;line-height:1}.hsk-cb-ai-body:hover .hsk-cb-msg-actions,.hsk-cb-ai-body:focus-within .hsk-cb-msg-actions{opacity:1;pointer-events:auto;transform:translateY(0)}.hsk-cb-sent-status{font-size:11px;line-height:1;color:var(--hsk-chat-muted,#8a8f98);padding:0;display:inline-flex;align-items:center;user-select:none;animation:hsk-sent-in .2s ease-out both}.hsk-cb-msg-actions{display:inline-flex;align-items:center;gap:2px;padding:0;opacity:0;pointer-events:none;transform:translateX(3px);transition:opacity .18s cubic-bezier(.16,1,.3,1),transform .18s cubic-bezier(.16,1,.3,1)}.hsk-cb-user-msg:hover .hsk-cb-msg-actions,.hsk-cb-user-msg:focus-within .hsk-cb-msg-actions,.hsk-cb-msg-actions--visible{opacity:1;pointer-events:auto;transform:translateX(0)}.hsk-cb-msg-actions--failed{opacity:1 !important;pointer-events:auto !important;transform:translateX(0) !important}.hsk-cb-msg-action{display:inline-flex;align-items:center;gap:3.5px;padding:1px 6.5px;height:16px;border-radius:999px;font-size:11px;font-weight:500;font-family:var(--hsk-font);line-height:1;color:var(--hsk-chat-muted,#8a8f98);background:transparent;border:none;box-shadow:none;cursor:pointer;user-select:none;transition:color .15s ease,background-color .15s ease,transform .18s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-msg-action .hsk-cb-msg-action-label{font-size:11px;line-height:1}.hsk-cb-msg-action:hover:not(:disabled){color:var(--hsk-chat-text,#ffffff) !important;background:var(--hsk-chat-divide,rgba(140,140,140,.18));transform:translateY(-0.5px)}.hsk-cb-msg-action:active:not(:disabled){transform:translateY(0) scale(.95);transition-duration:.1s}.hsk-cb-msg-action--retry{color:var(--hsk-primary,#ff6a33);background:color-mix(in srgb,var(--hsk-primary,#ff6a33) 10%,transparent)}.hsk-cb-msg-action--retry:hover:not(:disabled){color:var(--hsk-on-active,#ffffff) !important;background:var(--hsk-primary,#ff6a33) !important;box-shadow:0 1px 6px color-mix(in srgb,var(--hsk-primary,#ff6a33) 35%,transparent)}.hsk-cb-failed-notice{display:inline-flex;align-items:center;gap:4px;font-size:11px;line-height:1;color:#ef4444;font-weight:500;user-select:none}.hsk-cb-failed-dot{width:5px;height:5px;border-radius:999px;background:#ef4444;box-shadow:0 0 5px rgba(239,68,68,.6);animation:hsk-failed-pulse 1.8s ease-in-out infinite}@keyframes hsk-failed-pulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.25);opacity:.7}}.hsk-cb-msg-action--copied{color:#10b981 !important;background:rgba(16,185,129,.15) !important;font-weight:600}@media (max-width:640px){.hsk-cb-msg-actions{display:none !important}}@keyframes hsk-sent-in{from{opacity:0}to{opacity:1}}.hsk-cb-user-bubble--queued{opacity:.55}.hsk-cb-queued-status{display:inline-flex;align-items:center;gap:5px;font-size:11px;line-height:1;color:var(--hsk-chat-muted,#8a8f98);padding:4px 0 0;background:none;border:none;cursor:pointer;font-family:var(--hsk-font);animation:hsk-sent-in .2s ease-out both}.hsk-cb-queued-dot{width:5px;height:5px;border-radius:999px;background:currentColor;animation:hsk-queued-pulse 1.1s ease-in-out infinite}@keyframes hsk-queued-pulse{0%,100%{opacity:.35;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}.hsk-cb-queued-now{color:var(--hsk-primary,#ff6a33);font-weight:600;transition:opacity .15s ease}.hsk-cb-queued-status:hover .hsk-cb-queued-now{opacity:.7}@media (prefers-reduced-motion:reduce){.hsk-cb-queued-dot{animation:none;opacity:.8}}.hsk-cb-timeline{display:none}@media (min-width:900px){.hsk-cb-timeline.hsk-cb-timeline--left{display:block;position:absolute;left:auto !important;right:100% !important;margin-right:28px !important;top:50%;transform:translateY(-50%) !important;width:180px;max-height:60%;overflow:hidden;z-index:10;pointer-events:auto;direction:ltr !important;-webkit-mask-image:linear-gradient(to bottom,transparent,#000 14%,#000 86%,transparent);mask-image:linear-gradient(to bottom,transparent,#000 14%,#000 86%,transparent)}.hsk-cb-timeline.hsk-cb-timeline--right{display:block;position:absolute;left:100% !important;right:auto !important;margin-left:28px !important;top:50%;transform:translateY(-50%) !important;width:180px;max-height:60%;overflow:hidden;z-index:10;pointer-events:auto;direction:ltr !important;-webkit-mask-image:linear-gradient(to bottom,transparent,#000 14%,#000 86%,transparent);mask-image:linear-gradient(to bottom,transparent,#000 14%,#000 86%,transparent)}.hsk-cb-timeline-track{animation:hsk-tl-in .32s cubic-bezier(.22,1,.36,1) both}}@keyframes hsk-tl-in{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}.hsk-cb-timeline-track{--hsk-tl-x:9px;position:relative;padding-left:26px !important;padding-right:6px !important;transition:transform .28s cubic-bezier(.22,1,.36,1)}.hsk-cb-timeline-track::before,.hsk-cb-timeline-track::after{content:'';position:absolute;left:calc(var(--hsk-tl-x) - 1px) !important;right:auto !important;top:8px;bottom:8px;width:2px;border-radius:2px}.hsk-cb-timeline-track::before{background:var(--hsk-chat-divide,rgba(0,0,0,.09))}.hsk-cb-timeline-track::after{background:var(--hsk-primary,#ff6a33);opacity:.5;transform-origin:top;transform:scaleY(var(--hsk-tl-progress,0));transition:transform .18s linear}.hsk-cb-tl-item{--hsk-tl-d:0;position:relative;display:block;width:100%;padding:7px 6px 7px 0 !important;border:none;background:none;text-align:left !important;cursor:pointer;font-family:var(--hsk-font)}.hsk-cb-tl-dot{position:absolute;left:calc(var(--hsk-tl-x,9px) - 3.5px) !important;right:auto !important;top:50%;width:7px;height:7px;margin-top:-3.5px;border-radius:999px;background:var(--hsk-chat-divide,rgba(0,0,0,.18));opacity:max(.25,calc(1 - var(--hsk-tl-d) * .22));transition:transform .28s cubic-bezier(.34,1.4,.64,1),opacity .46s cubic-bezier(.22,1,.36,1),background .2s ease}.hsk-cb-tl-label{display:block;font-size:12px;line-height:1.4;color:var(--hsk-chat-muted,#8a8f98);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transform:translateX(calc(var(--hsk-tl-d) * 7px));opacity:max(.32,calc(.9 - var(--hsk-tl-d) * .15));transition:transform .46s cubic-bezier(.22,1,.36,1),opacity .46s cubic-bezier(.22,1,.36,1),color .2s ease}.hsk-cb-tl-item:hover .hsk-cb-tl-label{opacity:1;transform:translateX(calc(var(--hsk-tl-d) * 7px - 2px))}.hsk-cb-tl-item:hover .hsk-cb-tl-dot{transform:scale(1.25)}.hsk-cb-tl-cursor{position:absolute;left:calc(var(--hsk-tl-x,9px) - 4.5px) !important;right:auto !important;top:0;width:9px;height:9px;margin-top:-4.5px;border-radius:999px;background:var(--hsk-primary,#ff6a33);transform:translateY(0);transition:transform .44s cubic-bezier(.22,1,.36,1);will-change:transform;pointer-events:none}.hsk-cb-tl-item--on .hsk-cb-tl-dot{opacity:.35}.hsk-cb-tl-item--on .hsk-cb-tl-label{color:var(--hsk-chat-text,#1f1f1f);opacity:1;font-weight:500}@media (prefers-reduced-motion:reduce){.hsk-cb-timeline-track{animation:none}.hsk-cb-timeline-track::after,.hsk-cb-tl-label,.hsk-cb-tl-cursor,.hsk-cb-tl-dot{transition:none}}@media (prefers-color-scheme:dark){.hsk-cb-ai-text{--hsk-chat-ai-bg:#26262a;background:var(--hsk-chat-ai-bg);color:#f9fafb}}.hsk-cb-sources-wrap{position:relative;margin-top:20px}.hsk-cb-sources{display:flex;flex-direction:row;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;padding-bottom:4px}.hsk-cb-sources::-webkit-scrollbar{display:none}.hsk-cb-sources-fade-left,.hsk-cb-sources-fade-right{position:absolute;top:0;bottom:4px;width:30px;pointer-events:none;z-index:2}.hsk-cb-sources-fade-left,.hsk-cb-sources-fade-right{background-color:var(--hsk-fade-bg,var(--hsk-chat-bg,#0e0e0f))}.hsk-cb-sources-fade-left,[dir=\\\"rtl\\\"] .hsk-cb-sources-fade-right{-webkit-mask-image:linear-gradient(to right,#000 0,rgba(0,0,0,.55) 45%,transparent 100%);mask-image:linear-gradient(to right,#000 0,rgba(0,0,0,.55) 45%,transparent 100%)}.hsk-cb-sources-fade-right,[dir=\\\"rtl\\\"] .hsk-cb-sources-fade-left{-webkit-mask-image:linear-gradient(to left,#000 0,rgba(0,0,0,.55) 45%,transparent 100%);mask-image:linear-gradient(to left,#000 0,rgba(0,0,0,.55) 45%,transparent 100%)}.hsk-cb-sources-fade-left{inset-inline-start:0}.hsk-cb-sources-fade-right{inset-inline-end:0}.hsk-cb-sources-next,.hsk-cb-sources-prev{position:absolute;top:42%;transform:translateY(-50%);width:34px;height:34px;border-radius:50% !important;background:var(--hsk-chat-bg,#ffffff) !important;border:1px solid var(--hsk-chat-divide,rgba(0,0,0,.12)) !important;color:var(--hsk-primary,#ff6a33) !important;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 14px rgba(0,0,0,.14);z-index:10;cursor:pointer;transition:transform .2s cubic-bezier(.34,1.56,.64,1),background .18s ease,color .18s ease,box-shadow .18s ease}.hsk-cb-sources-next:hover,.hsk-cb-sources-prev:hover{background:var(--hsk-primary,#ff6a33) !important;color:#ffffff !important;border-color:var(--hsk-primary,#ff6a33) !important;transform:translateY(-50%) scale(1.1);box-shadow:0 6px 18px rgba(255,106,51,.35)}.hsk-cb-sources-next{inset-inline-end:2px}.hsk-cb-sources-prev{inset-inline-start:2px}[dir=\\\"rtl\\\"] .hsk-cb-sources-next svg,[dir=\\\"rtl\\\"] .hsk-cb-sources-prev svg{transform:scaleX(-1)}.hsk-cb-carousel-dots{display:flex;align-items:center;justify-content:center;gap:5px;margin-top:10px}.hsk-cb-dot-item{width:6px;height:6px;border-radius:50%;background:rgba(150,150,150,.35);transition:all .25s cubic-bezier(.34,1.56,.64,1);cursor:pointer}.hsk-cb-dot-item--active{width:18px;border-radius:999px;background:var(--hsk-primary,#ff6a33)}.hsk-cb-source{flex:0 0 188px;scroll-snap-align:start;border-radius:var(--hsk-border-radius,0);border:none;background:transparent;cursor:pointer;transition:transform .14s,opacity .14s;animation:hsk-card-in .26s ease-out both;overflow:visible}@keyframes hsk-card-in{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}.hsk-cb-source:hover{transform:translateY(-3px);opacity:.92}.hsk-cb-src-imgwrap{width:188px;height:188px;overflow:hidden;border-radius:var(--hsk-border-radius,0);display:block;background:var(--hsk-chat-source-bg,#f8f9fa)}.hsk-cb-src-imgwrap img{width:100%;height:100%;object-fit:cover;transition:transform .22s;display:block}.hsk-cb-source:hover .hsk-cb-src-imgwrap img{transform:scale(1.05)}.hsk-cb-src-imgwrap-empty{width:188px;height:188px;background:var(--hsk-chat-divide,rgba(0,0,0,.06));display:flex;align-items:center;justify-content:center;color:var(--hsk-chat-muted,#555);font-size:32px}.hsk-cb-src-info{padding:8px 2px 0}.hsk-cb-sources-wrap--compact{margin-top:10px}.hsk-cb-sources-wrap--compact .hsk-cb-sources{gap:10px}.hsk-cb-sources-wrap--compact .hsk-cb-source{flex:0 0 96px}.hsk-cb-sources-wrap--compact .hsk-cb-src-imgwrap,.hsk-cb-sources-wrap--compact .hsk-cb-src-imgwrap-empty{width:96px;height:96px}.hsk-cb-sources-wrap--compact .hsk-cb-src-imgwrap-empty{font-size:20px}.hsk-cb-sources-wrap--compact .hsk-cb-src-name{font-size:12px;-webkit-line-clamp:1}.hsk-cb-sources-wrap--compact .hsk-cb-src-price{font-size:11px;padding:1px 6px}.hsk-cb-sources-wrap--compact .hsk-cb-source-ref-badge{display:none}.hsk-cb-src-name{font-size:13px;font-weight:600;color:var(--hsk-chat-text,#333);line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.hsk-cb-src-price{display:inline-flex;align-items:center;width:fit-content;max-width:100%;padding:2px 9px;border-radius:9999px;background:var(--hsk-chat-source-bg,rgba(0,0,0,.05));border:1px solid var(--hsk-chat-divide,rgba(0,0,0,.08));font-size:12px;font-weight:600;color:var(--hsk-primary,#ff6a33);margin-top:5px;line-height:1.2}.hsk-cb-typing-row{display:flex;align-items:flex-start;gap:14px;padding:20px 0}@keyframes hsk-shimmer{0%{background-position:130% 0}100%{background-position:-110% 0}}.hsk-cb-input-wrap{position:relative;--hsk-composer-pad-top:16px;--hsk-composer-pad-x:var(--hsk-gutter,24px);padding:var(--hsk-composer-pad-top) var(--hsk-composer-pad-x) 24px;flex-shrink:0;background:transparent !important;z-index:10}.hsk-cb-input-wrap::after{display:none !important}.hsk-cb-input-card{border-radius:20px;background:var(--hsk-chat-input-bg,#ffffff);border:none !important;outline:none !important;box-shadow:0 3px 14px -1px rgba(0,0,0,.05),0 1px 4px rgba(0,0,0,.03) !important;overflow:hidden;position:relative;z-index:1;transition:height .22s cubic-bezier(.32,.72,0,1)}.hsk-cb-input-card:focus-within{border:none !important;outline:none !important;box-shadow:0 4px 18px -1px rgba(0,0,0,.07),0 2px 6px rgba(0,0,0,.04) !important}.hsk-cb-docked-header{display:flex;align-items:center;gap:8px;padding:10px 16px 6px;background:transparent;border-bottom:none !important;user-select:none}.hsk-cb-docked-icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;color:var(--hsk-primary,#ff6a33)}.hsk-cb-docked-title{font-size:13px;font-weight:700;color:var(--hsk-primary,#ff6a33);letter-spacing:-0.01em}.hsk-cb-docked-sub{font-size:12px;font-weight:500;letter-spacing:-0.01em;color:var(--hsk-chat-text,#1f1f1f);flex:1}.hsk-cb-docked-close{background:none;border:none;color:var(--hsk-chat-muted,rgba(0,0,0,.4));font-size:16px;line-height:1;cursor:pointer;padding:2px 6px;border-radius:50%;transition:background .12s,color .12s}.hsk-cb-docked-close:hover{background:rgba(0,0,0,.08);color:var(--hsk-chat-text,#111111)}.hsk-cb-field{margin-inline:5px}.hsk-cb-input-box[data-expanded=\\\"true\\\"]>.hsk-cb-field{margin-inline:0}.hsk-cb-docked-options{display:flex;flex-direction:column;padding:4px 6px;background:transparent;border-bottom:none !important;max-height:220px;overflow-y:auto;scrollbar-width:thin}.hsk-cb-docked-option{display:flex;align-items:center;gap:10px;width:100%;padding:8px 12px;border:none;background:transparent !important;border-radius:10px;color:var(--hsk-chat-text,#1f1f1f);font-family:inherit;font-size:14px;text-align:start;cursor:pointer;transition:color .15s ease}.hsk-cb-docked-option:hover,.hsk-cb-docked-option:focus{background:transparent !important;color:var(--hsk-primary,#ff6a33)}.hsk-cb-docked-option-icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:8px;background:color-mix(in srgb,var(--hsk-primary,#ff6a33) 12%,transparent);color:var(--hsk-primary,#ff6a33);flex-shrink:0;overflow:hidden;transition:transform .2s cubic-bezier(.34,1.56,.64,1),background .18s ease}.hsk-cb-docked-option:hover .hsk-cb-docked-option-icon,.hsk-cb-docked-option:focus .hsk-cb-docked-option-icon{background:color-mix(in srgb,var(--hsk-primary,#ff6a33) 22%,transparent);transform:scale(1.15) rotate(4deg)}.hsk-cb-docked-option-icon img{width:100%;height:100%;object-fit:cover}.hsk-cb-docked-option-title{font-weight:500;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .15s ease}.hsk-cb-docked-option-desc{font-size:12px;color:var(--hsk-chat-muted,#6b7280);font-weight:400}.hsk-cb-docked-option-price{font-size:12px;font-weight:600;color:var(--hsk-chat-muted,#6b7280)}.hsk-cb-input-box{position:relative;display:grid;grid-template-columns:auto auto 1fr auto auto;grid-template-rows:auto 0;align-items:center;justify-items:start;column-gap:10px;row-gap:0;transition:grid-template-rows .2s cubic-bezier(.32,.72,0,1),row-gap .2s cubic-bezier(.32,.72,0,1);background:transparent !important;border:none !important;outline:none !important;border-radius:0 !important;padding-block:12px;padding-inline:18px 14px;box-shadow:none !important}.hsk-cb-tools-toggle{display:none}.hsk-cb-toolsheet-wrap{position:absolute;bottom:calc(100% - 6px);inset-inline-start:var(--hsk-composer-pad-x,14px);inset-inline-end:auto;z-index:100;transform-origin:bottom left;animation:hsk-toolsheet-in .22s cubic-bezier(.16,1,.3,1) both;pointer-events:auto}[dir=\\\"rtl\\\"] .hsk-cb-toolsheet-wrap,.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-toolsheet-wrap{transform-origin:bottom right}.hsk-cb-toolsheet{position:relative;z-index:1;min-width:200px;padding:6px;border-radius:16px;background:var(--hsk-chat-source-bg,rgba(255,255,255,.08));border:none !important;box-shadow:none !important}@keyframes hsk-toolsheet-in{0%{opacity:0;transform:translateY(8px) scale(.92)}100%{opacity:1;transform:translateY(0) scale(1)}}.hsk-cb-toolsheet-scrim{position:fixed;inset:0;z-index:90;background:transparent;cursor:default}.hsk-cb-toolsheet-item{display:flex;align-items:center;gap:11px;width:100%;padding:10px 12px;border:none;border-radius:11px;background:transparent;color:var(--hsk-chat-text,#111827);font-family:var(--hsk-font);font-size:15px;text-align:start;cursor:pointer;transition:background-color .15s ease}.hsk-cb-toolsheet-item:hover:not(:disabled){background:var(--hsk-chat-subtle,rgba(0,0,0,.05))}.hsk-cb-toolsheet-item:disabled{opacity:.45;cursor:default}.hsk-cb-toolsheet-item>svg{flex-shrink:0;color:var(--hsk-chat-muted,#6b7280)}[data-hsk-theme] .hsk-cb-toolsheet{background:var(--hsk-sheet-bg,var(--hsk-chat-input-bg,#f3f4f6)) !important;border:none !important}[data-hsk-theme] .hsk-cb-toolsheet-item{color:var(--hsk-chat-text,#111827) !important}[data-hsk-theme] .hsk-cb-toolsheet-item:hover:not(:disabled){background:var(--hsk-sheet-hover,var(--hsk-surface-2,rgba(0,0,0,.05))) !important}[data-hsk-theme] .hsk-cb-toolsheet-item>svg{color:var(--hsk-chat-muted,#6b7280) !important}@media (prefers-reduced-motion:reduce){.hsk-cb-toolsheet-wrap,.hsk-cb-toolsheet-stem{animation:none}.hsk-cb-toolsheet-stem{transform:scale(.62)}}.hsk-cb-input-box>.hsk-cb-attach-btn{grid-column:1;grid-row:1}.hsk-cb-input-box>.hsk-cb-voice-mode-btn{grid-column:2;grid-row:1}.hsk-cb-input-box>.hsk-cb-field{grid-column:3;grid-row:1}.hsk-cb-input-box>.hsk-cb-mic-btn{grid-column:4;grid-row:1}.hsk-cb-input-box>.hsk-cb-send,.hsk-cb-input-box>.hsk-chat-send{grid-column:5;grid-row:1}.hsk-cb-input-box[data-expanded=\\\"true\\\"]{grid-template-rows:auto 36px;row-gap:6px}.hsk-cb-input-box[data-expanded=\\\"true\\\"]>.hsk-cb-field{grid-column:1 / -1;grid-row:1}.hsk-cb-input-box[data-expanded=\\\"true\\\"]>.hsk-cb-attach-btn,.hsk-cb-input-box[data-expanded=\\\"true\\\"]>.hsk-cb-voice-mode-btn,.hsk-cb-input-box[data-expanded=\\\"true\\\"]>.hsk-cb-mic-btn,.hsk-cb-input-box[data-expanded=\\\"true\\\"]>.hsk-cb-send,.hsk-cb-input-box[data-expanded=\\\"true\\\"]>.hsk-chat-send{grid-row:2}.hsk-cb-textarea{width:100%;background:transparent;border:none;outline:none;resize:none;font-size:var(--hsk-input-font-size,16px);font-family:var(--hsk-font);color:var(--hsk-chat-text,#111);min-height:28px;max-height:140px;field-sizing:content;line-height:var(--hsk-input-line-height,1.55);word-break:break-word;overflow-wrap:break-word;padding:0;transition:height .18s cubic-bezier(.32,.72,0,1),color .42s cubic-bezier(.16,1,.3,1);scrollbar-width:none}.hsk-cb-textarea::-webkit-scrollbar{width:0;height:0}.hsk-cb-textarea::placeholder{color:var(--hsk-chat-muted,#9ca3af);font-family:var(--hsk-font);font-size:16px}.hsk-cb-attach-btn,.hsk-cb-mic-btn,.hsk-cb-send,.hsk-chat-send{width:36px;height:36px;border-radius:12px;display:flex;align-items:center;justify-content:center;flex-shrink:0;border:none;cursor:pointer;transition:transform .2s cubic-bezier(.34,1.56,.64,1),box-shadow .2s cubic-bezier(.34,1.56,.64,1),background-color .42s cubic-bezier(.16,1,.3,1),opacity .2s ease;font-family:inherit;margin:0;padding:0}.hsk-cb-send,.hsk-chat-send{background:linear-gradient(135deg,#007aff 0,#0056b3 100%);color:#ffffff;border-radius:12px !important;box-shadow:0 4px 14px rgba(0,122,255,.38),inset 0 1px 0 rgba(255,255,255,.35);position:relative;overflow:hidden}.hsk-cb-send .hsk-telegram-icon,.hsk-chat-send .hsk-telegram-icon{transition:transform .25s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-send:hover:not(:disabled),.hsk-chat-send:hover:not(:disabled){opacity:1;transform:translateY(-1px) scale(1.05);box-shadow:0 6px 18px rgba(0,122,255,.48),inset 0 1px 0 rgba(255,255,255,.45)}.hsk-cb-send:hover:not(:disabled) .hsk-telegram-icon,.hsk-chat-send:hover:not(:disabled) .hsk-telegram-icon{transform:translate(2px,-2px) rotate(-10deg) scale(1.1)}.hsk-cb-send:active:not(:disabled),.hsk-chat-send:active:not(:disabled){transform:translateY(0) scale(.94);box-shadow:0 1px 4px rgba(0,122,255,.3)}.hsk-cb-send:disabled,.hsk-chat-send:disabled{opacity:.4;cursor:not-allowed;background:var(--hsk-chat-muted,#ccc);box-shadow:none}.hsk-cb-send--stop{background:#e5342a !important}.hsk-cb-send--stop:hover{background:#c92a21 !important;opacity:1}.hsk-cb-hint{text-align:center;font-size:9px;line-height:14px;color:var(--hsk-chat-muted,#bbb);margin-top:10px}.hsk-cb-field{position:relative;grid-area:field;display:flex;align-items:center;width:100%;min-width:0;--hsk-input-font-size:16px;--hsk-input-line-height:1.55;--hsk-input-control:36px;--hsk-input-line-box:calc(var(--hsk-input-font-size) * var(--hsk-input-line-height))}.hsk-cb-listening{position:absolute;inset:0;display:flex;align-items:center;justify-content:space-between;pointer-events:none}.hsk-cb-listening span{width:2px;height:2px;border-radius:999px;background:var(--hsk-primary,#ff6a33);opacity:.3;transform-origin:center;will-change:transform,opacity;transition:transform 90ms linear,opacity 90ms linear}.hsk-animated-placeholder{position:absolute;inset:0;display:flex;align-items:center;height:100%;pointer-events:none;overflow:hidden;user-select:none;padding:0;z-index:1}.hsk-cb-input-box>*{--hsk-cascade-ease:cubic-bezier(.45,0,.55,1);--hsk-cascade-dur:.44s;--hsk-cascade-step:55ms}.hsk-cb-input-box[data-cascade]>*:not([type=\\\"file\\\"]):not(.hsk-cb-field){animation-duration:var(--hsk-cascade-dur);animation-timing-function:var(--hsk-cascade-ease);animation-fill-mode:none}.hsk-cb-input-box[data-cascade=\\\"a\\\"]>*:not([type=\\\"file\\\"]):not(.hsk-cb-field){animation-name:hsk-leaf-settle-a}.hsk-cb-input-box[data-cascade=\\\"b\\\"]>*:not([type=\\\"file\\\"]):not(.hsk-cb-field){animation-name:hsk-leaf-settle-b}.hsk-cb-input-box[data-cascade]>*:not([type=\\\"file\\\"]):not(.hsk-cb-field),.hsk-animated-placeholder__char{will-change:transform}.hsk-cb-input-box:hover>*,.hsk-cb-input-box:focus-within>*{will-change:auto}.hsk-cb-input-box>*{--hsk-cascade-field:110ms}.hsk-cb-input-box[data-cascade]>.hsk-cb-attach-btn{animation-delay:0ms}.hsk-cb-input-box[data-cascade]>.hsk-cb-voice-mode-btn{animation-delay:var(--hsk-cascade-step)}.hsk-cb-input-box[data-cascade]>.hsk-cb-mic-btn{animation-delay:calc(var(--hsk-cascade-field)+var(--hsk-text-sweep,0ms))}.hsk-cb-input-box[data-cascade]>.hsk-cb-send,.hsk-cb-input-box[data-cascade]>.hsk-chat-send{animation-delay:calc(var(--hsk-cascade-field)+var(--hsk-text-sweep,0ms)+var(--hsk-cascade-step))}@keyframes hsk-leaf-settle-a{0%{transform:translateY(0) scale(1)}42%{transform:translateY(-3px) scale(1.05)}100%{transform:translateY(0) scale(1)}}@keyframes hsk-leaf-settle-b{0%{transform:translateY(0) scale(1)}42%{transform:translateY(-3px) scale(1.05)}100%{transform:translateY(0) scale(1)}}.hsk-cb-input-box>.hsk-cb-field .hsk-animated-placeholder__char{animation-name:hsk-placeholder-animate-up}@media (prefers-reduced-motion:reduce){.hsk-cb-input-box[data-cascade=\\\"a\\\"]>*,.hsk-cb-input-box[data-cascade=\\\"b\\\"]>*{animation:none;transform:none;opacity:1}.hsk-cb-textarea,.hsk-cb-input-card{transition-property:background-color,box-shadow}}.hsk-animated-placeholder__char{display:inline-block;font-size:var(--hsk-input-font-size,16px);line-height:var(--hsk-input-line-height,1.55);color:var(--hsk-chat-muted,#9ca3af);font-family:var(--hsk-font);white-space:pre;animation:hsk-placeholder-animate-up .46s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-placeholder-animate-up{0%{opacity:0;transform:translateY(9px);color:hsl(var(--hsk-ph-hue,0) var(--hsk-ph-sat,68%) var(--hsk-ph-light,55%))}55%{opacity:1;color:hsl(var(--hsk-ph-hue,0) var(--hsk-ph-sat,68%) var(--hsk-ph-light,55%))}100%{opacity:1;transform:translateY(0);color:var(--hsk-chat-muted,#9ca3af)}}@media (prefers-reduced-motion:reduce){.hsk-animated-placeholder__char{animation:none;transform:none;opacity:1;color:var(--hsk-chat-muted,#9ca3af);animation-delay:0ms !important}}.hsk-cb-voice-error{display:flex;align-items:center;justify-content:center;gap:8px;font-size:12px;line-height:1.4;max-width:90%;margin-inline:auto;text-wrap:balance;color:#ff6b6b;margin-top:8px;padding:4px 12px;border-radius:12px;background:rgba(229,72,77,.12);border:none;cursor:pointer;animation:hsk-msg-in .2s ease-out both}.hsk-cb-voice-error-dismiss{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;border:none;background:rgba(255,255,255,.12);color:inherit;font-size:14px;line-height:1;cursor:pointer;padding:0;flex-shrink:0;transition:background .15s ease,transform .15s ease}.hsk-cb-voice-error-dismiss:hover{background:rgba(255,255,255,.25);transform:scale(1.1)}.hsk-cb-img-strip{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:10px 18px 2px 18px;background:transparent;border:none;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;animation:hsk-msg-in .2s ease-out both}.hsk-cb-img-thumb-wrap{position:relative;width:60px;height:60px;flex-shrink:0;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.08),0 0 0 1px rgba(255,255,255,.12);transition:transform .2s cubic-bezier(.16,1,.3,1),box-shadow .2s cubic-bezier(.16,1,.3,1);overflow:visible}.hsk-cb-img-thumb-wrap:hover{transform:translateY(-2px);box-shadow:0 6px 14px rgba(0,0,0,.12),0 0 0 1px rgba(255,255,255,.2)}.hsk-cb-img-thumb{width:100%;height:100%;object-fit:cover;border-radius:12px;border:none;display:block}.hsk-cb-img-thumb-remove{position:absolute;top:-5px;inset-inline-end:-5px;width:18px;height:18px;border-radius:50%;background:rgba(20,20,24,.75);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:#ffffff;border:1px solid rgba(255,255,255,.25);box-shadow:0 2px 6px rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;transition:transform .15s cubic-bezier(.16,1,.3,1),background-color .15s ease;z-index:2}.hsk-cb-img-thumb-remove:hover{background:rgba(239,68,68,.92);border-color:rgba(255,255,255,.4);transform:scale(1.15)}.hsk-cb-attach-btn,.hsk-cb-mic-btn,.hsk-cb-voice-mode-btn{position:relative;width:36px;height:36px;border-radius:12px;border:none !important;outline:none !important;background:transparent;color:var(--hsk-chat-muted,#71717a);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:none !important;opacity:.75;transition:transform .35s cubic-bezier(.34,1.8,.64,1),background-color .2s ease,color .2s ease,opacity .2s ease;font-family:inherit;overflow:visible}.hsk-cb-attach-btn:hover:not(:disabled),.hsk-cb-mic-btn:hover:not(:disabled),.hsk-cb-voice-mode-btn:hover:not(:disabled){opacity:1;color:var(--hsk-chat-text,#1f1f1f);background:transparent;transform:translateY(-1px)}.hsk-cb-attach-btn:active:not(:disabled),.hsk-cb-mic-btn:active:not(:disabled),.hsk-cb-voice-mode-btn:active:not(:disabled){transform:translateY(0) scale(.94);transition-duration:.1s}.hsk-cb-attach-btn svg,.hsk-cb-mic-btn svg,.hsk-cb-voice-mode-btn svg{overflow:visible}.hsk-cb-attach-btn svg{transition:transform .34s cubic-bezier(.22,1,.36,1)}.hsk-cb-attach-btn:hover:not(:disabled) svg{transform:rotate(-14deg) translateY(-1px)}.hsk-mic-cap{transform-box:fill-box;transform-origin:center;transition:transform .32s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-mic-btn:hover:not(:disabled) .hsk-mic-cap{transform:translateY(-1.5px)}.hsk-wave-bar{transform-box:fill-box;transform-origin:center;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-voice-mode-btn:hover:not(:disabled) .hsk-wave-bar{animation:hsk-wave-wake .52s cubic-bezier(.34,1.8,.64,1) both,hsk-wave-live var(--hsk-period,1.1s) ease-in-out .52s infinite;animation-delay:calc(var(--hsk-bar,0) * 55ms),calc(.52s+var(--hsk-bar,0) * 55ms)}.hsk-cb-voice-mode-btn:hover:not(:disabled) .hsk-wave-bar--tip{animation-name:hsk-wave-wake-tip,hsk-wave-live-tip}@keyframes hsk-wave-wake{0%{transform:scaleY(.12)}55%{transform:scaleY(calc(var(--hsk-amp,1.6) * 1.12))}100%{transform:scaleY(1)}}@keyframes hsk-wave-live{0%,100%{transform:scaleY(1)}30%{transform:scaleY(var(--hsk-amp,1.6))}55%{transform:scaleY(calc(1+(var(--hsk-amp,1.6) - 1) * .22))}78%{transform:scaleY(calc(1+(var(--hsk-amp,1.6) - 1) * .62))}}@keyframes hsk-wave-wake-tip{0%{transform:scaleX(.2);opacity:.4}55%{transform:scaleX(calc(var(--hsk-amp,1.9) * 1.1));opacity:1}100%{transform:scaleX(1);opacity:.8}}@keyframes hsk-wave-live-tip{0%,100%{transform:scaleX(1);opacity:.7}30%{transform:scaleX(var(--hsk-amp,1.9));opacity:1}70%{transform:scaleX(1.15);opacity:.8}}.hsk-copy-sheet,.hsk-copy-back{transform-box:fill-box;transform-origin:center;transition:transform .3s cubic-bezier(.22,1,.36,1)}.hsk-cb-kiku-id-pill:hover .hsk-copy-sheet{transform:translate(.9px,.9px)}.hsk-cb-kiku-id-pill:hover .hsk-copy-back{transform:translate(-0.9px,-0.9px)}@media (prefers-reduced-motion:reduce){.hsk-cb-attach-btn:hover:not(:disabled) svg,.hsk-cb-mic-btn:hover:not(:disabled) .hsk-mic-cap,.hsk-cb-kiku-id-pill:hover .hsk-copy-sheet,.hsk-cb-kiku-id-pill:hover .hsk-copy-back{transform:none}.hsk-cb-voice-mode-btn:hover:not(:disabled) .hsk-wave-bar{animation:none}}.hsk-cb-attach-btn:disabled,.hsk-cb-mic-btn:disabled,.hsk-cb-voice-mode-btn:disabled{opacity:.3;cursor:not-allowed;transform:none}.hsk-cb-mic-btn--listening{color:#ef4444 !important;background:rgba(239,68,68,.16) !important;transform:scale(1.1) !important}.hsk-cb-mic-btn--processing{color:var(--hsk-primary,#ff6a33) !important;opacity:.85}.hsk-cb-user-imgs{display:grid;gap:2px;width:fit-content;max-width:min(78%,320px);margin-bottom:4px;margin-left:auto;border-radius:18px 18px 4px 18px;overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,.16)}.hsk-cb-user-imgs[data-count=\\\"1\\\"]{grid-template-columns:1fr}.hsk-cb-user-imgs[data-count=\\\"2\\\"]{grid-template-columns:1fr 1fr}.hsk-cb-user-imgs[data-count=\\\"3\\\"]{grid-template-columns:2fr 1fr;grid-template-rows:1fr 1fr}.hsk-cb-user-imgs[data-count=\\\"3\\\"]>:first-child{grid-row:span 2}.hsk-cb-user-imgs[data-count=\\\"4\\\"]{grid-template-columns:1fr 1fr}.hsk-cb-user-img-cell{position:relative;display:block;padding:0;border:none;background:none;cursor:pointer;overflow:hidden;min-width:0;line-height:0}.hsk-cb-user-imgs[data-count=\\\"1\\\"] .hsk-cb-user-img-cell{aspect-ratio:auto}.hsk-cb-user-imgs:not([data-count=\\\"1\\\"]) .hsk-cb-user-img-cell{aspect-ratio:1}.hsk-cb-user-img-more{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.45);color:#fff;font-size:20px;font-weight:600;line-height:1}.hsk-cb-user-img-thumb{width:100%;height:100%;object-fit:cover;display:block;cursor:pointer}.hsk-cb-user-imgs[data-count=\\\"1\\\"] .hsk-cb-user-img-thumb{height:auto;max-height:300px;object-fit:contain}.hsk-cb-user-img-cell:hover .hsk-cb-user-img-thumb{filter:brightness(.93)}.hsk-cb-error{display:block;width:fit-content;max-width:min(560px,100%);margin:10px auto 8px;padding:10px 14px;border-radius:10px;background:rgba(239,68,68,.08);border:1px solid rgba(239,68,68,.2);color:#ef4444;font-size:13px;line-height:1.5;font-family:var(--hsk-font);text-align:center}.hsk-kiku-badge{display:inline-block;font-size:var(--hsk-font-size,16px);font-family:var(--hsk-font);font-weight:600;background:rgba(255,255,255,.22);border:1px solid rgba(255,255,255,.35);color:#ffffff;padding:1px 7px;border-radius:6px;margin-inline-end:6px}.hsk-cb-memory-pill{display:inline-flex;align-items:center;gap:10px;align-self:flex-start;margin:12px 0 6px 0;padding:12px 22px;font-size:15px;font-weight:600;text-decoration:none;color:#ffffff;background:linear-gradient(135deg,#007aff 0,#0056b3 100%);border:none;border-radius:18px 18px 18px 4px !important;box-shadow:0 4px 16px -2px rgba(0,122,255,.38),inset 0 1px 0 rgba(255,255,255,.28);transition:transform .18s cubic-bezier(.34,1.56,.64,1),opacity .15s,box-shadow .18s ease;cursor:pointer}.hsk-cb-memory-pill:hover{opacity:.96;transform:translateY(-1px) scale(1.02);box-shadow:0 6px 20px rgba(0,122,255,.48)}.hsk-cb-think{position:relative;z-index:2;margin-bottom:-11px;margin-inline-start:12px;font-size:14px;font-family:var(--hsk-font)}.hsk-cb-think-head{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 11px;border:none;border-radius:999px;background:var(--hsk-chat-ai-bg,#eeeef0);box-shadow:0 0 0 3px var(--hsk-chat-bg,#ffffff),0 1px 3px rgba(0,0,0,.13);font-family:var(--hsk-font);font-size:12px;font-weight:600;color:var(--hsk-chat-muted,#6b7280);cursor:pointer;user-select:none;line-height:28px}.hsk-cb-think-head:hover{color:var(--hsk-chat-text,#111827)}.hsk-cb-think-head--static{cursor:default}.hsk-cb-think-head--static:hover{color:var(--hsk-chat-muted,#6b7280)}.hsk-cb-think-spin{animation:hsk-think-spin 3s linear infinite}@keyframes hsk-think-spin{to{transform:rotate(360deg)}}.hsk-cb-think-chevron{font-size:9px;transition:transform .12s}.hsk-cb-think-chevron--open{transform:rotate(90deg)}.hsk-cb-think-body{margin-top:6px;padding:8px 12px;border-left:2px solid var(--hsk-chat-border,rgba(128,128,128,.25));color:var(--hsk-chat-muted,#4b5563);white-space:pre-wrap;line-height:1.5;font-family:var(--hsk-font);font-size:14px}.hsk-cb-stopped{display:flex;flex-direction:column;align-items:start;gap:8px;margin:10px 0 14px}.hsk-cb-stopped--empty{align-items:center;text-align:center;margin:22px auto 18px}.hsk-cb-stopped--empty .hsk-cb-stopped-label{text-align:center}.hsk-cb-stopped-dots{display:flex;gap:5px;margin-bottom:2px}.hsk-cb-stopped-dots i{width:5px;height:5px;border-radius:50%;background:var(--hsk-chat-muted,#888);opacity:.4}.hsk-cb-stopped-label{font-size:13px;line-height:1.5;color:var(--hsk-chat-muted,#888);font-family:var(--hsk-font);text-align:start}.hsk-cb-continue{display:inline-flex;align-items:center;gap:7px;padding:7px 14px;font-size:13px;font-weight:500;font-family:var(--hsk-font);color:var(--hsk-chat-text,#111);background:var(--hsk-chat-source-bg,rgba(0,0,0,.04));border:1px solid transparent;border-radius:999px;cursor:pointer;transition:border-color .15s,color .15s,background .15s}.hsk-cb-continue:hover{border-color:var(--hsk-primary);color:var(--hsk-primary);background:transparent}.hsk-cb-continue svg{flex:none}[dir=\\\"rtl\\\"] .hsk-cb-continue svg{transform:scaleX(-1)}@media (prefers-color-scheme:dark){.hsk-cb-continue{background:rgba(255,255,255,.06);color:#f0efed}.hsk-cb-continue:hover{background:transparent}}.hsk-sb-wrap{--hsk-bg:#ffffff;--hsk-border:#f1f3f4;--hsk-text:#1f1f1f;--hsk-muted:#5f6368;--hsk-hover:#f8f9fa;--hsk-drop-shadow:0 8px 30px rgba(0,0,0,.06);--hsk-primary:var(--chat-primary-color,#ff6a33);position:relative;width:100%;font-family:inherit}@media (prefers-color-scheme:dark){.hsk-sb-wrap{--hsk-bg:#0a0a0a;--hsk-border:#202124;--hsk-text:#e8eaed;--hsk-muted:#888;--hsk-hover:#1a1a1b;--hsk-drop-shadow:0 12px 40px rgba(0,0,0,.4)}}.hsk-sb-input{width:100%;padding:10px 16px 10px 40px;font-size:14px;border-radius:var(--hsk-border-radius,0);border:1.5px solid var(--hsk-border);outline:none;box-sizing:border-box;background:var(--hsk-bg);color:var(--hsk-text);transition:border-color .15s,box-shadow .15s;font-family:inherit}.hsk-sb-input::placeholder{color:var(--hsk-muted)}.hsk-sb-input:focus{border-color:var(--hsk-primary);box-shadow:0 0 0 3px rgba(255,106,51,.12)}.hsk-sb-icon{position:absolute;inset-inline-start:14px;top:50%;transform:translateY(-50%);color:var(--hsk-muted);pointer-events:none;display:flex;align-items:center}.hsk-sb-drop{position:absolute;top:calc(100%+6px);left:0;right:0;background:var(--hsk-bg);border:1px solid var(--hsk-border);border-radius:var(--hsk-border-radius,0);box-shadow:var(--hsk-drop-shadow);z-index:9999;overflow:hidden;padding:6px 0}.hsk-sb-row{display:flex;align-items:center;gap:12px;padding:9px 16px;cursor:pointer;transition:background .1s}.hsk-sb-row:hover{background:var(--hsk-hover)}.hsk-sb-row-icon{color:var(--hsk-muted);flex-shrink:0;display:flex;align-items:center}.hsk-sb-row-thumb{width:38px;height:38px;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:var(--hsk-muted);background:var(--hsk-hover);border-radius:var(--hsk-border-radius,0);overflow:hidden}.hsk-sb-row-thumb img{width:100%;height:100%;object-fit:cover;display:block}.hsk-sb-row-body{flex:1;min-width:0}.hsk-sb-row-title{font-size:13px;font-weight:500;color:var(--hsk-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.3}.hsk-sb-row-sub{font-size:11px;color:var(--hsk-muted);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hsk-sb-empty{padding:14px 16px;font-size:13px;color:var(--hsk-muted)}.hsk-sb-loading-bar{height:2px;background:linear-gradient(90deg,transparent,var(--hsk-primary),transparent);background-size:200% 100%;animation:hsk-sweep .9s linear infinite;position:absolute;top:0;left:0;right:0}@keyframes hsk-sweep{0%{background-position:200% 0}100%{background-position:-200% 0}}.hsk-sb-fade{animation:hsk-fin .1s ease-out both}@keyframes hsk-fin{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}.hsk-sb-skeleton-row{display:flex;align-items:center;gap:12px;padding:9px 16px}.hsk-sb-skeleton-icon{width:38px;height:38px;background:var(--hsk-hover,rgba(0,0,0,.05));border-radius:var(--hsk-border-radius,0);flex-shrink:0;animation:hsk-pulse 1.5s ease-in-out infinite}.hsk-sb-skeleton-text1{height:12px;background:var(--hsk-hover,rgba(0,0,0,.05));border-radius:3px;width:60%;animation:hsk-pulse 1.5s ease-in-out infinite}.hsk-sb-skeleton-text2{height:8px;background:var(--hsk-hover,rgba(0,0,0,.05));border-radius:2px;width:35%;margin-top:5px;animation:hsk-pulse 1.5s ease-in-out infinite}@keyframes hsk-pulse{0%,100%{opacity:.6}50%{opacity:1}}.hsk-tapback-overlay{position:absolute;inset:0;z-index:1000;background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;touch-action:none}.hsk-tapback-group{position:absolute;z-index:1002;display:flex;flex-direction:column;animation:hsk-tapback-flow-up .26s cubic-bezier(.34,1.56,.64,1) both}.hsk-tapback-group.is-above{transform-origin:var(--tail-x,80%) calc(100%+14px)}.hsk-tapback-group.is-below{transform-origin:var(--tail-x,80%) -14px}.hsk-tapback-capsule{display:inline-flex;align-items:center;gap:2px;padding:4px 6px;height:38px;min-height:38px;border-radius:999px;background:color-mix(in srgb,var(--hsk-surface-1,var(--hsk-bubble-bg,var(--hsk-chat-bg,#1c1c1e))) 80%,transparent);border:1px solid color-mix(in srgb,var(--hsk-chat-text,#ffffff) 14%,transparent);box-shadow:0 12px 32px rgba(0,0,0,.26),0 3px 8px rgba(0,0,0,.08),inset 0 1px 1px color-mix(in srgb,var(--hsk-chat-text,#ffffff) 12%,transparent);backdrop-filter:blur(28px) saturate(190%);-webkit-backdrop-filter:blur(28px) saturate(190%);max-width:calc(100vw - 20px);position:relative;z-index:2;box-sizing:border-box}.hsk-tapback-tail{position:absolute;top:calc(100% - 6px);transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;pointer-events:none;z-index:1}.hsk-tapback-tail.is-below{top:auto;bottom:calc(100% - 6px);flex-direction:column-reverse}.hsk-tapback-dot{display:block;border-radius:50%;flex-shrink:0;position:relative}.hsk-tapback-dot--top{width:20px;height:20px;background:color-mix(in srgb,var(--hsk-surface-1,var(--hsk-bubble-bg,var(--hsk-chat-bg,#1c1c1e))) 80%,transparent);border:1px solid color-mix(in srgb,var(--hsk-chat-text,#ffffff) 14%,transparent);backdrop-filter:blur(28px) saturate(190%);-webkit-backdrop-filter:blur(28px) saturate(190%);box-shadow:0 3px 8px rgba(0,0,0,.16);z-index:3}.hsk-tapback-dot-bridge{position:absolute;top:-3px;left:2px;right:2px;height:8px;background:color-mix(in srgb,var(--hsk-surface-1,var(--hsk-bubble-bg,var(--hsk-chat-bg,#1c1c1e))) 90%,transparent);border-radius:999px;z-index:4}.hsk-tapback-tail.is-below .hsk-tapback-dot-bridge{top:auto;bottom:-3px}.hsk-tapback-dot--mid{width:11px;height:11px;margin-top:-3px;background:color-mix(in srgb,var(--hsk-surface-1,var(--hsk-bubble-bg,var(--hsk-chat-bg,#1c1c1e))) 80%,transparent);border:1px solid color-mix(in srgb,var(--hsk-chat-text,#ffffff) 14%,transparent);backdrop-filter:blur(28px) saturate(190%);-webkit-backdrop-filter:blur(28px) saturate(190%);box-shadow:0 2px 5px rgba(0,0,0,.14);z-index:2}.hsk-tapback-tail.is-below .hsk-tapback-dot--mid{margin-top:0;margin-bottom:-3px}.hsk-tapback-dot--anchor{width:6px;height:6px;margin-top:-2px;background:var(--hsk-anchor-color,var(--hsk-primary,#007aff));box-shadow:0 1px 3px rgba(0,0,0,.18);z-index:1}.hsk-tapback-tail.is-below .hsk-tapback-dot--anchor{margin-top:0;margin-bottom:-2px}.hsk-tapback-tool-btn{display:inline-flex;align-items:center;gap:5px;padding:4px 11px;height:30px;border-radius:999px;font-size:12.5px;font-weight:500;font-family:var(--hsk-font);line-height:1;color:var(--hsk-chat-text,#f3f4f6);background:transparent;border:none;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color .15s ease,transform .12s ease;white-space:nowrap;animation:hsk-tapback-tool-pop .2s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(.02s+var(--tool-idx,0) * .02s)}.hsk-tapback-tool-btn:hover{background:color-mix(in srgb,var(--hsk-chat-text,#ffffff) 14%,transparent)}.hsk-tapback-tool-btn:active{transform:scale(.92)}.hsk-tapback-tool-btn--pin{color:var(--hsk-primary,#ff6a33)}.hsk-tapback-tool-btn--pin:hover{background:color-mix(in srgb,var(--hsk-primary,#ff6a33) 18%,transparent)}.hsk-tapback-tool-btn--copy.is-copied{color:#10b981 !important}@keyframes hsk-tapback-flow-up{0%{opacity:0;transform:scale(.18) translateY(14px)}55%{opacity:1;transform:scale(1.05) translateY(-2px)}75%{transform:scale(.98) translateY(0)}100%{opacity:1;transform:scale(1) translateY(0)}}@keyframes hsk-tapback-tool-pop{0%{opacity:0;transform:scale(.85)}100%{opacity:1;transform:scale(1)}}.hsk-cb-scout-defs{position:absolute;width:0;height:0}.hsk-cb-scout-trigger-icon{display:inline-flex;align-items:center;flex-shrink:0}.hsk-cb-scout-trigger-dot{inline-size:6px;block-size:6px;border-radius:999px;background:#10b981;box-shadow:0 0 6px #10b981}.hsk-cb-scout-card-head{display:flex;align-items:center;justify-content:space-between;padding:2px 3px 6px}.hsk-cb-scout-card-title{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:650;color:var(--hsk-chat-text)}.hsk-cb-scout-card-x{border:none;background:none;padding:2px;display:inline-flex;color:var(--hsk-chat-muted);cursor:pointer;opacity:.7}.hsk-cb-scout-card-x:hover{opacity:1}.hsk-cb-scouts-stage{position:relative}.hsk-cb-scouts-glue{position:absolute;inset-block-start:3px;inset-inline-start:0;inline-size:100%;display:flex;flex-wrap:wrap;align-content:flex-start;gap:2px;row-gap:24px;pointer-events:none}.hsk-cb-glue-cell{flex:0 0 46px;display:grid;place-items:center;transform:scaleX(1.34);animation:hsk-glue-drift 3.4s ease-in-out infinite}.hsk-cb-glue-cell:nth-child(2n){animation-duration:4.1s}.hsk-cb-glue-cell:nth-child(3n){animation-duration:3.7s}.hsk-cb-glue-cell.is-loose{transform:none;animation:none}@keyframes hsk-glue-drift{0%,100%{transform:scaleX(1.34) translateY(0)}35%{transform:scaleX(1.42) translateY(-1px)}70%{transform:scaleX(1.29) translateY(.5px)}}@media (prefers-reduced-motion:reduce){.hsk-cb-glue-cell{animation:none}.hsk-cb-scout-hatch-pick,.hsk-cb-scout{transition:opacity .2s ease,filter .2s ease}.hsk-cb-scout-hatch-pick:hover,.hsk-cb-scout:hover{transform:none}}.hsk-cb-scout-time{padding:10px 2px 2px}.hsk-cb-dial{position:relative;block-size:18px;display:flex;align-items:center;transform-origin:center;transition:transform .22s cubic-bezier(.16,1,.3,1)}.hsk-cb-dial.is-dragging{transform:scale(1.045)}.hsk-cb-dial-track{position:relative;inline-size:100%;block-size:6px;border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-text) 10%,transparent);overflow:visible;transition:block-size .22s cubic-bezier(.16,1,.3,1)}.hsk-cb-dial.is-dragging .hsk-cb-dial-track{block-size:12px}.hsk-cb-dial-fill{position:absolute;inset-block:0;inset-inline-start:0;border-radius:999px;background:linear-gradient( to right,color-mix(in srgb,var(--hsk-primary) 62%,transparent),var(--hsk-primary) );transition:inline-size .18s cubic-bezier(.16,1,.3,1)}.hsk-cb-dial-input{position:absolute;inset-inline:0;inset-block:0;inline-size:100%;margin:0;padding:0;appearance:none;-webkit-appearance:none;background:transparent;cursor:grab}.hsk-cb-dial-input:active{cursor:grabbing}.hsk-cb-dial-input::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;inline-size:16px;block-size:16px;border:2.5px solid var(--hsk-chat-bg);border-radius:999px;background:var(--hsk-primary);box-shadow:0 2px 8px -1px color-mix(in srgb,var(--hsk-primary) 70%,transparent);cursor:grab;transition:transform .16s cubic-bezier(.16,1,.3,1),box-shadow .16s ease}.hsk-cb-dial-input:hover::-webkit-slider-thumb{transform:scale(1.12)}.hsk-cb-dial.is-dragging .hsk-cb-dial-input::-webkit-slider-thumb{transform:scale(1.28);box-shadow:0 0 0 7px color-mix(in srgb,var(--hsk-primary) 18%,transparent)}.hsk-cb-dial-input:active::-webkit-slider-thumb{transform:scale(1.24);box-shadow:0 0 0 6px color-mix(in srgb,var(--hsk-primary) 20%,transparent)}.hsk-cb-dial-input:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px color-mix(in srgb,var(--hsk-primary) 32%,transparent)}.hsk-cb-dial-input::-moz-range-thumb{inline-size:16px;block-size:16px;border:2.5px solid var(--hsk-chat-bg);border-radius:999px;background:var(--hsk-primary);cursor:grab}.hsk-cb-dial-input::-moz-range-track{background:transparent}.hsk-cb-scout-time-row{display:flex;align-items:baseline;gap:5px;padding-block-start:7px;transform-origin:center;transition:transform .22s cubic-bezier(.16,1,.3,1)}.hsk-cb-scout-time-row.is-lifted{transform:scale(1.06)}@media (prefers-reduced-motion:reduce){.hsk-cb-dial,.hsk-cb-dial-track,.hsk-cb-scout-time-row{transition:none}.hsk-cb-dial.is-dragging,.hsk-cb-scout-time-row.is-lifted{transform:none}}.hsk-cb-scouts-row{position:relative;display:flex;flex-wrap:wrap;align-items:flex-end;gap:2px}.hsk-cb-scout-slot{position:relative;flex:0 0 auto}.hsk-cb-scout{position:relative;display:flex;flex-direction:column;align-items:center;gap:1px;padding:3px 4px 2px;border:none;border-radius:13px;background:transparent;color:var(--hsk-chat-text);cursor:pointer;font:inherit;transition:transform .18s cubic-bezier(.16,1,.3,1)}.hsk-cb-scout:hover,.hsk-cb-scout:focus-visible{transform:translateY(-3px) scale(1.14);z-index:2;outline:none}.hsk-cb-scout:active{transform:translateY(0) scale(.96)}.hsk-cb-scout-face{position:relative;inline-size:38px;block-size:38px;display:grid;place-items:center}.hsk-cb-scout-char{display:block;overflow:visible}.hsk-cb-scout-pulse{position:absolute;inset-block-start:0;inset-inline-end:0;inline-size:6px;block-size:6px;border-radius:999px;background:#10b981;box-shadow:0 0 0 2px var(--hsk-chat-bg);animation:hsk-scout-breathe 2.4s ease-in-out infinite}@keyframes hsk-scout-breathe{0%,100%{opacity:1}50%{opacity:.35}}.hsk-cb-scout-own{direction:ltr;position:absolute;inset-block-end:-2px;inset-inline-end:-3px;padding:0 4px;border-radius:999px;background:var(--hsk-surface-2);color:var(--hsk-chat-muted);unicode-bidi:isolate;font-size:8px;font-weight:700;line-height:12px;box-shadow:0 0 0 1.5px var(--hsk-chat-bg)}.hsk-cb-scout-name{max-inline-size:48px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;unicode-bidi:isolate;font-size:9px;font-weight:600;color:var(--hsk-chat-muted)}.hsk-cb-scout.is-triggered .hsk-cb-scout-name{color:var(--hsk-primary)}.hsk-cb-scout.is-paused .hsk-cb-scout-face{opacity:.72}.hsk-cb-scout-bin{position:absolute;inset-block-start:-1px;inset-inline-start:-1px;z-index:3;inline-size:16px;block-size:16px;display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;border-radius:999px;background:var(--hsk-surface-2);color:var(--hsk-chat-muted);box-shadow:0 0 0 1.5px var(--hsk-chat-bg);cursor:pointer;opacity:0;transform:scale(.6);transition:opacity .16s ease,transform .16s cubic-bezier(.16,1,.3,1),color .16s ease}.hsk-cb-scout-slot:hover .hsk-cb-scout-bin,.hsk-cb-scout-bin:focus-visible{opacity:1;transform:none}.hsk-cb-scout-bin:hover{color:#e5484d}.hsk-cb-scout-new{flex:0 0 auto;align-self:center;inline-size:34px;block-size:34px;margin-block-end:12px;display:inline-flex;align-items:center;justify-content:center;padding:0;border:1.5px dashed color-mix(in srgb,var(--hsk-chat-text) 24%,transparent);border-radius:12px;background:transparent;color:var(--hsk-chat-muted);cursor:pointer;transition:color .18s ease,border-color .18s ease,transform .18s cubic-bezier(.16,1,.3,1)}.hsk-cb-scout-new:hover{color:var(--hsk-primary);border-color:var(--hsk-primary);transform:translateY(-2px)}.hsk-cb-scout-pool-line{direction:ltr;display:flex;align-items:center;justify-content:flex-start;gap:2px;padding:6px 4px 2px;unicode-bidi:isolate;font-size:9.5px;font-weight:600;color:var(--hsk-chat-muted)}.hsk-cb-scout-picker{position:absolute;inset-block-end:calc(100%+5px);inset-inline-start:50%;transform:translateX(-50%);z-index:50;display:flex;gap:1px;padding:3px;border-radius:13px;background:color-mix(in srgb,var(--hsk-chat-bg) 88%,transparent);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border:1px solid color-mix(in srgb,var(--hsk-chat-text) 12%,transparent);box-shadow:0 12px 30px -8px color-mix(in srgb,var(--hsk-chat-text) 26%,transparent);animation:hsk-theme-morph-in .22s cubic-bezier(.16,1,.3,1) both}.hsk-cb-scout-pick{display:inline-flex;padding:1px;border:none;border-radius:9px;background:transparent;cursor:pointer;transition:background .15s ease,transform .15s ease}.hsk-cb-scout-pick:hover{background:color-mix(in srgb,var(--hsk-primary) 14%,transparent);transform:translateY(-1px)}.hsk-cb-scout-pick.is-on{background:color-mix(in srgb,var(--hsk-primary) 22%,transparent)}.hsk-cb-scout-hatch{padding:2px 0 4px}.hsk-cb-scout-hatch-row{position:relative;display:flex;align-items:center;justify-content:space-between}.hsk-cb-scout-hatch-pick{position:relative;display:inline-flex;flex-direction:column;align-items:center;gap:1px;padding:1px;border:none;border-radius:10px;background:transparent;cursor:pointer;animation:hsk-scout-ooze .5s cubic-bezier(.16,1,.3,1) backwards;transition:transform .2s cubic-bezier(.16,1,.3,1),opacity .2s ease,filter .2s ease}.hsk-cb-scout-hatch-pick:hover,.hsk-cb-scout-hatch-pick:focus-visible{transform:translateY(-5px) scale(1.42);z-index:3;outline:none}.hsk-cb-scout-hatch-pick.is-on{transform:translateY(-3px) scale(1.2);z-index:2;animation:hsk-scout-burst .42s cubic-bezier(.16,1,.3,1)}@keyframes hsk-scout-burst{0%{filter:grayscale(1) saturate(1);transform:translateY(0) scale(1)}45%{filter:grayscale(0) saturate(1.9);transform:translateY(-6px) scale(1.34)}100%{filter:grayscale(0) saturate(1);transform:translateY(-3px) scale(1.2)}}.hsk-cb-scout-hatch-pick.is-on:hover,.hsk-cb-scout-hatch-pick.is-on:focus-visible{transform:translateY(-5px) scale(1.48)}.hsk-cb-scout-hatch-pick:not(.is-on){opacity:.75}.hsk-cb-scout-hatch-pick.is-unpaid{filter:grayscale(1);opacity:.5}.hsk-cb-scout-nick{font-size:7.5px;font-weight:700;letter-spacing:.02em;color:var(--hsk-chat-muted);white-space:nowrap}.hsk-cb-scout-hatch-pick.is-on .hsk-cb-scout-nick{color:var(--hsk-primary)}.hsk-cb-scout-hatch-pick.is-unpaid:hover,.hsk-cb-scout-hatch-pick.is-unpaid:focus-visible{filter:grayscale(.25);opacity:.92}.hsk-cb-scout-hatch-pick.is-unpaid.is-on{filter:grayscale(.4);opacity:.85}.hsk-cb-scout-time{padding:8px 2px 2px}.hsk-cb-scout-time-row{display:flex;align-items:baseline;gap:5px;padding-block-start:7px;transform-origin:center;transition:transform .22s cubic-bezier(.16,1,.3,1)}.hsk-cb-scout-time-row.is-lifted{transform:scale(1.06)}@media (prefers-reduced-motion:reduce){.hsk-cb-dial,.hsk-cb-dial-track,.hsk-cb-scout-time-row{transition:none}.hsk-cb-dial.is-dragging,.hsk-cb-scout-time-row.is-lifted{transform:none}}.hsk-cb-scouts-row{position:relative;display:flex;flex-wrap:wrap;align-items:flex-end;gap:2px}.hsk-cb-scout-slot{position:relative;flex:0 0 auto}.hsk-cb-scout{position:relative;display:flex;flex-direction:column;align-items:center;gap:1px;padding:3px 4px 2px;border:none;border-radius:13px;background:transparent;color:var(--hsk-chat-text);cursor:pointer;font:inherit;transition:transform .18s cubic-bezier(.16,1,.3,1)}.hsk-cb-scout:hover,.hsk-cb-scout:focus-visible{transform:translateY(-3px) scale(1.14);z-index:2;outline:none}.hsk-cb-scout:active{transform:translateY(0) scale(.96)}.hsk-cb-scout-face{position:relative;inline-size:38px;block-size:38px;display:grid;place-items:center}.hsk-cb-scout-char{display:block;overflow:visible}.hsk-cb-scout-pulse{position:absolute;inset-block-start:0;inset-inline-end:0;inline-size:6px;block-size:6px;border-radius:999px;background:#10b981;box-shadow:0 0 0 2px var(--hsk-chat-bg);animation:hsk-scout-breathe 2.4s ease-in-out infinite}@keyframes hsk-scout-breathe{0%,100%{opacity:1}50%{opacity:.35}}.hsk-cb-scout-own{direction:ltr;position:absolute;inset-block-end:-2px;inset-inline-end:-3px;padding:0 4px;border-radius:999px;background:var(--hsk-surface-2);color:var(--hsk-chat-muted);unicode-bidi:isolate;font-size:8px;font-weight:700;line-height:12px;box-shadow:0 0 0 1.5px var(--hsk-chat-bg)}.hsk-cb-scout-name{max-inline-size:48px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;unicode-bidi:isolate;font-size:9px;font-weight:600;color:var(--hsk-chat-muted)}.hsk-cb-scout.is-triggered .hsk-cb-scout-name{color:var(--hsk-primary)}.hsk-cb-scout.is-paused .hsk-cb-scout-face{opacity:.72}.hsk-cb-scout-bin{position:absolute;inset-block-start:-1px;inset-inline-start:-1px;z-index:3;inline-size:16px;block-size:16px;display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;border-radius:999px;background:var(--hsk-surface-2);color:var(--hsk-chat-muted);box-shadow:0 0 0 1.5px var(--hsk-chat-bg);cursor:pointer;opacity:0;transform:scale(.6);transition:opacity .16s ease,transform .16s cubic-bezier(.16,1,.3,1),color .16s ease}.hsk-cb-scout-slot:hover .hsk-cb-scout-bin,.hsk-cb-scout-bin:focus-visible{opacity:1;transform:none}.hsk-cb-scout-bin:hover{color:#e5484d}.hsk-cb-scout-new{flex:0 0 auto;align-self:center;inline-size:34px;block-size:34px;margin-block-end:12px;display:inline-flex;align-items:center;justify-content:center;padding:0;border:1.5px dashed color-mix(in srgb,var(--hsk-chat-text) 24%,transparent);border-radius:12px;background:transparent;color:var(--hsk-chat-muted);cursor:pointer;transition:color .18s ease,border-color .18s ease,transform .18s cubic-bezier(.16,1,.3,1)}.hsk-cb-scout-new:hover{color:var(--hsk-primary);border-color:var(--hsk-primary);transform:translateY(-2px)}.hsk-cb-scout-pool-line{direction:ltr;display:flex;align-items:center;justify-content:flex-start;gap:2px;padding:6px 4px 2px;unicode-bidi:isolate;font-size:9.5px;font-weight:600;color:var(--hsk-chat-muted)}.hsk-cb-scout-picker{position:absolute;inset-block-end:calc(100%+5px);inset-inline-start:50%;transform:translateX(-50%);z-index:50;display:flex;gap:1px;padding:3px;border-radius:13px;background:color-mix(in srgb,var(--hsk-chat-bg) 88%,transparent);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border:1px solid color-mix(in srgb,var(--hsk-chat-text) 12%,transparent);box-shadow:0 12px 30px -8px color-mix(in srgb,var(--hsk-chat-text) 26%,transparent);animation:hsk-theme-morph-in .22s cubic-bezier(.16,1,.3,1) both}.hsk-cb-scout-pick{display:inline-flex;padding:1px;border:none;border-radius:9px;background:transparent;cursor:pointer;transition:background .15s ease,transform .15s ease}.hsk-cb-scout-pick:hover{background:color-mix(in srgb,var(--hsk-primary) 14%,transparent);transform:translateY(-1px)}.hsk-cb-scout-pick.is-on{background:color-mix(in srgb,var(--hsk-primary) 22%,transparent)}.hsk-cb-scout-hatch{padding:2px 0 4px}@keyframes hsk-scout-ooze{from{transform:scale(.15);opacity:0}to{transform:none;opacity:1}}.hsk-cb-scout-hatch-row{position:relative;display:flex;align-items:center;justify-content:space-between}.hsk-cb-scout-hatch-pick{position:relative;display:inline-flex;flex-direction:column;align-items:center;gap:1px;padding:1px;border:none;border-radius:10px;background:transparent;cursor:pointer;animation:hsk-scout-ooze .5s cubic-bezier(.16,1,.3,1) backwards;transition:transform .2s cubic-bezier(.16,1,.3,1),opacity .2s ease,filter .2s ease}.hsk-cb-scout-hatch-pick:hover,.hsk-cb-scout-hatch-pick:focus-visible{transform:translateY(-5px) scale(1.42);z-index:3;outline:none}.hsk-cb-scout-hatch-pick.is-on{transform:translateY(-3px) scale(1.2);z-index:2;animation:hsk-scout-burst .42s cubic-bezier(.16,1,.3,1)}@keyframes hsk-scout-burst{0%{filter:grayscale(1) saturate(1);transform:translateY(0) scale(1)}45%{filter:grayscale(0) saturate(1.9);transform:translateY(-6px) scale(1.34)}100%{filter:grayscale(0) saturate(1);transform:translateY(-3px) scale(1.2)}}.hsk-cb-scout-hatch-pick.is-on:hover,.hsk-cb-scout-hatch-pick.is-on:focus-visible{transform:translateY(-5px) scale(1.48)}.hsk-cb-scout-hatch-pick:not(.is-on){opacity:.75}.hsk-cb-scout-hatch-pick.is-unpaid{filter:grayscale(1);opacity:.5}.hsk-cb-scout-nick{font-size:7.5px;font-weight:700;letter-spacing:.02em;color:var(--hsk-chat-muted);white-space:nowrap}.hsk-cb-scout-hatch-pick.is-on .hsk-cb-scout-nick{color:var(--hsk-primary)}.hsk-cb-scout-hatch-pick.is-unpaid:hover,.hsk-cb-scout-hatch-pick.is-unpaid:focus-visible{filter:grayscale(.25);opacity:.92}.hsk-cb-scout-hatch-pick.is-unpaid.is-on{filter:grayscale(.4);opacity:.85}.hsk-cb-scout-time{padding:8px 2px 2px}.hsk-cb-scout-slider{inline-size:100%;block-size:4px;margin:0 0 8px;padding:0;border-radius:999px;appearance:none;-webkit-appearance:none;background:color-mix(in srgb,var(--hsk-chat-text) 14%,transparent);cursor:pointer}.hsk-cb-scout-slider::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;inline-size:14px;block-size:14px;border:none;border-radius:999px;background:var(--hsk-primary);box-shadow:0 1px 5px color-mix(in srgb,var(--hsk-primary) 55%,transparent);cursor:pointer}.hsk-cb-scout-slider::-moz-range-thumb{inline-size:14px;block-size:14px;border:none;border-radius:999px;background:var(--hsk-primary);cursor:pointer}.hsk-cb-scout-time-row{display:flex;align-items:baseline;gap:5px}.hsk-cb-scout-mins{direction:ltr;border:none;background:transparent;padding:0;cursor:text;display:inline-flex;align-items:baseline;gap:3px;unicode-bidi:isolate;font-size:13px;font-weight:700;color:var(--hsk-chat-text)}.hsk-cb-scout-mins-input{direction:ltr;inline-size:46px;padding:0;border:none;border-block-end:1.5px solid var(--hsk-primary);background:transparent;color:var(--hsk-chat-text);font:inherit;font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;outline:none}.hsk-cb-scout-mins-input::-webkit-outer-spin-button,.hsk-cb-scout-mins-input::-webkit-inner-spin-button{appearance:none;margin:0}.hsk-cb-scout-mins-unit{font-size:9.5px;font-weight:600;color:var(--hsk-chat-muted)}.hsk-cb-scout-price{direction:ltr;margin-inline-start:auto;unicode-bidi:isolate;font-size:17px;font-weight:700;color:var(--hsk-primary)}.hsk-cb-num{display:inline-flex;align-items:baseline;direction:ltr;font-variant-numeric:tabular-nums;line-height:1}.hsk-cb-num-fix{display:inline-block}.hsk-cb-num-slot{display:inline-block;block-size:1em;overflow:hidden;vertical-align:baseline}.hsk-cb-num-col{display:flex;flex-direction:column;transition:transform .52s cubic-bezier(.22,1,.28,1);will-change:transform}.hsk-cb-num-d{display:block;block-size:1em;line-height:1;text-align:center}@media (prefers-reduced-motion:reduce){.hsk-cb-num-col{transition:none}}.hsk-cb-scout-buy-go{inline-size:100%;margin-block-start:8px;padding:7px 0;border:none;border-radius:11px;background:var(--hsk-primary);color:var(--hsk-on-active,#fff);font:inherit;font-size:11px;font-weight:700;cursor:pointer}.hsk-cb-scout-buy-go:disabled{opacity:.45;cursor:not-allowed}.hsk-cb-scout-foot-note{display:block;padding:5px 2px 0;unicode-bidi:isolate;font-size:9px;line-height:1.35;color:var(--hsk-chat-muted)}.hsk-cb-scout-card-pin{border:none;background:none;padding:2px;margin-inline-start:auto;margin-inline-end:2px;display:inline-flex;color:var(--hsk-chat-muted);cursor:pointer;opacity:.7}.hsk-cb-scout-card-pin:hover{opacity:1;color:var(--hsk-primary)}.hsk-cb-pin-body{margin:0;padding:8px;box-sizing:border-box;background:var(--hsk-chat-bg,#18181b);font-family:var(--hsk-font)}.hsk-cb-scout-rail-card.hsk-cb-pin-card{inline-size:100%;max-inline-size:none;min-inline-size:0;animation:none}.hsk-cb-pin-count{font-size:9px;font-weight:700;color:#10b981}.hsk-cb-pin-row{display:flex;align-items:center;gap:6px;padding:2px 0}.hsk-cb-pin-text{display:flex;flex-direction:column;gap:3px;min-inline-size:0;flex:1}.hsk-cb-pin-watch{direction:ltr;font-size:9.5px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--hsk-chat-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hsk-cb-pin-bar{block-size:3px;border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-text) 12%,transparent);overflow:hidden}.hsk-cb-pin-fill{display:block;block-size:100%;border-radius:999px;background:var(--hsk-primary);transition:inline-size .4s cubic-bezier(.16,1,.3,1)}.hsk-cb-pin-hit{font-size:8.5px;font-weight:800;text-transform:uppercase;letter-spacing:.04em;color:var(--hsk-primary)}.hsk-sp-btn{--hsk-primary:var(--chat-primary-color,#ff6a33);display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--hsk-border-radius,0);border:1px solid var(--hsk-sp-border,rgba(255,106,51,.35));background:var(--hsk-sp-bg,rgba(255,106,51,.08));color:var(--hsk-primary);cursor:pointer;font-size:15px;line-height:1;transition:background .15s,border-color .15s,transform .12s;flex-shrink:0;padding:0}.hsk-sp-btn:hover{background:rgba(255,106,51,.18);border-color:rgba(255,106,51,.7);transform:scale(1.1)}.hsk-sp-btn:active{transform:scale(.92)}.hsk-sp-backdrop{position:fixed;inset:0;width:100vw;height:100vh;min-height:100dvh;z-index:2147483647 !important;display:flex;align-items:center;justify-content:center;padding:24px;animation:hsk-bd-in .2s ease-out both;background:var(--hsk-chat-bg,#ffffff) !important;box-sizing:border-box}@keyframes hsk-bd-in{from{opacity:0}to{opacity:1}}.hsk-sp-card{--hsk-primary:var(--chat-primary-color,#ff6a33);width:100%;max-width:600px;border-radius:var(--hsk-border-radius,0);overflow:hidden;animation:hsk-card-in .24s cubic-bezier(.34,1.36,.64,1) both;flex-shrink:0;background:var(--hsk-modal-card-bg,#ffffff);border:1px solid var(--hsk-modal-card-border,#f1f3f4);box-shadow:0 32px 80px rgba(0,0,0,.08),0 2px 8px rgba(0,0,0,.04);display:flex;flex-direction:column}.hsk-sp-card.hsk-sp-fullscreen{max-width:1000px;width:90vw;height:85vh;max-height:800px}@media (max-width:768px){.hsk-sp-backdrop{padding:0}.hsk-sp-card.hsk-sp-fullscreen{width:100vw;height:100vh;height:100dvh;max-height:100vh;max-height:100dvh;border:none;border-radius:0}}@keyframes hsk-card-in{from{opacity:0;transform:scale(.96) translateY(-12px)}to{opacity:1;transform:scale(1) translateY(0)}}.hsk-sp-header{display:flex;align-items:center;gap:10px;padding:18px 20px 14px;border-bottom:1px solid var(--hsk-modal-divide,#f1f3f4);flex-shrink:0}.hsk-sp-header-icon{font-size:18px;color:var(--hsk-primary);flex-shrink:0;display:flex;align-items:center}.hsk-sp-header-body{flex:1;min-width:0}.hsk-sp-header-title{font-size:14px;font-weight:600;color:var(--hsk-modal-text,#1f1f1f);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hsk-sp-header-sub{font-size:11px;color:var(--hsk-modal-muted,#5f6368);margin-top:2px}.hsk-sp-close{width:30px;height:30px;border-radius:var(--hsk-border-radius,0);border:1px solid var(--hsk-modal-divide,#f1f3f4);background:none;color:var(--hsk-modal-muted,#5f6368);cursor:pointer;font-size:18px;display:flex;align-items:center;justify-content:center;transition:all .15s;flex-shrink:0}.hsk-sp-close:hover{border-color:var(--hsk-primary);color:var(--hsk-primary)}.hsk-sp-bar{height:2px;background:linear-gradient(90deg,transparent 0,var(--hsk-primary) 40%,#ffaa80 60%,transparent 100%);background-size:200% 100%;animation:hsk-bar .9s linear infinite;flex-shrink:0}@keyframes hsk-bar{0%{background-position:200% 0}100%{background-position:-200% 0}}.hsk-sp-body{display:flex;flex:1;overflow:hidden}.hsk-sp-details-pane{flex:1;overflow-y:auto;padding:24px;border-right:1px solid var(--hsk-modal-divide,#f1f3f4);display:flex;flex-direction:column;gap:20px}.hsk-sp-chat-pane{flex:1.2;display:flex;flex-direction:column;background:var(--hsk-chat-bg,#ffffff)}.hsk-sp-product-profile{display:flex;gap:20px}@media (max-width:480px){.hsk-sp-product-profile{flex-direction:column}}.hsk-sp-details-imgwrap{width:140px;height:140px;flex-shrink:0;border:1px solid var(--hsk-modal-divide,#f1f3f4);background:#ffffff;display:flex;align-items:center;justify-content:center;padding:8px;border-radius:var(--hsk-border-radius,0)}.hsk-sp-details-imgwrap img{max-width:100%;max-height:100%;object-fit:contain}.hsk-sp-details-meta{flex:1;display:flex;flex-direction:column;gap:6px}.hsk-sp-details-name{font-size:20px;font-weight:700;color:var(--hsk-modal-text,#1f1f1f);margin:0;line-height:1.3}.hsk-sp-details-desc{margin-top:12px}.hsk-sp-details-desc h4{font-size:13px;font-weight:600;color:var(--hsk-modal-text,#1f1f1f);margin:0 0 4px 0}.hsk-sp-details-desc p{font-size:13px;line-height:1.5;color:var(--hsk-modal-muted,#5f6368);margin:0}.hsk-sp-similar-section{border-top:1px solid var(--hsk-modal-divide,#f1f3f4);padding-top:20px}.hsk-sp-similar-section h3{font-size:14px;font-weight:600;color:var(--hsk-modal-text,#1f1f1f);margin:0 0 12px 0}.hsk-sp-results{padding:10px 0;display:flex;flex-direction:row;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:8px}.hsk-sp-empty{padding:40px;text-align:center;font-size:13px;color:var(--hsk-modal-muted,#999)}.hsk-sp-item{display:flex;flex-direction:column;gap:10px;padding:12px;border-radius:var(--hsk-border-radius,0);border:1px solid var(--hsk-modal-item-border,#f1f3f4);background:var(--hsk-modal-item-bg,#f8f9fa);animation:hsk-toast-up .28s cubic-bezier(.22,.68,0,1.2) both;overflow:hidden;flex:0 0 170px;scroll-snap-align:start}@keyframes hsk-toast-up{from{opacity:0;transform:translateY(18px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}.hsk-sp-img-wrap{width:100%;height:120px;border-radius:var(--hsk-border-radius,0);background:#fff;border:1px solid var(--hsk-modal-divide,#f1f3f4);flex-shrink:0;overflow:hidden;display:flex;align-items:center;justify-content:center;padding:6px}.hsk-sp-img-wrap img{max-width:100%;max-height:100%;object-fit:contain}.hsk-sp-img-placeholder{font-size:26px}.hsk-sp-item-body{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:space-between;gap:6px}.hsk-sp-item-name{font-size:13px;font-weight:600;color:var(--hsk-modal-text,#1f1f1f);line-height:1.35;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.hsk-sp-item-cat{font-size:11px;font-weight:600;color:var(--hsk-primary);text-transform:uppercase;letter-spacing:.05em}.hsk-sp-item-price-row{display:flex;align-items:baseline;gap:4px;margin-top:2px;flex-wrap:wrap}.hsk-sp-item-price{font-size:15px;font-weight:700;color:var(--hsk-modal-text,#1f1f1f)}.hsk-sp-item-currency{font-size:11px;color:var(--hsk-modal-muted,#5f6368)}.hsk-sp-actions{display:flex;gap:6px;margin-top:auto}.hsk-sp-action{flex:1;padding:6px 8px;border-radius:var(--hsk-border-radius,0);font-size:11px;font-weight:600;cursor:pointer;border:1px solid transparent;transition:all .15s;text-align:center;font-family:inherit}.hsk-sp-action-primary{background:var(--hsk-primary);color:#fff;border-color:var(--hsk-primary)}.hsk-sp-action-primary:hover{opacity:.88}.hsk-sp-action-secondary{background:var(--hsk-action-sec-bg,#f1f3f4);color:var(--hsk-modal-muted,#5f6368);border-color:var(--hsk-modal-divide,#f1f3f4)}.hsk-sp-action-secondary:hover{background:var(--hsk-action-sec-bg-hover,#e8eaed);color:var(--hsk-modal-text,#1f1f1f)}.hsk-sp-footer{padding:12px 20px;border-top:1px solid var(--hsk-modal-divide,#f1f3f4);display:flex;align-items:center;gap:8px;flex-shrink:0}.hsk-sp-badge{font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--hsk-primary);background:rgba(255,106,51,.1);border:1px solid rgba(255,106,51,.25);padding:2px 8px;border-radius:var(--hsk-border-radius,0)}.hsk-sp-esc{font-size:11px;color:var(--hsk-modal-muted,#5f6368);margin-inline-start:auto}@media (max-width:768px){.hsk-cb-overlay{--hsk-font-size:var(--hsk-mobile-font-size,14px) !important;position:fixed !important;inset:0 !important;top:0 !important;left:0 !important;right:0 !important;width:100vw !important;height:100% !important;height:var(--hsk-vvh,100dvh) !important;min-height:0 !important;z-index:2147483647 !important;display:flex !important;flex-direction:column !important;overflow:hidden !important;overscroll-behavior:contain !important;background:var(--hsk-chat-bg,#0a0a0a) !important;box-sizing:border-box !important}.hsk-cb-panel{position:relative !important;height:100% !important;width:100% !important;max-width:100% !important;margin:0 !important;display:flex !important;flex-direction:column !important;overflow:hidden !important;border-radius:0 !important;background:var(--hsk-chat-bg,#0a0a0a) !important;box-sizing:border-box !important}.hsk-cb-main{flex:1 1 auto !important;height:100% !important;min-height:0 !important;display:flex !important;flex-direction:column !important;justify-content:space-between !important;overflow:hidden !important;background:var(--hsk-chat-bg,#0a0a0a) !important;box-sizing:border-box !important}.hsk-cb-topbar{padding:14px 14px 8px !important}.hsk-cb-msgs{flex:1 1 auto !important;min-height:0 !important;overflow-y:auto !important;-webkit-overflow-scrolling:touch !important;padding:10px 14px 0 !important}.hsk-cb-empty{flex:1 1 auto !important;min-height:0 !important;justify-content:center !important;padding:16px 4px !important}.hsk-cb-input-box{grid-template-columns:auto 1fr auto auto}.hsk-cb-input-box>.hsk-cb-attach-btn,.hsk-cb-input-box>.hsk-cb-voice-mode-btn{display:none}.hsk-cb-input-box>.hsk-cb-field{grid-column:2}.hsk-cb-input-box>.hsk-cb-mic-btn{grid-column:3}.hsk-cb-input-box>.hsk-cb-send,.hsk-cb-input-box>.hsk-chat-send{grid-column:4}.hsk-cb-tools-toggle{display:flex;grid-column:1;grid-row:1;width:36px;height:36px;align-items:center;justify-content:center;flex-shrink:0;padding:0;border:none;border-radius:12px;background:var(--hsk-chat-subtle,rgba(0,0,0,.045));color:var(--hsk-chat-muted,#6b7280);cursor:pointer;transition:transform .26s cubic-bezier(.34,1.56,.64,1),background-color .2s ease}.hsk-cb-tools-toggle--open{transform:rotate(45deg);background:var(--hsk-chat-divide,rgba(0,0,0,.09))}.hsk-cb-toolsheet-wrap,.hsk-cb-toolsheet-scrim{display:block}.hsk-cb-toolsheet-item{display:flex}.hsk-cb-input-box[data-expanded=\\\"true\\\"]>.hsk-cb-tools-toggle{grid-row:2}.hsk-cb-ai-msg--inline{display:block !important;padding-inline-end:34px}.hsk-cb-hello-avatar{display:none !important}.hsk-cb-hello-wrap{align-items:center !important;text-align:center !important;gap:4px !important;width:100% !important;max-width:min(520px,100%) !important;padding-inline:16px !important;box-sizing:border-box !important;margin-inline:auto !important}.hsk-cb-ink-skeleton{align-items:center !important}.hsk-cb-hello{font-size:clamp(21px,5.8vw,30px) !important;font-weight:600 !important;line-height:1.25 !important;letter-spacing:-0.02em !important;color:var(--hsk-chat-muted,#8b8b8f) !important;text-align:center !important;text-wrap:balance;max-width:100% !important;overflow-wrap:break-word}.hsk-cb-hello-lead,.hsk-cb-hello-ask{font-size:14px !important;font-weight:400 !important;line-height:1.45 !important;text-align:center !important;text-wrap:balance;max-width:100% !important;overflow-wrap:break-word;color:color-mix(in srgb,var(--hsk-chat-muted,#8b8b8f) 78%,transparent) !important}.hsk-cb-hello-lead{font-size:14px !important;margin-top:4px !important}.hsk-cb-lang-chips{justify-content:center !important;width:100% !important;gap:8px !important;margin:12px 0 6px !important}.hsk-cb-lang-chips-hint{width:100% !important;justify-content:center !important;margin-top:6px !important;margin-inline-start:0 !important}.hsk-cb-onboarding-head{justify-content:flex-end !important;margin-bottom:12px !important}.hsk-cb-doodles{opacity:.92 !important}.hsk-cb-input-wrap{margin-top:auto !important;flex-shrink:0 !important;--hsk-composer-pad-top:8px;--hsk-composer-pad-x:14px;padding:8px 14px !important;padding-bottom:max(12px,env(safe-area-inset-bottom)) !important;background:var(--hsk-chat-bg,#0a0a0a) !important;position:relative !important;z-index:10 !important}.hsk-cb-attach-btn,.hsk-cb-mic-btn,.hsk-cb-send,.hsk-chat-send{width:32px !important;height:32px !important;border-radius:8px !important}.hsk-cb-attach-btn svg,.hsk-cb-mic-btn svg,.hsk-cb-send svg,.hsk-chat-send svg{width:15px !important;height:15px !important}.hsk-sp-backdrop.hsk-sp-mobile-view{position:fixed !important;top:0 !important;left:0 !important;right:0 !important;bottom:auto !important;width:100vw !important;height:var(--hsk-vvh,100dvh) !important;min-height:0 !important;z-index:2147483647 !important;display:flex !important;flex-direction:column !important;overflow:hidden !important;overscroll-behavior:contain !important;background:var(--hsk-chat-bg,#0a0a0a) !important;padding:0 !important;box-sizing:border-box !important}.hsk-sp-card.hsk-sp-mobile-card{position:relative !important;width:100% !important;height:100% !important;max-width:100% !important;margin:0 !important;display:flex !important;flex-direction:column !important;justify-content:space-between !important;overflow:hidden !important;border-radius:0 !important;background:var(--hsk-chat-bg,#0a0a0a) !important;box-sizing:border-box !important}.hsk-sp-body{flex:1 1 auto !important;min-height:0 !important;display:flex !important;flex-direction:column !important;overflow-y:auto !important;-webkit-overflow-scrolling:touch !important;background:var(--hsk-chat-bg,#0a0a0a) !important}.hsk-cb-input-box{padding:10px 10px 10px 14px}.hsk-cb-user-bubble{max-width:85%}.hsk-sp-footer{padding:8px 12px}}@media (prefers-color-scheme:dark){.hsk-sp-backdrop{background:#000000 !important}.hsk-sp-card{--hsk-modal-card-bg:#0a0a0a;--hsk-modal-card-border:#202124;--hsk-modal-text:#e8eaed;--hsk-modal-muted:#888;--hsk-action-sec-bg:#202124;--hsk-action-sec-bg-hover:#2d2f34}.hsk-sp-details-imgwrap{background:#202124;border-color:#202124}.hsk-sp-img-wrap{background:#202124;border-color:#202124}.hsk-sp-chat-pane{background:var(--hsk-chat-bg,#0a0a0a)}}@media (prefers-color-scheme:light){.hsk-sp-backdrop{background:#ffffff !important}}.hsk-table-wrapper{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:12px 0 8px;width:100%;max-width:100%;min-width:0;border-radius:0;padding:0 0 6px;background:transparent;box-shadow:none;box-sizing:border-box;scrollbar-width:thin;scrollbar-color:var(--hsk-chat-divide,rgba(0,0,0,.2)) transparent;cursor:grab;user-select:auto;transition:mask-image .15s ease,-webkit-mask-image .15s ease}.hsk-table-wrapper.is-dragging{cursor:grabbing;user-select:none}.hsk-table-wrapper::-webkit-scrollbar{height:5px}.hsk-table-wrapper::-webkit-scrollbar-track{background:transparent}.hsk-table-wrapper::-webkit-scrollbar-thumb{background:var(--hsk-chat-divide,rgba(0,0,0,.25));border-radius:4px}.hsk-table-wrapper::-webkit-scrollbar-thumb:hover{background:var(--hsk-chat-muted,rgba(0,0,0,.5))}.hsk-cb-ai-text .hsk-markdown-p{margin:0 0 10px}.hsk-cb-ai-text .hsk-markdown-p:last-child{margin-bottom:0}.hsk-cb-ai-text .hsk-markdown-list{margin:0 0 10px;padding-inline-start:1.2em}.hsk-cb-ai-text .hsk-markdown-list:last-child{margin-bottom:0}.hsk-cb-ai-text .hsk-markdown-ul{list-style:disc outside}.hsk-cb-ai-text .hsk-markdown-ol{list-style:decimal outside}.hsk-cb-ai-text .hsk-markdown-list li{margin:0 0 7px;padding-left:3px;line-height:1.5}.hsk-cb-ai-text .hsk-markdown-list li:last-child{margin-bottom:0}.hsk-cb-ai-text .hsk-markdown-list li::marker{color:var(--hsk-primary,#ff6a33)}.hsk-cb-ai-text .hsk-markdown-h1,.hsk-cb-ai-text .hsk-markdown-h2,.hsk-cb-ai-text .hsk-markdown-h3{margin:14px 0 7px;font-weight:650;line-height:1.3;letter-spacing:-0.01em}.hsk-cb-ai-text .hsk-markdown-h1{font-size:1.09em}.hsk-cb-ai-text .hsk-markdown-h2{font-size:1.03em}.hsk-cb-ai-text .hsk-markdown-h3{font-size:1em}.hsk-cb-ai-text>:first-child{margin-top:0}.hsk-markdown-table{width:max-content;min-width:100%;border-collapse:collapse;border-spacing:0;text-align:start;font-size:13px;background:transparent;margin:0;border:none;font-variant-numeric:tabular-nums}.hsk-markdown-table th{padding:8px 16px 6px 16px;vertical-align:bottom;line-height:1.35;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;color:var(--hsk-chat-muted,rgba(0,0,0,.55));border-bottom:1px solid var(--hsk-chat-divide,rgba(0,0,0,.1));background:transparent !important}.hsk-markdown-table td{padding:8px 16px 8px 16px;vertical-align:middle;line-height:1.45;font-size:13px;white-space:nowrap;color:var(--hsk-chat-text,inherit);border-bottom:.5px solid var(--hsk-chat-divide,rgba(0,0,0,.06));background:transparent !important}.hsk-markdown-table th:first-child,.hsk-markdown-table td:first-child{padding-inline-start:0;font-weight:590;white-space:normal;max-width:280px;min-width:150px;line-height:1.35}.hsk-markdown-table th:last-child,.hsk-markdown-table td:last-child{padding-inline-end:0}.hsk-markdown-table tbody tr:last-child td{border-bottom:none}.hsk-markdown-table td *{color:inherit}.hsk-markdown-table .hsk-markdown-link{display:inline-flex;align-items:center;padding:2px 8px;background-color:var(--hsk-chat-source-bg,rgba(0,0,0,.04));border:1px solid var(--hsk-chat-divide,rgba(0,0,0,.08));color:var(--hsk-primary,#ff6a33);font-size:12px;font-weight:500;border-radius:6px;text-decoration:none !important;margin:2px 0;transition:opacity .15s ease}.hsk-markdown-table .hsk-markdown-link:hover{opacity:.8}@media (prefers-color-scheme:dark){.hsk-markdown-table th{color:var(--hsk-chat-muted,rgba(255,255,255,.5));border-bottom-color:var(--hsk-chat-divide,rgba(255,255,255,.1))}.hsk-markdown-table td{color:var(--hsk-chat-text,#f0efed);border-bottom-color:var(--hsk-chat-divide,rgba(255,255,255,.06))}}.hsk-markdown-link{color:var(--hsk-primary,#ff6a33);text-decoration:underline;text-underline-offset:2px}.hsk-markdown-code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\\\"Liberation Mono\\\",\\\"Courier New\\\",monospace,var(--hsk-font);font-size:.85em;background-color:rgba(128,128,128,.15);padding:.2em .4em;border-radius:var(--hsk-border-radius,0);color:inherit;word-break:break-word}.hsk-markdown-img-block{margin:8px 0;line-height:0}.hsk-markdown-img{display:block;max-width:100%;width:auto;max-height:220px;border-radius:10px;box-shadow:0 2px 12px rgba(0,0,0,.18);object-fit:cover;background:rgba(128,128,128,.08)}.hsk-sp-item-original-price{font-size:12px;text-decoration:line-through;color:var(--hsk-modal-muted,#888);margin-left:6px}.hsk-sp-item-discount{font-size:11px;font-weight:600;color:#10b981;margin-left:6px}.hsk-sp-item-meta-badges{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}.hsk-sp-meta-badge{font-size:11px;font-weight:500;padding:3px 8px;border-radius:var(--hsk-border-radius,0);background:var(--hsk-modal-item-bg,#f8f9fa);border:1px solid var(--hsk-modal-divide,#f1f3f4);color:var(--hsk-modal-muted,#5f6368)}.hsk-sp-meta-badge-rating{color:#f59e0b;background:rgba(245,158,11,.08);border-color:rgba(245,158,11,.2)}.hsk-sp-meta-badge-avail.in-stock{color:#10b981;background:rgba(16,185,129,.08);border-color:rgba(16,185,129,.2)}.hsk-sp-meta-badge-avail.out-stock{color:#ef4444;background:rgba(239,68,68,.08);border-color:rgba(239,68,68,.2)}.hsk-sp-item-brand{font-size:11px;font-weight:700;color:var(--hsk-modal-muted,#888);text-transform:uppercase;letter-spacing:.05em;margin-bottom:-2px}.hsk-chat-widget::-webkit-scrollbar,.hsk-sp-card::-webkit-scrollbar,.hsk-cb-msgs::-webkit-scrollbar,.hsk-sp-details-pane::-webkit-scrollbar,.hsk-sp-results::-webkit-scrollbar,.hsk-chat-messages::-webkit-scrollbar{width:3px;height:3px}.hsk-chat-widget::-webkit-scrollbar-track,.hsk-sp-card::-webkit-scrollbar-track,.hsk-cb-msgs::-webkit-scrollbar-track,.hsk-sp-details-pane::-webkit-scrollbar-track,.hsk-sp-results::-webkit-scrollbar-track,.hsk-chat-messages::-webkit-scrollbar-track{background:transparent}.hsk-chat-widget::-webkit-scrollbar-thumb,.hsk-sp-card::-webkit-scrollbar-thumb,.hsk-cb-msgs::-webkit-scrollbar-thumb,.hsk-sp-details-pane::-webkit-scrollbar-thumb,.hsk-sp-results::-webkit-scrollbar-thumb,.hsk-chat-messages::-webkit-scrollbar-thumb{background:rgba(0,0,0,.06);border-radius:99px;transition:background .2s ease}.hsk-chat-widget::-webkit-scrollbar-thumb:hover,.hsk-cb-msgs::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.15)}@media (prefers-color-scheme:dark){.hsk-chat-widget::-webkit-scrollbar-thumb,.hsk-sp-card::-webkit-scrollbar-thumb,.hsk-cb-msgs::-webkit-scrollbar-thumb,.hsk-sp-details-pane::-webkit-scrollbar-thumb,.hsk-sp-results::-webkit-scrollbar-thumb,.hsk-chat-messages::-webkit-scrollbar-thumb{background:rgba(255,255,255,.08)}.hsk-chat-widget::-webkit-scrollbar-thumb:hover,.hsk-cb-msgs::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.2)}}.hsk-sp-details-pane,.hsk-sp-results,.hsk-chat-messages{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.06) transparent}@media (prefers-color-scheme:dark){.hsk-sp-details-pane,.hsk-sp-results,.hsk-chat-messages{scrollbar-color:rgba(255,255,255,.08) transparent}}.hsk-sp-specs-horizontal{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.hsk-sp-spec-item-horizontal{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;background:var(--hsk-modal-item-bg,#f8f9fa);border:1px solid var(--hsk-modal-divide,#f1f3f4);border-radius:var(--hsk-border-radius,0);font-size:11px}.hsk-sp-spec-label-horizontal{font-weight:500;color:var(--hsk-modal-muted,#888)}.hsk-sp-spec-value-horizontal{font-weight:600;color:var(--hsk-modal-text,#1f1f1f)}@media (prefers-color-scheme:dark){.hsk-sp-spec-item-horizontal{background:#1a1a1b;border-color:#202124}}.hsk-cb-phone-form{display:flex;flex-direction:column;gap:8px;margin-top:8px}.hsk-cb-phone-label{font-size:.875rem;color:var(--hsk-chat-text,#111);margin:0}.hsk-cb-phone-input{width:100%;box-sizing:border-box;padding:8px 12px;border:1px solid var(--hsk-chat-divide,rgba(0,0,0,.12));border-radius:var(--hsk-border-radius,0);background:var(--hsk-chat-input-bg,rgba(0,0,0,.04));color:var(--hsk-chat-text,#111);font-size:.9rem;outline:none;transition:border-color .15s}.hsk-cb-phone-input::placeholder{color:var(--hsk-chat-muted,#888)}.hsk-cb-phone-input:focus{border-color:var(--hsk-primary,#ff6a33)}.hsk-cb-phone-submit{align-self:flex-start;padding:8px 16px;border:1px solid var(--hsk-chat-divide,rgba(0,0,0,.12));border-radius:var(--hsk-border-radius,0);background:transparent;color:var(--hsk-chat-text,#111);font-size:.875rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.hsk-cb-phone-submit:hover{border-color:var(--hsk-primary,#ff6a33);color:var(--hsk-primary,#ff6a33)}.hsk-cb-main{flex:1;min-width:0;display:flex;flex-direction:column;height:100%;overflow:hidden}@keyframes hsk-fade-in-up{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.hsk-action-pills{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;animation:hsk-fade-in-up .35s ease .1s both}.hsk-action-pill{display:inline-flex;align-items:center;gap:5px;padding:6px 12px;border-radius:20px;border:1px solid var(--hsk-chat-divide,rgba(0,0,0,.12));background:var(--hsk-pill-bg,rgba(255,255,255,.8));color:var(--hsk-chat-text,#1f1f1f);font-size:12px;font-weight:500;cursor:pointer;font-family:inherit;transition:all .15s;white-space:nowrap;backdrop-filter:blur(4px)}.hsk-action-pill:hover:not(:disabled){border-color:var(--hsk-primary,#ff6a33);background:color-mix(in srgb,var(--hsk-primary,#ff6a33) 8%,transparent);color:var(--hsk-primary,#ff6a33);transform:translateY(-1px);box-shadow:0 2px 8px rgba(0,0,0,.08)}.hsk-action-pill:disabled{opacity:.4;cursor:not-allowed}.hsk-pill-emoji{font-size:13px;line-height:1}@media (prefers-color-scheme:dark){.hsk-action-pill{--hsk-pill-bg:rgba(40,40,42,.85);border-color:rgba(255,255,255,.1);color:var(--hsk-chat-text,#e8eaed)}}[data-hsk-theme=\\\"dark\\\"] .hsk-action-pill{--hsk-pill-bg:rgba(40,40,42,.85);border-color:rgba(255,255,255,.1);color:var(--hsk-chat-text,#e8eaed)}.hsk-sp-tabs-mobile{display:none}@media (max-width:768px){.hsk-sp-tabs-mobile{display:flex;border-bottom:1px solid var(--hsk-modal-divide,#f1f3f4);background:var(--hsk-modal-card-bg,#ffffff);flex-shrink:0}.hsk-sp-tab-btn{flex:1;padding:12px 8px;background:none;border:none;border-bottom:2px solid transparent;font-size:13px;font-weight:600;color:var(--hsk-modal-muted,#5f6368);cursor:pointer;text-align:center;transition:all .15s;font-family:inherit}.hsk-sp-tab-btn.active{color:var(--hsk-primary);border-bottom-color:var(--hsk-primary)}.hsk-sp-pane-hidden-mobile{display:none !important}.hsk-sp-details-pane,.hsk-sp-chat-pane{flex:1 !important;height:100% !important;max-height:none !important}}@media (max-width:768px){.hsk-sp-header-title-row{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%}.hsk-sp-header-specs-btn{flex-shrink:0;padding:4px 10px;font-size:11px;font-weight:600;color:var(--hsk-modal-muted,#5f6368);background:var(--hsk-action-sec-bg,#f1f3f4);border:1px solid var(--hsk-modal-divide,#f1f3f4);border-radius:20px;cursor:pointer;font-family:inherit;transition:all .2s ease}.hsk-sp-header-specs-btn:hover{background:var(--hsk-action-sec-bg-hover,#e8eaed);color:var(--hsk-primary)}.hsk-sp-mobile-attachment-deck{margin-top:10px;display:flex;flex-direction:column;gap:10px;width:100%}.hsk-sp-mobile-main-card{display:flex;align-items:center;gap:12px;padding:10px 12px;background:var(--hsk-modal-item-bg,#f8f9fa);border:1px solid var(--hsk-modal-divide,#f1f3f4);border-radius:8px;width:100%;box-sizing:border-box}.hsk-sp-mobile-main-card-img{width:44px;height:44px;flex-shrink:0;border:1px solid var(--hsk-modal-divide,#f1f3f4);border-radius:6px;background:#ffffff;display:flex;align-items:center;justify-content:center;padding:3px;overflow:hidden}.hsk-sp-mobile-main-card-img img{max-width:100%;max-height:100%;object-fit:contain}.hsk-sp-mobile-main-card-info{flex:1;min-width:0}.hsk-sp-mobile-main-card-brand{font-size:9px;font-weight:700;color:var(--hsk-modal-muted,#888);text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hsk-sp-mobile-main-card-name{font-size:13px;font-weight:600;color:var(--hsk-modal-text,#1f1f1f);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}.hsk-sp-mobile-main-card-price{font-size:12px;font-weight:700;color:var(--hsk-primary);margin-top:1px}.hsk-sp-mobile-main-card-specs-btn{padding:5px 10px;font-size:11px;font-weight:600;color:var(--hsk-primary);background:transparent;border:1px solid var(--hsk-primary);border-radius:4px;cursor:pointer;font-family:inherit;transition:all .2s ease}.hsk-sp-mobile-main-card-specs-btn:hover{background:var(--hsk-primary);color:#ffffff}.hsk-sp-mobile-similar-carousel-inline{display:flex;flex-direction:column;gap:6px;width:100%}.hsk-sp-mobile-similar-carousel-title{font-size:10px;font-weight:700;color:var(--hsk-modal-muted,#888);text-transform:uppercase;letter-spacing:.05em;padding-left:2px}.hsk-sp-mobile-similar-carousel-list{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px}.hsk-sp-mobile-similar-carousel-list::-webkit-scrollbar{display:none}.hsk-sp-mobile-similar-carousel-item{flex:0 0 160px;display:flex;align-items:center;gap:8px;padding:6px 8px;background:var(--hsk-modal-item-bg,#f8f9fa);border:1px solid var(--hsk-modal-divide,#f1f3f4);border-radius:6px;cursor:pointer;box-sizing:border-box;transition:transform .15s ease,border-color .15s ease}.hsk-sp-mobile-similar-carousel-item:hover{border-color:var(--hsk-primary)}.hsk-sp-mobile-similar-carousel-img{width:32px;height:32px;flex-shrink:0;border-radius:4px;background:#ffffff;border:1px solid var(--hsk-modal-divide,#f1f3f4);display:flex;align-items:center;justify-content:center;padding:2px;overflow:hidden}.hsk-sp-mobile-similar-carousel-img img{max-width:100%;max-height:100%;object-fit:contain}.hsk-sp-mobile-similar-carousel-meta{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}.hsk-sp-mobile-similar-carousel-name{font-size:11px;font-weight:600;color:var(--hsk-modal-text,#1f1f1f);line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hsk-sp-mobile-similar-carousel-price{font-size:10px;font-weight:700;color:var(--hsk-primary);margin-top:1px}.hsk-sp-mobile-chat-container{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--hsk-chat-bg,#ffffff)}.hsk-sp-mobile-specs-overlay{position:fixed;inset:0;z-index:100000;background:rgba(0,0,0,.4);display:flex;align-items:flex-end;animation:hsk-bd-in .2s ease-out}.hsk-sp-mobile-specs-drawer{width:100%;background:var(--hsk-modal-card-bg,#ffffff);border-top-left-radius:12px;border-top-right-radius:12px;max-height:70vh;display:flex;flex-direction:column;animation:hsk-drawer-in .25s cubic-bezier(0,0,.2,1);box-shadow:0 -8px 24px rgba(0,0,0,.15)}@keyframes hsk-drawer-in{from{transform:translateY(100%)}to{transform:translateY(0)}}.hsk-sp-mobile-specs-header{display:flex;justify-content:space-between;align-items:center;padding:14px 16px;border-bottom:1px solid var(--hsk-modal-divide,#f1f3f4)}.hsk-sp-mobile-specs-header h3{margin:0;font-size:14px;font-weight:700;color:var(--hsk-modal-text,#1f1f1f)}.hsk-sp-mobile-specs-header button{background:none;border:none;font-size:12px;font-weight:600;color:var(--hsk-primary);cursor:pointer;font-family:inherit}.hsk-sp-mobile-specs-body{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:16px}.hsk-sp-mobile-specs-title{font-size:15px;font-weight:700;color:var(--hsk-modal-text,#1f1f1f);margin:0}.hsk-sp-mobile-specs-desc h5,.hsk-sp-mobile-specs-list h5{margin:0 0 6px 0;font-size:11px;font-weight:700;color:var(--hsk-modal-muted,#888);text-transform:uppercase;letter-spacing:.05em}.hsk-sp-mobile-specs-desc p{margin:0;font-size:13px;line-height:1.5;color:var(--hsk-modal-text,#333)}.hsk-sp-mobile-specs-list{display:flex;flex-direction:column;gap:8px}.hsk-sp-mobile-spec-row{display:flex;justify-content:space-between;padding:8px 10px;background:var(--hsk-modal-item-bg,#f8f9fa);border:1px solid var(--hsk-modal-divide,#f1f3f4);border-radius:var(--hsk-border-radius,4px);font-size:12px;gap:12px}.hsk-sp-mobile-spec-label{color:var(--hsk-modal-muted,#5f6368);font-weight:500}.hsk-sp-mobile-spec-value{color:var(--hsk-modal-text,#1f1f1f);font-weight:600;text-align:right}}@media (prefers-color-scheme:dark){.hsk-sp-mobile-main-card{background:#0a0a0a !important}.hsk-sp-mobile-main-card-img{background:#1a1a1b !important}.hsk-sp-mobile-similar-carousel-item{background:#0a0a0a !important}.hsk-sp-mobile-similar-carousel-img{background:#1a1a1b !important}.hsk-sp-mobile-specs-drawer{background:#0a0a0a !important}.hsk-sp-mobile-spec-row{background:#1a1a1b !important}}.kiku-voice-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;border:none;background:transparent;color:var(--hsk-text-muted,#888);cursor:pointer;transition:color .2s,background .2s;flex-shrink:0}.kiku-voice-btn:hover{background:var(--hsk-hover-bg,rgba(0,0,0,.06));color:var(--hsk-primary,#6c47ff)}.kiku-voice-btn--active{color:#ef4444;background:rgba(239,68,68,.1)}.kiku-voice-btn:disabled{opacity:.4;cursor:not-allowed}.kiku-voice-ripple{position:absolute;inset:-4px;border-radius:50%;border:2px solid #ef4444;animation:kiku-voice-pulse 1.2s ease-out infinite;pointer-events:none}@keyframes kiku-voice-pulse{0%{transform:scale(1);opacity:1}100%{transform:scale(1.6);opacity:0}}.kiku-vs-btn{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;border:none;background:transparent;color:var(--hsk-text-muted,#888);cursor:pointer;transition:color .2s,background .2s;flex-shrink:0}.kiku-vs-btn:hover{background:var(--hsk-hover-bg,rgba(0,0,0,.06));color:var(--hsk-primary,#6c47ff)}.kiku-vs-btn--loading{opacity:.6;pointer-events:none}@keyframes kiku-vs-rotate{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.kiku-vs-spin{animation:kiku-vs-rotate .8s linear infinite}.kiku-style-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}.kiku-style-tag{display:inline-flex;align-items:center;gap:3px;padding:2px 8px;border-radius:99px;background:var(--hsk-primary-alpha,rgba(108,71,255,.1));color:var(--hsk-primary,#6c47ff);font-size:11px;font-weight:500;white-space:nowrap}.kiku-vs-preview-banner{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--hsk-surface,#f9f9f9);border-radius:10px;margin-bottom:12px;border:1px solid var(--hsk-border,#e5e5e5)}.kiku-vs-preview-img{width:44px;height:44px;object-fit:cover;border-radius:8px;flex-shrink:0}.kiku-vs-preview-info{flex:1;min-width:0}.kiku-vs-preview-label{font-size:11px;color:var(--hsk-text-muted,#888);margin-bottom:2px}.kiku-vs-preview-palette{font-size:13px;font-weight:600;color:var(--hsk-text,#1a1a1a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kiku-voice-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;border:none;background:transparent;color:var(--hsk-text-muted,#888);cursor:pointer;transition:color .2s,background .2s;flex-shrink:0}.kiku-voice-btn:hover{background:var(--hsk-hover-bg,rgba(0,0,0,.06));color:var(--hsk-primary,#ff6a33)}.kiku-voice-btn--active{color:#ef4444;background:rgba(239,68,68,.1)}.kiku-voice-btn:disabled{opacity:.4;cursor:not-allowed}.kiku-voice-ripple{position:absolute;inset:-4px;border-radius:50%;border:2px solid #ef4444;animation:kiku-voice-pulse 1.2s ease-out infinite;pointer-events:none}@keyframes kiku-voice-pulse{0%{transform:scale(1);opacity:1}100%{transform:scale(1.7);opacity:0}}.kiku-vs-btn{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;border:none;background:transparent;color:var(--hsk-text-muted,#888);cursor:pointer;transition:color .2s,background .2s;flex-shrink:0}.kiku-vs-btn:hover{background:var(--hsk-hover-bg,rgba(0,0,0,.06));color:var(--hsk-primary,#ff6a33)}.kiku-vs-btn--loading{opacity:.6;pointer-events:none}@keyframes kiku-vs-rotate{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.kiku-vs-spin{animation:kiku-vs-rotate .8s linear infinite}.kiku-style-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}.kiku-style-tag{display:inline-flex;align-items:center;gap:3px;padding:2px 8px;border-radius:99px;background:rgba(255,106,51,.1);color:var(--hsk-primary,#ff6a33);font-size:11px;font-weight:500;white-space:nowrap}.kiku-vs-preview-banner{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--hsk-surface,#f9f9f9);border-radius:10px;margin-bottom:12px;border:1px solid var(--hsk-border,#e5e5e5);animation:hsk-msg-in .22s ease-out both}.kiku-vs-preview-img{width:44px;height:44px;object-fit:cover;border-radius:8px;flex-shrink:0}.kiku-vs-preview-info{flex:1;min-width:0}.kiku-vs-preview-label{font-size:11px;color:var(--hsk-text-muted,#888);margin-bottom:2px}.kiku-vs-preview-palette{font-size:13px;font-weight:600;color:var(--hsk-text,#1a1a1a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hsk-cb-source--referenced{}.hsk-source-card--referenced{}.hsk-cb-source-ref-badge{position:absolute;top:6px;right:6px;background:#fbbf24;color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 4px rgba(0,0,0,.15);z-index:10;animation:hsk-badge-pop .3s cubic-bezier(.34,1.56,.64,1) both}@keyframes hsk-badge-pop{from{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}.hsk-sources-group-title{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#888;margin:14px 0 8px 0;display:flex;align-items:center;gap:4px}.hsk-kiku-badge{display:inline-flex;align-items:center;gap:3px;font-size:13px;font-weight:700;letter-spacing:-0.01em;color:#ffffff;background:rgba(255,255,255,.28);border:1px solid rgba(255,255,255,.45);padding:2px 8px;border-radius:8px;margin-inline-end:8px;vertical-align:middle;position:relative;top:-1px;box-shadow:0 1px 3px rgba(0,0,0,.12)}.hsk-markdown-img,.hsk-cb-user-img-thumb,.hsk-cb-source .hsk-cb-src-imgwrap img{cursor:zoom-in}.hsk-lightbox{position:fixed;inset:0;z-index:999999;background:rgba(0,0,0,.85);display:flex;align-items:center;justify-content:center;padding:24px;animation:hsk-lightbox-in .15s ease-out both;cursor:zoom-out}@keyframes hsk-lightbox-in{from{opacity:0}to{opacity:1}}.hsk-lightbox-img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;border-radius:4px;cursor:default}.hsk-lightbox-close{position:absolute;top:16px;right:16px;width:36px;height:36px;border-radius:50%;border:none;background:rgba(255,255,255,.15);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s}.hsk-lightbox-close:hover{background:rgba(255,255,255,.28)}.hsk-cb-viz{margin-top:10px;animation:hsk-msg-in .2s ease-out both}.hsk-cb-viz img,.hsk-cb-viz video{width:100%;max-width:420px;border-radius:8px;display:block}.hsk-cb-viz-disclaimer{max-width:420px;margin-top:4px;font-size:11px;line-height:1.4;color:var(--hsk-chat-muted,#9aa0a6)}.hsk-cb-calc-disclaimer{max-width:440px;margin-top:8px;padding:8px 12px;font-size:11.5px;line-height:1.45;color:var(--hsk-chat-muted,rgba(255,255,255,.65));background:var(--hsk-chat-callout-bg,rgba(255,255,255,.04));border:1px solid var(--hsk-border-subtle,rgba(255,255,255,.08));border-radius:8px}[data-hsk-theme=\\\"light\\\"] .hsk-cb-calc-disclaimer{color:rgba(0,0,0,.6);background:rgba(0,0,0,.03);border-color:rgba(0,0,0,.08)}.hsk-cb-stale{max-width:420px;margin-top:8px;padding:8px 10px;border:1px solid rgba(220,38,38,.35);border-left-width:3px;border-radius:6px;background:rgba(220,38,38,.06)}.hsk-cb-stale-title{font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#dc2626}.hsk-cb-stale-item{margin-top:3px;font-size:12px;line-height:1.45;color:var(--hsk-chat-text,#202124)}.hsk-cb-stale-reason{color:var(--hsk-chat-muted,#9aa0a6)}.hsk-cb-viz-imgwrap{position:relative;display:inline-block;max-width:100%}.hsk-cb-viz-mark{position:absolute;right:10px;bottom:10px;display:inline-flex;align-items:center;gap:6px;padding:8px 14px;font-size:13px;font-weight:600;color:#fff;background:rgba(0,0,0,.62);backdrop-filter:blur(6px);border:1px solid rgba(255,255,255,.35);border-radius:999px;cursor:pointer;transition:background .15s}.hsk-cb-viz-mark:hover{background:var(--hsk-primary,#ff6a33);border-color:transparent}.hsk-markup-overlay{position:fixed;inset:0;z-index:999999;background:rgba(0,0,0,.88);display:flex;align-items:center;justify-content:center;padding:16px;animation:hsk-lightbox-in .15s ease-out both}.hsk-markup{display:flex;flex-direction:column;gap:12px;width:min(720px,100%);max-height:100%;overflow-y:auto}.hsk-markup-head{display:flex;align-items:center;justify-content:space-between}.hsk-markup-title{font-size:14px;font-weight:600;color:#fff}.hsk-markup-cancel{padding:6px 12px;font-size:12px;font-weight:600;color:#fff;background:rgba(255,255,255,.12);border:none;border-radius:var(--hsk-border-radius,0);cursor:pointer}.hsk-markup-cancel:hover{background:rgba(255,255,255,.22)}.hsk-markup-stage{display:flex;justify-content:center}.hsk-markup-canvas-wrap{position:relative;max-width:100%}.hsk-markup-canvas{display:block;max-width:100%;max-height:60vh;border-radius:var(--hsk-border-radius,0);touch-action:none}.hsk-markup-canvas--pen,.hsk-markup-canvas--eraser{cursor:crosshair}.hsk-markup-canvas--text{cursor:text}.hsk-markup-textinput{position:absolute;transform:translateY(-100%);min-width:140px;padding:4px 6px;font-size:14px;font-weight:600;background:rgba(0,0,0,.55);border:1px dashed rgba(255,255,255,.6);border-radius:4px;outline:none}.hsk-markup-loading,.hsk-markup-error{padding:40px 16px;font-size:13px;color:rgba(255,255,255,.75);text-align:center}.hsk-markup-tools{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.hsk-markup-colors{display:flex;gap:8px}.hsk-markup-color{width:22px;height:22px;border-radius:50%;border:2px solid transparent;cursor:pointer;padding:0}.hsk-markup-color--on{border-color:#fff;transform:scale(1.15)}.hsk-markup-actions{display:flex;gap:6px}.hsk-markup-tool{padding:6px 11px;font-size:12px;font-weight:600;color:#fff;background:rgba(255,255,255,.12);border:none;border-radius:var(--hsk-border-radius,0);cursor:pointer}.hsk-markup-tool:hover:not(:disabled){background:rgba(255,255,255,.22)}.hsk-markup-tool--on{background:var(--hsk-primary,#ff6a33)}.hsk-markup-tool--on:hover:not(:disabled){background:var(--hsk-primary,#ff6a33)}.hsk-markup-tool:disabled{opacity:.4;cursor:default}.hsk-markup-send{display:flex;gap:8px}.hsk-markup-instruction{flex:1;min-width:0;padding:10px 12px;font-size:14px;color:#fff;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.25);border-radius:var(--hsk-border-radius,0);outline:none}.hsk-markup-instruction::placeholder{color:rgba(255,255,255,.5)}.hsk-markup-instruction:focus{border-color:var(--hsk-primary,#ff6a33)}.hsk-markup-go{padding:10px 20px;font-size:13px;font-weight:600;color:#fff;background:var(--hsk-primary,#ff6a33);border:none;border-radius:var(--hsk-border-radius,0);cursor:pointer}.hsk-markup-go:hover:not(:disabled){opacity:.9}.hsk-markup-go:disabled{opacity:.45;cursor:default}.hsk-cb-kimgs{margin-top:10px;display:flex;flex-direction:column;gap:10px;animation:hsk-msg-in .2s ease-out both}.hsk-cb-kimg-grid{display:flex;flex-wrap:wrap;gap:6px}.hsk-cb-kimg{width:132px;height:132px;object-fit:cover;border-radius:8px;cursor:zoom-in;border:1px solid var(--hsk-chat-border,rgba(0,0,0,.08))}.hsk-cb-kimg:only-child{width:100%;max-width:320px;height:auto}.hsk-cb-kimg-caption{margin-top:4px;font-size:11px;line-height:1.4;color:var(--hsk-chat-muted,#9aa0a6)}.hsk-cb-viz--loading{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--hsk-chat-muted,#888);padding:10px 0}.hsk-cb-viz-spinner{width:14px;height:14px;border-radius:50%;border:2px solid var(--hsk-chat-divide,rgba(0,0,0,.15));border-top-color:var(--hsk-primary,#ff6a33);animation:hsk-viz-spin .7s linear infinite}@keyframes hsk-viz-spin{to{transform:rotate(360deg)}}.hsk-cb-panel[data-script=\\\"nonlatin\\\"][data-host-font=\\\"gap\\\"]{--hsk-font:\\\"Geist\\\",system-ui,-apple-system,'Segoe UI',Roboto,'Noto Sans',sans-serif}.hsk-cb-panel[data-script=\\\"nonlatin\\\"],.hsk-cb-panel[data-script=\\\"nonlatin\\\"] *{letter-spacing:normal;font-family:var(--hsk-font)}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-hello,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-hello-lead,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-hello-ask,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-ai-text,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-user-bubble,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-hint,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-chip,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-topbar-btn,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-textarea,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-entlang-opt-title,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-entlang-opt-note,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-ai-text .hsk-markdown-list li,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-ai-text .hsk-markdown-h1,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-ai-text .hsk-markdown-h2,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-ai-text .hsk-markdown-h3,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-markdown-table th,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-markdown-table td{line-height:1.9}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-hint{font-size:11px;line-height:16px;bottom:4px}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-voice-error{font-size:12px;line-height:22px;max-width:30ch}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-hello{font-size:clamp(20px,3.4vw,26px);line-height:1.5;text-wrap:balance;overflow-wrap:break-word}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-hello-ask{font-size:15px;line-height:1.75}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-hello-wrap{max-width:100%;min-width:0}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cascade__w{white-space:normal}.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-hello,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-hello-lead,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-hello-ask,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-ai-text,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-user-bubble,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-hint,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-chip,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-topbar-btn,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-textarea,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-entlang-opt-title,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-entlang-opt-note,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-ai-text .hsk-markdown-list li,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-ai-text .hsk-markdown-h1,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-ai-text .hsk-markdown-h2,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-ai-text .hsk-markdown-h3,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-markdown-table th,.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-markdown-table td{line-height:2.2}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-chip{font-size:14px}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-topbar-btn{height:auto;min-height:34px;padding:5px 14px}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-field{--hsk-input-line-height:1.9}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-textarea{min-height:34px}.hsk-cb-panel[data-nastaliq=\\\"true\\\"] .hsk-cb-field{--hsk-input-line-height:2.2}.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-user-bubble,.hsk-cb-panel[data-script=\\\"nonlatin\\\"] .hsk-cb-ai-text{overflow-wrap:break-word;word-break:normal}.hsk-cb-viz-broken{font-size:13px;color:var(--hsk-chat-muted,#71717a);padding:14px 16px;border:1px dashed var(--hsk-chat-divide,rgba(0,0,0,.12));border-radius:12px}.hsk-msg-audio-btn{background:transparent;border:none;color:#888;cursor:pointer;padding:4px;border-radius:4px;display:inline-flex;align-items:center}.hsk-cb-voice-mode-btn{width:36px;height:36px;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;background:transparent;border:1px solid transparent;border-radius:12px;color:var(--hsk-chat-muted,#71717a);cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);font-family:inherit}.hsk-cb-voice-mode-btn:hover:not(:disabled),.hsk-cb-mic-btn:hover:not(:disabled){border-color:color-mix(in srgb,var(--hsk-primary,#ff6a33) 25%,transparent);color:var(--hsk-primary,#ff6a33);background:color-mix(in srgb,var(--hsk-primary,#ff6a33) 8%,transparent);transform:translateY(-1px)}.hsk-cb-voice-mode-btn:disabled{opacity:.35;cursor:not-allowed}.hsk-cb-voice-mode-btn--active,.hsk-cb-mic-btn--listening{color:var(--hsk-primary,#ff6a33);background:color-mix(in srgb,var(--hsk-primary,#ff6a33) 12%,transparent)}.hsk-cb-mic-btn--processing{color:var(--hsk-primary,#ff6a33);opacity:.7}.hsk-voice-overlay{position:absolute;inset:0;z-index:30;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:clamp(12px,2.2vh,26px);padding:clamp(14px,2.5vh,24px);overflow-y:auto;overscroll-behavior:contain;background:var(--hsk-chat-bg,#ffffff);animation:hsk-voice-in .32s cubic-bezier(.2,.8,.2,1);will-change:opacity;contain:paint}.hsk-voice-overlay::before{content:'';position:absolute;inset:0;background:radial-gradient(42% 26% at 50% 40%,color-mix(in srgb,var(--hsk-primary,#ff6a33) 8%,transparent) 0,transparent 68%);pointer-events:none}.hsk-voice-overlay>*{position:relative}@keyframes hsk-voice-in{from{opacity:0}to{opacity:1}}.hsk-voice-allowance{position:absolute;top:14px;left:14px;display:flex;align-items:center;justify-content:center;min-width:36px;height:36px;padding:0 10px;font-size:12px;font-variant-numeric:tabular-nums;font-weight:600;border:1px solid color-mix(in srgb,var(--hsk-chat-text,#1f1f1f) 14%,transparent);border-radius:999px;color:var(--hsk-chat-muted,#71717a);transition:color .18s ease,border-color .18s ease}.hsk-voice-allowance--low{color:#dc2626;border-color:color-mix(in srgb,#dc2626 40%,transparent)}.hsk-voice-exit{position:absolute;top:14px;right:14px;display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;background:transparent;border:1px solid color-mix(in srgb,var(--hsk-chat-text,#1f1f1f) 14%,transparent);border-radius:999px;color:var(--hsk-chat-muted,#71717a);cursor:pointer;transition:color .18s ease,border-color .18s ease}.hsk-voice-exit:hover{color:var(--hsk-chat-text,#1f1f1f);border-color:color-mix(in srgb,var(--hsk-chat-text,#1f1f1f) 32%,transparent)}.hsk-voice-stage{width:min(560px,100%);height:clamp(110px,24vh,240px);flex:none}.hsk-voice-canvas{display:block;width:100%;height:100%}.hsk-voice-controls{display:flex;align-items:center;gap:12px}.hsk-voice-control{display:flex;align-items:center;justify-content:center;width:52px;height:52px;padding:0;background:var(--hsk-surface-2,rgba(255,255,255,.95));border:1px solid color-mix(in srgb,var(--hsk-chat-text,#000000) 10%,transparent);border-radius:999px;color:var(--hsk-chat-text,#1f1f1f);cursor:pointer;box-shadow:0 2px 12px rgba(0,0,0,.08),0 1px 3px rgba(0,0,0,.04);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);transition:color .2s ease,border-color .2s ease,background .2s ease,transform .2s cubic-bezier(.16,1,.3,1),box-shadow .2s ease}.hsk-voice-control:hover{transform:scale(1.06);box-shadow:0 4px 18px rgba(0,0,0,.12)}.hsk-voice-control:active{transform:scale(.92);transition-duration:.08s}.hsk-voice-control--muted{color:var(--hsk-chat-muted,#888888);border-color:color-mix(in srgb,var(--hsk-chat-text,#000000) 12%,transparent);background:color-mix(in srgb,var(--hsk-chat-bg,#ffffff) 85%,transparent);box-shadow:0 1px 4px rgba(0,0,0,.04)}.hsk-voice-control-icon{display:inline-flex;align-items:center;justify-content:center;z-index:2;transition:transform .2s ease}@keyframes hsk-voice-icon-in{from{opacity:0;transform:scale(.6) rotate(-12deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes hsk-voice-control-pulse{0%{transform:scale(1);box-shadow:0 0 0 0 color-mix(in srgb,var(--hsk-primary,#ff6a33) 45%,transparent)}40%{transform:scale(1.08);box-shadow:0 0 0 8px color-mix(in srgb,var(--hsk-primary,#ff6a33) 0,transparent)}100%{transform:scale(1);box-shadow:0 0 0 0 transparent}}@media (prefers-reduced-motion:reduce){.hsk-voice-control-icon,.hsk-voice-control--muted{animation:none}}.hsk-voice-caption{display:flex;flex-direction:column;align-items:center;gap:10px;max-width:min(520px,100%);text-align:center}.hsk-voice-phase{font-family:var(--hsk-font);font-size:.72rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--hsk-chat-muted,#71717a);transition:color .25s ease}.hsk-voice-phase--listening,.hsk-voice-phase--speaking{color:var(--hsk-primary,#ff6a33)}.hsk-voice-phase--thinking{animation:hsk-voice-breathe 1.6s ease-in-out infinite}@keyframes hsk-voice-breathe{0%,100%{opacity:.45}50%{opacity:1}}.hsk-voice-stage--connecting{opacity:.4;transition:opacity .25s ease}.hsk-voice-connecting{display:flex;align-items:center;gap:7px;font-family:var(--hsk-font);font-size:13px;color:var(--hsk-chat-muted,#8a8f98);animation:hsk-sent-in .2s ease-out both}.hsk-voice-connecting-dot{width:6px;height:6px;border-radius:999px;background:currentColor;animation:hsk-queued-pulse 1s ease-in-out infinite}@media (prefers-reduced-motion:reduce){.hsk-voice-connecting-dot{animation:none;opacity:.7}}.hsk-voice-heard{font-family:var(--hsk-font);font-size:1.05rem;line-height:1.5;color:var(--hsk-chat-text,#1f1f1f)}.hsk-voice-hint-sub{font-family:var(--hsk-font);font-size:14px;color:var(--hsk-chat-muted,#a1a1aa);line-height:1.4;opacity:.85}.hsk-voice-items{display:flex;flex-wrap:wrap;align-items:stretch;justify-content:center;gap:10px;width:min(620px,100%)}.hsk-voice-item{display:flex;flex-direction:column;align-items:flex-start;gap:6px;width:clamp(108px,30vw,132px);padding:8px;text-align:start;background:transparent;border:1px solid color-mix(in srgb,var(--hsk-chat-text,#1f1f1f) 10%,transparent);border-radius:12px;cursor:pointer;font-family:var(--hsk-font);animation:hsk-voice-item-in .34s cubic-bezier(.2,.8,.2,1) both;transition:border-color .18s ease,transform .18s ease}.hsk-voice-item:hover{border-color:color-mix(in srgb,var(--hsk-primary,#ff6a33) 45%,transparent);transform:translateY(-2px)}@keyframes hsk-voice-item-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}.hsk-voice-item-img{width:100%;height:clamp(52px,8.5vh,78px);object-fit:cover;border-radius:8px;background:color-mix(in srgb,var(--hsk-chat-text,#1f1f1f) 5%,transparent)}.hsk-voice-item-img--empty{display:flex;align-items:center;justify-content:center;color:color-mix(in srgb,var(--hsk-chat-text,#1f1f1f) 30%,transparent)}.hsk-voice-item-name{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:.78rem;line-height:1.35;color:var(--hsk-chat-text,#1f1f1f)}.hsk-voice-item-price{font-size:.78rem;font-weight:600;color:var(--hsk-primary,#ff6a33)}@media (prefers-reduced-motion:reduce){.hsk-voice-item{animation:none}}.hsk-voice-error{font-family:var(--hsk-font);font-size:.85rem;color:#e5484d;text-align:center}@media (prefers-reduced-motion:reduce){.hsk-voice-overlay,.hsk-voice-phase--thinking{animation:none}}.hsk-cb-listen{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;margin-top:6px;padding:0;background:transparent;border:none;border-radius:999px;color:var(--hsk-chat-muted,#71717a);cursor:pointer;opacity:0;transition:opacity .18s ease,color .18s ease}.hsk-cb-msg-group:hover .hsk-cb-listen,.hsk-cb-listen:focus-visible,.hsk-cb-listen--active{opacity:1}.hsk-cb-listen:hover,.hsk-cb-listen--active{color:var(--hsk-primary,#ff6a33)}.hsk-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.hsk-voice-picker{position:absolute;top:clamp(14px,3vh,28px);left:50%;transform:translateX(-50%);display:flex;gap:8px;flex-wrap:nowrap;justify-content:center;max-width:min(100%,420px);padding:0 56px;z-index:2}.hsk-voice-pill{display:inline-flex;align-items:center;gap:7px;padding:5px 11px;border-radius:999px;border:1px solid rgba(0,0,0,.09);background:rgba(255,255,255,.72);backdrop-filter:blur(8px);font:inherit;font-size:11px;letter-spacing:.01em;color:#5b5b5b;cursor:pointer;transition:background 160ms ease,border-color 160ms ease,color 160ms ease,transform 160ms ease;opacity:0;animation:hsk-voice-pill-in 420ms cubic-bezier(.16,1,.3,1) forwards}.hsk-voice-pill--on{animation:hsk-voice-pill-in 420ms cubic-bezier(.16,1,.3,1) forwards,hsk-voice-pill-pop 260ms ease}@keyframes hsk-voice-pill-in{from{opacity:0;transform:translateY(-6px) scale(.92)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes hsk-voice-pill-pop{0%{transform:scale(1)}40%{transform:scale(1.06)}100%{transform:scale(1)}}@media (prefers-reduced-motion:reduce){.hsk-voice-pill{opacity:1;animation:none}}@media (max-width:520px){.hsk-voice-picker{gap:5px;padding:0 44px}.hsk-voice-pill{padding:5px 8px;gap:4px}}.hsk-voice-pill:hover{background:rgba(255,255,255,.95);border-color:rgba(0,0,0,.16)}.hsk-voice-pill--on:hover{background:#1c1c1c;border-color:#1c1c1c;color:#fff}.hsk-voice-pill--on{background:#1a1a1a;border-color:#1a1a1a;color:#fff}@media (prefers-color-scheme:dark){.hsk-voice-pill{border-color:rgba(255,255,255,.14);background:rgba(30,30,30,.7);color:#cfcfcf}.hsk-voice-pill:hover{background:rgba(45,45,45,.9)}.hsk-voice-pill--on:hover{background:#f2f2f2;border-color:#f2f2f2;color:#141414}.hsk-voice-pill--on{background:#f2f2f2;border-color:#f2f2f2;color:#141414}}@media (max-width:520px){.hsk-cb-input-box{gap:6px;padding:10px 10px 10px 12px}.hsk-cb-attach-btn,.hsk-cb-mic-btn,.hsk-cb-send,.hsk-cb-voice-mode-btn,.hsk-chat-send{width:32px;height:32px;border-radius:10px}.hsk-cb-textarea{flex:1 1 auto;min-width:0;font-size:16px}.hsk-cb-input-box .hsk-cb-listening{display:none}}.hsk-cb-main{position:relative}.hsk-cb-main,.hsk-voice-overlay{--hsk-doodle-ink:31,31,31;--hsk-doodle-tint:255,106,51}@keyframes hsk-doodles-shimmer-in{0%{opacity:0}100%{opacity:.9}}.hsk-cb-doodles{position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;opacity:.9;animation:hsk-doodles-shimmer-in .28s cubic-bezier(.16,1,.3,1) both}.hsk-cb-main>*:not(.hsk-cb-doodles){position:relative}@media (prefers-color-scheme:dark){.hsk-cb-main,.hsk-voice-overlay{--hsk-doodle-ink:240,239,237;--hsk-doodle-tint:255,150,110}}[data-hsk-theme=\\\"light\\\"] .hsk-cb-main,[data-hsk-theme=\\\"light\\\"] .hsk-voice-overlay{--hsk-doodle-ink:31,31,31;--hsk-doodle-tint:255,106,51}[data-hsk-theme=\\\"dark\\\"] .hsk-cb-main,[data-hsk-theme=\\\"dark\\\"] .hsk-voice-overlay{--hsk-doodle-ink:240,239,237;--hsk-doodle-tint:255,150,110}.hsk-cb-docked-option-price,.hsk-cb-entlang-price,.hsk-cb-src-price,.hsk-kiku-picker-item-price,.hsk-source-price,.hsk-sp-item-discount,.hsk-sp-item-original-price,.hsk-sp-item-price,.hsk-sp-mobile-main-card-price,.hsk-sp-mobile-similar-carousel-price,.hsk-voice-item-price,.hsk-live-cell{font-variant-numeric:tabular-nums}.hsk-live-wrap{margin:6px 0 2px;width:100%;max-width:100%;box-sizing:border-box}.hsk-live-carousel{display:flex;flex-wrap:wrap;gap:6px;align-items:flex-start;width:100%;box-sizing:border-box}.hsk-live-card{flex:0 1 auto;width:fit-content;min-width:120px;max-width:100%;background:var(--hsk-chat-source-bg,rgba(255,255,255,.05));border:1px solid var(--hsk-chat-divide,rgba(255,255,255,.08));border-radius:12px;padding:6px 10px;box-sizing:border-box;display:flex;flex-direction:column;gap:3px;transition:opacity .2s ease;overflow:hidden}.hsk-live-card.is-stale{opacity:.75}.hsk-live-card__top{display:flex;align-items:center;justify-content:space-between;gap:8px}.hsk-live-card__badge{display:inline-flex;align-items:center;gap:5px}.hsk-live-card__body{display:flex;align-items:center}.hsk-live-dot{width:6px;height:6px;border-radius:50%;background:#10b981;flex-shrink:0}@media (prefers-reduced-motion:no-preference){.hsk-live-dot:not(.is-stale){animation:hsk-live-pulse 2s ease-in-out infinite}}.hsk-live-dot.is-stale{background:var(--hsk-chat-muted,#9ca3af)}.hsk-live-card__title{font-size:13px;font-weight:600;color:var(--hsk-chat-text,#111827);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:-0.01em}.hsk-live-card__close{font-size:10.5px;font-weight:500;color:var(--hsk-chat-muted,#6b7280);opacity:.85;white-space:nowrap}.hsk-live-card__age{font-size:10.5px;font-weight:500;color:var(--hsk-chat-muted,#6b7280);white-space:nowrap;flex-shrink:0}.hsk-live-card__pills{display:flex;flex-wrap:wrap;gap:4px;align-items:center;margin-top:1px}.hsk-live-pill{display:inline-flex;align-items:center;gap:4px;padding:2px 7px;background:color-mix(in srgb,var(--hsk-surface-1,var(--hsk-chat-bg,#ffffff)) 85%,transparent);border:1px solid color-mix(in srgb,var(--hsk-chat-text,#ffffff) 10%,transparent);border-radius:6px;font-size:11.5px;font-variant-numeric:tabular-nums;line-height:1.25;color:var(--hsk-chat-text,#111827);box-shadow:0 1px 2px rgba(0,0,0,.03)}.hsk-live-pill__label{font-weight:500;color:var(--hsk-chat-muted,#6b7280);font-size:11px;text-transform:capitalize}.hsk-live-pill__value{font-weight:650;color:var(--hsk-chat-text,#111827)}@media (prefers-reduced-motion:no-preference){.hsk-live-pill.is-changed{animation:hsk-live-pill-flash 1.2s ease-out}@keyframes hsk-live-pill-flash{0%{background:rgba(16,185,129,.25);border-color:#10b981}100%{background:var(--hsk-chat-bg,#ffffff);border-color:var(--hsk-chat-divide,rgba(0,0,0,.08))}}}@media (max-width:640px){.hsk-cb-source{flex:0 0 128px}.hsk-cb-src-imgwrap,.hsk-cb-src-imgwrap-empty{width:128px;height:128px;font-size:24px}.hsk-cb-sources{gap:10px}.hsk-cb-src-name{font-size:12px;line-height:1.35}.hsk-cb-src-price{font-size:11px;padding:1px 7px;margin-top:4px}.hsk-live{max-width:100%;width:100%}}@media (max-width:480px){.hsk-cb-source{flex:0 0 114px}.hsk-cb-src-imgwrap,.hsk-cb-src-imgwrap-empty{width:114px;height:114px;font-size:20px}.hsk-cb-sources{gap:8px}.hsk-live{border-radius:12px;padding:2px 0 8px;margin:8px 0 2px}.hsk-live-card{flex:0 0 auto;width:fit-content;max-width:100%}}.hsk-cb-overlay[data-hsk-theme],[data-hsk-theme] .hsk-cb-overlay{background:var(--hsk-chat-bg) !important;color:var(--hsk-chat-text) !important}[data-hsk-theme] .hsk-cb-panel{background:transparent !important;color:var(--hsk-chat-text) !important}[data-hsk-theme] .hsk-cb-topbar-name{background:var(--hsk-surface-2) !important;color:var(--hsk-name-text,var(--hsk-chat-text)) !important;box-shadow:0 0 0 3px var(--hsk-chat-bg),0 1px 3px rgba(var(--hsk-primary-rgb),.2) !important}[data-hsk-theme] .hsk-cb-think-head{background:var(--hsk-surface-2) !important;color:var(--hsk-think-text) !important;box-shadow:0 0 0 3px var(--hsk-chat-bg),0 1px 3px rgba(var(--hsk-primary-rgb),.2) !important}[data-hsk-theme] .hsk-cb-chip,[data-hsk-theme] .hsk-cb-lang-chip,[data-hsk-theme] .hsk-action-pill{border:var(--hsk-chip-border,none) !important;background:var(--hsk-surface-1) !important;color:var(--hsk-chat-text) !important}[data-hsk-theme] .hsk-cb-chip:hover,[data-hsk-theme] .hsk-cb-lang-chip:hover,[data-hsk-theme] .hsk-action-pill:hover{background:rgba(var(--hsk-primary-rgb),.12) !important;color:var(--hsk-primary) !important}[data-hsk-theme] .hsk-cb-ai-text{background:var(--hsk-bubble-bg) !important;color:var(--hsk-chat-text) !important}[data-hsk-theme] .hsk-cb-ai-text:not(:has(~.hsk-cb-ai-text))::before{background:var(--hsk-bubble-bg) !important}[data-hsk-theme] .hsk-cb-ai-text:not(:has(~.hsk-cb-ai-text))::after{background:var(--hsk-chat-bg) !important}[data-hsk-theme] .hsk-cb-user-bubble--tail::before{background:#007aff !important}[data-hsk-theme] .hsk-cb-user-bubble--tail::after{background:var(--hsk-chat-bg) !important}[data-hsk-theme] .hsk-cb-topbar-title{color:var(--hsk-chat-text) !important}[data-hsk-theme] .hsk-cb-topbar-btn,[data-hsk-theme] .hsk-cb-back{background:var(--hsk-surface-1) !important;color:var(--hsk-chat-muted) !important}[data-hsk-theme] .hsk-cb-input-box{background:transparent !important;border:none !important;border-radius:inherit !important}[data-hsk-theme] .hsk-cb-textarea{color:var(--hsk-chat-text) !important}[data-hsk-theme] .hsk-cb-textarea::placeholder{color:var(--hsk-placeholder) !important}[data-hsk-theme] .hsk-markdown-table th{color:var(--hsk-chat-muted) !important;border-bottom:1px solid var(--hsk-chat-divide) !important}[data-hsk-theme] .hsk-markdown-table td{color:var(--hsk-chat-text) !important;border-bottom:1px solid var(--hsk-chat-divide) !important}[data-hsk-theme] .hsk-cb-kiku-id-pill{background:var(--hsk-surface-1) !important;border:none !important;box-shadow:none !important;color:var(--hsk-chat-muted) !important}[data-hsk-theme] .hsk-cb-kiku-id-pill:hover{color:var(--hsk-primary) !important}[data-hsk-theme] .hsk-cb-theme-2x2-grid,[data-hsk-theme] .hsk-cb-topbar-ooze-menu,[data-hsk-theme] .hsk-cb-scout-rail-card{background:var(--hsk-glass-bg) !important;border:var(--hsk-glass-border) !important;border-top:var(--hsk-glass-border-top) !important;box-shadow:var(--hsk-glass-shadow) !important;backdrop-filter:blur(28px) saturate(var(--hsk-glass-saturate,180%)) !important;-webkit-backdrop-filter:blur(28px) saturate(var(--hsk-glass-saturate,180%)) !important}[data-hsk-theme] .hsk-cb-theme-squircle-trigger,[data-hsk-theme] .hsk-cb-scout-rail-trigger{background:var(--hsk-pill-bg) !important;color:var(--hsk-chat-text) !important;border:var(--hsk-glass-border) !important;border-top:var(--hsk-glass-border-top) !important;box-shadow:var(--hsk-glass-shadow) !important;backdrop-filter:blur(20px) saturate(var(--hsk-glass-saturate,160%)) !important;-webkit-backdrop-filter:blur(20px) saturate(var(--hsk-glass-saturate,160%)) !important}[data-hsk-theme] .hsk-cb-theme-grid-item{background:var(--hsk-grid-bg) !important;color:var(--hsk-chat-muted) !important;border:none !important;box-shadow:none !important}[data-hsk-theme] .hsk-cb-theme-grid-item.is-active{background:var(--hsk-active-bg) !important;color:var(--hsk-on-active) !important;box-shadow:none !important}[data-hsk-theme] .hsk-cb-src-name,[data-hsk-theme] .hsk-source-card__title{color:var(--hsk-src-title) !important;font-weight:650 !important}[data-hsk-theme] .hsk-cb-src-desc,[data-hsk-theme] .hsk-cb-src-detail,[data-hsk-theme] .hsk-source-card__desc{color:var(--hsk-src-desc) !important}[data-hsk-theme] .hsk-cb-src-price{background:var(--hsk-price-bg) !important;color:var(--hsk-price-text) !important;font-weight:700 !important}[data-hsk-theme] .hsk-cb-main,[data-hsk-theme] .hsk-voice-overlay{--hsk-doodle-ink:var(--hsk-ink) !important;--hsk-doodle-tint:var(--hsk-tint) !important}[data-hsk-theme] .hsk-voice-pill{background:var(--hsk-chat-input-bg) !important;border-color:var(--hsk-chat-divide) !important;color:var(--hsk-chat-muted) !important}[data-hsk-theme] .hsk-voice-pill:hover{background:var(--hsk-surface-2) !important;color:var(--hsk-chat-text) !important}[data-hsk-theme] .hsk-voice-pill--on,[data-hsk-theme] .hsk-voice-pill--on:hover{background:var(--hsk-active-bg) !important;border-color:var(--hsk-active-bg) !important;color:var(--hsk-on-active) !important}.hsk-cb-overlay[data-hsk-theme=\\\"light\\\"],[data-hsk-theme=\\\"light\\\"] .hsk-cb-overlay{--hsk-primary:#ff6a33 !important;--hsk-primary-rgb:255,106,51 !important;--hsk-chat-bg:#ffffff !important;--hsk-chat-text:#1f1f1f !important;--hsk-chat-muted:#5f6368 !important;--hsk-chat-divide:#e5e7eb !important;--hsk-chat-input-bg:#f3f4f6 !important;--hsk-chat-source-bg:#f9fafb !important;--hsk-fade-bg:#ffffff !important;--hsk-goo-fill:#ffffff !important;--hsk-surface-1:rgba(0,0,0,.05) !important;--hsk-surface-2:#f1f3f4 !important;--hsk-bubble-bg:#f3f4f6 !important;--hsk-think-text:#4b5563 !important;--hsk-placeholder:#757575 !important;--hsk-grid-bg:#ffffff !important;--hsk-active-bg:#1f1f1f !important;--hsk-on-active:#ffffff !important;--hsk-src-title:#111827 !important;--hsk-src-desc:#4b5563 !important;--hsk-price-bg:#f3f4f6 !important;--hsk-price-text:#ea580c !important;--hsk-sheet-bg:#f3f4f6 !important;--hsk-chip-border:1px solid rgba(0,0,0,.08) !important;--hsk-ink:55,65,81 !important;--hsk-tint:145,77,47 !important;--hsk-glass-bg:rgba(255,255,255,.72) !important;--hsk-glass-border:1px solid rgba(0,0,0,.07) !important;--hsk-glass-border-top:1px solid rgba(255,255,255,.9) !important;--hsk-glass-shadow:0 12px 32px -4px rgba(0,0,0,.10),0 1px 0 0 rgba(255,255,255,.85) inset !important;--hsk-glass-saturate:190% !important;--hsk-pill-bg:rgba(255,255,255,.65) !important}.hsk-cb-overlay[data-hsk-theme=\\\"dark\\\"],[data-hsk-theme=\\\"dark\\\"] .hsk-cb-overlay{--hsk-primary:#ff6a33 !important;--hsk-primary-rgb:255,106,51 !important;--hsk-chat-bg:#0a0a0a !important;--hsk-chat-text:#f0efed !important;--hsk-chat-muted:#888888 !important;--hsk-chat-divide:rgba(255,255,255,.08) !important;--hsk-chat-input-bg:#191919 !important;--hsk-chat-source-bg:rgba(255,255,255,.04) !important;--hsk-fade-bg:#0a0a0a !important;--hsk-goo-fill:#1a1a1c !important;--hsk-surface-1:rgba(255,255,255,.06) !important;--hsk-surface-2:#1f1f22 !important;--hsk-bubble-bg:#1f1f22 !important;--hsk-think-text:#a6a6a6 !important;--hsk-placeholder:#555555 !important;--hsk-grid-bg:#1a1a1c !important;--hsk-active-bg:#f0efed !important;--hsk-on-active:#0a0a0a !important;--hsk-src-title:#f9fafb !important;--hsk-src-desc:#9ca3af !important;--hsk-price-bg:rgba(255,255,255,.08) !important;--hsk-price-text:#ff7a45 !important;--hsk-sheet-bg:#1f1f22 !important;--hsk-ink:240,239,237 !important;--hsk-tint:248,195,174 !important;--hsk-glass-bg:rgba(255,255,255,.07) !important;--hsk-glass-border:1px solid rgba(255,255,255,.10) !important;--hsk-glass-border-top:1px solid rgba(255,255,255,.22) !important;--hsk-glass-shadow:0 12px 32px -4px rgba(0,0,0,.45),0 1px 0 0 rgba(255,255,255,.10) inset !important;--hsk-glass-saturate:160% !important;--hsk-pill-bg:rgba(255,255,255,.06) !important}.hsk-cb-overlay[data-hsk-theme=\\\"mahogany\\\"],[data-hsk-theme=\\\"mahogany\\\"] .hsk-cb-overlay{--hsk-primary:#e07a38 !important;--hsk-primary-rgb:224,122,56 !important;--hsk-chat-bg:#140d09 !important;--hsk-chat-text:#f6eee3 !important;--hsk-chat-muted:#a89485 !important;--hsk-chat-divide:rgba(217,140,85,.18) !important;--hsk-chat-input-bg:#211610 !important;--hsk-chat-source-bg:#1c130d !important;--hsk-fade-bg:#140d09 !important;--hsk-goo-fill:#211610 !important;--hsk-surface-1:#211610 !important;--hsk-surface-2:#2b1c14 !important;--hsk-bubble-bg:#261912 !important;--hsk-think-text:#c4b1a1 !important;--hsk-placeholder:#7a6557 !important;--hsk-grid-bg:#2b1c14 !important;--hsk-active-bg:#e07a38 !important;--hsk-on-active:#ffffff !important;--hsk-src-title:#fdf8f4 !important;--hsk-src-desc:#c4b1a1 !important;--hsk-price-bg:#2b1c14 !important;--hsk-price-text:#f59e0b !important;--hsk-sheet-bg:#211610 !important;--hsk-ink:246,238,227 !important;--hsk-tint:235,180,142 !important;--hsk-glass-bg:rgba(255,220,180,.07) !important;--hsk-glass-border:1px solid rgba(217,140,85,.15) !important;--hsk-glass-border-top:1px solid rgba(255,200,150,.25) !important;--hsk-glass-shadow:0 12px 32px -4px rgba(0,0,0,.55),0 1px 0 0 rgba(255,200,150,.12) inset !important;--hsk-glass-saturate:155% !important;--hsk-pill-bg:rgba(255,220,180,.06) !important}.hsk-cb-overlay[data-hsk-theme=\\\"blush\\\"],[data-hsk-theme=\\\"blush\\\"] .hsk-cb-overlay{--hsk-primary:#ec4899 !important;--hsk-primary-rgb:236,72,153 !important;--hsk-chat-bg:#fff5f7 !important;--hsk-chat-text:#3d1424 !important;--hsk-chat-muted:#94536d !important;--hsk-chat-divide:rgba(236,72,153,.18) !important;--hsk-chat-input-bg:#ffe4ec !important;--hsk-chat-source-bg:#fff0f4 !important;--hsk-fade-bg:#fff5f7 !important;--hsk-goo-fill:#ffe4ec !important;--hsk-surface-1:#ffe4ec !important;--hsk-surface-2:#fbcfe8 !important;--hsk-bubble-bg:#ffebf1 !important;--hsk-think-text:#831843 !important;--hsk-name-text:#831843 !important;--hsk-placeholder:#b57a91 !important;--hsk-grid-bg:#fff0f4 !important;--hsk-active-bg:#ec4899 !important;--hsk-on-active:#ffffff !important;--hsk-src-title:#2b0c19 !important;--hsk-src-desc:#702648 !important;--hsk-price-bg:#fce7f3 !important;--hsk-price-text:#db2777 !important;--hsk-sheet-bg:#ffe4ec !important;--hsk-sheet-hover:#ffd2e0 !important;--hsk-ink:130,36,75 !important;--hsk-tint:175,38,97 !important;--hsk-glass-bg:rgba(255,240,248,.75) !important;--hsk-glass-border:1px solid rgba(236,72,153,.10) !important;--hsk-glass-border-top:1px solid rgba(255,255,255,.90) !important;--hsk-glass-shadow:0 12px 32px -4px rgba(180,30,100,.08),0 1px 0 0 rgba(255,255,255,.85) inset !important;--hsk-glass-saturate:185% !important;--hsk-pill-bg:rgba(255,228,236,.80) !important}.hsk-cb-overlay[data-hsk-theme=\\\"coffee\\\"],[data-hsk-theme=\\\"coffee\\\"] .hsk-cb-overlay{--hsk-primary:#a9714b !important;--hsk-primary-rgb:169,113,75 !important;--hsk-chat-bg:#f7f1e8 !important;--hsk-chat-text:#3b2a1d !important;--hsk-chat-muted:#8a7561 !important;--hsk-chat-divide:rgba(169,113,75,.18) !important;--hsk-chat-input-bg:#efe4d6 !important;--hsk-chat-source-bg:#f2eade !important;--hsk-fade-bg:#f7f1e8 !important;--hsk-goo-fill:#efe4d6 !important;--hsk-surface-1:#efe4d6 !important;--hsk-surface-2:#e6d7c4 !important;--hsk-bubble-bg:#f0e7da !important;--hsk-think-text:#6b543f !important;--hsk-placeholder:#a89680 !important;--hsk-grid-bg:#f2eade !important;--hsk-active-bg:#a9714b !important;--hsk-on-active:#ffffff !important;--hsk-src-title:#2a1c11 !important;--hsk-src-desc:#6b543f !important;--hsk-price-bg:#ece0cf !important;--hsk-price-text:#9a5f32 !important;--hsk-sheet-bg:#efe4d6 !important;--hsk-sheet-hover:#e6d7c4 !important;--hsk-ink:59,42,29 !important;--hsk-tint:120,88,62 !important;--hsk-glass-bg:rgba(247,241,232,.78) !important;--hsk-glass-border:1px solid rgba(169,113,75,.12) !important;--hsk-glass-border-top:1px solid rgba(255,255,255,.88) !important;--hsk-glass-shadow:0 12px 32px -4px rgba(90,55,20,.10),0 1px 0 0 rgba(255,255,255,.80) inset !important;--hsk-glass-saturate:185% !important;--hsk-pill-bg:rgba(239,228,214,.82) !important}.hsk-cb-overlay[data-hsk-theme=\\\"midnight\\\"],[data-hsk-theme=\\\"midnight\\\"] .hsk-cb-overlay{--hsk-primary:#6366f1 !important;--hsk-primary-rgb:99,102,241 !important;--hsk-chat-bg:#0f1420 !important;--hsk-chat-text:#dfe6f5 !important;--hsk-chat-muted:#8792ad !important;--hsk-chat-divide:rgba(99,102,241,.18) !important;--hsk-chat-input-bg:#1a2133 !important;--hsk-chat-source-bg:#161d2c !important;--hsk-fade-bg:#0f1420 !important;--hsk-goo-fill:#1a2133 !important;--hsk-surface-1:#1a2133 !important;--hsk-surface-2:#222b40 !important;--hsk-bubble-bg:#1e2637 !important;--hsk-think-text:#a8b3cc !important;--hsk-placeholder:#5c6780 !important;--hsk-grid-bg:#222b40 !important;--hsk-active-bg:#6366f1 !important;--hsk-on-active:#ffffff !important;--hsk-src-title:#f2f5fc !important;--hsk-src-desc:#a8b3cc !important;--hsk-price-bg:#222b40 !important;--hsk-price-text:#818cf8 !important;--hsk-sheet-bg:#1a2133 !important;--hsk-sheet-hover:#222b40 !important;--hsk-ink:223,230,245 !important;--hsk-tint:150,160,200 !important;--hsk-glass-bg:rgba(180,190,255,.06) !important;--hsk-glass-border:1px solid rgba(99,102,241,.18) !important;--hsk-glass-border-top:1px solid rgba(180,185,255,.25) !important;--hsk-glass-shadow:0 12px 32px -4px rgba(0,0,0,.55),0 1px 0 0 rgba(180,190,255,.10) inset !important;--hsk-glass-saturate:155% !important;--hsk-pill-bg:rgba(180,190,255,.06) !important}.hsk-cb-back-icon{display:inline-flex;transition:transform .22s cubic-bezier(.22,1,.36,1)}.hsk-cb-back:hover:not(:disabled) .hsk-cb-back-icon{transform:translateX(-2px)}.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-back:hover:not(:disabled) .hsk-cb-back-icon{transform:scaleX(-1) translateX(-2px)}.hsk-cb-tools-toggle{transition:transform .26s cubic-bezier(.34,1.56,.64,1),background-color .42s cubic-bezier(.16,1,.3,1),color .42s cubic-bezier(.16,1,.3,1)}.hsk-cb-tools-toggle:hover:not(:disabled){color:var(--hsk-primary,#ff6a33);transform:rotate(90deg)}.hsk-cb-tools-toggle--open:hover:not(:disabled){transform:rotate(135deg)}.hsk-cb-tools-toggle:active:not(:disabled){transform:scale(.9);transition-duration:.1s}.hsk-cb-theme-trigger-icon{display:inline-flex;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-theme-squircle-trigger:hover .hsk-cb-theme-trigger-icon{transform:translateY(-1.5px) rotate(-8deg)}.hsk-cb-dot-item:hover:not(.hsk-cb-dot-item--active){background:var(--hsk-chat-muted,rgba(120,120,120,.6));transform:scale(1.35)}.hsk-msg-audio-btn{transition:color .18s ease,transform .22s cubic-bezier(.34,1.56,.64,1)}.hsk-msg-audio-btn:hover:not(:disabled){color:var(--hsk-primary,#ff6a33);transform:scale(1.12)}.hsk-msg-audio-btn:active:not(:disabled){transform:scale(.94);transition-duration:.1s}.hsk-markup-color{transition:transform .22s cubic-bezier(.34,1.56,.64,1),border-color .18s ease}.hsk-markup-color:hover:not(.hsk-markup-color--on){transform:scale(1.22)}.hsk-markup-color--on:hover{transform:scale(1.15)}@media (prefers-reduced-motion:reduce){.hsk-cb-back:hover:not(:disabled) .hsk-cb-back-icon,.hsk-cb-panel[dir=\\\"rtl\\\"] .hsk-cb-back:hover:not(:disabled) .hsk-cb-back-icon,.hsk-cb-theme-squircle-trigger:hover .hsk-cb-theme-trigger-icon,.hsk-cb-dot-item:hover:not(.hsk-cb-dot-item--active),.hsk-msg-audio-btn:hover:not(:disabled),.hsk-markup-color:hover:not(.hsk-markup-color--on){transform:none}.hsk-cb-tools-toggle:hover:not(:disabled),.hsk-cb-tools-toggle--open:hover:not(:disabled){transform:none}}.hsk-voice-control{position:relative;isolation:isolate;border-radius:999px}.hsk-voice-control:not(.hsk-voice-control--muted)::before{content:'';position:absolute;inset:-1.5px;border-radius:inherit;background:conic-gradient( from 0deg,#ff3b30,#ff9500,#ffd60a,#34c759,#00c7be,#30b0c7,#007aff,#5856d6,#af52de,#ff2d55,#ff3b30 );-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#000 calc(100% - 2px));mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#000 calc(100% - 2px));animation:hsk-apple-siri-spin 3s linear infinite;pointer-events:none;z-index:1}.hsk-voice-control::after{display:none !important}.hsk-voice-control-icon{will-change:transform}.hsk-voice-control:not(.hsk-voice-control--muted) .hsk-voice-control-icon{animation:hsk-apple-siri-mic-pulse 2.2s ease-in-out infinite}@keyframes hsk-apple-siri-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes hsk-apple-siri-breathe{0%,100%{transform:scale(.95);opacity:.55}50%{transform:scale(1.15);opacity:.95}}@keyframes hsk-apple-siri-mic-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}.hsk-voice-control--muted::before,.hsk-voice-control--muted::after{display:none}@media (prefers-reduced-motion:reduce){.hsk-voice-control:not(:hover):not(.hsk-voice-control--muted) .hsk-voice-control-icon,.hsk-voice-control:hover::before,.hsk-voice-control--muted::before,.hsk-voice-control--muted::after{animation:none}.hsk-voice-control:hover,.hsk-voice-control:hover .hsk-mic-cap{transform:none}}.hsk-cb-voice-error{animation:hsk-error-shake .26s cubic-bezier(.36,.07,.19,.97) both}@keyframes hsk-error-shake{0%,100%{transform:translateX(0)}22%{transform:translateX(-3px)}55%{transform:translateX(2px)}80%{transform:translateX(-1px)}}@media (prefers-reduced-motion:reduce){.hsk-cb-voice-error{animation:none}}.hsk-sun-rays,.hsk-sun-core,.hsk-moon-body,.hsk-wood-layer,.hsk-heart-body,.hsk-steam,.hsk-star-spark,.hsk-check-mark,.hsk-send-tail,.hsk-send-body{transform-box:fill-box;transform-origin:center}.hsk-sun-rays{transform-origin:12px 12px;transition:transform .5s cubic-bezier(.22,1,.36,1)}.hsk-cb-theme-grid-item:hover .hsk-sun-rays,.hsk-cb-theme-squircle-trigger:hover .hsk-sun-rays{transform:rotate(45deg)}.hsk-sun-core{transition:transform .32s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-theme-grid-item:hover .hsk-sun-core,.hsk-cb-theme-squircle-trigger:hover .hsk-sun-core{transform:scale(1.14)}.hsk-moon-body{transition:transform .34s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-theme-grid-item:hover .hsk-moon-body,.hsk-cb-theme-squircle-trigger:hover .hsk-moon-body{transform:rotate(-16deg)}.hsk-wood-layer{transition:transform .34s cubic-bezier(.34,1.56,.64,1)}.hsk-wood-layer{transition-delay:calc(var(--hsk-layer,0) * 45ms)}.hsk-cb-theme-grid-item:hover .hsk-wood-layer,.hsk-cb-theme-squircle-trigger:hover .hsk-wood-layer{transform:translateY(-1.2px)}.hsk-cb-theme-grid-item:hover .hsk-heart-body,.hsk-cb-theme-squircle-trigger:hover .hsk-heart-body{animation:hsk-heartbeat 1.1s ease-in-out infinite}@keyframes hsk-heartbeat{0%,100%{transform:scale(1)}14%{transform:scale(1.18)}28%{transform:scale(1)}42%{transform:scale(1.12)}56%{transform:scale(1)}}.hsk-steam{opacity:.9}.hsk-cb-theme-grid-item:hover .hsk-steam,.hsk-cb-theme-squircle-trigger:hover .hsk-steam{animation:hsk-steam-rise 1.6s ease-out infinite;animation-delay:calc(var(--hsk-steam,0) * 220ms)}@keyframes hsk-steam-rise{0%{transform:translateY(2px) scaleY(.5);opacity:0}35%{opacity:.95}100%{transform:translateY(-3px) scaleY(1.15);opacity:0}}.hsk-cb-theme-grid-item:hover .hsk-star-spark,.hsk-cb-theme-squircle-trigger:hover .hsk-star-spark{animation:hsk-twinkle 1.4s ease-in-out infinite}@keyframes hsk-twinkle{0%,100%{transform:scale(1) rotate(0deg);opacity:.85}50%{transform:scale(1.45) rotate(20deg);opacity:1}}.hsk-check-mark{stroke-dasharray:30;stroke-dashoffset:30;animation:hsk-check-draw .42s cubic-bezier(.65,0,.35,1) forwards}@keyframes hsk-check-draw{to{stroke-dashoffset:0}}.hsk-send-body,.hsk-send-tail{transition:transform .28s cubic-bezier(.22,1,.36,1)}.hsk-send-tail{transition-delay:40ms}.hsk-chat-send:hover:not(:disabled) .hsk-send-body,.hsk-cb-send:hover:not(:disabled) .hsk-send-body{transform:translate(1.5px,-1.5px)}.hsk-chat-send:hover:not(:disabled) .hsk-send-tail,.hsk-cb-send:hover:not(:disabled) .hsk-send-tail{transform:translate(2.5px,-2.5px)}@media (prefers-reduced-motion:reduce){.hsk-sun-rays,.hsk-sun-core,.hsk-moon-body,.hsk-wood-layer,.hsk-send-body,.hsk-send-tail{transition:none;transform:none !important}.hsk-cb-theme-grid-item:hover .hsk-heart-body,.hsk-cb-theme-squircle-trigger:hover .hsk-heart-body,.hsk-cb-theme-grid-item:hover .hsk-steam,.hsk-cb-theme-squircle-trigger:hover .hsk-steam,.hsk-cb-theme-grid-item:hover .hsk-star-spark,.hsk-cb-theme-squircle-trigger:hover .hsk-star-spark{animation:none}.hsk-check-mark{animation:none;stroke-dashoffset:0}}.hsk-cb-send-stage{position:relative;display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%;overflow:visible}.hsk-cb-send-seam{position:absolute;top:50%;left:50%;width:2px;height:15px;border-radius:2px;background:currentColor;transform:translate(-50%,-50%) rotate(38deg) scaleY(0);transform-origin:center;opacity:0;pointer-events:none}.hsk-cb-send-kite{display:inline-flex;transform-origin:center;will-change:transform}.hsk-cb-send:hover:not(:disabled) .hsk-cb-send-kite{transform:translate(1.5px,-1.5px);transition:transform .26s cubic-bezier(.22,1,.36,1)}.hsk-cb-send.is-launching .hsk-cb-send-kite{animation:hsk-kite-tear .55s cubic-bezier(.22,1,.36,1) both}.hsk-cb-send.is-launching .hsk-cb-send-seam{animation:hsk-seam-heal .55s cubic-bezier(.4,0,.3,1) both}@keyframes hsk-kite-tear{0%{transform:translate(0,0) scale(1) rotate(0deg);opacity:1}18%{transform:translate(-1px,2.5px) scale(.92,1.08) rotate(-4deg);opacity:1}45%{transform:translate(3px,-16px) scale(1.2,.8) rotate(6deg);opacity:.95}75%{transform:translate(6px,-38px) scale(1.05,.7) rotate(10deg);opacity:.6}100%{transform:translate(8px,-56px) scale(.6,.4) rotate(12deg);opacity:0}}@keyframes hsk-seam-heal{0%{transform:translate(-50%,-50%) rotate(38deg) scaleY(0);opacity:0}22%{transform:translate(-50%,-50%) rotate(38deg) scaleY(1);opacity:.9}45%{transform:translate(-50%,-50%) rotate(38deg) scaleY(1.3);opacity:.8}72%{transform:translate(-50%,-50%) rotate(38deg) scaleY(.3);opacity:.35}100%{transform:translate(-50%,-50%) rotate(38deg) scaleY(0);opacity:0}}.hsk-kite-wing{transform-box:fill-box;transform-origin:100% 0}.hsk-cb-send:not(:disabled):not(.is-launching) .hsk-kite-wing--far{animation:hsk-wing-beat-far .62s ease-in-out infinite}.hsk-cb-send:not(:disabled):not(.is-launching) .hsk-kite-wing--near{animation:hsk-wing-beat-near .62s ease-in-out .07s infinite}.hsk-cb-send:not(:disabled):not(.is-launching) .hsk-cb-send-kite{animation:hsk-kite-strain 2.4s cubic-bezier(.45,0,.35,1) infinite}.hsk-cb-send:not(:disabled):not(.is-launching) .hsk-cb-send-seam{animation:hsk-seam-strain 2.4s cubic-bezier(.45,0,.35,1) infinite}@keyframes hsk-kite-strain{0%,10%{transform:translate(0,0) scale(1) rotate(0deg)}20%{transform:translate(-1.2px,2px) scale(.94,1.05) rotate(-4deg)}34%{transform:translate(3.5px,-5px) scale(1.16,.86) rotate(8deg)}42%{transform:translate(4.2px,-6px) scale(1.2,.82) rotate(9deg)}50%{transform:translate(2.4px,-3.4px) scale(1.06,.94) rotate(5deg)}64%{transform:translate(-.6px,1.2px) scale(.97,1.03) rotate(-2deg)}78%,100%{transform:translate(0,0) scale(1) rotate(0deg)}}@keyframes hsk-seam-strain{0%,22%{transform:translate(-50%,-50%) rotate(38deg) scaleY(0);opacity:0}34%{transform:translate(-50%,-50%) rotate(38deg) scaleY(.6);opacity:.34}42%{transform:translate(-50%,-50%) rotate(38deg) scaleY(.95);opacity:.5}52%{transform:translate(-50%,-50%) rotate(38deg) scaleY(.55);opacity:.3}66%,100%{transform:translate(-50%,-50%) rotate(38deg) scaleY(0);opacity:0}}@keyframes hsk-wing-beat-far{0%,100%{transform:scaleX(1) skewY(0deg)}50%{transform:scaleX(.86) skewY(-4deg)}}@keyframes hsk-wing-beat-near{0%,100%{transform:scaleX(1) skewY(0deg)}50%{transform:scaleX(1.1) skewY(3deg)}}.hsk-stop-ring{transform-box:fill-box;transform-origin:center;stroke-dasharray:22 38;opacity:.85;animation:hsk-stop-orbit 1.4s linear infinite}.hsk-stop-core{transform-box:fill-box;transform-origin:center;animation:hsk-stop-pulse 1.4s ease-in-out infinite;transition:rx .2s ease,transform .2s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-send--stop:hover .hsk-stop-core{transform:scale(1.16);animation-play-state:paused}.hsk-cb-send--stop:hover .hsk-stop-ring{animation-duration:.7s}@keyframes hsk-stop-orbit{to{transform:rotate(1turn)}}@keyframes hsk-stop-pulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.86);opacity:.75}}@media (prefers-reduced-motion:reduce){.hsk-cb-send.is-launching .hsk-cb-send-kite,.hsk-cb-send.is-launching .hsk-cb-send-seam,.hsk-cb-send:hover:not(:disabled) .hsk-cb-send-kite{animation:none;transform:none}}.hsk-cb-send.is-launching{overflow:visible !important}.hsk-cb-send-sheath{position:absolute;inset:-1px;background:radial-gradient(120% 90% at 32% 22%,rgba(255,255,255,.44) 0,rgba(255,255,255,0) 58%),linear-gradient(150deg,color-mix(in srgb,var(--hsk-primary,#1273e6) 72%,#ffffff) 0,var(--hsk-primary,#1273e6) 46%,color-mix(in srgb,var(--hsk-primary,#1273e6) 74%,#000000) 100%);border-radius:46% 54% 52% 48% / 50% 47% 53% 50%;box-shadow:inset 0 2px 3px rgba(255,255,255,.5),inset 0 -3px 5px color-mix(in srgb,var(--hsk-primary,#1273e6) 30%,rgba(0,0,0,.55)),0 2px 5px rgba(0,0,0,.20),0 7px 16px color-mix(in srgb,var(--hsk-primary,#1273e6) 16%,transparent);transform-origin:58% 62%;pointer-events:none;z-index:1;will-change:transform,border-radius;transition:border-radius .5s cubic-bezier(.34,1.6,.5,1),box-shadow .3s ease}.hsk-cb-send-stage{z-index:2;position:relative}.hsk-cb-send:not(:disabled):not(.is-launching) .hsk-cb-send-sheath{animation:hsk-sheath-press 2.4s cubic-bezier(.35,.8,.3,1) infinite}@keyframes hsk-sheath-press{0%,12%{transform:scale(1);border-radius:46% 54% 52% 48% / 50% 47% 53% 50%}22%{transform:scale(.94,1.08) translate(-1.4px,2.2px);border-radius:52% 48% 44% 56% / 58% 40% 60% 42%}36%{transform:scale(1.14,.87) translate(2.6px,-3.4px) rotate(2deg);border-radius:38% 66% 54% 46% / 40% 62% 38% 60%}46%{transform:scale(1.19,.83) translate(3.6px,-4.6px) rotate(2.8deg);border-radius:34% 72% 56% 44% / 36% 68% 32% 64%}58%{transform:scale(.93,1.09) translate(-1.2px,1.8px) rotate(-1.4deg);border-radius:56% 44% 42% 58% / 60% 38% 62% 40%}70%{transform:scale(1.05,.96) translate(.8px,-1px) rotate(.6deg);border-radius:44% 56% 50% 50% / 46% 54% 46% 54%}80%{transform:scale(.98,1.03);border-radius:50% 50% 48% 52% / 52% 48% 52% 48%}88%,100%{transform:scale(1);border-radius:46% 54% 52% 48% / 50% 47% 53% 50%}}.hsk-cb-send.is-launching .hsk-cb-send-sheath{animation:hsk-sheath-yield .55s cubic-bezier(.3,.7,.25,1) both}@keyframes hsk-sheath-yield{0%{transform:scale(1);border-radius:46% 54% 52% 48% / 50% 47% 53% 50%}20%{transform:scale(.88,1.14) translate(-2px,3.4px);border-radius:56% 44% 40% 60% / 64% 34% 66% 36%}45%{transform:scale(1.34,.68) translate(6px,-10px) rotate(4.6deg);border-radius:24% 86% 62% 38% / 26% 80% 20% 74%}65%{transform:scale(.86,1.16) translate(-2.2px,3.6px) rotate(-2.2deg);border-radius:60% 40% 38% 62% / 68% 30% 70% 32%}82%{transform:scale(1.06,.95) translate(1px,-1px) rotate(.8deg);border-radius:44% 56% 52% 48% / 46% 54% 46% 54%}100%{transform:scale(1);border-radius:46% 54% 52% 48% / 50% 47% 53% 50%}}.hsk-cb-send:disabled .hsk-cb-send-sheath{opacity:0}.hsk-cb-send--stop .hsk-cb-send-sheath{display:none}.hsk-cb-send:active:not(:disabled) .hsk-cb-send-sheath{box-shadow:inset 0 1px 2px rgba(255,255,255,.3),inset 0 -1px 3px color-mix(in srgb,var(--hsk-primary,#1273e6) 24%,rgba(0,0,0,.6)),0 1px 3px rgba(0,0,0,.24)}@media (prefers-reduced-motion:reduce){.hsk-cb-send:not(:disabled):not(.is-launching) .hsk-cb-send-sheath,.hsk-cb-send.is-launching .hsk-cb-send-sheath{animation:none}}.hsk-cb-send:not(.hsk-cb-send--stop):not(:disabled){background:transparent !important;box-shadow:none !important;overflow:visible !important}.hsk-cb-send:not(.hsk-cb-send--stop):not(:disabled):hover{box-shadow:none !important}.hsk-cb-send:not(:disabled):hover .hsk-cb-send-sheath{box-shadow:inset 0 2px 4px rgba(255,255,255,.58),inset 0 -3px 6px color-mix(in srgb,var(--hsk-primary,#1273e6) 28%,rgba(0,0,0,.5)),0 3px 7px rgba(0,0,0,.22),0 10px 22px color-mix(in srgb,var(--hsk-primary,#1273e6) 20%,transparent)}.hsk-cb-terms-sanctuary{display:flex;flex-direction:column;margin:18px 0 22px;width:100%;max-width:520px;text-align:start;background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:none;border-radius:0;padding:0;box-shadow:none;opacity:0;animation:hsk-terms-delicate-in .5s cubic-bezier(.16,1,.3,1) .05s forwards}@keyframes hsk-terms-delicate-in{0%{opacity:0;transform:translateY(8px)}100%{opacity:1;transform:translateY(0)}}.hsk-cb-terms-item{display:flex;flex-direction:column;gap:4px;opacity:0;animation:hsk-terms-item-in .45s cubic-bezier(.16,1,.3,1) forwards;animation-delay:calc(var(--hsk-row-idx,0) * 60ms+80ms)}@keyframes hsk-terms-item-in{0%{opacity:0;transform:translateY(6px)}100%{opacity:1;transform:translateY(0)}}.hsk-cb-terms-head{display:flex;align-items:baseline;gap:10px}.hsk-cb-terms-numeral{font-family:ui-serif,Georgia,Cambria,\\\"Times New Roman\\\",Times,serif;font-style:italic;font-size:11px;font-weight:600;letter-spacing:.12em;color:var(--hsk-primary,#ff6a33);opacity:.85;flex-shrink:0;user-select:none}.hsk-cb-terms-title{margin:0;font-size:14.5px;font-weight:700;letter-spacing:-0.015em;color:var(--hsk-chat-text,#ffffff)}.hsk-cb-terms-desc{margin:0;padding-inline-start:22px;font-size:13px;line-height:1.55;color:var(--hsk-chat-muted,#9ca3af);font-weight:400}.hsk-cb-terms-divider{height:1px;margin:14px 0;background:linear-gradient( 90deg,transparent 0,color-mix(in srgb,var(--hsk-chat-text,#000000) 8%,transparent) 20%,color-mix(in srgb,var(--hsk-chat-text,#000000) 8%,transparent) 80%,transparent 100% )}.hsk-cb-terms-action-wrap{display:flex;justify-content:center;width:100%;margin-top:14px}.hsk-cb-terms-agree-btn{display:inline-flex;align-items:center;justify-content:center;padding:12px 34px;font-size:14px;font-weight:600;border-radius:9999px;border:1px solid var(--hsk-chat-divide,rgba(255,255,255,.08));background:var(--hsk-chat-divide,rgba(255,255,255,.06));color:var(--hsk-chat-muted,rgba(255,255,255,.4));cursor:not-allowed;transition:all .3s cubic-bezier(.16,1,.3,1);letter-spacing:-0.01em}.hsk-cb-terms-agree-btn.is-active{background:var(--hsk-primary,#ff6a33);color:#ffffff;border-color:var(--hsk-primary,#ff6a33);cursor:pointer;box-shadow:0 4px 14px color-mix(in srgb,var(--hsk-primary,#ff6a33) 35%,transparent)}.hsk-cb-terms-agree-btn.is-active:hover{filter:brightness(.92);transform:translateY(-1px);box-shadow:0 6px 18px color-mix(in srgb,var(--hsk-primary,#ff6a33) 45%,transparent)}.hsk-cb-terms-agree-btn.is-active:active{transform:translateY(0);box-shadow:0 2px 6px color-mix(in srgb,var(--hsk-primary,#ff6a33) 25%,transparent)}@keyframes hsk-theme-morph-in{0%{opacity:0;transform:scale(.92) translateY(4px)}100%{opacity:1;transform:scale(1) translateY(0)}}@keyframes hsk-theme-morph-out{0%{opacity:1;transform:scale(1) translateY(0)}100%{opacity:0;transform:scale(.92) translateY(4px)}}.hsk-retry-icon{display:inline-flex;transform-origin:center;transition:transform .36s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-msg-action:hover:not(:disabled) .hsk-retry-icon{transform:rotate(-180deg)}.hsk-cb-msg-action:active:not(:disabled) .hsk-retry-icon{transform:rotate(-360deg) scale(.85);transition-duration:.18s}.hsk-retry-icon--spinning{animation:hsk-spin .65s linear infinite !important}.hsk-edit-icon{display:inline-flex;transform-origin:20% 80%;transition:transform .26s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-msg-action:hover:not(:disabled) .hsk-edit-icon{transform:translateY(-1.5px) rotate(-14deg)}.hsk-cb-msg-action:active:not(:disabled) .hsk-edit-icon{transform:translateY(1px) scale(.88);transition-duration:.1s}.hsk-copy-icon{display:inline-flex}.hsk-copy-sheet{transition:transform .22s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-msg-action:hover:not(:disabled) .hsk-copy-sheet{transform:translate(-1.5px,-1.5px)}.hsk-check-icon{display:inline-flex;animation:hsk-check-pop .28s cubic-bezier(.34,1.56,.64,1) both}@keyframes hsk-check-pop{0%{transform:scale(.4);opacity:0}60%{transform:scale(1.24);opacity:1}100%{transform:scale(1);opacity:1}}@keyframes hsk-actions-enter{0%{opacity:0;transform:translateY(4px) scale(.96)}100%{opacity:1;transform:translateY(0) scale(1)}}@media (prefers-reduced-motion:reduce){.hsk-cb-msg-action:hover:not(:disabled) .hsk-retry-icon,.hsk-cb-msg-action:hover:not(:disabled) .hsk-edit-icon,.hsk-cb-msg-action:hover:not(:disabled) .hsk-copy-sheet,.hsk-check-icon{transform:none !important;animation:none !important}}\";\n","import cssText from '../generated/cssText';\r\n\r\nconst CONTAINER_ID = 'akropolys-kiku-root';\r\nlet container: HTMLElement | null = null;\r\nlet shadow: ShadowRoot | null = null;\r\n\r\nfunction applyStyles(root: ShadowRoot): void {\r\n if (typeof CSSStyleSheet !== 'undefined' && 'replaceSync' in CSSStyleSheet.prototype) {\r\n try {\r\n const sheet = new CSSStyleSheet();\r\n sheet.replaceSync(cssText);\r\n root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];\r\n return;\r\n } catch {\r\n }\r\n }\r\n const style = document.createElement('style');\r\n style.textContent = cssText;\r\n root.appendChild(style);\r\n}\r\n\r\nexport function getShadowContainer(): HTMLElement | null {\r\n if (typeof document === 'undefined') return null; // SSR\r\n if (shadow) return shadow as unknown as HTMLElement;\r\n\r\n container = document.getElementById(CONTAINER_ID);\r\n if (!container) {\r\n container = document.createElement('div');\r\n container.id = CONTAINER_ID;\r\n container.style.cssText = 'all: initial;';\r\n document.body.appendChild(container);\r\n }\r\n\r\n shadow = container.shadowRoot ?? container.attachShadow({ mode: 'open' });\r\n applyStyles(shadow);\r\n\r\n return shadow as unknown as HTMLElement;\r\n}\r\n\r\nexport function destroyShadowContainer(): void {\r\n container?.remove();\r\n container = null;\r\n shadow = null;\r\n}\r\n","import type { ScriptFont } from '@akropolys/sdk';\r\n\r\n// baseFont() is a bare fetch with no client-side cache, and every component running\r\n// useScriptFont calls it — six round trips per open. One promise per client instead.\r\nconst BASE_FONT = new WeakMap<object, Promise<ScriptFont | null>>();\r\n\r\nexport function cachedBaseFont(client: any): Promise<ScriptFont | null> {\r\n if (!client) return Promise.resolve(null);\r\n const hit = BASE_FONT.get(client);\r\n if (hit) return hit;\r\n const p = Promise.resolve()\r\n .then(() => client.baseFont?.() ?? null)\r\n .catch(() => null);\r\n BASE_FONT.set(client, p);\r\n return p;\r\n}\r\n\r\n// Pulled forward on hover/idle so the click doesn't pay for the round trips.\r\nexport function warmChrome(client: any, shopperLanguage: string, defaults: Record<string, string>): void {\r\n if (!client) return;\r\n cachedBaseFont(client);\r\n if (shopperLanguage) {\r\n try { client.getUIStrings?.(shopperLanguage, defaults)?.catch?.(() => {}); } catch { }\r\n }\r\n}\r\n","import { useEffect } from 'react';\r\nimport type { AkropolysTheme, ScriptFont } from '@akropolys/sdk';\r\n\r\nconst MOUNTED = new Map<string, number>();\r\n\r\nfunction formatFor(url: string): string {\r\n const ext = url.split('?')[0].split('#')[0].split('.').pop()?.toLowerCase();\r\n if (ext === 'woff2') return 'woff2';\r\n if (ext === 'woff') return 'woff';\r\n if (ext === 'otf') return 'opentype';\r\n if (ext === 'ttf') return 'truetype';\r\n return '';\r\n}\r\n\r\nfunction safeUrl(url: string): string | null {\r\n const u = url.trim();\r\n if (!u) return null;\r\n if (/[\"'()\\\\\\s]/.test(u)) return null;\r\n if (/^(javascript|vbscript):/i.test(u)) return null;\r\n return u;\r\n}\r\n\r\nconst RANGE_SEGMENT = /^[Uu]\\+[0-9A-Fa-f?]{1,6}(-[0-9A-Fa-f]{1,6})?$/;\r\n\r\nconst safeRange = (r: string): string => {\r\n const parts = r.split(',').map(s => s.trim()).filter(Boolean);\r\n if (parts.length === 0 || !parts.every(p => RANGE_SEGMENT.test(p))) return '';\r\n return parts.join(', ');\r\n};\r\n\r\nconst safeWeight = (w: string): string => (/^\\d{3}( \\d{3})?$/.test(w) ? w : '400');\r\n\r\nfunction useMountedFaces(key: string, css: string): void {\r\n useEffect(() => {\r\n if (!key || !css || typeof document === 'undefined') return;\r\n let h = 5381;\r\n for (let i = 0; i < key.length; i++) h = ((h << 5) + h + key.charCodeAt(i)) >>> 0;\r\n const id = `hsk-font-${h.toString(36)}`;\r\n\r\n MOUNTED.set(key, (MOUNTED.get(key) ?? 0) + 1);\r\n if (!document.getElementById(id)) {\r\n const el = document.createElement('style');\r\n el.id = id;\r\n el.textContent = css;\r\n document.head.appendChild(el);\r\n }\r\n\r\n return () => {\r\n const left = (MOUNTED.get(key) ?? 1) - 1;\r\n if (left > 0) { MOUNTED.set(key, left); return; }\r\n MOUNTED.delete(key);\r\n document.getElementById(id)?.remove();\r\n };\r\n }, [key, css]);\r\n}\r\n\r\nfunction scriptFontCSS(font: ScriptFont): string {\r\n return font.faces\r\n .map(f => {\r\n const url = safeUrl(f.url);\r\n if (!url) return '';\r\n return `@font-face{font-family:\"${font.family}\";font-style:normal;` +\r\n `font-weight:${safeWeight(f.weight)};font-display:swap;src:url(${url}) format(\"woff2\");` +\r\n (safeRange(f.unicodeRange) ? `unicode-range:${safeRange(f.unicodeRange)};` : '') + '}';\r\n })\r\n .join('');\r\n}\r\n\r\nexport function useScriptFontFace(font: ScriptFont | null | undefined): void {\r\n const faces = font?.faces ?? [];\r\n const css = font && faces.length ? scriptFontCSS(font) : '';\r\n useMountedFaces(css ? `script|${font!.family}|${faces.map(f => f.url).join('|')}` : '', css);\r\n}\r\n\r\nexport async function preloadScriptFont(font: ScriptFont, timeoutMs = 1200): Promise<void> {\r\n if (typeof document === 'undefined' || !('fonts' in document)) return;\r\n const css = scriptFontCSS(font);\r\n if (!css) return;\r\n\r\n const key = `script|${font.family}|${font.faces.map(f => f.url).join('|')}`;\r\n let h = 5381;\r\n for (let i = 0; i < key.length; i++) h = ((h << 5) + h + key.charCodeAt(i)) >>> 0;\r\n const id = `hsk-font-${h.toString(36)}`;\r\n if (!document.getElementById(id)) {\r\n const el = document.createElement('style');\r\n el.id = id;\r\n el.textContent = css;\r\n document.head.appendChild(el);\r\n }\r\n\r\n const fonts = (document as any).fonts;\r\n const loads = font.faces.map(() =>\r\n fonts.load(`16px \"${font.family}\"`).catch(() => {})\r\n );\r\n await Promise.race([\r\n Promise.all(loads),\r\n new Promise(resolve => setTimeout(resolve, timeoutMs)),\r\n ]);\r\n}\r\n\r\nexport function useHostFontFace(theme: 'light' | 'dark' | AkropolysTheme | undefined): void {\r\n const t = typeof theme === 'object' && theme ? theme : undefined;\r\n const family = t?.fontFamily?.split(',')[0].trim().replace(/^['\"]|['\"]$/g, '') ?? '';\r\n const urls = typeof t?.fontUrl === 'string' ? { normal: t.fontUrl } : (t?.fontUrl ?? {});\r\n const normal = urls.normal ?? '';\r\n const bold = urls.bold ?? '';\r\n const variable = urls.variable ?? '';\r\n\r\n useEffect(() => {\r\n if (!family || (!normal && !bold && !variable)) return;\r\n\r\n const weights: ReadonlyArray<readonly [string, string]> = variable\r\n ? [['100 900', variable]]\r\n : [['400', normal], ['700', bold]];\r\n\r\n const faces: string[] = [];\r\n for (const [weight, raw] of weights) {\r\n if (!raw) continue;\r\n const url = safeUrl(raw);\r\n if (!url) continue;\r\n const fmt = formatFor(url);\r\n faces.push(\r\n `@font-face{font-family:\"${family}\";font-style:normal;font-weight:${weight};` +\r\n `font-display:swap;src:url(${url})${fmt ? ` format(\"${fmt}\")` : ''};}`\r\n );\r\n }\r\n if (faces.length === 0) return;\r\n\r\n const css = faces.join('');\r\n const key = `${family}|${normal}|${bold}|${variable}`;\r\n let h = 5381;\r\n for (let i = 0; i < key.length; i++) h = ((h << 5) + h + key.charCodeAt(i)) >>> 0;\r\n const id = `hsk-host-font-${h.toString(36)}`;\r\n\r\n MOUNTED.set(key, (MOUNTED.get(key) ?? 0) + 1);\r\n if (!document.getElementById(id)) {\r\n const el = document.createElement('style');\r\n el.id = id;\r\n el.textContent = css;\r\n document.head.appendChild(el);\r\n }\r\n\r\n return () => {\r\n const left = (MOUNTED.get(key) ?? 1) - 1;\r\n if (left > 0) { MOUNTED.set(key, left); return; }\r\n MOUNTED.delete(key);\r\n document.getElementById(id)?.remove();\r\n };\r\n }, [family, normal, bold, variable]);\r\n}\r\n","import React from 'react';\r\nimport type { AkropolysTheme, ChatSource } from '@akropolys/sdk';\r\nimport type { KikuButtonProps } from '../KikuButton';\r\n\r\nexport const DEFAULT_CHIPS: string[] = [];\r\n\r\nexport const LANGUAGE_CHOICES = [\r\n { value: 'English', native: 'English', tag: 'en', rtl: false },\r\n { value: 'Chinese', native: '中文', tag: 'zh', rtl: false },\r\n { value: 'Spanish', native: 'Español', tag: 'es', rtl: false },\r\n { value: 'Arabic', native: 'العربية', tag: 'ar', rtl: true },\r\n { value: 'Hindi', native: 'हिन्दी', tag: 'hi', rtl: false },\r\n { value: 'French', native: 'Français', tag: 'fr', rtl: false },\r\n { value: 'Swahili', native: 'Kiswahili', tag: 'sw', rtl: false },\r\n { value: 'Portuguese', native: 'Português', tag: 'pt', rtl: false },\r\n { value: 'Japanese', native: '日本語', tag: 'ja', rtl: false },\r\n { value: 'Urdu', native: 'اردو', tag: 'ur', rtl: true },\r\n];\r\n\r\nexport function endonymFor(lang: string | null | undefined): string | undefined {\r\n if (!lang) return undefined;\r\n const typed = lang.trim();\r\n if (!typed) return undefined;\r\n const l = typed.toLowerCase();\r\n const hit = LANGUAGE_CHOICES.find(\r\n x => x.value.toLowerCase() === l || x.native.toLowerCase() === l || x.tag === l\r\n );\r\n return hit ? hit.native : typed;\r\n}\r\n\r\nexport function isRTLText(s: string): boolean {\r\n for (const ch of s) {\r\n const code = ch.codePointAt(0) ?? 0;\r\n if (\r\n (code >= 0x0590 && code <= 0x08ff) || // Hebrew, Arabic, Syriac, Arabic Supplement, Thaana, NKo, Samaritan, Mandaic, Arabic Extended-A\r\n (code >= 0xfb1d && code <= 0xfdff) || // Hebrew/Arabic presentation forms A\r\n (code >= 0xfe70 && code <= 0xfeff) // Arabic presentation forms B\r\n ) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nexport const LANGUAGE_METAS: Record<string, { preparing: string; changeLang: string; rtl?: boolean; endonym?: string }> = {\r\n english: { preparing: 'Preparing in English…', changeLang: 'Change language', endonym: 'English' },\r\n swahili: { preparing: 'Inatayarisha kwa Kiswahili…', changeLang: 'Badilisha lugha', endonym: 'Kiswahili' },\r\n french: { preparing: 'Configuration en français…', changeLang: 'Changer de langue', endonym: 'Français' },\r\n spanish: { preparing: 'Configurando en español…', changeLang: 'Cambiar idioma', endonym: 'Español' },\r\n arabic: { preparing: 'جارٍ الإعداد باللغة العربية…', changeLang: 'تغيير اللغة', rtl: true, endonym: 'العربية' },\r\n portuguese: { preparing: 'Configurando em português…', changeLang: 'Alterar idioma', endonym: 'Português' },\r\n hindi: { preparing: 'हिन्दी में तैयार किया जा रहा है…', changeLang: 'भाषा बदलें', endonym: 'हिन्दी' },\r\n chinese: { preparing: '正在准备中文环境…', changeLang: '更改语言', endonym: '中文' },\r\n urdu: { preparing: 'اردو میں تیاری جاری ہے…', changeLang: 'زبان تبدیل کریں', rtl: true, endonym: 'اردو' },\r\n japanese: { preparing: '日本語を設定中…', changeLang: '言語を変更', endonym: '日本語' },\r\n german: { preparing: 'Wird auf Deutsch eingerichtet…', changeLang: 'Sprache ändern', endonym: 'Deutsch' },\r\n italian: { preparing: 'Configurazione in italiano…', changeLang: 'Cambia lingua', endonym: 'Italiano' },\r\n russian: { preparing: 'Настройка на русском…', changeLang: 'Изменить язык', endonym: 'Русский' },\r\n korean: { preparing: '한국어로 설정 중…', changeLang: '언어 변경', endonym: '한국어' },\r\n turkish: { preparing: 'Türkçe olarak hazırlanıyor…', changeLang: 'Dili değiştir', endonym: 'Türkçe' },\r\n vietnamese: { preparing: 'Đang thiết lập bằng Tiếng Việt…', changeLang: 'Đổi ngôn ngữ', endonym: 'Tiếng Việt' },\r\n indonesian: { preparing: 'Menyiapkan dalam Bahasa Indonesia…', changeLang: 'Ubah bahasa', endonym: 'Bahasa Indonesia' },\r\n polish: { preparing: 'Przygotowywanie w języku polskim…', changeLang: 'Zmień język', endonym: 'Polski' },\r\n dutch: { preparing: 'Instellen in het Nederlands…', changeLang: 'Taal wijzigen', endonym: 'Nederlands' },\r\n thai: { preparing: 'กำลังตั้งค่าเป็นภาษาไทย…', changeLang: 'เปลี่ยนภาษา', endonym: 'ไทย' },\r\n bengali: { preparing: 'বাংলায় প্রস্তুত করা হচ্ছে…', changeLang: 'ভাষা পরিবর্তন করুন', endonym: 'বাংলা' },\r\n tamil: { preparing: 'தமிழில் தயார் செய்யப்படுகிறது…', changeLang: 'மொழியை மாற்றவும்', endonym: 'தமிழ்' },\r\n telugu: { preparing: 'తెలుగులో సిద్ధం చేస్తోంది…', changeLang: 'భాషను మార్చండి', endonym: 'తెలుగు' },\r\n persian: { preparing: 'در حال آمادهسازی به زبان فارسی…', changeLang: 'تغییر زبان', rtl: true, endonym: 'فارسی' },\r\n farsi: { preparing: 'در حال آمادهسازی به زبان فارسی…', changeLang: 'تغییر زبان', rtl: true, endonym: 'فارسی' },\r\n greek: { preparing: 'Ρύθμιση στα ελληνικά…', changeLang: 'Αλλαγή γλώσσας', endonym: 'Ελληνικά' },\r\n hebrew: { preparing: 'מגדיר בעברית…', changeLang: 'שנה שפה', rtl: true, endonym: 'עברית' },\r\n swedish: { preparing: 'Ställer in på svenska…', changeLang: 'Byt språk', endonym: 'Svenska' },\r\n kikuyu: { preparing: 'Gĩkũyũ gĩgĩthondekwo…', changeLang: 'Cenjia rũthiomi', endonym: 'Gĩkũyũ' },\r\n gikuyu: { preparing: 'Gĩkũyũ gĩgĩthondekwo…', changeLang: 'Cenjia rũthiomi', endonym: 'Gĩkũyũ' },\r\n akan: { preparing: 'Yɛresiesie wɔ Akan mu…', changeLang: 'Sesa kasa', endonym: 'Akan' },\r\n twi: { preparing: 'Yɛresiesie wɔ Twi mu…', changeLang: 'Sesa kasa', endonym: 'Twi' },\r\n yoruba: { preparing: 'Ngbaradi ni Èdè Yorùbá…', changeLang: 'Yi ede pada', endonym: 'Èdè Yorùbá' },\r\n amharic: { preparing: 'በአማርኛ በመዘጋጀት ላይ…', changeLang: 'ቋንቋ ቀይር', endonym: 'አማርኛ' },\r\n somali: { preparing: 'Diyaarinta af Soomaali…', changeLang: 'Beddel luqadda', endonym: 'Af-Soomaali' },\r\n hausa: { preparing: 'Shirya cikin Hausa…', changeLang: 'Canja harshe', endonym: 'Hausa' },\r\n zulu: { preparing: 'Ilungiselela ngesiZulu…', changeLang: 'Shintsha ulimi', endonym: 'isiZulu' },\r\n oromo: { preparing: 'Afaan Oromootiin qophaa\\'aa jira…', changeLang: 'Afaan jijjiiri', endonym: 'Afaan Oromoo' },\r\n luganda: { preparing: 'Tuteekateeka mu Oluganda…', changeLang: 'Kyusa olulimi', endonym: 'Oluganda' },\r\n};\r\n\r\nfunction formatLangName(str: string): string {\r\n const trimmed = str.trim();\r\n if (!trimmed) return '…';\r\n return trimmed.charAt(0).toUpperCase() + trimmed.slice(1);\r\n}\r\n\r\nexport function getLoadingMeta(lang: string | null | undefined) {\r\n if (!lang) {\r\n return {\r\n nativeName: '…',\r\n preparing: 'Preparing…',\r\n changeLang: '←',\r\n rtl: false,\r\n known: true,\r\n };\r\n }\r\n const l = lang.trim().toLowerCase();\r\n const hit = Object.entries(LANGUAGE_METAS).find(\r\n ([k, v]) => k === l || v.endonym?.toLowerCase() === l || endonymFor(k)?.toLowerCase() === l\r\n );\r\n if (hit) {\r\n return {\r\n nativeName: hit[1].endonym || endonymFor(lang) || formatLangName(lang),\r\n preparing: hit[1].preparing,\r\n changeLang: hit[1].changeLang,\r\n rtl: !!hit[1].rtl || isRTLText(hit[1].preparing),\r\n known: true,\r\n };\r\n }\r\n const rawName = endonymFor(lang) || lang;\r\n const nativeName = formatLangName(rawName);\r\n const rtl = isRTLText(nativeName);\r\n return {\r\n nativeName,\r\n preparing: `Preparing in ${nativeName}…`,\r\n changeLang: rtl ? 'تغيير' : 'Change',\r\n rtl,\r\n known: false,\r\n };\r\n}\r\n\r\nexport const LIVE_VOICES = [\r\n { name: 'Puck', label: 'Puck', gender: 'male' },\r\n { name: 'Charon', label: 'Charon', gender: 'male' },\r\n { name: 'Kore', label: 'Kore', gender: 'female' },\r\n { name: 'Aoede', label: 'Aoede', gender: 'female' },\r\n] as const;\r\n\r\nexport type { VoicePhase } from '../../utils/voiceSession';\r\n\r\nexport const VOICE_STORAGE_KEY = 'hsk-live-voice';\r\n\r\nexport const DEFAULT_UI_STRINGS = {\r\n langPlaceholder: 'Type your preferred language…',\r\n nameStepTitle: 'Nice to meet you.',\r\n nameStepLead: 'I can search, visualize, or capture anything for you — on this site or any other.',\r\n nameStepAsk: 'What should I call you?',\r\n namePlaceholder: 'Type your name…',\r\n attachImage: 'Attach a photo',\r\n vizUnavailable: 'The preview could not be loaded.',\r\n vizDisclaimerImage: 'Generated using Artificial Intelligence — colours, size and placement may differ from the real product.',\r\n vizDisclaimerVideo: 'Generated using Artificial Intelligence — colours, size and movement may differ from the real product.',\r\n calcDisclaimer: 'This is a calculation from live figures, not a guarantee — the market can move against it.',\r\n staleTitle: 'No longer available',\r\n staleRemoved: '{title} has been removed and is no longer on offer.',\r\n staleUnavailable: '{title} is currently unavailable.',\r\n keyPastePrompt: 'Paste your public id — or create one',\r\n keyPastePlaceholder: 'your public id…',\r\n keyUseMine: 'Use my id',\r\n keyCreating: 'Creating…',\r\n keyCreateNew: \"I'm new — create one\",\r\n keySecretTitle: 'Your secret — shown only once',\r\n keyDismiss: 'Dismiss',\r\n keyCopySecret: 'Copy secret',\r\n keyCopied: 'Copied',\r\n keySecretHint: 'Keep it private — use it to unlock your memory.',\r\n keyPublicTitle: 'Your public id',\r\n keyCopyId: 'Copy id',\r\n keyPublicHint: 'Paste this on any site to save to the same memory.',\r\n keyAutoHide: 'Hides automatically in {seconds}s.',\r\n greetReturning: 'Hi, {name}.',\r\n greetReturningLead: 'What can I find for you today?',\r\n howShouldResultsLook: 'How should results look?',\r\n entityLangIntro: 'I reply in {lang}. Product names stay as this site lists them — the details can too, or be translated.',\r\n asWritten: 'As written',\r\n inLanguage: 'In {lang}',\r\n namesAsWritten: 'Details exactly as the site lists them.',\r\n detailsTranslated: 'Details translated. Numbers and links stay exactly as listed.',\r\n entityLangPlaceholder: 'Pick one of the two cards above…',\r\n termsStepTitle: 'Privacy & Terms of Use',\r\n termsStepSubtitle: 'Transparent, anonymous, and zero-PII by design.',\r\n termsPiiTitle: 'Zero PII Collection',\r\n termsPiiDesc: 'We never collect or store personal identifying information (no emails, phone numbers, or real-world identities) from your chats or voice sessions.',\r\n termsSessionTitle: 'Anonymous Session Tokens',\r\n termsSessionDesc: 'Your session uses an anonymous client-side token solely to maintain context. It is never linked to your real identity.',\r\n termsMemoryTitle: 'Ephemeral Chats vs. Mimi Vault',\r\n termsMemoryDesc: 'Regular chats are ephemeral — closing the tab or clicking \"Clear Chat\" terminates them forever. Items you save with \"@kiku\" are encrypted and can be unlocked at mimi.akropolys.cloud with your Secret Access Key.',\r\n termsCookieTitle: 'Host Website Telemetry',\r\n termsCookieDesc: 'The host website where Kiku is embedded may collect cookies and analytics per their own cookie policy, outside Kiku\\'s control.',\r\n termsAgreeButton: 'Agree & Continue',\r\n termsAgreeCounting: 'Agree & Continue ({seconds}s)',\r\n termsPlaceholder: 'Please review our Privacy & Terms above…',\r\n allSet: \"You're all set, {name}.\",\r\n replyingTranslated: 'Replying in {lang}, results translated too. Ask me anything.',\r\n replyingOriginal: 'Replying in {lang}, results as this site wrote them. Ask me anything.',\r\n defaultPlaceholder: 'Ask me anything…',\r\n footerHint: 'kiku · searches the whole catalogue in real time',\r\n voiceListening: 'Listening… tap the mic to stop',\r\n voiceSending: 'Got it — sending…',\r\n voiceModeStart: 'Hands-free conversation',\r\n voiceModeExit: 'Leave hands-free',\r\n voicePhaseListening: 'Listening',\r\n voicePhaseThinking: 'Thinking',\r\n voicePhaseSpeaking: 'Speaking',\r\n voiceHint: \"Just talk — I'll answer when you pause.\",\r\n voiceMuted: 'Muted',\r\n voiceMutedHint: 'Tap the microphone to speak again.',\r\n micDenied: 'Microphone blocked. Allow mic access for this site, then try again.',\r\n micInsecure: 'Voice needs a secure (https) connection.',\r\n micMissing: 'No microphone found.',\r\n micLangUnsupported: 'This browser cannot transcribe that language yet. Type instead.',\r\n micNetwork: \"Couldn't reach voice. Try again in a moment.\",\r\n voiceUnavailable: 'Voice is unavailable right now. Try again in a moment.',\r\n voiceLimitReached: \"You've used up today's voice time. It resets in a day — chat still works.\",\r\n voiceSiteLimit: 'Voice is out of allowance on this site for now. Chat still works.',\r\n voicePickerLabel: 'Choose a voice',\r\n micNoSpeech: \"Didn't catch anything. Try again, a little closer to the mic.\",\r\n micFailed: \"Couldn't hear that. Try again.\",\r\n clearChat: 'Clear chat',\r\n thinking: 'Thinking',\r\n thoughtForSeconds: 'Thought for {duration}',\r\n thoughtProcess: 'Thought process',\r\n captureAndRemember: 'kiku — capture & remember',\r\n captureCurrentPage: 'Capture current page',\r\n captureAll: 'Capture all ({count})',\r\n whatHaveYouSaved: 'What have you saved?',\r\n deleteThis: 'Delete this',\r\n errShopperReplyLimit: \"You've reached this site's reply limit for your account.\",\r\n errAccessRevoked: 'Your access to the assistant has been revoked by the store.',\r\n errAccountRequired: 'Please create an account to continue using the chat assistant.',\r\n errStreamInterrupted: 'The reply was interrupted. Please try again.',\r\n errNetwork: \"The assistant couldn't respond just now — please try again in a moment.\",\r\n errGeneric: 'Something went wrong. Please try again.',\r\n vizWorking: 'Visualizing…',\r\n vizMarkEdit: 'Mark & edit',\r\n markupTitle: 'Mark where you want the change',\r\n markupCancel: 'Cancel',\r\n markupSketch: 'Sketch',\r\n markupText: 'Text',\r\n markupEraser: 'Eraser',\r\n markupUndo: 'Undo',\r\n markupClear: 'Clear',\r\n markupSend: 'Send',\r\n markupTextHint: 'Type, then Enter',\r\n markupInstruction: 'Describe the change — e.g. add the sofa here',\r\n markupDialogLabel: 'Mark up image',\r\n markupColorLabel: 'Colour {colour}',\r\n markupError: \"Couldn't process this image — try a newer visualization.\",\r\n markupLoadError: \"This image can't be edited here.\",\r\n markupLoading: 'Loading image…',\r\n markupApplyMarks: 'Apply the change I marked on the image.',\r\n openMemory: 'Open my memory on mimi',\r\n errTooManyRequests: 'The assistant is currently receiving too many requests. Please try again in a few moments.',\r\n errTokenLimit: \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\",\r\n statusSent: 'Sent',\r\n statusStopped: 'Sent · reply stopped',\r\n queuedWaiting: 'Queued',\r\n queuedSendNow: 'Send now',\r\n jumpToLatest: 'Scroll to latest',\r\n timelineLabel: 'Questions in this conversation',\r\n voiceConnecting: 'Connecting — wait for the tone before speaking',\r\n stoppedByYou: 'You stopped this response.',\r\n stoppedInterrupted: 'This response was interrupted.',\r\n continueGenerating: 'Continue generating',\r\n generateResponse: 'Generate response',\r\n pillCompareTop2: 'Compare top 2',\r\n pillCompareTop2Query: 'Compare the {a} and {b}',\r\n pillMoreOn: 'More on {name}',\r\n pillMoreOnQuery: 'Tell me more about the {name}',\r\n pillUnder: 'Under {amount}',\r\n pillUnderQuery: 'Show me options under {amount}',\r\n pillSimilarOptions: 'Similar options',\r\n pillSimilarOptionsQuery: 'Show me more like the {name}',\r\n pillWhichBest: 'Which is best?',\r\n pillWhichBestQuery: 'Which one would you recommend and why?',\r\n pillFindAlternatives: 'Find alternatives',\r\n pillFindAlternativesQuery: 'What are good alternatives to the {name}?',\r\n pillShowPopular: 'Show popular items',\r\n pillShowPopularQuery: 'What are your most popular items?',\r\n pillRecommend: 'Recommend something',\r\n pillRecommendQuery: 'What do you recommend for me?',\r\n cardClickAnswer: 'The {name}',\r\n cardClickQuery: 'Tell me more about the {name}{price} — what are its key details, who is it best suited for, and what should I know?',\r\n displayCapture: 'capture {name}',\r\n displayCaptureAll: 'capture all ({count} items)',\r\n displayViewHistory: 'what have you saved?',\r\n displayDelete: 'delete this',\r\n retry: 'Retry',\r\n edit: 'Edit',\r\n copy: 'Copy',\r\n copied: 'Copied',\r\n msgFailed: 'Failed to send',\r\n} as const;\r\n\r\nexport type UIStringKey = keyof typeof DEFAULT_UI_STRINGS;\r\nexport type Translate = (key: UIStringKey, vars?: Record<string, string>) => string;\r\n\r\nexport const UIStringsContext = React.createContext<Translate>(\r\n (key, vars) => {\r\n let s: string = DEFAULT_UI_STRINGS[key];\r\n if (vars) for (const [k, v] of Object.entries(vars)) s = s.split(`{${k}}`).join(v);\r\n return s;\r\n }\r\n);\r\nexport const useT = () => React.useContext(UIStringsContext);\r\n\r\nexport function extractName(raw: string): string | null {\r\n let s = raw.trim();\r\n if (!s || s.length > 40 || s.includes('?')) return null;\r\n s = s.replace(/^(hi|hey|hello|yo)[,!.\\s]+/i, '');\r\n s = s.replace(/^(i['’]?m|im|my name is|call me|it['’]?s|this is|name['’]?s)\\s+/i, '');\r\n s = s.trim().replace(/[.!,]+$/, '');\r\n const words = s.split(/\\s+/);\r\n if (words.length === 0 || words.length > 3) return null;\r\n if (!/^[\\p{L}][\\p{L}\\-'’ ]{0,30}$/u.test(s)) return null;\r\n const q = s.toLowerCase();\r\n const queryish = ['phone', 'laptop', 'tv', 'cheap', 'best', 'under', 'buy', 'search', 'find', 'show', 'need', 'want', 'price', 'sofa', 'shoe', 'headphone', 'camera', 'gift', 'help'];\r\n if (queryish.some(w => q.includes(w))) return null;\r\n const name = words[0];\r\n return name.charAt(0).toUpperCase() + name.slice(1);\r\n}\r\n\r\nexport const SERVER_ERROR_STRINGS: Record<string, UIStringKey> = {\r\n shopper_reply_limit: 'errShopperReplyLimit',\r\n RATE_LIMIT_EXCEEDED: 'errShopperReplyLimit',\r\n access_revoked: 'errAccessRevoked',\r\n account_required: 'errAccountRequired',\r\n stream_interrupted: 'errStreamInterrupted',\r\n};\r\n\r\nexport const TERMINAL_ERROR_CODES = new Set(['account_required', 'access_revoked', 'shopper_reply_limit', 'RATE_LIMIT_EXCEEDED']);\r\n\r\nexport const isTerminalError = (code: string | null | undefined): boolean =>\r\n Boolean(code && TERMINAL_ERROR_CODES.has(code));\r\n\r\nexport const getFriendlyError = (err: any, tr: Translate) => {\r\n const code = err && typeof err === 'object' ? (err as { code?: string }).code : undefined;\r\n if (code && SERVER_ERROR_STRINGS[code]) return tr(SERVER_ERROR_STRINGS[code]);\r\n\r\n let str = '';\r\n if (typeof err === 'string') str = err;\r\n else if (err && typeof err === 'object' && err.message) str = err.message;\r\n else try { str = JSON.stringify(err); } catch { str = String(err); }\r\n\r\n const lower = str.toLowerCase();\r\n if (\r\n lower.includes('429') ||\r\n lower.includes('too many requests') ||\r\n lower.includes('requests per minute limit exceeded') ||\r\n lower.includes('too_many_requests_error') ||\r\n lower.includes('request_quota_exceeded') ||\r\n lower.includes('quota')\r\n ) {\r\n return tr('errTooManyRequests');\r\n }\r\n\r\n if (lower.includes('token limit')) {\r\n return tr('errTokenLimit');\r\n }\r\n\r\n if (lower.includes('failed to fetch') || lower.includes('networkerror') || lower.includes('request failed')) {\r\n return tr('errNetwork');\r\n }\r\n\r\n if (str) {\r\n try { console.warn('[kiku] untranslated error:', str); } catch { /* no console */ }\r\n }\r\n return tr('errGeneric');\r\n};\r\n\r\nexport const isSecureOrigin = () =>\r\n typeof window === 'undefined' || window.isSecureContext !== false;\r\n\r\nexport const KIKU_KEY_REVEAL_SECONDS = 15;\r\n\r\nexport interface ModalOrigin {\r\n x: number;\r\n y: number;\r\n r: number;\r\n top?: number;\r\n left?: number;\r\n width?: number;\r\n height?: number;\r\n borderRadius?: number;\r\n}\r\n\r\nexport interface ChatModalProps extends Pick<KikuButtonProps, 'title' | 'placeholder' | 'backdropColor' | 'backdropBlur' | 'onSelectSource' | 'defaultCurrency' | 'chips' | 'theme' | 'classNames' | 'enableVoice' | 'voiceLang' | 'enableVision' | 'visionCategoryHint' | 'enableAudioResponse' | 'ttsVoice' | 'autoSpeakResponses'> {\r\n theme?: 'light' | 'dark' | AkropolysTheme;\r\n classNames?: any;\r\n origin?: ModalOrigin | null;\r\n onClose: () => void;\r\n}\r\n","import React, { useState, useEffect, useLayoutEffect, useRef, useCallback, useId } from 'react';\nimport { flushSync } from 'react-dom';\nimport { THEMES, isThemeId, themeDef, DEFAULT_DARK, DEFAULT_LIGHT, type ThemeId } from './themes';\nimport { useKiku, useScouts, ChatSource, ChatAttachment, CaptureTarget, subscribeLiveStream } from '@akropolys/sdk';\nimport { useAkropolysContext } from '@akropolys/sdk';\nimport { cn } from '../../utils/cn';\nimport { resolveTheme } from '../../utils/theme';\nimport { useHostFontFace } from '../../utils/hostFont';\nimport { useDragToDismiss } from '../../utils/sheetGesture';\nimport { downscaleImage } from '../../utils/downscaleImage';\nimport { MarkupEditor } from '../MarkupEditor';\nimport { ScoutRail } from '../Scouts';\nimport type { KikuState } from '../KikuAvatar';\nimport KikuDoodles from '../KikuDoodles';\n\nimport {\n DEFAULT_CHIPS,\n UIStringsContext,\n extractName,\n ChatModalProps,\n} from './types';\nimport { useScriptFont } from './hooks/useScriptFont';\nimport { useChatScroll } from './hooks/useChatScroll';\nimport { useKikuKey } from './hooks/useKikuKey';\nimport { useChatCommands } from './hooks/useChatCommands';\nimport { useVoiceController } from './hooks/useVoiceController';\nimport { ChatTopbar } from './ChatTopbar';\nimport { CopyIcon, CheckIcon, CloseIcon } from './icons';\nimport { OnboardingView } from './OnboardingView';\n\nconst RadarIcon = ({ size = 14 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2Z\"/>\n <path d=\"M12 6a6 6 0 1 0 6 6 6 6 0 0 0-6-6Z\"/>\n <circle cx=\"12\" cy=\"12\" r=\"2\"/>\n </svg>\n);\nimport { ChatMessages } from './ChatMessages';\nimport { ChatComposer } from './ChatComposer';\nimport { VoiceOverlay } from './VoiceOverlay';\nimport { LightboxModal } from './components/LightboxModal';\nimport { ConversationTimeline } from './components/ConversationTimeline';\nimport { TapbackMenu } from './components/TapbackMenu';\n\nexport function ChatModal({\n title = 'kiku',\n placeholder = 'Ask me anything…',\n backdropColor,\n backdropBlur,\n onClose,\n onSelectSource,\n defaultCurrency = '',\n chips = DEFAULT_CHIPS,\n theme,\n classNames = {},\n enableVoice = false,\n voiceLang,\n enableVision = false,\n visionCategoryHint,\n enableAudioResponse = true,\n ttsVoice = 'Puck',\n autoSpeakResponses = true,\n origin,\n}: ChatModalProps) {\n const client = useAkropolysContext();\n const { messages, sources, loading, streaming, error, errorCode, lastAction, lastIntent, allowedActions, send, queuedMessage, sendQueuedNow, appendSpokenExchange, stop, stopped, interrupted, continueGenerating, reset, referencedIds } = useKiku();\n const { activeScouts } = useScouts();\n\n\n const [shopperName, setShopperNameState] = useState<string>(() => {\n try { return client.getShopperName?.() ?? ''; } catch { return ''; }\n });\n const [shopperLanguage, setShopperLanguageState] = useState<string>(() => {\n try { return client.getShopperLanguage?.() ?? ''; } catch { return ''; }\n });\n const [entityLangPref, setEntityLangPrefState] = useState<string>(() => {\n try { return client.getEntityLanguageMode?.() ?? ''; } catch { return ''; }\n });\n const [justCompleted, setJustCompleted] = useState(false);\n\n const {\n chromeReady,\n isRTL,\n speechLang,\n scriptFont,\n fontStack,\n isNonLatin,\n hostFontCovers,\n t,\n tNode,\n } = useScriptFont({ shopperLanguage, theme });\n\n const discussedSources = React.useMemo(() => {\n const byRef = sources.filter(s => s.id && referencedIds.includes(s.id));\n const answer = [...messages].reverse().find(m => m.role === 'assistant')?.content ?? '';\n if (!answer) return byRef;\n const seen = new Set(byRef.map(s => s.id));\n const hay = answer.toLowerCase().replace(/\\s+/g, ' ');\n const aliases = (name: string) => {\n const n = String(name ?? '').toLowerCase().replace(/\\s+/g, ' ').trim();\n const w = n.split(' ');\n const out = [n];\n if (w.length > 3) out.push(w.slice(0, 3).join(' '));\n if (w.length > 4) out.push(w.slice(0, 4).join(' '));\n return out.filter(a => a.length >= 5);\n };\n const named = sources.filter(s =>\n s.id && !seen.has(s.id) && aliases(s.name).some(a => hay.includes(a))\n );\n return [...byRef, ...named];\n }, [sources, referencedIds, messages]);\n\n const captureAllowed = allowedActions === null || allowedActions.includes('capture');\n const [input, setInput] = useState('');\n const [showKikuPicker, setShowKikuPicker] = useState(false);\n const [showAtPicker, setShowAtPicker] = useState(false);\n const [attachments, setAttachments] = useState<ChatAttachment[]>([]);\n const imageInputRef = useRef<HTMLInputElement>(null);\n const [vizState, setVizState] = useState<Record<string, 'ok' | 'err'>>({});\n const [lightboxSrc, setLightboxSrc] = useState<string | null>(null);\n const [markupSrc, setMarkupSrc] = useState<string | null>(null);\n\n const [termsAgreed, setTermsAgreed] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false;\n try {\n return localStorage.getItem('akropolys_terms_agreed') === 'true';\n } catch {\n return false;\n }\n });\n\n const onboarding = messages.length === 0;\n const awaitingLang = onboarding && !shopperLanguage;\n const awaitingName = onboarding && !!shopperLanguage && !shopperName;\n const awaitingEntityLang = onboarding && !!shopperLanguage && !!shopperName && !entityLangPref;\n const awaitingConsent = onboarding && !!shopperLanguage && !!shopperName && !!entityLangPref && !termsAgreed;\n const inOnboarding = awaitingLang || awaitingName || awaitingEntityLang || awaitingConsent;\n\n const hasLiveData = React.useMemo(\n () => messages.some(m => (m as any).liveKeys?.length > 0),\n [messages]\n );\n useEffect(() => {\n if (!hasLiveData) return;\n return subscribeLiveStream({ client });\n }, [hasLiveData, client]);\n\n const [isNarrow, setIsNarrow] = useState(false);\n useEffect(() => {\n const mq = window.matchMedia?.('(max-width: 768px)');\n if (!mq) return;\n const apply = () => setIsNarrow(mq.matches);\n apply();\n mq.addEventListener?.('change', apply);\n return () => mq.removeEventListener?.('change', apply);\n }, []);\n\n const chooseLanguage = (lang: string) => {\n const v = lang.trim();\n if (!v) {\n try { client.setShopperLanguage?.(''); } catch { }\n setShopperLanguageState('');\n return;\n }\n try { client.setShopperLanguage?.(v); } catch { }\n setShopperLanguageState(v);\n setJustCompleted(false);\n };\n\n const chooseEntityLang = (mode: 'translated' | 'original') => {\n try { client.setEntityLanguageMode?.(mode); } catch { }\n setEntityLangPrefState(mode);\n if (termsAgreed) {\n setJustCompleted(true);\n }\n };\n\n const agreeTerms = () => {\n try {\n localStorage.setItem('akropolys_terms_agreed', 'true');\n } catch { /* noop */ }\n setTermsAgreed(true);\n setJustCompleted(true);\n };\n\n const activeTitle = title === 'kiku' ? (t('nameStepTitle') ? 'kiku' : title) : title;\n const activePlaceholder =\n awaitingLang ? t('langPlaceholder')\n : awaitingName ? t('namePlaceholder')\n : awaitingEntityLang ? t('entityLangPlaceholder')\n : awaitingConsent ? t('termsPlaceholder')\n : (placeholder === 'Ask me anything…' ? t('defaultPlaceholder') : placeholder);\n\n const activeChips = !chips || chips === DEFAULT_CHIPS ? [] : (Array.isArray(chips) ? chips : []);\n const onboardingMood: KikuState =\n awaitingLang ? 'curious'\n : awaitingName ? 'welcoming'\n : awaitingEntityLang ? 'guiding'\n : awaitingConsent ? 'focused'\n : 'happy';\n\n const [currentTheme, setCurrentTheme] = useState<ThemeId>(() => {\n if (isThemeId(theme)) return theme;\n if (typeof window !== 'undefined') {\n const saved = localStorage.getItem('akropolys_theme');\n if (isThemeId(saved)) return saved;\n return window.matchMedia?.('(prefers-color-scheme: light)').matches ? DEFAULT_LIGHT : DEFAULT_DARK;\n }\n return DEFAULT_DARK;\n });\n\n // Fluid theme switch: updates active theme and lets CSS & canvas glyphs animate live\n const handleToggleTheme = (next: ThemeId, alsoCloseMenu = false) => {\n setCurrentTheme(next);\n if (alsoCloseMenu) {\n setThemeMenuOpen(false);\n setThemeMenuClosing(false);\n }\n try { localStorage.setItem('akropolys_theme', next); } catch { /* noop */ }\n };\n\n const { vars: customStyles } = resolveTheme(theme);\n const hskThemeAttr = currentTheme;\n useHostFontFace(theme);\n\n const handleSendRef = useRef<(text: string) => void>(() => {});\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const handleSend = async (text?: string, extraAttachments?: ChatAttachment[], forcedIntent?: string, captureTargets?: CaptureTarget[]) => {\n const raw = (text ?? input).trim();\n const toSend = extraAttachments ?? attachments;\n if ((!raw && toSend.length === 0) || !chromeReady || queuedMessage) return;\n\n if (awaitingName) {\n if (!raw) return;\n const name = extractName(raw) || raw.slice(0, 40);\n try { client.setShopperName?.(name); } catch { }\n setShopperNameState(name);\n setInput('');\n return;\n }\n if (awaitingLang) {\n if (!raw) return;\n chooseLanguage(raw);\n setInput('');\n return;\n }\n if (awaitingEntityLang) {\n setInput('');\n return;\n }\n\n setShowKikuPicker(false);\n setShowAtPicker(false);\n setInput('');\n setAttachments([]);\n const queryToSend = raw || (toSend.some(a => a.type === 'image') ? 'Analyze this image' : 'What is this?');\n await send(queryToSend, raw, toSend.length > 0 ? toSend : undefined, forcedIntent, captureTargets);\n };\n\n const [retrying, setRetrying] = useState(false);\n\n const handleRetryMessage = useCallback(async (msg?: ChatMessage) => {\n const target = (msg && msg.role === 'user') ? msg : [...messages].reverse().find(m => m.role === 'user');\n if (!target?.content) return;\n setRetrying(true);\n try {\n await handleSend(target.content);\n } finally {\n setRetrying(false);\n }\n }, [messages, handleSend]);\n\n const handleEditMessage = useCallback((msg: ChatMessage) => {\n if (!msg?.content) return;\n setInput(msg.content);\n setTimeout(() => {\n if (textareaRef.current) {\n textareaRef.current.focus();\n const len = msg.content.length;\n try {\n textareaRef.current.setSelectionRange(len, len);\n } catch {}\n }\n }, 50);\n }, [setInput, textareaRef]);\n\n const retryLastMessage = useCallback(async () => {\n await handleRetryMessage();\n }, [handleRetryMessage]);\n\n const {\n keyInput,\n setKeyInput,\n keyPhase,\n setKeyPhase,\n mintedKey,\n setMintedKey,\n mintedPub,\n setMintedPub,\n copied,\n keyCountdown,\n minting,\n copyValue,\n handleUseExistingKey,\n handleCreateKey,\n } = useKikuKey(lastAction, retryLastMessage);\n\n const getStoredKikuId = useCallback((): string => {\n if (typeof window === 'undefined') return 'N/A';\n try {\n const fromSession = sessionStorage.getItem('akropolys_kiku_pub') || sessionStorage.getItem('kiku_pub');\n if (fromSession) return fromSession;\n const fromLocal = localStorage.getItem('akropolys_kiku_pub') || localStorage.getItem('kiku_pub') || localStorage.getItem('kiku_id');\n if (fromLocal) return fromLocal;\n const match = document.cookie.match(/(?:^|;\\s*)(?:akropolys_kiku_pub|kiku_pub|kiku_id)=([^;]+)/);\n if (match) return decodeURIComponent(match[1]);\n } catch {}\n return 'N/A';\n }, []);\n\n const displayKikuPub = mintedPub ?? client?.getKikuPub?.() ?? getStoredKikuId();\n\n const [tapbackTarget, setTapbackTarget] = useState<{\n msg: any;\n rect: { top: number; left: number; width: number; height: number };\n isUser: boolean;\n } | null>(null);\n\n const handleLongPressMessage = useCallback((\n msg: any,\n rect: { top: number; left: number; width: number; height: number },\n isUser: boolean\n ) => {\n setTapbackTarget({ msg, rect, isUser });\n }, []);\n\n const handlePinMessage = useCallback(async (msg: any) => {\n const snippet = (msg.content || '').slice(0, 50).replace(/\\n+/g, ' ');\n const display = `@kiku pin ${snippet}`;\n await send(msg.content || 'pin message', display, undefined, 'capture');\n }, [send]);\n\n const {\n handleKikuCapture,\n handleKikuCaptureAll,\n handleKikuViewHistory,\n handleKikuDelete,\n } = useChatCommands({\n attachments,\n setAttachments,\n setInput,\n send,\n defaultCurrency,\n t,\n });\n\n const {\n voiceMode,\n voicePhase,\n voiceConnecting,\n voiceError,\n setVoiceError,\n voiceMuted,\n setVoiceMuted,\n voiceSecondsLeft,\n voiceBlocked,\n liveVoiceName,\n chooseVoice,\n canConverse,\n startVoice,\n stopVoice,\n voice,\n live,\n } = useVoiceController({\n voiceLang,\n speechLang,\n shopperLanguage,\n ttsVoice,\n handleSendUtterance: (text) => handleSendRef.current(text),\n appendSpokenExchange,\n });\n\n const panelRef = useRef<HTMLDivElement>(null);\n const [themeMenuOpen, setThemeMenuOpen] = useState(false);\n const [scoutsOpen, setScoutsOpen] = useState(false);\n const [themeMenuClosing, setThemeMenuClosing] = useState(false);\n const themeMenuCloseTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const themeMenuRef = useRef<HTMLDivElement>(null);\n const mobileThemeRef = useRef<HTMLDivElement>(null);\n\n\n const messageRefs = useRef<(HTMLDivElement | null)[]>([]);\n const bottomRef = useRef<HTMLDivElement>(null);\n const overlayRef = useRef<HTMLDivElement>(null);\n const gooId = `hsk-goo-${useId()}`;\n\n // keeps the panel mounted long enough to morph back into the pill\n const closeThemeMenu = useCallback(() => {\n if (themeMenuCloseTimer.current) return;\n setThemeMenuClosing(true);\n themeMenuCloseTimer.current = setTimeout(() => {\n setThemeMenuOpen(false);\n setThemeMenuClosing(false);\n themeMenuCloseTimer.current = null;\n }, 200);\n }, []);\n\n useEffect(() => () => {\n if (themeMenuCloseTimer.current) clearTimeout(themeMenuCloseTimer.current);\n }, []);\n\n useEffect(() => {\n if (!themeMenuOpen) return;\n const handleOutside = (e: MouseEvent | TouchEvent) => {\n const path = (e.composedPath ? e.composedPath() : []) as EventTarget[];\n const isInsideRail = themeMenuRef.current && (path.includes(themeMenuRef.current) || themeMenuRef.current.contains(e.target as Node));\n const isInsideMobile = mobileThemeRef.current && (path.includes(mobileThemeRef.current) || mobileThemeRef.current.contains(e.target as Node));\n const targetEl = e.target as HTMLElement | null;\n const isInsideTopbarMark = targetEl?.closest?.('.hsk-cb-topbar-mark');\n const isInsideOoze = targetEl?.closest?.('.hsk-cb-topbar-ooze-menu') || path.some((el: any) => el?.classList?.contains?.('hsk-cb-topbar-ooze-menu'));\n\n if (isInsideRail || isInsideMobile || isInsideTopbarMark || isInsideOoze) {\n return;\n }\n closeThemeMenu();\n };\n document.addEventListener('mousedown', handleOutside);\n document.addEventListener('touchstart', handleOutside, { passive: true });\n return () => {\n document.removeEventListener('mousedown', handleOutside);\n document.removeEventListener('touchstart', handleOutside);\n };\n }, [themeMenuOpen]);\n\n const {\n msgsContainerRef,\n lastExternalScrollRef,\n showJumpToBottom,\n scrollProgress,\n activeMsgIdx,\n unreadBelow,\n jumpToMessage,\n jumpToBottom,\n } = useChatScroll({ messages, loading, messageRefs });\n\n useDragToDismiss({\n panel: useCallback(() => panelRef.current, []),\n scroller: useCallback(() => msgsContainerRef.current, []),\n onDismiss: onClose,\n quiescent: useCallback(() => performance.now() - lastExternalScrollRef.current > 90, []),\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n const prevOverflow = document.body.style.overflow;\n const prevPadding = document.body.style.paddingRight;\n\n if (scrollbarWidth > 0) {\n const computedPadding = parseFloat(window.getComputedStyle(document.body).paddingRight) || 0;\n document.body.style.paddingRight = `${computedPadding + scrollbarWidth}px`;\n document.documentElement.style.setProperty('--hsk-scrollbar-width', `${scrollbarWidth}px`);\n }\n\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.body.style.overflow = prevOverflow;\n document.body.style.paddingRight = prevPadding;\n document.documentElement.style.removeProperty('--hsk-scrollbar-width');\n };\n }, []);\n\n useEffect(() => {\n const vv = window.visualViewport;\n if (!vv) return;\n const root = document.documentElement;\n const apply = () => { root.style.setProperty('--hsk-vvh', `${vv.height}px`); };\n apply();\n vv.addEventListener('resize', apply);\n vv.addEventListener('scroll', apply);\n return () => {\n vv.removeEventListener('resize', apply);\n vv.removeEventListener('scroll', apply);\n root.style.removeProperty('--hsk-vvh');\n };\n }, []);\n\n useEffect(() => {\n const h = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n if (lightboxSrc) { setLightboxSrc(null); return; }\n onClose();\n };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, [lightboxSrc, onClose]);\n\n const handleReset = useCallback(() => {\n reset();\n setKeyPhase('idle');\n }, [reset, setKeyPhase]);\n\n const handleSourceClick = (src: ChatSource) => {\n onSelectSource?.(src);\n const lastAssistant = [...messages].reverse().find(m => m.role === 'assistant');\n if (lastAssistant && lastAssistant.content.trim().endsWith('?')) {\n send(t('cardClickAnswer', { name: src.name }));\n return;\n }\n const price = src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : '';\n send(t('cardClickQuery', { name: src.name, price }));\n };\n\n const handleSelectExtension = (ext: string) => {\n setInput(ext + ' ');\n setShowAtPicker(false);\n setShowKikuPicker(true);\n if (textareaRef.current) textareaRef.current.focus();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Escape' && showKikuPicker) { e.preventDefault(); setShowKikuPicker(false); return; }\n if (e.key === 'Escape' && showAtPicker) { e.preventDefault(); setShowAtPicker(false); return; }\n if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { e.preventDefault(); handleSend(); }\n };\n\n const composerHeight = useRef(28);\n const singleRowFieldWidth = useRef(280);\n const measureCanvasRef = useRef<HTMLCanvasElement | null>(null);\n\n const getTextWidth = (text: string, font: string): number => {\n try {\n if (!measureCanvasRef.current && typeof document !== 'undefined') {\n measureCanvasRef.current = document.createElement('canvas');\n }\n const ctx = measureCanvasRef.current?.getContext('2d');\n if (!ctx) return text.length * 8.5;\n ctx.font = font;\n return ctx.measureText(text).width;\n } catch {\n return text.length * 8.5;\n }\n };\n\n const autoGrow = (el: HTMLTextAreaElement) => {\n const box = el.closest('.hsk-cb-input-box') as HTMLElement | null;\n if (!box) return;\n\n const val = el.value;\n const isCurrentlyExpanded = box.dataset.expanded === 'true';\n\n if (!isCurrentlyExpanded && el.clientWidth > 50) {\n singleRowFieldWidth.current = el.clientWidth;\n }\n\n const cs = window.getComputedStyle(el);\n const font = cs.font || `${cs.fontSize || '16px'} ${cs.fontFamily || 'Geist, sans-serif'}`;\n const textWidth = getTextWidth(val, font);\n\n const threshold = Math.max(120, singleRowFieldWidth.current - 14);\n const hasNewline = val.includes('\\n');\n const shouldExpand = Boolean(val && (hasNewline || textWidth > threshold));\n\n if (box.dataset.expanded !== (shouldExpand ? 'true' : 'false')) {\n box.dataset.expanded = shouldExpand ? 'true' : 'false';\n }\n\n if (!val) {\n composerHeight.current = 28;\n el.style.height = '';\n return;\n }\n\n if (!shouldExpand) {\n composerHeight.current = 28;\n el.style.height = '';\n return;\n }\n\n el.style.height = 'auto';\n const targetHeight = Math.max(28, Math.min(el.scrollHeight, 140));\n composerHeight.current = targetHeight;\n el.style.height = `${targetHeight}px`;\n };\n\n useEffect(() => {\n if (textareaRef.current) autoGrow(textareaRef.current);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [input]);\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const val = e.target.value;\n setInput(val);\n if (voiceError) setVoiceError('');\n const trimmed = val.trim();\n setShowAtPicker(trimmed === '@');\n setShowKikuPicker(/^@kiku\\s*$/i.test(trimmed));\n };\n\n useEffect(() => {\n handleSendRef.current = (text: string) => { void handleSend(text); };\n });\n\n const handleImageFiles = async (files: FileList | null) => {\n if (!files || files.length === 0) return;\n const list = Array.from(files);\n for (const file of list) {\n if (!file.type.startsWith('image/')) continue;\n try {\n const dataUrl = await downscaleImage(file);\n setAttachments(prev => [...prev, { type: 'image', data: dataUrl }]);\n } catch { }\n }\n };\n\n const removeAttachment = (idx: number) => {\n setAttachments(prev => prev.filter((_, i) => i !== idx));\n };\n\n const shownSources = (live.sources?.length ?? 0) > 0 ? live.sources : discussedSources;\n const hasTranslucentBackdrop = backdropColor && (backdropColor.includes('rgba') || backdropColor.includes('hsla') || backdropColor === 'transparent');\n const backdropFilterStyle = (backdropBlur || hasTranslucentBackdrop) ? {\n backdropFilter: `blur(${typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur || '20px')})`,\n WebkitBackdropFilter: `blur(${typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur || '20px')})`,\n } : {};\n const halted = (stopped || interrupted) && !loading && !streaming;\n\n const displayMessages = React.useMemo(() => {\n const inFlight = loading || streaming;\n return messages.filter((m, i) => {\n if (m.role !== 'assistant') return true;\n const isLastMsg = i === messages.length - 1;\n if (isLastMsg && inFlight) return true;\n const hasBody = !!m.content || !!m.visualization || m.visualizing ||\n (m.knowledgeImages?.length ?? 0) > 0 || (m.referencedIds?.length ?? 0) > 0;\n return hasBody;\n });\n }, [messages, loading, streaming]);\n\n const timelineItems = React.useMemo(\n () => displayMessages\n .map((m, idx) => ({ m, idx }))\n .filter(({ m }) => m.role === 'user' && !!m.content.trim())\n .map(({ m, idx }) => {\n const clean = m.content.replace(/^@kiku\\s*/i, '').replace(/\\s+/g, ' ').trim();\n return { idx, text: clean.length > 30 ? clean.slice(0, 29).trimEnd() + '…' : clean };\n }),\n [displayMessages]\n );\n\n const haltedEmpty =\n halted && displayMessages[displayMessages.length - 1]?.role !== 'assistant';\n\n const mountTimeRef = useRef(Date.now());\n useEffect(() => {\n mountTimeRef.current = Date.now();\n }, []);\n\n return (\n <UIStringsContext.Provider value={t}>\n <div\n ref={overlayRef}\n className={cn(\"hsk-cb-overlay\", origin && \"hsk-cb-overlay--grows\", classNames.overlay)}\n onPointerDown={e => {\n if (e.target === e.currentTarget) {\n (overlayRef.current as any)._ptrDown = true;\n }\n }}\n onClick={e => {\n if (e.target === e.currentTarget && (overlayRef.current as any)?._ptrDown && Date.now() - mountTimeRef.current > 200) {\n onClose();\n }\n if (overlayRef.current) (overlayRef.current as any)._ptrDown = false;\n }}\n data-hsk-theme={hskThemeAttr}\n style={{\n ...(backdropFilterStyle),\n ...(backdropColor ? { background: backdropColor } : {}),\n ...(origin ? {\n '--hsk-ox': `${origin.x}px`,\n '--hsk-oy': `${origin.y}px`,\n '--hsk-or': `${Math.ceil(origin.r)}px`,\n '--hsk-bt': `${Math.round(origin.top ?? origin.y)}px`,\n '--hsk-bl': `${Math.round(origin.left ?? origin.x)}px`,\n '--hsk-bw': `${Math.round(origin.width ?? 0)}px`,\n '--hsk-bh': `${Math.round(origin.height ?? 0)}px`,\n '--hsk-bbr': `${Math.round(origin.borderRadius ?? 12)}px`,\n } as React.CSSProperties : {}),\n ...customStyles,\n }}\n >\n <div\n ref={panelRef}\n className={cn(\"hsk-cb-panel\", classNames.panel)}\n dir={isRTL ? 'rtl' : 'ltr'}\n data-script={isNonLatin ? 'nonlatin' : 'latin'}\n data-host-font={hostFontCovers ? 'covers' : 'gap'}\n data-nastaliq={(scriptFont?.family === 'Noto Nastaliq Urdu' || shopperLanguage?.toLowerCase() === 'urdu' || shopperLanguage?.toLowerCase() === 'ur' || shopperLanguage === 'اردو') ? 'true' : undefined}\n style={fontStack ? ({ '--hsk-font': fontStack } as React.CSSProperties) : undefined}\n onClick={e => {\n e.stopPropagation();\n const target = e.target as HTMLElement;\n if (target.tagName === 'IMG' && (target.classList.contains('hsk-markdown-img') || target.classList.contains('hsk-cb-user-img-thumb'))) {\n const src = (target as HTMLImageElement).src;\n if (src) setLightboxSrc(src);\n }\n }}\n >\n <LightboxModal src={lightboxSrc} onClose={() => setLightboxSrc(null)} />\n\n {markupSrc && (\n <div className=\"hsk-markup-overlay\">\n <MarkupEditor\n src={markupSrc}\n t={t as (key: string, vars?: Record<string, string>) => string}\n onCancel={() => setMarkupSrc(null)}\n onSend={(dataUrl, instruction, marks, preview) => {\n setMarkupSrc(null);\n handleSend(\n instruction || t('markupApplyMarks'),\n [{ type: 'image', data: dataUrl, annotated: true, marks, instructed: !!instruction, preview }],\n );\n }}\n />\n </div>\n )}\n\n <div className=\"hsk-cb-main\">\n <KikuDoodles seed={(client as any)?.api?.siteId ?? ''} theme={hskThemeAttr} dir={isRTL ? 'rtl' : 'ltr'} />\n\n <ChatTopbar\n title={activeTitle}\n hasMessages={messages.length > 0}\n avatarState={streaming ? 'speaking' : loading ? 'thinking' : 'idle'}\n unread={unreadBelow}\n awayFromBottom={showJumpToBottom}\n themeMenuOpen={themeMenuOpen}\n themeMenuClosing={themeMenuClosing}\n isNarrow={isNarrow}\n currentTheme={currentTheme}\n onJumpToLatest={jumpToBottom}\n onReset={handleReset}\n onClose={onClose}\n onToggleThemeMenu={() => (themeMenuOpen ? closeThemeMenu() : setThemeMenuOpen(true))}\n onSelectTheme={(t) => { handleToggleTheme(t, true); }}\n />\n\n <div className=\"hsk-cb-msgs\" ref={msgsContainerRef as any}>\n {displayMessages.length === 0 ? (\n <OnboardingView\n inOnboarding={inOnboarding}\n justCompleted={justCompleted}\n onboardingMood={onboardingMood}\n awaitingLang={awaitingLang}\n awaitingName={awaitingName}\n awaitingEntityLang={awaitingEntityLang}\n awaitingConsent={awaitingConsent}\n termsAgreed={termsAgreed}\n shopperLanguage={shopperLanguage}\n shopperName={shopperName}\n entityLangPref={entityLangPref}\n chromeReady={chromeReady}\n activeChips={activeChips}\n t={t}\n tNode={tNode}\n chooseLanguage={chooseLanguage}\n chooseEntityLang={chooseEntityLang}\n agreeTerms={agreeTerms}\n handleSend={handleSend}\n />\n ) : (\n <ChatMessages\n displayMessages={displayMessages}\n messageRefs={messageRefs}\n isNarrow={isNarrow}\n loading={loading}\n streaming={streaming}\n sources={sources}\n referencedIds={referencedIds}\n discussedSources={discussedSources}\n lastIntent={lastIntent}\n lastAction={lastAction}\n defaultCurrency={defaultCurrency}\n stopped={stopped}\n interrupted={interrupted}\n halted={halted}\n haltedEmpty={haltedEmpty}\n error={error}\n errorCode={errorCode}\n keyPhase={keyPhase}\n keyInput={keyInput}\n setKeyInput={setKeyInput}\n mintedKey={mintedKey}\n setMintedKey={setMintedKey}\n mintedPub={mintedPub}\n setMintedPub={setMintedPub}\n minting={minting}\n copied={copied}\n keyCountdown={keyCountdown}\n handleUseExistingKey={handleUseExistingKey}\n handleCreateKey={handleCreateKey}\n copyValue={copyValue}\n queuedMessage={queuedMessage}\n sendQueuedNow={sendQueuedNow}\n setLightboxSrc={setLightboxSrc}\n setMarkupSrc={setMarkupSrc}\n handleSend={handleSend}\n handleSourceClick={handleSourceClick}\n onRetry={handleRetryMessage}\n onEdit={handleEditMessage}\n onLongPress={handleLongPressMessage}\n retrying={retrying}\n continueGenerating={continueGenerating}\n t={t}\n bottomRef={bottomRef}\n vizState={vizState}\n setVizState={setVizState}\n messages={messages}\n />\n )}\n </div>\n\n <ChatComposer\n gooId={gooId}\n input={input}\n setInput={setInput}\n showKikuPicker={showKikuPicker}\n setShowKikuPicker={setShowKikuPicker}\n showAtPicker={showAtPicker}\n setShowAtPicker={setShowAtPicker}\n captureAllowed={captureAllowed}\n discussedSources={discussedSources}\n defaultCurrency={defaultCurrency}\n handleSelectExtension={handleSelectExtension}\n handleKikuCapture={handleKikuCapture}\n handleKikuCaptureAll={handleKikuCaptureAll}\n handleKikuViewHistory={handleKikuViewHistory}\n handleKikuDelete={handleKikuDelete}\n attachments={attachments}\n removeAttachment={removeAttachment}\n chromeLoading={!chromeReady}\n imageInputRef={imageInputRef}\n handleImageFiles={handleImageFiles}\n enableVision={enableVision}\n enableVoice={enableVoice}\n canConverse={canConverse}\n voiceMode={voiceMode}\n startVoice={startVoice}\n stopVoice={stopVoice}\n voiceBlocked={voiceBlocked}\n textareaRef={textareaRef}\n classNames={classNames}\n handleInput={handleInput}\n handleKeyDown={handleKeyDown}\n voice={voice}\n voicePhase={voicePhase}\n activePlaceholder={activePlaceholder}\n loading={loading}\n streaming={streaming}\n stop={stop}\n handleSend={handleSend}\n voiceError={voiceError}\n setVoiceError={setVoiceError}\n shopperLanguage={shopperLanguage}\n t={t}\n />\n </div>\n\n <ConversationTimeline\n items={timelineItems}\n activeIdx={activeMsgIdx}\n progress={scrollProgress}\n onJump={jumpToMessage}\n side={isRTL ? 'left' : 'right'}\n />\n\n <div className={cn(\"hsk-cb-kiku-id-rail\", isRTL ? \"hsk-cb-kiku-id-rail--right\" : \"hsk-cb-kiku-id-rail--left\")}>\n <ScoutRail\n themeAttr={hskThemeAttr}\n open={scoutsOpen}\n onOpenChange={(v) => {\n setScoutsOpen(v);\n if (v && themeMenuOpen) closeThemeMenu();\n }}\n onAsk={(scout) => { void handleSend(`scout ${scout.id}`); }}\n onNew={() => {\n setInput('');\n setTimeout(() => textareaRef.current?.focus(), 60);\n }}\n />\n\n {/* Themes Expandable Selection */}\n <div className={cn(\"hsk-cb-theme-squircle-wrap\", themeMenuOpen && \"is-open\", themeMenuClosing && \"is-closing\")} ref={themeMenuRef}>\n {!themeMenuOpen ? (\n <button\n type=\"button\"\n className=\"hsk-cb-theme-squircle-trigger\"\n onClick={() => { setScoutsOpen(false); setThemeMenuOpen(true); }}\n aria-label=\"Themes\"\n aria-expanded=\"false\"\n >\n <span className=\"hsk-cb-theme-trigger-icon\">\n {React.createElement(themeDef(currentTheme).Icon)}\n </span>\n <span className=\"hsk-cb-theme-trigger-label\">\n {themeDef(currentTheme).label}\n </span>\n </button>\n ) : (\n <div className=\"hsk-cb-theme-2x2-grid\" role=\"dialog\" aria-label=\"Theme selector\">\n {THEMES.map(({ id, label, Icon }) => (\n <button\n key={id}\n type=\"button\"\n className={cn(\"hsk-cb-theme-grid-item\", currentTheme === id && \"is-active\")}\n onClick={(e) => { e.stopPropagation(); handleToggleTheme(id, true); }}\n >\n <Icon />\n <span>{label}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Kiku ID Pill */}\n <button\n type=\"button\"\n className=\"hsk-cb-kiku-id-pill\"\n onClick={() => displayKikuPub !== 'N/A' && copyValue(displayKikuPub, 'pub')}\n title={t('keyCopyId')}\n >\n <span className=\"hsk-cb-kiku-id-rail-val\">{displayKikuPub}</span>\n {copied === 'pub' ? <CheckIcon /> : <CopyIcon />}\n </button>\n </div>\n\n {voiceMode === 'converse' && (\n <VoiceOverlay\n siteId={(client as any)?.api?.siteId ?? ''}\n themeAttr={hskThemeAttr}\n stopVoice={stopVoice}\n chooseVoice={chooseVoice}\n liveVoiceName={liveVoiceName}\n voiceSecondsLeft={voiceSecondsLeft}\n voiceConnecting={voiceConnecting}\n voicePhase={voicePhase}\n live={live}\n voiceMuted={voiceMuted}\n setVoiceMuted={setVoiceMuted}\n shownSources={shownSources}\n onSelectSource={onSelectSource}\n defaultCurrency={defaultCurrency}\n voiceError={voiceError}\n t={t}\n />\n )}\n\n {tapbackTarget && (\n <TapbackMenu\n msg={tapbackTarget.msg}\n rect={tapbackTarget.rect}\n containerRect={panelRef.current?.getBoundingClientRect()}\n isUser={tapbackTarget.isUser}\n canRetry={!loading && !streaming}\n canEdit={tapbackTarget.isUser}\n onPin={handlePinMessage}\n onRetry={handleRetryMessage}\n onEdit={handleEditMessage}\n onCopy={(text) => {\n try { navigator.clipboard.writeText(text); } catch {}\n }}\n onClose={() => setTapbackTarget(null)}\n t={t}\n />\n )}\n </div>\n </div>\n </UIStringsContext.Provider>\n );\n}\n","import React from 'react';\r\nimport { cn } from '../../utils/cn';\r\n\r\nexport const KikuIcon = ({ className, size = 18, tight = false }: { className?: string; size?: number; tight?: boolean }) => (\r\n <svg\r\n className={cn(\"hsk-brand-mark\", className)}\r\n width={size}\r\n height={size}\r\n viewBox={tight ? \"10.2 17.4 79.5 79.5\" : \"0 0 100 100\"}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-label=\"kiku\"\r\n >\r\n <g transform=\"translate(22.7 19) scale(0.62)\" fill=\"currentColor\" fillRule=\"evenodd\">\r\n <path d=\"M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z\" />\r\n <circle cx=\"55\" cy=\"82\" r=\"3.4\" />\r\n </g>\r\n </svg>\r\n);\r\n\r\nexport const SparkleIcon = KikuIcon;\r\n\r\nexport const StopIcon = () => (\r\n <svg className=\"hsk-stop-icon\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle\r\n className=\"hsk-stop-ring\"\r\n cx=\"12\" cy=\"12\" r=\"9.5\"\r\n stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\"\r\n />\r\n <rect className=\"hsk-stop-core\" x=\"8.5\" y=\"8.5\" width=\"7\" height=\"7\" rx=\"1.8\" fill=\"currentColor\" />\r\n </svg>\r\n);\r\n\r\nexport const SpeakerIcon = ({ active }: { active?: boolean }) => (\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" fill={active ? 'currentColor' : 'none'} />\r\n {active ? (\r\n <>\r\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\r\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\r\n </>\r\n ) : (\r\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\r\n )}\r\n </svg>\r\n);\r\n\r\nexport const ExternalIcon = () => (\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\r\n <polyline points=\"15 3 21 3 21 9\" />\r\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\r\n </svg>\r\n);\r\n\r\nexport const ContinueIcon = () => (\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M8 5v14l11-7z\" />\r\n </svg>\r\n);\r\n\r\nexport const CloseIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nexport const ChevronLeftIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m15 18-6-6 6-6\"/>\r\n </svg>\r\n);\r\n\r\nexport const ChevronRightIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m9 18 6-6-6-6\"/>\r\n </svg>\r\n);\r\n\r\nexport const HistoryIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/>\r\n <path d=\"M3 3v5h5\"/>\r\n <path d=\"M12 7v5l4 2\"/>\r\n </svg>\r\n);\r\n\r\nexport const BookmarkIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M19 21 12 16l-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z\"/>\r\n </svg>\r\n);\r\n\r\nexport const TrashIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M3 6h18\"/>\r\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/>\r\n </svg>\r\n);\r\n\r\nexport const SecureShieldIcon = ({ className, size = 18 }: { className?: string; size?: number }) => (\r\n <svg\r\n className={className}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2.5\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n <path d=\"M12 11a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z\" />\r\n <path d=\"M12 11v4\" />\r\n </svg>\r\n);\r\n\r\nexport const PlusIcon = () => (\r\n <svg width=\"19\" height=\"19\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\r\n <path d=\"M12 5v14M5 12h14\"/>\r\n </svg>\r\n);\r\n\r\nexport const PaperclipIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\"/>\r\n </svg>\r\n);\r\n\r\nexport const RetryIcon = ({ className, size = 13 }: { className?: string; size?: number } = {}) => (\r\n <svg\r\n className={cn(\"hsk-retry-icon\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2.2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path className=\"hsk-retry-arrow\" d=\"M21.5 2v6h-6\" />\r\n <path className=\"hsk-retry-arc\" d=\"M21.34 15.57a10 10 0 1 1-.57-8.38l5.67-5.19\" />\r\n </svg>\r\n);\r\n\r\nexport const EditIcon = ({ className, size = 13 }: { className?: string; size?: number } = {}) => (\r\n <svg\r\n className={cn(\"hsk-edit-icon\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2.2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path className=\"hsk-edit-pencil\" d=\"M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z\" />\r\n <path className=\"hsk-edit-lead\" d=\"m15 5 4 4\" />\r\n </svg>\r\n);\r\n\r\nexport const CopyIcon = ({ className, size = 13 }: { className?: string; size?: number } = {}) => (\r\n <svg\r\n className={cn(\"hsk-copy-icon\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <rect className=\"hsk-copy-sheet\" x=\"8.5\" y=\"7\" width=\"12\" height=\"14\" rx=\"3.5\" />\r\n <path className=\"hsk-copy-back\" d=\"M5 15H4.5A2.5 2.5 0 0 1 2 12.5V4.5A2.5 2.5 0 0 1 4.5 2h8A2.5 2.5 0 0 1 15 4.5V5\" />\r\n </svg>\r\n);\r\n\r\nexport const CheckIcon = ({ className, size = 13 }: { className?: string; size?: number } = {}) => (\r\n <svg\r\n className={cn(\"hsk-check-icon\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2.4\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <polyline className=\"hsk-check-mark\" points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n);\r\n\r\nexport const MicIcon = ({ className, size = 18 }: { className?: string; size?: number } = {}) => (\r\n <svg className={className} width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path className=\"hsk-mic-cap\" d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\"/>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\r\n </svg>\r\n);\r\n\r\nexport const MicOffIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\"/>\r\n <path d=\"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2\"/>\r\n <path d=\"M5 10v2a7 7 0 0 0 12 5\"/>\r\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\"/>\r\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\r\n </svg>\r\n);\r\n\r\nexport const WaveformIcon = ({ active }: { active?: boolean }) => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path className=\"hsk-wave-bar hsk-wave-bar--tip\" style={{ '--hsk-bar': 0, '--hsk-amp': 1.9, '--hsk-period': '1.24s' } as React.CSSProperties} d=\"M2 12h2\" />\r\n <path className=\"hsk-wave-bar\" style={{ '--hsk-bar': 1, '--hsk-amp': 1.78, '--hsk-period': '0.94s' } as React.CSSProperties} d=\"M6 8v8\" />\r\n <path className=\"hsk-wave-bar\" style={{ '--hsk-bar': 2, '--hsk-amp': 1.26, '--hsk-period': '1.42s' } as React.CSSProperties} d=\"M10 4v16\" />\r\n <path className=\"hsk-wave-bar\" style={{ '--hsk-bar': 3, '--hsk-amp': 1.62, '--hsk-period': '1.08s' } as React.CSSProperties} d=\"M14 7v10\" />\r\n <path className=\"hsk-wave-bar\" style={{ '--hsk-bar': 4, '--hsk-amp': 2.05, '--hsk-period': '0.86s' } as React.CSSProperties} d=\"M18 9v6\" />\r\n <path className=\"hsk-wave-bar hsk-wave-bar--tip\" style={{ '--hsk-bar': 5, '--hsk-amp': 1.9, '--hsk-period': '1.32s' } as React.CSSProperties} d=\"M22 12h-2\" />\r\n </svg>\r\n);\r\n\r\nexport const ArrowUpIcon = () => (\r\n <svg\r\n className=\"hsk-telegram-icon\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n {/* the silhouette is unchanged at rest; splitting it at the fold gives two\r\n wings that can beat independently */}\r\n <polygon className=\"hsk-kite-wing hsk-kite-wing--far\" points=\"22 2 11 13 2 9\" />\r\n <polygon className=\"hsk-kite-wing hsk-kite-wing--near\" points=\"22 2 15 22 11 13\" />\r\n <line className=\"hsk-kite-spine\" x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\r\n </svg>\r\n);\r\n\r\nexport const SunIcon = () => (\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <circle className=\"hsk-sun-core\" cx=\"12\" cy=\"12\" r=\"5\"/>\r\n <g className=\"hsk-sun-rays\">\r\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"/>\r\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"/>\r\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"/>\r\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"/>\r\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"/>\r\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"/>\r\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"/>\r\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"/>\r\n </g>\r\n </svg>\r\n);\r\n\r\nexport const MoonIcon = () => (\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path className=\"hsk-moon-body\" d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"/>\r\n </svg>\r\n);\r\n\r\nexport const WoodIcon = () => (\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path className=\"hsk-wood-layer\" style={{ '--hsk-layer': 0 } as React.CSSProperties} d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\r\n <path className=\"hsk-wood-layer\" style={{ '--hsk-layer': 2 } as React.CSSProperties} d=\"M2 17l10 5 10-5\"/>\r\n <path className=\"hsk-wood-layer\" style={{ '--hsk-layer': 1 } as React.CSSProperties} d=\"M2 12l10 5 10-5\"/>\r\n </svg>\r\n);\r\n\r\nexport const HeartIcon = () => (\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path className=\"hsk-heart-body\" d=\"M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z\"/>\r\n </svg>\r\n);\r\n\r\nexport const CoffeeIcon = () => (\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M17 8h1a4 4 0 1 1 0 8h-1\"/>\r\n <path d=\"M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4z\"/>\r\n <line className=\"hsk-steam\" style={{ '--hsk-steam': 0 } as React.CSSProperties} x1=\"6\" y1=\"1\" x2=\"6\" y2=\"4\"/>\r\n <line className=\"hsk-steam\" style={{ '--hsk-steam': 1 } as React.CSSProperties} x1=\"10\" y1=\"1\" x2=\"10\" y2=\"4\"/>\r\n <line className=\"hsk-steam\" style={{ '--hsk-steam': 2 } as React.CSSProperties} x1=\"14\" y1=\"1\" x2=\"14\" y2=\"4\"/>\r\n </svg>\r\n);\r\n\r\nexport const StarIcon = () => (\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M12 3a6.5 6.5 0 0 0 9 9 9 9 0 1 1-9-9z\"/>\r\n <path className=\"hsk-star-spark\" d=\"M18.5 2.5l.6 1.6 1.6.6-1.6.6-.6 1.6-.6-1.6-1.6-.6 1.6-.6z\"/>\r\n </svg>\r\n);\r\n\r\nexport const ShieldIcon = ({ size = 18 }: { size?: number }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\r\n <path d=\"m9 12 2 2 4-4\"/>\r\n </svg>\r\n);\r\n\r\nexport const KeyOutlineIcon = ({ size = 18 }: { size?: number }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m21 2-2 2m-1.5 1.5L14 9a5.5 5.5 0 1 0 2 2l3.5-3.5\"/>\r\n <circle cx=\"7.5\" cy=\"15.5\" r=\"2.5\"/>\r\n </svg>\r\n);\r\n\r\nexport const VaultIcon = ({ size = 18 }: { size?: number }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"3\"/>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\r\n <path d=\"m14.5 9.5-5 5\"/>\r\n </svg>\r\n);\r\n\r\nexport const GlobeIcon = ({ size = 18 }: { size?: number }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\r\n <line x1=\"2\" x2=\"22\" y1=\"12\" y2=\"12\"/>\r\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/>\r\n </svg>\r\n);\r\n\r\nexport const XIcon = ({ size = 11 }: { size?: number }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n);\r\n\r\nexport const PinIcon = ({ className, size = 16, filled = false }: { className?: string; size?: number; filled?: boolean } = {}) => (\r\n <svg\r\n className={cn(\"hsk-pin-icon\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill={filled ? \"currentColor\" : \"none\"}\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"22\" />\r\n <path d=\"M5 17h14v-1.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V6h1a2 2 0 0 0 0-4H8a2 2 0 0 0 0 4h1v4.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V17z\" />\r\n </svg>\r\n);\r\n\r\nexport const ShareTrayIcon = ({ className, size = 16 }: { className?: string; size?: number } = {}) => (\r\n <svg\r\n className={cn(\"hsk-share-tray-icon\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path d=\"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8\" />\r\n <polyline points=\"16 6 12 2 8 6\" />\r\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"15\" />\r\n </svg>\r\n);\r\n\r\nexport const VisualSearchSparkleIcon = ({ className, size = 16 }: { className?: string; size?: number } = {}) => (\r\n <svg\r\n className={cn(\"hsk-visual-search-icon\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <circle cx=\"10\" cy=\"10\" r=\"6.5\" />\r\n <line x1=\"21\" y1=\"21\" x2=\"14.65\" y2=\"14.65\" />\r\n <path\r\n d=\"M10 5.5l.8 2.2 2.2.8-2.2.8-.8 2.2-.8-2.2-2.2-.8 2.2-.8.8-2.2z\"\r\n fill=\"currentColor\"\r\n stroke=\"none\"\r\n />\r\n </svg>\r\n);\r\n\r\n\r\n\r\n\r\n\r\n","import type { ComponentType } from 'react';\r\nimport { SunIcon, MoonIcon, WoodIcon, HeartIcon, CoffeeIcon, StarIcon } from './icons';\r\n\r\nexport interface ThemeDef {\r\n id: string;\r\n label: string;\r\n Icon: ComponentType;\r\n dark: boolean;\r\n}\r\n\r\n// Single source of truth. Add a theme here plus a token block in styles.css.\r\nexport const THEMES: ThemeDef[] = [\r\n { id: 'light', label: 'Silver', Icon: SunIcon, dark: false },\r\n { id: 'dark', label: 'Onyx', Icon: MoonIcon, dark: true },\r\n { id: 'mahogany', label: 'Mahogany', Icon: WoodIcon, dark: true },\r\n { id: 'blush', label: 'Blush', Icon: HeartIcon, dark: false },\r\n { id: 'coffee', label: 'Coffee', Icon: CoffeeIcon, dark: false },\r\n { id: 'midnight', label: 'Midnight', Icon: StarIcon, dark: true },\r\n];\r\n\r\nexport type ThemeId = string;\r\n\r\nexport const DEFAULT_DARK: ThemeId = 'dark';\r\nexport const DEFAULT_LIGHT: ThemeId = 'light';\r\n\r\nexport function isThemeId(value: unknown): value is ThemeId {\r\n return typeof value === 'string' && THEMES.some(t => t.id === value);\r\n}\r\n\r\nexport function themeDef(id: ThemeId): ThemeDef {\r\n return THEMES.find(t => t.id === id) ?? THEMES[0];\r\n}\r\n","import { useEffect, useRef } from 'react';\r\n\r\nexport function rubberBand(offset: number, dimension: number, coeff = 0.55): number {\r\n if (dimension <= 0) return 0;\r\n return (offset * dimension * coeff) / (dimension + coeff * Math.abs(offset));\r\n}\r\n\r\ntype SpringOpts = { stiffness?: number; damping?: number; onFrame: (v: number) => void; onRest?: () => void };\r\n\r\nexport function createSpring({ stiffness = 500, damping = 45, onFrame, onRest }: SpringOpts) {\r\n let value = 0, velocity = 0, target = 0;\r\n let raf: number | null = null;\r\n let last = 0;\r\n\r\n const tick = (now: number) => {\r\n const dt = Math.min(0.032, (now - last) / 1000) || 1 / 60;\r\n last = now;\r\n const steps = Math.max(1, Math.ceil(dt / 0.008));\r\n const h = dt / steps;\r\n for (let i = 0; i < steps; i++) {\r\n const a = -stiffness * (value - target) - damping * velocity;\r\n velocity += a * h;\r\n value += velocity * h;\r\n }\r\n if (Math.abs(value - target) < 0.5 && Math.abs(velocity) < 0.5) {\r\n value = target; velocity = 0; raf = null;\r\n onFrame(value); onRest?.();\r\n return;\r\n }\r\n onFrame(value);\r\n raf = requestAnimationFrame(tick);\r\n };\r\n\r\n const start = () => { if (raf === null) { last = performance.now(); raf = requestAnimationFrame(tick); } };\r\n\r\n return {\r\n\r\n track(v: number) {\r\n if (raf !== null) { cancelAnimationFrame(raf); raf = null; }\r\n value = v; velocity = 0; onFrame(value);\r\n },\r\n\r\n to(t: number, v0 = 0) { target = t; velocity = v0; start(); },\r\n get value() { return value; },\r\n stop() { if (raf !== null) { cancelAnimationFrame(raf); raf = null; } },\r\n };\r\n}\r\n\r\ntype Opts = {\r\n panel: () => HTMLElement | null;\r\n scroller: () => HTMLElement | null;\r\n onDismiss: () => void;\r\n\r\n quiescent?: () => boolean;\r\n enabled?: boolean;\r\n};\r\n\r\nexport function useDragToDismiss({ panel, scroller, onDismiss, quiescent, enabled = true }: Opts): void {\r\n const dismissRef = useRef(onDismiss);\r\n dismissRef.current = onDismiss;\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n const el = panel();\r\n if (!el) return;\r\n if (typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches) return;\r\n\r\n let dragging = false, startY = 0, startX = 0, offset = 0, pointerId = -1;\r\n let lastY = 0, lastT = 0, velocity = 0, decided = false, exiting = false;\r\n\r\n const apply = (v: number) => {\r\n el.style.transform = v === 0 ? '' : `translate3d(0, ${v}px, 0)`;\r\n const host = el.parentElement;\r\n if (host) host.style.opacity = v === 0 ? '' : String(Math.max(0.35, 1 - v / (el.offsetHeight || 1) * 1.1));\r\n };\r\n const spring = createSpring({\r\n onFrame: apply,\r\n onRest: () => {\r\n el.style.willChange = '';\r\n if (exiting) { exiting = false; dismissRef.current(); }\r\n },\r\n });\r\n\r\n const atTop = () => {\r\n const s = scroller();\r\n if (s && s.scrollTop > 0) return false;\r\n return quiescent ? quiescent() : true;\r\n };\r\n\r\n const onDown = (e: PointerEvent) => {\r\n if (e.pointerType === 'mouse' || !e.isPrimary) return;\r\n dragging = false; decided = false;\r\n pointerId = e.pointerId;\r\n startY = lastY = e.clientY; startX = e.clientX;\r\n lastT = e.timeStamp; velocity = 0;\r\n offset = spring.value;\r\n };\r\n\r\n const onMove = (e: PointerEvent) => {\r\n if (e.pointerId !== pointerId) return;\r\n const dy = e.clientY - startY;\r\n const dx = e.clientX - startX;\r\n\r\n if (!decided) {\r\n if (Math.abs(dy) < 6 && Math.abs(dx) < 6) return;\r\n decided = true;\r\n dragging = dy > 0 && Math.abs(dy) > Math.abs(dx) && atTop();\r\n if (dragging) {\r\n try { el.setPointerCapture(e.pointerId); } catch { }\r\n spring.stop();\r\n el.style.animation = 'none';\r\n el.style.willChange = 'transform';\r\n }\r\n }\r\n if (!dragging) return;\r\n\r\n const dt = e.timeStamp - lastT;\r\n if (dt > 0) velocity = ((e.clientY - lastY) / dt) * 1000;\r\n lastY = e.clientY; lastT = e.timeStamp;\r\n\r\n const raw = offset + dy;\r\n spring.track(raw < 0 ? -rubberBand(-raw, el.offsetHeight || 1) : raw);\r\n if (e.cancelable) e.preventDefault();\r\n };\r\n\r\n const onUp = (e: PointerEvent) => {\r\n if (e.pointerId !== pointerId) return;\r\n try { if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId); } catch { }\r\n pointerId = -1;\r\n if (!dragging) return;\r\n dragging = false;\r\n const h = el.offsetHeight || 1;\r\n const projected = spring.value + velocity * 0.12;\r\n if (projected > h * 0.3 || velocity > 900) {\r\n exiting = true;\r\n el.style.pointerEvents = 'none';\r\n spring.to(h, velocity);\r\n } else {\r\n spring.to(0, velocity);\r\n }\r\n };\r\n\r\n el.addEventListener('pointerdown', onDown, { passive: true });\r\n el.addEventListener('pointermove', onMove, { passive: false });\r\n el.addEventListener('pointerup', onUp, { passive: true });\r\n el.addEventListener('pointercancel', onUp, { passive: true });\r\n return () => {\r\n spring.stop();\r\n el.removeEventListener('pointerdown', onDown);\r\n el.removeEventListener('pointermove', onMove);\r\n el.removeEventListener('pointerup', onUp);\r\n el.removeEventListener('pointercancel', onUp);\r\n el.style.transform = ''; el.style.willChange = ''; el.style.animation = ''; el.style.pointerEvents = '';\r\n const host = el.parentElement;\r\n if (host) host.style.opacity = '';\r\n };\r\n }, [enabled, panel, scroller, quiescent]);\r\n}\r\n","import React, { useEffect, useRef, useState } from 'react';\r\nimport { buildMarkRegions, type MarkRegion } from '../utils/markRegions';\r\n\r\ntype Tool = 'pen' | 'eraser' | 'text';\r\n\r\ninterface Point { x: number; y: number }\r\ninterface StrokeAction { kind: 'stroke'; tool: 'pen' | 'eraser'; color: string; size: number; points: Point[] }\r\ninterface TextAction { kind: 'text'; x: number; y: number; color: string; value: string; size: number }\r\ntype Action = StrokeAction | TextAction;\r\n\r\nconst COLORS = ['#111111', '#ff5a5a', '#ffb300', '#22c55e', '#06b6d4', '#d946ef', '#9ca3af'];\r\nconst MAX_EXPORT_DIM = 1280;\r\n\r\nexport function MarkupEditor({ src, onCancel, onSend, t }: {\r\n src: string;\r\n onCancel: () => void;\r\n onSend: (dataUrl: string, instruction: string, marks: MarkRegion[], preview: string) => void;\r\n t: (key: string, vars?: Record<string, string>) => string;\r\n}) {\r\n const [img, setImg] = useState<HTMLImageElement | null>(null);\r\n const [loadError, setLoadError] = useState(false);\r\n const [tool, setTool] = useState<Tool>('pen');\r\n const [color, setColor] = useState(COLORS[1]);\r\n const [actions, setActions] = useState<Action[]>([]);\r\n const [pendingText, setPendingText] = useState<{ x: number; y: number } | null>(null);\r\n const [textValue, setTextValue] = useState('');\r\n const [instruction, setInstruction] = useState('');\r\n const [exportError, setExportError] = useState(false);\r\n\r\n const canvasRef = useRef<HTMLCanvasElement>(null);\r\n const drawingRef = useRef<StrokeAction | null>(null);\r\n const textInputRef = useRef<HTMLInputElement>(null);\r\n\r\n useEffect(() => {\r\n const el = new Image();\r\n el.crossOrigin = 'anonymous';\r\n el.onload = () => setImg(el);\r\n el.onerror = () => setLoadError(true);\r\n el.src = src;\r\n }, [src]);\r\n\r\n const dims = (() => {\r\n if (!img) return { w: 0, h: 0 };\r\n const scale = Math.min(1, MAX_EXPORT_DIM / Math.max(img.naturalWidth, img.naturalHeight));\r\n return { w: Math.round(img.naturalWidth * scale), h: Math.round(img.naturalHeight * scale) };\r\n })();\r\n\r\n const markLayer = useRef<HTMLCanvasElement | null>(null);\r\n const paint = (live?: StrokeAction | null) => {\r\n const canvas = canvasRef.current;\r\n if (!canvas || !img) return;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n if (!markLayer.current) markLayer.current = document.createElement('canvas');\r\n const layer = markLayer.current;\r\n layer.width = canvas.width;\r\n layer.height = canvas.height;\r\n const lctx = layer.getContext('2d')!;\r\n const all = live ? [...actions, live] : actions;\r\n for (const a of all) {\r\n if (a.kind === 'stroke') {\r\n lctx.save();\r\n lctx.globalCompositeOperation = a.tool === 'eraser' ? 'destination-out' : 'source-over';\r\n lctx.strokeStyle = a.color;\r\n lctx.lineWidth = a.tool === 'eraser' ? a.size * 3 : a.size;\r\n lctx.lineCap = 'round';\r\n lctx.lineJoin = 'round';\r\n lctx.beginPath();\r\n a.points.forEach((p, i) => (i === 0 ? lctx.moveTo(p.x, p.y) : lctx.lineTo(p.x, p.y)));\r\n if (a.points.length === 1) lctx.lineTo(a.points[0].x + 0.01, a.points[0].y);\r\n lctx.stroke();\r\n lctx.restore();\r\n } else {\r\n lctx.save();\r\n lctx.fillStyle = a.color;\r\n lctx.font = `600 ${a.size}px system-ui, sans-serif`;\r\n lctx.fillText(a.value, a.x, a.y);\r\n lctx.restore();\r\n }\r\n }\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\r\n ctx.drawImage(layer, 0, 0);\r\n };\r\n\r\n useEffect(() => { paint(); }, [img, actions, dims.w, dims.h]);\r\n useEffect(() => { if (pendingText) textInputRef.current?.focus(); }, [pendingText]);\r\n\r\n const toCanvasPoint = (e: React.PointerEvent): Point => {\r\n const canvas = canvasRef.current!;\r\n const rect = canvas.getBoundingClientRect();\r\n return {\r\n x: ((e.clientX - rect.left) / rect.width) * canvas.width,\r\n y: ((e.clientY - rect.top) / rect.height) * canvas.height,\r\n };\r\n };\r\n\r\n const strokeSize = () => Math.max(4, Math.round(dims.w / 180));\r\n const textSize = () => Math.max(18, Math.round(dims.w / 28));\r\n\r\n const onPointerDown = (e: React.PointerEvent) => {\r\n if (!img) return;\r\n const p = toCanvasPoint(e);\r\n if (tool === 'text') {\r\n setPendingText({ x: p.x, y: p.y });\r\n setTextValue('');\r\n return;\r\n }\r\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\r\n drawingRef.current = { kind: 'stroke', tool, color, size: strokeSize(), points: [p] };\r\n paint(drawingRef.current);\r\n };\r\n const onPointerMove = (e: React.PointerEvent) => {\r\n if (!drawingRef.current) return;\r\n drawingRef.current.points.push(toCanvasPoint(e));\r\n paint(drawingRef.current);\r\n };\r\n const onPointerUp = () => {\r\n if (!drawingRef.current) return;\r\n const done = drawingRef.current;\r\n drawingRef.current = null;\r\n setActions(prev => [...prev, done]);\r\n };\r\n\r\n const commitText = () => {\r\n if (pendingText && textValue.trim()) {\r\n setActions(prev => [...prev, { kind: 'text', x: pendingText.x, y: pendingText.y, color, value: textValue.trim(), size: textSize() }]);\r\n }\r\n setPendingText(null);\r\n setTextValue('');\r\n };\r\n\r\n const handleSend = () => {\r\n if (!img) return;\r\n try {\r\n const clean = document.createElement('canvas');\r\n clean.width = dims.w;\r\n clean.height = dims.h;\r\n const cctx = clean.getContext('2d');\r\n if (!cctx) { setExportError(true); return; }\r\n cctx.drawImage(img, 0, 0, dims.w, dims.h);\r\n const dataUrl = clean.toDataURL('image/jpeg', 0.92);\r\n const drawn = canvasRef.current?.toDataURL('image/jpeg', 0.85) || dataUrl;\r\n onSend(dataUrl, instruction.trim(), buildMarkRegions(actions, dims.w, dims.h), drawn);\r\n } catch {\r\n setExportError(true);\r\n }\r\n };\r\n\r\n const hasMarks = actions.length > 0;\r\n\r\n return (\r\n <div className=\"hsk-markup\" role=\"dialog\" aria-label={t('markupDialogLabel')}>\r\n <div className=\"hsk-markup-head\">\r\n <span className=\"hsk-markup-title\">{t('markupTitle')}</span>\r\n <button className=\"hsk-markup-cancel\" onClick={onCancel}>{t('markupCancel')}</button>\r\n </div>\r\n\r\n <div className=\"hsk-markup-stage\">\r\n {loadError ? (\r\n <div className=\"hsk-markup-error\">{t('markupLoadError')}</div>\r\n ) : !img ? (\r\n <div className=\"hsk-markup-loading\">{t('markupLoading')}</div>\r\n ) : (\r\n <div className=\"hsk-markup-canvas-wrap\">\r\n <canvas\r\n ref={canvasRef}\r\n width={dims.w}\r\n height={dims.h}\r\n className={`hsk-markup-canvas hsk-markup-canvas--${tool}`}\r\n onPointerDown={onPointerDown}\r\n onPointerMove={onPointerMove}\r\n onPointerUp={onPointerUp}\r\n onPointerLeave={onPointerUp}\r\n />\r\n {pendingText && canvasRef.current && (\r\n <input\r\n ref={textInputRef}\r\n className=\"hsk-markup-textinput\"\r\n style={{\r\n left: `${(pendingText.x / dims.w) * 100}%`,\r\n top: `${(pendingText.y / dims.h) * 100}%`,\r\n color,\r\n }}\r\n value={textValue}\r\n placeholder={t('markupTextHint')}\r\n onChange={e => setTextValue(e.target.value)}\r\n onKeyDown={e => { if (e.key === 'Enter') commitText(); if (e.key === 'Escape') { setPendingText(null); setTextValue(''); } }}\r\n onBlur={commitText}\r\n />\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n <div className=\"hsk-markup-tools\">\r\n <div className=\"hsk-markup-colors\">\r\n {COLORS.map(c => (\r\n <button\r\n key={c}\r\n className={`hsk-markup-color${color === c ? ' hsk-markup-color--on' : ''}`}\r\n style={{ background: c }}\r\n onClick={() => { setColor(c); if (tool === 'eraser') setTool('pen'); }}\r\n aria-label={t('markupColorLabel', { colour: c })}\r\n />\r\n ))}\r\n </div>\r\n <div className=\"hsk-markup-actions\">\r\n <button className={`hsk-markup-tool${tool === 'pen' ? ' hsk-markup-tool--on' : ''}`} onClick={() => setTool('pen')}>{t('markupSketch')}</button>\r\n <button className={`hsk-markup-tool${tool === 'text' ? ' hsk-markup-tool--on' : ''}`} onClick={() => setTool('text')}>{t('markupText')}</button>\r\n <button className={`hsk-markup-tool${tool === 'eraser' ? ' hsk-markup-tool--on' : ''}`} onClick={() => setTool('eraser')}>{t('markupEraser')}</button>\r\n <button className=\"hsk-markup-tool\" onClick={() => setActions(prev => prev.slice(0, -1))} disabled={!hasMarks}>{t('markupUndo')}</button>\r\n <button className=\"hsk-markup-tool\" onClick={() => setActions([])} disabled={!hasMarks}>{t('markupClear')}</button>\r\n </div>\r\n </div>\r\n\r\n <div className=\"hsk-markup-send\">\r\n <input\r\n className=\"hsk-markup-instruction\"\r\n value={instruction}\r\n placeholder={t('markupInstruction')}\r\n onChange={e => setInstruction(e.target.value)}\r\n onKeyDown={e => { if (e.key === 'Enter' && (hasMarks || instruction.trim())) handleSend(); }}\r\n />\r\n <button\r\n className=\"hsk-markup-go\"\r\n onClick={handleSend}\r\n disabled={!img || (!hasMarks && !instruction.trim())}\r\n >\r\n {t('markupSend')}\r\n </button>\r\n </div>\r\n {exportError && <div className=\"hsk-markup-error\">{t('markupError')}</div>}\r\n </div>\r\n );\r\n}\r\n","\r\nexport interface Point { x: number; y: number }\r\n\r\nexport type MarkGesture = 'ring' | 'cross' | 'scribble' | 'arrow' | 'text';\r\n\r\nexport interface MarkRegion {\r\n gesture: MarkGesture;\r\n box: [number, number, number, number];\r\n to?: [number, number];\r\n text?: string;\r\n}\r\n\r\nconst dist = (a: Point, b: Point) => Math.hypot(a.x - b.x, a.y - b.y);\r\n\r\nfunction pathLength(pts: Point[]): number {\r\n let n = 0;\r\n for (let i = 1; i < pts.length; i++) n += dist(pts[i - 1], pts[i]);\r\n return n;\r\n}\r\n\r\nfunction bbox(pts: Point[]) {\r\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\r\n for (const p of pts) {\r\n if (p.x < minX) minX = p.x;\r\n if (p.y < minY) minY = p.y;\r\n if (p.x > maxX) maxX = p.x;\r\n if (p.y > maxY) maxY = p.y;\r\n }\r\n return { minX, minY, maxX, maxY };\r\n}\r\n\r\nconst clamp1000 = (v: number) => Math.max(0, Math.min(1000, Math.round(v)));\r\n\r\nfunction norm(b: ReturnType<typeof bbox>, w: number, h: number): [number, number, number, number] {\r\n return [\r\n clamp1000((b.minY / h) * 1000),\r\n clamp1000((b.minX / w) * 1000),\r\n clamp1000((b.maxY / h) * 1000),\r\n clamp1000((b.maxX / w) * 1000),\r\n ];\r\n}\r\n\r\nfunction overlaps(a: [number, number, number, number], b: [number, number, number, number]): boolean {\r\n const [ay0, ax0, ay1, ax1] = a;\r\n const [by0, bx0, by1, bx1] = b;\r\n const iw = Math.min(ax1, bx1) - Math.max(ax0, bx0);\r\n const ih = Math.min(ay1, by1) - Math.max(ay0, by0);\r\n if (iw <= 0 || ih <= 0) return false;\r\n const smaller = Math.min((ax1 - ax0) * (ay1 - ay0), (bx1 - bx0) * (by1 - by0));\r\n return smaller > 0 && (iw * ih) / smaller > 0.35;\r\n}\r\n\r\nconst union = (\r\n a: [number, number, number, number],\r\n b: [number, number, number, number],\r\n): [number, number, number, number] =>\r\n [Math.min(a[0], b[0]), Math.min(a[1], b[1]), Math.max(a[2], b[2]), Math.max(a[3], b[3])];\r\n\r\ninterface Classified { gesture: MarkGesture; box: [number, number, number, number]; to?: [number, number]; straight: boolean }\r\n\r\nfunction classifyStroke(pts: Point[], w: number, h: number): Classified | null {\r\n if (pts.length < 2) return null;\r\n const b = bbox(pts);\r\n const box = norm(b, w, h);\r\n const diag = Math.hypot(b.maxX - b.minX, b.maxY - b.minY);\r\n if (diag < 4) return null; // a tap, not a gesture\r\n\r\n const len = pathLength(pts);\r\n const endGap = dist(pts[0], pts[pts.length - 1]);\r\n const straightness = len / Math.max(endGap, 1e-6);\r\n\r\n if (endGap / diag < 0.3 && len > diag * 1.8) return { gesture: 'ring', box, straight: false };\r\n\r\n if (straightness < 1.25) {\r\n return {\r\n gesture: 'arrow',\r\n box,\r\n to: [clamp1000((pts[pts.length - 1].y / h) * 1000), clamp1000((pts[pts.length - 1].x / w) * 1000)],\r\n straight: true,\r\n };\r\n }\r\n\r\n return { gesture: 'scribble', box, straight: false };\r\n}\r\n\r\nexport function buildMarkRegions(\r\n actions: ReadonlyArray<{ kind: string; points?: Point[]; x?: number; y?: number; value?: string; tool?: string }>,\r\n width: number,\r\n height: number,\r\n): MarkRegion[] {\r\n if (!width || !height) return [];\r\n\r\n const strokes: Classified[] = [];\r\n const texts: MarkRegion[] = [];\r\n\r\n for (const a of actions) {\r\n if (a.kind === 'text' && a.value && typeof a.x === 'number' && typeof a.y === 'number') {\r\n const p = { x: a.x, y: a.y };\r\n texts.push({ gesture: 'text', box: norm(bbox([p, p]), width, height), text: a.value });\r\n continue;\r\n }\r\n if (a.kind === 'stroke' && a.tool !== 'eraser' && a.points) {\r\n const c = classifyStroke(a.points, width, height);\r\n if (c) strokes.push(c);\r\n }\r\n }\r\n\r\n const used = new Set<number>();\r\n const out: MarkRegion[] = [];\r\n for (let i = 0; i < strokes.length; i++) {\r\n if (used.has(i)) continue;\r\n let cur = strokes[i];\r\n for (let j = i + 1; j < strokes.length; j++) {\r\n if (used.has(j) || !cur.straight || !strokes[j].straight) continue;\r\n if (!overlaps(cur.box, strokes[j].box)) continue;\r\n used.add(j);\r\n cur = { gesture: 'cross', box: union(cur.box, strokes[j].box), straight: false };\r\n }\r\n used.add(i);\r\n out.push(cur.gesture === 'arrow'\r\n ? { gesture: 'arrow', box: cur.box, to: cur.to }\r\n : { gesture: cur.gesture, box: cur.box });\r\n }\r\n\r\n return [...out, ...texts];\r\n}\r\n","import React, { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport { useScouts, useAkropolysContext, Scout } from '@akropolys/sdk';\nimport { cn } from '../../utils/cn';\nimport { ScoutCharacter, ScoutMood, speciesName, speciesNick, SPECIES_IDS } from './ScoutCharacter';\nimport { AnimatedNumber } from './AnimatedNumber';\nimport { ScoutPin, pinSupported } from './ScoutPin';\n\nexport interface ScoutRailProps {\n className?: string;\n themeAttr?: string;\n // Tapping a scout asks it what it is watching; the answer arrives in the\n // conversation like any other message, so nothing floats over the chat.\n onAsk?: (scout: Scout) => void;\n // Starting a new scout is a conversation, not a form.\n onNew?: (avatar: string) => void;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nconst MIN_MINUTES = 15;\nconst MAX_MINUTES = 480;\n\nfunction readable(m: number): string {\n if (m < 60) return `${m} minutes`;\n const h = Math.floor(m / 60);\n const rest = m % 60;\n return rest ? `${h}h ${rest}m` : `${h} hour${h > 1 ? 's' : ''}`;\n}\n\nconst RadarIcon = ({ size = 13 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2Z\" />\n <path d=\"M12 6a6 6 0 1 0 6 6 6 6 0 0 0-6-6Z\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n </svg>\n);\n\nfunction moodOf(scout: Scout): ScoutMood {\n switch (scout.status) {\n case 'active': return 'watching';\n case 'paused': return 'resting';\n case 'triggered': return 'struck';\n default: return 'gone';\n }\n}\n\nfunction label(scout: Scout): string {\n const inst = (scout.instrument || '').trim();\n if (inst && inst.length <= 9) return inst;\n const head = inst.split(/[\\s/]/)[0];\n if (head && head.length <= 9) return head;\n return speciesName(scout.id, scout.avatar);\n}\n\nexport function ScoutRail({ className, themeAttr, onAsk, onNew, open: openProp, onOpenChange }: ScoutRailProps) {\n const client = useAkropolysContext();\n const { scouts, balance, setAvatar, cancelScout } = useScouts();\n\n const [openState, setOpenState] = useState(false);\n const open = openProp ?? openState;\n const setOpen = useCallback((v: boolean) => {\n setOpenState(v);\n onOpenChange?.(v);\n }, [onOpenChange]);\n\n const [closing, setClosing] = useState(false);\n const closeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const wrapRef = useRef<HTMLDivElement>(null);\n\n const [minutes, setMinutes] = useState(90);\n const [priceUSD, setPriceUSD] = useState(0);\n const [picked, setPicked] = useState<string | null>(null);\n const [swapping, setSwapping] = useState<string | null>(null);\n const [roster, setRoster] = useState(false);\n const [pinned, setPinned] = useState(false);\n const [dragging, setDragging] = useState(false);\n const [typing, setTyping] = useState(false);\n const [draft, setDraft] = useState('');\n\n const gooId = `hsk-scout-goo-${useId().replace(/:/g, '')}`;\n\n // An idle scout is an avatar someone paid for that has not been told what to\n // watch yet. It is what makes \"send it out\" possible, and what greys the rest\n // of the roster out.\n const idle = scouts.filter(s => s.status === 'idle');\n const paidAvatars = new Set(idle.map(s => s.avatar).filter(Boolean));\n const waiting = idle.length > 0;\n\n const visible = scouts.filter(s => s.status !== 'canceled' && s.status !== 'expired' && s.status !== 'idle');\n const activeCount = visible.filter(s => s.status === 'active').length;\n const hasScouts = visible.length > 0;\n // Scouts drinking from the same pool are drawn as one fused mass. The glue is\n // the point: it is why adding another shortens them all.\n const sharing = visible.filter(s => s.status === 'active' && s.dedicatedMinutes <= 0).length > 1;\n const pct = ((minutes - MIN_MINUTES) / (MAX_MINUTES - MIN_MINUTES)) * 100;\n const runway = activeCount > 0 ? Math.floor(balance / activeCount) : balance;\n\n const close = useCallback(() => {\n if (closeTimer.current) return;\n setClosing(true);\n closeTimer.current = setTimeout(() => {\n setOpen(false);\n setClosing(false);\n setSwapping(null);\n closeTimer.current = null;\n }, 200);\n }, [setOpen]);\n\n useEffect(() => () => {\n if (closeTimer.current) clearTimeout(closeTimer.current);\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n const path = e.composedPath();\n if (wrapRef.current && (path.includes(wrapRef.current) || wrapRef.current.contains(e.target as Node))) return;\n close();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close();\n };\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n };\n }, [open, close]);\n\n // The price is the server's answer, not one recomputed here, so the number\n // someone agrees to is the number that was quoted. Dragging the dial would\n // otherwise ask once per step, so the request waits for the drag to settle.\n useEffect(() => {\n if (!client || !open) return;\n let stale = false;\n const t = setTimeout(() => {\n client.scouts\n .quote(minutes)\n .then(q => {\n if (!stale) setPriceUSD(q.priceUSD);\n })\n .catch(() => {});\n }, 90);\n return () => {\n stale = true;\n clearTimeout(t);\n };\n }, [client, minutes, open]);\n\n const beginDrag = () => {\n setDragging(true);\n window.addEventListener('pointerup', () => setDragging(false), { once: true });\n };\n\n const commitTyped = () => {\n const v = Number(draft);\n if (!Number.isNaN(v) && draft.trim() !== '') {\n setMinutes(Math.min(MAX_MINUTES, Math.max(MIN_MINUTES, Math.round(v))));\n }\n setTyping(false);\n };\n\n if (!open && !closing) {\n return (\n <div className={cn('hsk-cb-scout-rail-wrap', className)} ref={wrapRef}>\n <button\n type=\"button\"\n className=\"hsk-cb-scout-rail-trigger\"\n onClick={() => setOpen(true)}\n aria-label=\"Scouts\"\n aria-expanded=\"false\"\n >\n <span className=\"hsk-cb-scout-trigger-icon\" style={{ color: activeCount > 0 ? '#10b981' : undefined }}>\n <RadarIcon size={13} />\n </span>\n <span>{activeCount > 0 ? `${activeCount} in motion` : 'Scouts'}</span>\n {activeCount > 0 && <span className=\"hsk-cb-scout-trigger-dot\" />}\n </button>\n </div>\n );\n }\n\n return (\n <div className={cn('hsk-cb-scout-rail-wrap', 'is-open', closing && 'is-closing', className)} ref={wrapRef}>\n {pinned && <ScoutPin scouts={scouts} themeAttr={themeAttr} onClose={() => setPinned(false)} />}\n <svg width=\"0\" height=\"0\" aria-hidden=\"true\" className=\"hsk-cb-scout-defs\">\n <filter id={gooId} x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"4\" result=\"b\" />\n <feColorMatrix in=\"b\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7\" />\n </filter>\n </svg>\n\n <div className=\"hsk-cb-scout-rail-card\" role=\"dialog\" aria-label=\"Scouts\">\n <div className=\"hsk-cb-scout-card-head\">\n <span className=\"hsk-cb-scout-card-title\">\n <RadarIcon size={12} /> {hasScouts ? 'Scouts' : 'Send a scout'}\n </span>\n {hasScouts && pinSupported() && (\n <button\n type=\"button\"\n className=\"hsk-cb-scout-card-pin\"\n onClick={() => setPinned(true)}\n aria-label=\"Keep scouts on top\"\n >\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 3v6l3 4v2H6v-2l3-4V3\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"21\" />\n </svg>\n </button>\n )}\n <button type=\"button\" className=\"hsk-cb-scout-card-x\" onClick={close} aria-label=\"Close\">\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.6\" strokeLinecap=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n\n {hasScouts && !roster ? (\n <>\n <div className=\"hsk-cb-scouts-stage\">\n {/* The glue sits behind the faces: one blob per shared scout, fused\n by the goo filter into a single mass they all stand on. */}\n {/* The glue is the animals themselves: their silhouettes, drawn\n again behind the row and fused by the goo filter, so the\n bridge between two scouts is made of their own coats. The\n full characters sit exactly on top of their own copies, so\n all that shows is the neck between them. */}\n {sharing && (\n <div className=\"hsk-cb-scouts-glue\" style={{ filter: `url(#${gooId})` }} aria-hidden=\"true\">\n {visible.map(sc => (\n <span key={sc.id} className={cn('hsk-cb-glue-cell', sc.dedicatedMinutes > 0 && 'is-loose')}>\n <ScoutCharacter\n scoutId={sc.id}\n avatar={sc.avatar}\n mood={moodOf(sc)}\n size={38}\n layer=\"body\"\n />\n </span>\n ))}\n </div>\n )}\n\n <div className=\"hsk-cb-scouts-row\">\n {visible.map(scout => (\n <div key={scout.id} className=\"hsk-cb-scout-slot\">\n <button\n type=\"button\"\n className={cn('hsk-cb-scout', `is-${scout.status}`)}\n onClick={() => onAsk?.(scout)}\n onContextMenu={e => {\n e.preventDefault();\n setSwapping(swapping === scout.id ? null : scout.id);\n }}\n aria-label={`${scout.instrument} ${scout.operator} ${scout.targetValue}`}\n >\n <span className=\"hsk-cb-scout-face\">\n <ScoutCharacter scoutId={scout.id} avatar={scout.avatar} mood={moodOf(scout)} size={38} />\n {scout.status === 'active' && <span className=\"hsk-cb-scout-pulse\" />}\n {scout.dedicatedMinutes > 0 && (\n <span className=\"hsk-cb-scout-own\">{scout.dedicatedMinutes}m</span>\n )}\n </span>\n <span className=\"hsk-cb-scout-name\">{label(scout)}</span>\n </button>\n\n <button\n type=\"button\"\n className=\"hsk-cb-scout-bin\"\n onClick={e => {\n e.stopPropagation();\n void cancelScout(scout.id);\n }}\n aria-label={`Call ${label(scout)} back`}\n >\n <svg width=\"9\" height=\"9\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n </button>\n\n {swapping === scout.id && (\n <div className=\"hsk-cb-scout-picker\">\n {SPECIES_IDS.map(id => (\n <button\n key={id}\n type=\"button\"\n className={cn('hsk-cb-scout-pick', scout.avatar === id && 'is-on')}\n onClick={() => {\n void setAvatar(scout.id, id);\n setSwapping(null);\n }}\n aria-label={id}\n >\n <ScoutCharacter scoutId={scout.id} avatar={id} mood=\"watching\" size={26} />\n </button>\n ))}\n </div>\n )}\n </div>\n ))}\n\n <button\n type=\"button\"\n className=\"hsk-cb-scout-new\"\n onClick={() => {\n setPicked(null);\n setRoster(true);\n }}\n aria-label=\"Add another avatar\"\n >\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.4\" strokeLinecap=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div className=\"hsk-cb-scout-pool-line\">\n {sharing ? (\n <>\n <AnimatedNumber value={balance} suffix=\"m\" /> shared · ~<AnimatedNumber value={runway} suffix=\"m\" /> each\n </>\n ) : (\n <><AnimatedNumber value={balance} suffix=\"m\" /> left</>\n )}\n </div>\n </>\n ) : (\n // No scouts out, so there is no face to show. This is the shelf: pick\n // the animal that will wear this purchase. Nothing is glued here —\n // these are choices, not scouts sharing a pool.\n <div className=\"hsk-cb-scout-hatch\">\n <div className=\"hsk-cb-scout-hatch-row\">\n {SPECIES_IDS.map((id, i) => (\n <button\n key={id}\n type=\"button\"\n className={cn(\n 'hsk-cb-scout-hatch-pick',\n picked === id && 'is-on',\n // Grey means inert: not paid for, and not the one being\n // chosen right now. Picking wakes it up before any money\n // has moved.\n !paidAvatars.has(id) && picked !== id && 'is-unpaid',\n )}\n style={{ animationDelay: `${i * 34}ms` }}\n onClick={() => setPicked(picked === id ? null : id)}\n aria-label={paidAvatars.has(id) ? `${id}, ready to send out` : `${id}, not paid for`}\n aria-pressed={picked === id}\n >\n <ScoutCharacter scoutId={id} avatar={id} mood={paidAvatars.has(id) ? 'watching' : 'resting'} size={30} />\n </button>\n ))}\n </div>\n </div>\n )}\n\n <div className=\"hsk-cb-scout-time\">\n <div className={cn('hsk-cb-dial', dragging && 'is-dragging')}>\n <div className=\"hsk-cb-dial-track\">\n <div className=\"hsk-cb-dial-fill\" style={{ inlineSize: `${pct}%` }} />\n </div>\n <input\n className=\"hsk-cb-dial-input\"\n type=\"range\"\n min={MIN_MINUTES}\n max={MAX_MINUTES}\n step={5}\n value={minutes}\n onChange={e => setMinutes(Number(e.target.value))}\n aria-label=\"Minutes to buy\"\n aria-valuetext={readable(minutes)}\n onPointerDown={beginDrag}\n onFocus={() => setDragging(true)}\n onBlur={() => setDragging(false)}\n />\n </div>\n\n <div className={cn('hsk-cb-scout-time-row', dragging && 'is-lifted')}>\n {typing ? (\n <input\n className=\"hsk-cb-scout-mins-input\"\n type=\"number\"\n min={MIN_MINUTES}\n max={MAX_MINUTES}\n value={draft}\n autoFocus\n onChange={e => setDraft(e.target.value)}\n onBlur={commitTyped}\n onKeyDown={e => {\n if (e.key === 'Enter') commitTyped();\n if (e.key === 'Escape') setTyping(false);\n }}\n aria-label=\"Minutes\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"hsk-cb-scout-mins\"\n onClick={() => {\n setDraft(String(minutes));\n setTyping(true);\n }}\n aria-label={`${readable(minutes)}, tap to type an exact number`}\n >\n <AnimatedNumber value={minutes} />\n <span className=\"hsk-cb-scout-mins-unit\">min</span>\n </button>\n )}\n <span className=\"hsk-cb-scout-price\">\n <AnimatedNumber value={priceUSD} decimals={2} prefix=\"$\" />\n </span>\n </div>\n </div>\n\n <button\n type=\"button\"\n className=\"hsk-cb-scout-buy-go\"\n disabled={waiting ? false : !picked}\n onClick={() => {\n if (!waiting) return;\n setRoster(false);\n setPicked(null);\n close();\n onNew?.(picked ?? '');\n }}\n >\n {waiting ? 'Send it out' : picked ? 'Buy time' : 'Pick an avatar'}\n </button>\n </div>\n </div>\n );\n}\n","import React, { useEffect, useRef } from 'react';\n\nexport type ScoutMood = 'watching' | 'resting' | 'struck' | 'gone';\n\nexport type SpeciesId = 'pig' | 'hyena' | 'owl' | 'cat' | 'frog' | 'ram';\n\ntype Species = {\n id: SpeciesId;\n name: string;\n nick: string;\n bw: number;\n bh: number;\n coat: string;\n shade: string;\n snout: string;\n eyeGap: number;\n eyeY: number;\n ears: (bw: number, bh: number) => string;\n extras?: (bw: number, bh: number) => React.ReactNode;\n};\n\n// Kawaii proportions, the way Japanese and Chinese character sets do it: the\n// face is mostly forehead, the eyes sit low and far apart, and the palette is\n// pastel so a row reads as soft rather than as six stickers.\nconst SPECIES: Species[] = [\n {\n id: 'pig',\n name: 'Pig',\n nick: 'Piggy',\n bw: 34, bh: 30, coat: '#F4B8C1', shade: '#E093A0', snout: '#EFA3AE',\n eyeGap: 16, eyeY: 3,\n ears: (bw, bh) => `M${-bw * 0.78} ${-bh * 0.5} q${-16} ${-16} ${-2} ${-21} q${10} ${-2} ${14} ${16} Z M${bw * 0.78} ${-bh * 0.5} q${16} ${-16} ${2} ${-21} q${-10} ${-2} ${-14} ${16} Z`,\n extras: (_bw, bh) => (\n <g>\n <ellipse cx=\"0\" cy={bh * 0.42} rx=\"13\" ry=\"9\" fill=\"#EFA3AE\" />\n <ellipse cx=\"-4.4\" cy={bh * 0.42} rx=\"2.1\" ry=\"3\" fill=\"#D4818F\" />\n <ellipse cx=\"4.4\" cy={bh * 0.42} rx=\"2.1\" ry=\"3\" fill=\"#D4818F\" />\n </g>\n ),\n },\n {\n id: 'hyena',\n name: 'Hyena',\n nick: 'Giggles',\n bw: 32, bh: 31, coat: '#DCC08E', shade: '#BE9E67', snout: '#B08F5E',\n eyeGap: 15, eyeY: 2,\n ears: (bw, bh) => `M${-bw * 0.66} ${-bh * 0.6} q${-11} ${-30} ${13} ${-24} Z M${bw * 0.66} ${-bh * 0.6} q${11} ${-30} ${-13} ${-24} Z`,\n extras: (bw, bh) => (\n <g>\n <path d={`M${-bw * 0.2} ${-bh} q${bw * 0.2} ${-9} ${bw * 0.4} 0`} fill=\"none\" stroke=\"#B08F5E\" strokeWidth=\"4\" strokeLinecap=\"round\" />\n <ellipse cx={-bw * 0.42} cy={bh * 0.06} rx=\"4\" ry=\"3.2\" fill=\"#BE9E67\" opacity=\"0.75\" />\n <ellipse cx={bw * 0.46} cy={bh * 0.24} rx=\"3.4\" ry=\"2.8\" fill=\"#BE9E67\" opacity=\"0.75\" />\n <ellipse cx=\"0\" cy={bh * 0.46} rx=\"8\" ry=\"6\" fill=\"#B08F5E\" />\n </g>\n ),\n },\n {\n id: 'owl',\n name: 'Owl',\n nick: 'Hoot',\n bw: 33, bh: 32, coat: '#C3B9A6', shade: '#9C917E', snout: '#E8A94E',\n eyeGap: 17, eyeY: 3,\n ears: (bw, bh) => `M${-bw * 0.62} ${-bh * 0.74} l${-4} ${-21} l${17} ${11} Z M${bw * 0.62} ${-bh * 0.74} l${4} ${-21} l${-17} ${11} Z`,\n extras: (_bw, bh) => (\n <path d={`M0 ${bh * 0.06} l4.5 7 l-4.5 5 l-4.5 -5 Z`} fill=\"#E8A94E\" />\n ),\n },\n {\n id: 'cat',\n name: 'Cat',\n nick: 'Kitty',\n bw: 31, bh: 30, coat: '#AEB7C4', shade: '#8B94A2', snout: '#7C8592',\n eyeGap: 15, eyeY: 3,\n ears: (bw, bh) => `M${-bw * 0.74} ${-bh * 0.58} l${-3} ${-26} l${21} ${12} Z M${bw * 0.74} ${-bh * 0.58} l${3} ${-26} l${-21} ${12} Z`,\n extras: (bw, bh) => (\n <g stroke=\"#7C8592\" strokeWidth=\"1.6\" strokeLinecap=\"round\" opacity=\"0.8\">\n <path d={`M${-bw * 0.3} ${bh * 0.4} l${-14} ${-3}`} />\n <path d={`M${-bw * 0.3} ${bh * 0.46} l${-14} ${3}`} />\n <path d={`M${bw * 0.3} ${bh * 0.4} l${14} ${-3}`} />\n <path d={`M${bw * 0.3} ${bh * 0.46} l${14} ${3}`} />\n </g>\n ),\n },\n {\n id: 'frog',\n name: 'Frog',\n nick: 'Hopper',\n bw: 36, bh: 26, coat: '#A9D194', shade: '#7FA96C', snout: '#7FA96C',\n eyeGap: 17, eyeY: -8,\n ears: (bw, bh) => `M${-bw * 0.52} ${-bh * 0.7} a13 13 0 1 1 26 0 Z M${bw * 0.06} ${-bh * 0.7} a13 13 0 1 1 26 0 Z`,\n extras: (_bw, bh) => (\n <path d={`M-11 ${bh * 0.44} q11 7 22 0`} fill=\"none\" stroke=\"#7FA96C\" strokeWidth=\"2.4\" strokeLinecap=\"round\" />\n ),\n },\n {\n id: 'ram',\n name: 'Ram',\n nick: 'Bram',\n bw: 32, bh: 30, coat: '#E2D6C0', shade: '#B9AC96', snout: '#A79A84',\n eyeGap: 15, eyeY: 3,\n ears: (bw, bh) => `M${-bw * 0.86} ${-bh * 0.24} l${-17} ${5} l${14} ${9} Z M${bw * 0.86} ${-bh * 0.24} l${17} ${5} l${-14} ${9} Z`,\n extras: (bw, bh) => (\n <g fill=\"none\" stroke=\"#A79A84\" strokeWidth=\"4.5\" strokeLinecap=\"round\">\n <path d={`M${-bw * 0.66} ${-bh * 0.6} q${-13} ${4} ${-9} ${13} q${3} ${7} ${9} ${2}`} />\n <path d={`M${bw * 0.66} ${-bh * 0.6} q${13} ${4} ${9} ${13} q${-3} ${7} ${-9} ${2}`} />\n </g>\n ),\n },\n];\n\nexport const SPECIES_IDS = SPECIES.map(s => s.id);\n\n// A shopper's pick wins. Without one the species falls out of the scout id,\n// which the database already generated at random, so a new scout still arrives\n// wearing a face instead of a placeholder.\nexport function speciesFor(id: string, avatar?: string): Species {\n if (avatar) {\n const chosen = SPECIES.find(s => s.id === avatar);\n if (chosen) return chosen;\n }\n let h = 0;\n for (let i = 0; i < id.length; i++) h = (h * 31 + id.charCodeAt(i)) >>> 0;\n return SPECIES[h % SPECIES.length];\n}\n\nconst MOOD: Record<ScoutMood, { lid: number; perk: number; breath: number; tilt: number; dim: number }> = {\n watching: { lid: 1, perk: 1, breath: 1700, tilt: 0, dim: 1 },\n resting: { lid: 0.16, perk: 0.25, breath: 3400, tilt: 6, dim: 0.82 },\n struck: { lid: 1.15, perk: 1.3, breath: 700, tilt: 0, dim: 1 },\n gone: { lid: 0.08, perk: 0.1, breath: 4200, tilt: 10, dim: 0.45 },\n};\n\nfunction squircle(bw: number, bh: number) {\n const k = 0.46;\n const r = Math.min(bw, bh) * 0.72;\n const p = (x: number, y: number) => `${x.toFixed(2)} ${y.toFixed(2)}`;\n return (\n `M${p(-bw, -bh + r)}` +\n `C${p(-bw, -bh + r * k)} ${p(-bw + r * k, -bh)} ${p(-bw + r, -bh)}` +\n `L${p(bw - r, -bh)}` +\n `C${p(bw - r * k, -bh)} ${p(bw, -bh + r * k)} ${p(bw, -bh + r)}` +\n `L${p(bw, bh - r)}` +\n `C${p(bw, bh - r * k)} ${p(bw - r * k, bh)} ${p(bw - r, bh)}` +\n `L${p(-bw + r, bh)}` +\n `C${p(-bw + r * k, bh)} ${p(-bw, bh - r * k)} ${p(-bw, bh - r)}` +\n 'Z'\n );\n}\n\nexport interface ScoutCharacterProps {\n scoutId: string;\n avatar?: string;\n mood?: ScoutMood;\n size?: number;\n // 'body' draws the silhouette alone — ears and coat, no face. Behind a goo\n // filter those silhouettes fuse with their neighbours, which is how two\n // scouts sharing minutes are actually glued: their own bodies merge, rather\n // than a coloured shape being parked behind them. Body geometry is driven by\n // time and the id seed only, so a body layer stays in lockstep with the full\n // character drawn on top of it.\n layer?: 'all' | 'body';\n}\n\n// One animal, animated the way Kiku is: springs toward a target every frame,\n// blinks on its own schedule, and holds still for prefers-reduced-motion.\nexport function ScoutCharacter({ scoutId, avatar, mood = 'watching', size = 44, layer = 'all' }: ScoutCharacterProps) {\n const sp = speciesFor(scoutId, avatar);\n const moodRef = useRef(mood);\n moodRef.current = mood;\n\n const figRef = useRef<SVGGElement>(null);\n const bodyRef = useRef<SVGPathElement>(null);\n const earRef = useRef<SVGPathElement>(null);\n const eyeLRef = useRef<SVGRectElement>(null);\n const eyeRRef = useRef<SVGRectElement>(null);\n const shineLRef = useRef<SVGCircleElement>(null);\n const shineRRef = useRef<SVGCircleElement>(null);\n const mouthRef = useRef<SVGPathElement>(null);\n\n useEffect(() => {\n const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n const at = { lid: 1, perk: 1, tilt: 0, dim: 1, gx: 0, gy: 0, hop: 0 };\n const vel = { lid: 0, perk: 0, tilt: 0, dim: 0, gx: 0, gy: 0, hop: 0 };\n\n // Each character is offset in its own cycle so a row never breathes in\n // lockstep — that is what makes a group read as animals instead of a widget.\n let seed = 0;\n for (let i = 0; i < scoutId.length; i++) seed = (seed * 31 + scoutId.charCodeAt(i)) >>> 0;\n const phase = (seed % 1000) * 3;\n\n let blinkAt = 1200 + (seed % 2600);\n let blinkPhase = -1;\n let wander = 0;\n let wanderAt = 900;\n let hopDue = 2000 + (seed % 5000);\n let hopPhase = -1;\n let raf = 0;\n\n const spring = (k: keyof typeof at, want: number, stiff = 0.16, damp = 0.76) => {\n vel[k] = (vel[k] + (want - at[k]) * stiff) * damp;\n at[k] += vel[k];\n };\n\n const frame = (t: number) => {\n const m = MOOD[moodRef.current];\n const alive = moodRef.current === 'watching' || moodRef.current === 'struck';\n\n if (alive && !reduced && t > wanderAt) {\n wander = (Math.random() - 0.5) * 2;\n wanderAt = t + 1400 + Math.random() * 2800;\n }\n\n let lid = m.lid;\n if (!reduced && alive) {\n if (blinkPhase < 0 && t > blinkAt) blinkPhase = 0;\n if (blinkPhase >= 0) {\n blinkPhase += 1 / 6;\n lid = m.lid * Math.abs(blinkPhase - 0.5) * 2;\n if (blinkPhase >= 1) {\n blinkPhase = -1;\n // the occasional quick second blink, the tell that sells a creature\n blinkAt = t + (Math.random() < 0.24 ? 300 : 2200 + Math.random() * 3800);\n }\n }\n }\n\n // A struck scout jumps: it just did the one thing it was made to do.\n let lift = 0;\n if (moodRef.current === 'struck' && !reduced) {\n if (hopPhase < 0 && t > hopDue) hopPhase = 0;\n if (hopPhase >= 0) {\n hopPhase += 1 / 26;\n lift = -Math.sin(hopPhase * Math.PI) * 7;\n if (hopPhase >= 1) {\n hopPhase = -1;\n hopDue = t + 1600 + Math.random() * 2200;\n }\n }\n }\n\n const breath = reduced ? 0 : Math.sin((t + phase) / m.breath * Math.PI) * 0.03;\n\n spring('lid', lid, 0.3, 0.6);\n spring('perk', m.perk);\n spring('tilt', m.tilt);\n spring('dim', m.dim);\n spring('gx', alive && !reduced ? wander * 2.4 : 0, 0.08, 0.84);\n spring('gy', alive && !reduced ? Math.sin((t + phase) / 2200) * 1.4 : 1.5, 0.08, 0.84);\n\n const bw = sp.bw * (1 + breath * 0.9);\n const bh = sp.bh * (1 - breath);\n\n bodyRef.current?.setAttribute('d', squircle(bw, bh));\n earRef.current?.setAttribute('d', sp.ears(bw, bh));\n earRef.current?.setAttribute(\n 'transform',\n `translate(0 ${((1 - at.perk) * 7).toFixed(2)}) scale(1 ${Math.max(0.2, at.perk).toFixed(3)})`,\n );\n\n if (layer === 'body') {\n raf = requestAnimationFrame(frame);\n return;\n }\n\n const h = Math.max(1.4, 17 * Math.max(0.05, at.lid));\n for (const [eye, shine, dir] of [[eyeLRef, shineLRef, -1], [eyeRRef, shineRRef, 1]] as const) {\n const el = eye.current;\n if (el) {\n el.setAttribute('x', String(dir * sp.eyeGap - 6 + at.gx));\n el.setAttribute('y', String(sp.eyeY - h / 2 + at.gy));\n el.setAttribute('height', String(h));\n el.setAttribute('ry', String(Math.min(6, h / 2)));\n }\n const sh = shine.current;\n if (sh) {\n sh.setAttribute('cx', String(dir * sp.eyeGap - 1.8 + at.gx));\n sh.setAttribute('cy', String(sp.eyeY - h / 2 + 3.4 + at.gy));\n // The glint lives inside the eye, so it closes with the lid.\n sh.setAttribute('r', String(h > 7 ? 2.5 : 0));\n }\n }\n mouthRef.current?.setAttribute('transform', `translate(${at.gx.toFixed(2)} ${at.gy.toFixed(2)})`);\n\n figRef.current?.setAttribute(\n 'transform',\n `translate(0 ${lift.toFixed(2)}) rotate(${at.tilt.toFixed(2)})`,\n );\n figRef.current?.setAttribute('opacity', at.dim.toFixed(3));\n\n raf = requestAnimationFrame(frame);\n };\n\n raf = requestAnimationFrame(frame);\n return () => cancelAnimationFrame(raf);\n }, [scoutId, sp, layer]);\n\n return (\n <svg\n className=\"hsk-cb-scout-char\"\n width={size}\n height={size}\n viewBox=\"-50 -50 100 100\"\n role=\"img\"\n aria-label={sp.name}\n >\n <g ref={figRef}>\n <path ref={earRef} d={sp.ears(sp.bw, sp.bh)} fill={sp.shade} />\n <path ref={bodyRef} d={squircle(sp.bw, sp.bh)} fill={sp.coat} />\n {layer === 'all' && sp.extras?.(sp.bw, sp.bh)}\n{layer === 'all' && (\n <>\n <ellipse cx={-sp.eyeGap - 7} cy={sp.eyeY + 9} rx=\"6\" ry=\"3.6\" fill=\"#F08898\" opacity=\"0.5\" />\n <ellipse cx={sp.eyeGap + 7} cy={sp.eyeY + 9} rx=\"6\" ry=\"3.6\" fill=\"#F08898\" opacity=\"0.5\" />\n <rect ref={eyeLRef} x={-sp.eyeGap - 6} y={sp.eyeY - 8.5} width=\"12\" height=\"17\" rx=\"6\" fill=\"#3A322C\" />\n <rect ref={eyeRRef} x={sp.eyeGap - 6} y={sp.eyeY - 8.5} width=\"12\" height=\"17\" rx=\"6\" fill=\"#3A322C\" />\n <circle ref={shineLRef} cx={-sp.eyeGap - 1.8} cy={sp.eyeY - 5} r=\"2.5\" fill=\"#FFFFFF\" />\n <circle ref={shineRRef} cx={sp.eyeGap - 1.8} cy={sp.eyeY - 5} r=\"2.5\" fill=\"#FFFFFF\" />\n <path ref={mouthRef} d={`M-3.6 ${sp.eyeY + 13} q3.6 3.6 7.2 0`} fill=\"none\" stroke=\"#3A322C\" strokeWidth=\"1.8\" strokeLinecap=\"round\" opacity=\"0.75\" />\n </>\n )}\n </g>\n </svg>\n );\n}\n\nexport function speciesName(id: string, avatar?: string): string {\n return speciesFor(id, avatar).name;\n}\n\n// What a shopper would call it out loud.\nexport function speciesNick(id: string, avatar?: string): string {\n return speciesFor(id, avatar).nick;\n}\n","import React from 'react';\n\nexport interface AnimatedNumberProps {\n value: number;\n decimals?: number;\n prefix?: string;\n suffix?: string;\n className?: string;\n}\n\n// Each digit is its own column of 0-9 behind a clipped window, so changing a\n// value rolls the affected digits into place instead of swapping the text.\n// Positions are staggered from the right, which is the order they settle in on\n// a real odometer.\nfunction Digit({ d, delay }: { d: number; delay: number }) {\n return (\n <span className=\"hsk-cb-num-slot\">\n <span className=\"hsk-cb-num-col\" style={{ transform: `translateY(${-d * 10}%)`, transitionDelay: `${delay}ms` }}>\n {['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].map(n => (\n <span key={n} className=\"hsk-cb-num-d\">{n}</span>\n ))}\n </span>\n </span>\n );\n}\n\nexport function AnimatedNumber({ value, decimals = 0, prefix, suffix, className }: AnimatedNumberProps) {\n const text = Math.abs(value).toFixed(decimals);\n const chars = text.split('');\n // Right-most digit leads; each one further left waits a beat longer.\n const digitsTotal = chars.filter(c => c >= '0' && c <= '9').length;\n let seen = 0;\n\n return (\n <span className={['hsk-cb-num', className].filter(Boolean).join(' ')}>\n {prefix && <span className=\"hsk-cb-num-fix\">{prefix}</span>}\n {chars.map((c, i) => {\n if (c >= '0' && c <= '9') {\n const fromRight = digitsTotal - 1 - seen;\n seen += 1;\n return <Digit key={i} d={Number(c)} delay={fromRight * 34} />;\n }\n return <span key={i} className=\"hsk-cb-num-fix\">{c}</span>;\n })}\n {suffix && <span className=\"hsk-cb-num-fix\">{suffix}</span>}\n </span>\n );\n}\n","import React, { useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Scout } from '@akropolys/sdk';\nimport cssText from '../../generated/cssText';\nimport { ScoutCharacter, ScoutMood, speciesNick } from './ScoutCharacter';\n\n// Document Picture-in-Picture gives a floating, always-on-top window that\n// renders ordinary DOM. It is the only way to keep a card on screen once the\n// shopper has moved on to another app — a notification cannot stay put, and a\n// hidden tab cannot draw. The window never outlives the tab that opened it,\n// which is the honest limit of this approach.\nexport function pinSupported(): boolean {\n return typeof window !== 'undefined' && 'documentPictureInPicture' in window;\n}\n\nfunction moodOf(scout: Scout): ScoutMood {\n switch (scout.status) {\n case 'active': return 'watching';\n case 'paused': return 'resting';\n case 'triggered': return 'struck';\n default: return 'gone';\n }\n}\n\n// How far a scout has travelled from where it started toward its target.\nfunction progress(scout: Scout): number | null {\n const num = (v?: string) => {\n const n = parseFloat(String(v ?? '').replace(/[^0-9.\\-]/g, ''));\n return Number.isNaN(n) ? null : n;\n };\n const start = num(scout.initialValue);\n const target = num(scout.targetValue);\n if (start === null || target === null || start === target) return null;\n const now = num(scout.triggerValue) ?? start;\n const pct = ((now - start) / (target - start)) * 100;\n return Math.max(0, Math.min(100, Math.round(pct)));\n}\n\nexport interface ScoutPinProps {\n scouts: Scout[];\n themeAttr?: string;\n onClose: () => void;\n}\n\nexport function ScoutPin({ scouts, themeAttr, onClose }: ScoutPinProps) {\n const [pip, setPip] = useState<Window | null>(null);\n\n useEffect(() => {\n let win: Window | null = null;\n let cancelled = false;\n\n (async () => {\n try {\n const api = (window as any).documentPictureInPicture;\n win = await api.requestWindow({ width: 260, height: 300, disallowReturnToOpener: true });\n if (cancelled || !win) return;\n\n // The pinned window is a separate document: it inherits nothing, so the\n // widget's stylesheet has to be handed over with it.\n const style = win.document.createElement('style');\n style.textContent = cssText;\n win.document.head.appendChild(style);\n win.document.body.className = 'hsk-cb-pin-body';\n if (themeAttr) win.document.body.setAttribute('data-hsk-theme', themeAttr);\n\n win.addEventListener('pagehide', onClose);\n setPip(win);\n } catch {\n onClose();\n }\n })();\n\n return () => {\n cancelled = true;\n try {\n win?.close();\n } catch {\n /* already gone */\n }\n };\n }, [themeAttr, onClose]);\n\n if (!pip) return null;\n\n const live = scouts.filter(s => s.status !== 'canceled' && s.status !== 'expired' && s.status !== 'idle');\n\n return createPortal(\n // The same card, in a window that floats: identical shell, identical faces,\n // with the brief and progress each scout would otherwise only show in chat.\n <div className=\"hsk-cb-scout-rail-card hsk-cb-pin-card\">\n <div className=\"hsk-cb-scout-card-head\">\n <span className=\"hsk-cb-scout-card-title\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2Z\" />\n <path d=\"M12 6a6 6 0 1 0 6 6 6 6 0 0 0-6-6Z\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n </svg>\n Scouts\n </span>\n <span className=\"hsk-cb-pin-count\">\n {live.filter(s => s.status === 'active').length} in motion\n </span>\n </div>\n\n {live.length === 0 ? (\n <div className=\"hsk-cb-scout-pool-line\">Nothing out right now.</div>\n ) : (\n live.map(scout => {\n const pct = progress(scout);\n return (\n <div key={scout.id} className=\"hsk-cb-pin-row\">\n <span className={`hsk-cb-scout is-${scout.status}`}>\n <span className=\"hsk-cb-scout-face\">\n <ScoutCharacter scoutId={scout.id} avatar={scout.avatar} mood={moodOf(scout)} size={38} />\n {scout.status === 'active' && <span className=\"hsk-cb-scout-pulse\" />}\n </span>\n <span className=\"hsk-cb-scout-name\">{speciesNick(scout.id, scout.avatar)}</span>\n </span>\n\n <span className=\"hsk-cb-pin-text\">\n <span className=\"hsk-cb-pin-watch\">\n {scout.instrument} {scout.operator} {scout.targetValue}\n </span>\n {pct !== null && (\n <span className=\"hsk-cb-pin-bar\">\n <span className=\"hsk-cb-pin-fill\" style={{ inlineSize: `${pct}%` }} />\n </span>\n )}\n {scout.status === 'triggered' && <span className=\"hsk-cb-pin-hit\">hit</span>}\n </span>\n </div>\n );\n })\n )}\n </div>,\n pip.document.body,\n );\n}\n","import React, { useEffect, useRef } from 'react';\r\n\r\ntype Rng = () => number;\r\n\r\nfunction hashSeed(s: string): number {\r\n let h = 2166136261 >>> 0;\r\n for (let i = 0; i < s.length; i++) {\r\n h ^= s.charCodeAt(i);\r\n h = Math.imul(h, 16777619);\r\n }\r\n return h >>> 0;\r\n}\r\n\r\nfunction mulberry32(seed: number): Rng {\r\n let a = seed >>> 0;\r\n return () => {\r\n a = (a + 0x6d2b79f5) >>> 0;\r\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\r\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\r\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\r\n };\r\n}\r\n\r\nconst smooth = (t: number) => t * t * (3 - 2 * t);\r\n\r\nfunction makeNoise(rng: Rng) {\r\n const size = 256;\r\n const lat = new Float32Array(size * size);\r\n for (let i = 0; i < lat.length; i++) lat[i] = rng();\r\n const at = (x: number, y: number) => lat[(y & 255) * size + (x & 255)];\r\n\r\n return (x: number, y: number) => {\r\n const xi = Math.floor(x);\r\n const yi = Math.floor(y);\r\n const xf = smooth(x - xi);\r\n const yf = smooth(y - yi);\r\n const a = at(xi, yi);\r\n const b = at(xi + 1, yi);\r\n const c = at(xi, yi + 1);\r\n const d = at(xi + 1, yi + 1);\r\n return (a + (b - a) * xf) * (1 - yf) + (c + (d - c) * xf) * yf;\r\n };\r\n}\r\n\r\nfunction poisson(w: number, h: number, r: number, rng: Rng): Array<[number, number]> {\r\n const cell = r / Math.SQRT2;\r\n const gw = Math.ceil(w / cell);\r\n const gh = Math.ceil(h / cell);\r\n const grid = new Int32Array(gw * gh).fill(-1);\r\n const pts: Array<[number, number]> = [];\r\n const active: number[] = [];\r\n\r\n const place = (x: number, y: number) => {\r\n const i = pts.length;\r\n pts.push([x, y]);\r\n grid[Math.floor(y / cell) * gw + Math.floor(x / cell)] = i;\r\n active.push(i);\r\n };\r\n\r\n const fits = (x: number, y: number) => {\r\n if (x < 0 || y < 0 || x >= w || y >= h) return false;\r\n const cx = Math.floor(x / cell);\r\n const cy = Math.floor(y / cell);\r\n for (let gy = Math.max(cy - 2, 0); gy <= Math.min(cy + 2, gh - 1); gy++) {\r\n for (let gx = Math.max(cx - 2, 0); gx <= Math.min(cx + 2, gw - 1); gx++) {\r\n const j = grid[gy * gw + gx];\r\n if (j < 0) continue;\r\n const dx = pts[j][0] - x;\r\n const dy = pts[j][1] - y;\r\n if (dx * dx + dy * dy < r * r) return false;\r\n }\r\n }\r\n return true;\r\n };\r\n\r\n place(rng() * w, rng() * h);\r\n while (active.length) {\r\n const ai = (rng() * active.length) | 0;\r\n const [px, py] = pts[active[ai]];\r\n let placed = false;\r\n for (let k = 0; k < 24; k++) {\r\n const ang = rng() * Math.PI * 2;\r\n const rad = r * (1 + rng());\r\n const x = px + Math.cos(ang) * rad;\r\n const y = py + Math.sin(ang) * rad;\r\n if (fits(x, y)) {\r\n place(x, y);\r\n placed = true;\r\n break;\r\n }\r\n }\r\n if (!placed) active.splice(ai, 1);\r\n }\r\n return pts;\r\n}\r\n\r\ntype Glyph = (ctx: CanvasRenderingContext2D, s: number, rng: Rng) => void;\r\n\r\nconst wob = (rng: Rng, k: number) => (rng() - 0.5) * k;\r\n\r\nconst motifs: Glyph[] = [\r\n (ctx, s, rng) => {\r\n const h = s * 0.5;\r\n const w = s * (0.14 + rng() * 0.04);\r\n const cap = s * 0.07;\r\n ctx.beginPath();\r\n ctx.moveTo(-w - cap * 0.6, -h);\r\n ctx.lineTo(w + cap * 0.6, -h);\r\n ctx.moveTo(-w, -h + cap);\r\n ctx.lineTo(w, -h + cap);\r\n ctx.moveTo(-w, -h + cap);\r\n ctx.lineTo(-w * 0.85, h - cap);\r\n ctx.moveTo(w, -h + cap);\r\n ctx.lineTo(w * 0.85, h - cap);\r\n ctx.moveTo(0, -h + cap * 1.7);\r\n ctx.lineTo(0, h - cap * 1.7);\r\n ctx.moveTo(-w, h - cap);\r\n ctx.lineTo(w, h - cap);\r\n ctx.moveTo(-w - cap * 0.6, h);\r\n ctx.lineTo(w + cap * 0.6, h);\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n const eave = -q * (0.18 + rng() * 0.1);\r\n ctx.beginPath();\r\n ctx.moveTo(-q, eave);\r\n ctx.lineTo(0, -q);\r\n ctx.lineTo(q, eave);\r\n ctx.closePath();\r\n ctx.moveTo(-q * 0.92, eave + q * 0.16);\r\n ctx.lineTo(q * 0.92, eave + q * 0.16);\r\n for (const x of [-0.62, -0.21, 0.21, 0.62]) {\r\n ctx.moveTo(q * x, eave + q * 0.16);\r\n ctx.lineTo(q * x, q * 0.8);\r\n }\r\n ctx.moveTo(-q, q * 0.8);\r\n ctx.lineTo(q, q * 0.8);\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n const belly = q * (0.48 + rng() * 0.12);\r\n ctx.beginPath();\r\n ctx.moveTo(-q * 0.2, -q * 0.86);\r\n ctx.lineTo(q * 0.2, -q * 0.86);\r\n ctx.moveTo(-q * 0.15, -q * 0.78);\r\n ctx.bezierCurveTo(-belly, -q * 0.3, -belly * 0.85, q * 0.6, 0, q * 0.86);\r\n ctx.bezierCurveTo(belly * 0.85, q * 0.6, belly, -q * 0.3, q * 0.15, -q * 0.78);\r\n ctx.moveTo(-q * 0.17, -q * 0.64);\r\n ctx.quadraticCurveTo(-belly * 1.16, -q * 0.48, -belly * 0.7, -q * 0.04);\r\n ctx.moveTo(q * 0.17, -q * 0.64);\r\n ctx.quadraticCurveTo(belly * 1.16, -q * 0.48, belly * 0.7, -q * 0.04);\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.moveTo(-q * 0.9, q * 0.52);\r\n ctx.quadraticCurveTo(0, -q * 0.18, q * 0.9, -q * 0.58);\r\n ctx.stroke();\r\n const n = 4 + ((rng() * 3) | 0);\r\n for (let i = 0; i < n; i++) {\r\n const t = 0.16 + (i / n) * 0.8;\r\n const px = -q * 0.9 + t * q * 1.8;\r\n const py = q * 0.52 - t * q * 1.16 + (1 - t) * t * q * 0.3;\r\n const dir = i % 2 ? 1 : -1;\r\n const l = q * (0.26 + rng() * 0.1);\r\n ctx.beginPath();\r\n ctx.moveTo(px, py);\r\n ctx.quadraticCurveTo(px + l * 0.5, py + dir * l * 0.66, px + l * 0.9, py + dir * l * 0.08);\r\n ctx.quadraticCurveTo(px + l * 0.42, py + dir * l * 0.04, px, py);\r\n ctx.stroke();\r\n }\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.moveTo(-q * 0.85, -q * 0.7);\r\n ctx.quadraticCurveTo(-q * 0.1, -q * 0.35, q * 0.2, q * 0.1);\r\n ctx.stroke();\r\n const drupes: Array<[number, number]> = [\r\n [-q * 0.45, -q * 0.12],\r\n [q * 0.05, q * 0.3],\r\n [q * 0.42, -q * 0.4],\r\n ];\r\n for (const [ox, oy] of drupes) {\r\n ctx.beginPath();\r\n ctx.moveTo(ox, oy - q * 0.28);\r\n ctx.lineTo(ox - q * 0.02, oy - q * 0.16);\r\n ctx.stroke();\r\n ctx.beginPath();\r\n ctx.ellipse(ox, oy, q * (0.15 + rng() * 0.04), q * 0.19, wob(rng, 0.5), 0, Math.PI * 2);\r\n ctx.stroke();\r\n }\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n for (const side of [-1, 1]) {\r\n ctx.beginPath();\r\n ctx.arc(0, 0, q * 0.72, side > 0 ? -1.25 : 1.25, side > 0 ? 1.25 : Math.PI * 2 - 1.25, side < 0);\r\n ctx.stroke();\r\n for (let i = 0; i < 5; i++) {\r\n const a = -1.05 + (i / 4) * 2.1;\r\n const ax = Math.sin(a) * side * q * 0.72;\r\n const ay = Math.cos(a) * q * 0.72;\r\n const l = q * (0.2 + rng() * 0.08);\r\n ctx.beginPath();\r\n ctx.moveTo(ax, ay);\r\n ctx.quadraticCurveTo(ax + side * l * 0.9, ay - l * 0.5, ax + side * l * 0.6, ay - l * 1.05);\r\n ctx.stroke();\r\n }\r\n }\r\n },\r\n (ctx, s) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.moveTo(-q, q * 0.6);\r\n ctx.lineTo(q * 0.55, q * 0.6);\r\n ctx.lineTo(q * 0.55, -q * 0.6);\r\n ctx.lineTo(-q * 0.45, -q * 0.6);\r\n ctx.lineTo(-q * 0.45, q * 0.15);\r\n ctx.lineTo(q * 0.1, q * 0.15);\r\n ctx.lineTo(q * 0.1, -q * 0.18);\r\n ctx.stroke();\r\n },\r\n (ctx, s) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.moveTo(-q * 0.62, q * 0.8);\r\n ctx.lineTo(-q * 0.62, -q * 0.05);\r\n ctx.arc(0, -q * 0.05, q * 0.62, Math.PI, 0);\r\n ctx.lineTo(q * 0.62, q * 0.8);\r\n ctx.stroke();\r\n ctx.beginPath();\r\n ctx.moveTo(-q * 0.86, q * 0.8);\r\n ctx.lineTo(q * 0.86, q * 0.8);\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.arc(0, 0, q * 0.4, 0, Math.PI * 2);\r\n ctx.stroke();\r\n const off = rng() * 0.5;\r\n for (let i = 0; i < 8; i++) {\r\n const a = off + (i / 8) * Math.PI * 2;\r\n ctx.beginPath();\r\n ctx.moveTo(Math.cos(a) * q * 0.6, Math.sin(a) * q * 0.6);\r\n ctx.lineTo(Math.cos(a) * q * 0.94, Math.sin(a) * q * 0.94);\r\n ctx.stroke();\r\n }\r\n },\r\n (ctx, s) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.moveTo(-q * 0.44, q * 0.7);\r\n ctx.bezierCurveTo(-q, q * 0.2, -q * 0.8, -q * 0.7, -q * 0.3, -q * 0.6);\r\n ctx.moveTo(q * 0.44, q * 0.7);\r\n ctx.bezierCurveTo(q, q * 0.2, q * 0.8, -q * 0.7, q * 0.3, -q * 0.6);\r\n ctx.moveTo(-q * 0.32, -q * 0.64);\r\n ctx.lineTo(q * 0.32, -q * 0.64);\r\n ctx.moveTo(-q * 0.44, q * 0.7);\r\n ctx.lineTo(q * 0.44, q * 0.7);\r\n for (const x of [-0.16, 0.02, 0.2]) {\r\n ctx.moveTo(q * x, -q * 0.56);\r\n ctx.lineTo(q * x, q * 0.62);\r\n }\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n const lift = q * (0.4 + rng() * 0.18);\r\n ctx.beginPath();\r\n ctx.moveTo(-q, q * 0.16);\r\n ctx.quadraticCurveTo(-q * 0.5, -lift, 0, -q * 0.02);\r\n ctx.quadraticCurveTo(q * 0.5, -lift, q, q * 0.16);\r\n ctx.stroke();\r\n },\r\n];\r\n\r\nconst scribbles: Glyph[] = [\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n let px = -q + wob(rng, q * 0.3);\r\n let py = wob(rng, q);\r\n ctx.beginPath();\r\n ctx.moveTo(px, py);\r\n const n = 4 + ((rng() * 4) | 0);\r\n for (let i = 0; i < n; i++) {\r\n const nx = px + (q * 2) / n + wob(rng, q * 0.5);\r\n const ny = wob(rng, q * 1.5);\r\n ctx.quadraticCurveTo(px + wob(rng, q * 0.9), py + wob(rng, q * 1.6), nx, ny);\r\n px = nx;\r\n py = ny;\r\n }\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n const turns = 2.2 + rng() * 1.6;\r\n const dir = rng() < 0.5 ? -1 : 1;\r\n ctx.beginPath();\r\n for (let i = 0; i <= 60; i++) {\r\n const t = i / 60;\r\n const a = dir * t * turns * Math.PI * 2;\r\n const rr = q * t * (0.9 + wob(rng, 0.06));\r\n const x = Math.cos(a) * rr;\r\n const y = Math.sin(a) * rr;\r\n if (i === 0) ctx.moveTo(x, y);\r\n else ctx.lineTo(x, y);\r\n }\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n const n = 4 + ((rng() * 4) | 0);\r\n const lean = wob(rng, 0.7);\r\n for (let i = 0; i < n; i++) {\r\n const x = -q + (i / (n - 1)) * q * 2 + wob(rng, q * 0.16);\r\n const len = q * (0.7 + rng() * 0.6);\r\n ctx.beginPath();\r\n ctx.moveTo(x - lean * len * 0.5, -len * 0.5);\r\n ctx.quadraticCurveTo(x + wob(rng, q * 0.2), 0, x + lean * len * 0.5, len * 0.5);\r\n ctx.stroke();\r\n }\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.5;\r\n const n = 2 + ((rng() * 3) | 0);\r\n const step = (q * 2) / n;\r\n ctx.beginPath();\r\n ctx.moveTo(-q, q * 0.4);\r\n for (let i = 0; i < n; i++) {\r\n const x = -q + i * step;\r\n const r = step * (0.42 + rng() * 0.18);\r\n ctx.bezierCurveTo(x + r * 0.2, q * 0.4 - r * 2.1, x + step - r * 0.2, q * 0.4 - r * 2.1, x + step, q * 0.4 + wob(rng, q * 0.14));\r\n }\r\n ctx.stroke();\r\n },\r\n];\r\n\r\nconst specks: Glyph[] = [\r\n (ctx, s, rng) => {\r\n ctx.beginPath();\r\n ctx.arc(0, 0, s * 0.1 + rng() * s * 0.04, 0, Math.PI * 2);\r\n ctx.fill();\r\n },\r\n (ctx, s, rng) => {\r\n ctx.beginPath();\r\n ctx.arc(wob(rng, s * 0.04), wob(rng, s * 0.04), s * 0.32, 0, Math.PI * 2);\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const o = s * 0.4;\r\n const i = o * (0.2 + rng() * 0.12);\r\n ctx.beginPath();\r\n ctx.moveTo(0, -o);\r\n ctx.quadraticCurveTo(i, -i, o, 0);\r\n ctx.quadraticCurveTo(i, i, 0, o);\r\n ctx.quadraticCurveTo(-i, i, -o, 0);\r\n ctx.quadraticCurveTo(-i, -i, 0, -o);\r\n ctx.stroke();\r\n },\r\n (ctx, s, rng) => {\r\n const q = s * 0.4;\r\n ctx.beginPath();\r\n ctx.moveTo(-q, wob(rng, s * 0.08));\r\n ctx.quadraticCurveTo(0, wob(rng, s * 0.16), q, wob(rng, s * 0.08));\r\n ctx.stroke();\r\n },\r\n];\r\n\r\n// One per theme, drawn rarely and a touch brighter than the field around it.\r\nconst accents: Record<string, Glyph> = {\r\n light: (ctx, s) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.moveTo(0, -q);\r\n ctx.quadraticCurveTo(q * 0.16, -q * 0.16, q, 0);\r\n ctx.quadraticCurveTo(q * 0.16, q * 0.16, 0, q);\r\n ctx.quadraticCurveTo(-q * 0.16, q * 0.16, -q, 0);\r\n ctx.quadraticCurveTo(-q * 0.16, -q * 0.16, 0, -q);\r\n ctx.stroke();\r\n },\r\n dark: (ctx, s) => {\r\n const q = s * 0.44;\r\n ctx.beginPath();\r\n ctx.moveTo(-q * 0.6, -q * 0.5);\r\n ctx.lineTo(q * 0.6, -q * 0.5);\r\n ctx.lineTo(q, q * 0.05);\r\n ctx.lineTo(0, q);\r\n ctx.lineTo(-q, q * 0.05);\r\n ctx.closePath();\r\n ctx.moveTo(-q, q * 0.05);\r\n ctx.lineTo(q, q * 0.05);\r\n ctx.moveTo(-q * 0.6, -q * 0.5);\r\n ctx.lineTo(-q * 0.3, q * 0.05);\r\n ctx.lineTo(0, q);\r\n ctx.moveTo(q * 0.6, -q * 0.5);\r\n ctx.lineTo(q * 0.3, q * 0.05);\r\n ctx.lineTo(0, q);\r\n ctx.stroke();\r\n },\r\n mahogany: (ctx, s) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.moveTo(0, q);\r\n ctx.bezierCurveTo(-q * 0.9, q * 0.2, -q * 0.7, -q * 0.7, 0, -q);\r\n ctx.bezierCurveTo(q * 0.7, -q * 0.7, q * 0.9, q * 0.2, 0, q);\r\n ctx.moveTo(0, q * 0.86);\r\n ctx.lineTo(0, -q * 0.86);\r\n for (let i = 0; i < 3; i++) {\r\n const t = -0.34 + i * 0.36;\r\n ctx.moveTo(0, q * t);\r\n ctx.lineTo(q * 0.44, q * (t - 0.26));\r\n ctx.moveTo(0, q * t);\r\n ctx.lineTo(-q * 0.44, q * (t - 0.26));\r\n }\r\n ctx.stroke();\r\n },\r\n blush: (ctx, s) => {\r\n const q = s * 0.5;\r\n for (let i = 0; i < 5; i++) {\r\n const a = (i / 5) * Math.PI * 2 - Math.PI / 2;\r\n ctx.beginPath();\r\n ctx.ellipse(Math.cos(a) * q * 0.52, Math.sin(a) * q * 0.52, q * 0.42, q * 0.26, a, 0, Math.PI * 2);\r\n ctx.stroke();\r\n }\r\n ctx.beginPath();\r\n ctx.arc(0, 0, q * 0.19, 0, Math.PI * 2);\r\n ctx.stroke();\r\n },\r\n coffee: (ctx, s) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n ctx.ellipse(0, 0, q * 0.6, q * 0.9, 0, 0, Math.PI * 2);\r\n ctx.stroke();\r\n ctx.beginPath();\r\n ctx.moveTo(0, -q * 0.84);\r\n ctx.bezierCurveTo(q * 0.34, -q * 0.3, -q * 0.34, q * 0.3, 0, q * 0.84);\r\n ctx.stroke();\r\n },\r\n midnight: (ctx, s) => {\r\n const q = s * 0.5;\r\n ctx.beginPath();\r\n for (let i = 0; i < 10; i++) {\r\n const r = i % 2 === 0 ? q : q * 0.4;\r\n const a = (i / 10) * Math.PI * 2 - Math.PI / 2;\r\n const x = Math.cos(a) * r;\r\n const y = Math.sin(a) * r;\r\n if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);\r\n }\r\n ctx.closePath();\r\n ctx.stroke();\r\n },\r\n};\r\n\r\nconst rgb = (s: string): [number, number, number] => {\r\n const p = s.split(',').map(n => parseFloat(n.trim()));\r\n return [p[0] || 0, p[1] || 0, p[2] || 0];\r\n};\r\n\r\nfunction mix(a: string, b: string, k: number): string {\r\n const A = rgb(a);\r\n const B = rgb(b);\r\n return `rgb(${Math.round(A[0] + (B[0] - A[0]) * k)},${Math.round(A[1] + (B[1] - A[1]) * k)},${Math.round(A[2] + (B[2] - A[2]) * k)})`;\r\n}\r\n\r\ninterface DoodleGlyph {\r\n x: number;\r\n y: number;\r\n roll: number;\r\n rotation: number;\r\n lineWidth: number;\r\n alpha: number;\r\n baseColor: string;\r\n shimmerColor: string;\r\n drawFn: (ctx: CanvasRenderingContext2D, size: number, rng: Rng) => void;\r\n size: number;\r\n seed: number;\r\n normDist: number;\r\n}\r\n\r\nfunction getShimmerColor(seed: number, normDist: number, isDarkMode: boolean): string {\r\n // Exact rainbow spectrum as the animated placeholder text (0 -> 300 hue)\r\n const hue = Math.round((normDist * 300) % 360);\r\n const sat = isDarkMode ? 72 : 68;\r\n const light = isDarkMode ? 58 : 46;\r\n return `hsl(${hue}, ${sat}%, ${light}%)`;\r\n}\r\n\r\nfunction generateGlyphs(\r\n w: number,\r\n h: number,\r\n ink: string,\r\n tint: string,\r\n seed: number,\r\n isRTL: boolean,\r\n themeId?: string,\r\n): DoodleGlyph[] {\r\n const accent = themeId ? accents[themeId] : undefined;\r\n const rng = mulberry32(seed);\r\n const noise = makeNoise(mulberry32(seed ^ 0x9e3779b9));\r\n\r\n const area = w * h;\r\n const target = Math.max(40, Math.min(520, Math.round(area / 3100)));\r\n const raw = target / 0.48;\r\n const r = Math.max(26, Math.sqrt((0.7 * area) / raw));\r\n const pts = poisson(w, h, r, rng);\r\n\r\n const fa = 4.4 / Math.max(w, h);\r\n const fb = fa * 2.6;\r\n const reach = Math.hypot(w, h);\r\n const angle = rng() * Math.PI * 2;\r\n const ca = Math.cos(angle);\r\n const sa = Math.sin(angle);\r\n const poleX = w * (0.18 + rng() * 0.64);\r\n const poleY = h * (0.12 + rng() * 0.5);\r\n\r\n const glyphs: DoodleGlyph[] = [];\r\n const maxDist = Math.hypot(w, h) || 1;\r\n // light ink means it is being drawn onto a dark surface\r\n const [ir, ig, ib] = ink.split(',').map(n => parseFloat(n) || 0);\r\n const isDarkMode = 0.2126 * ir + 0.7152 * ig + 0.0722 * ib > 128;\r\n\r\n for (const [x, y] of pts) {\r\n const d = noise(x * fa, y * fa) * 0.72 + noise(x * fb, y * fb) * 0.28;\r\n const t = Math.min(1, Math.max(0, (d - 0.26) / 0.44));\r\n if (rng() > t * t * (3 - 2 * t)) continue;\r\n const roll = rng();\r\n const bloom = Math.max(0, 1 - Math.hypot(x - poleX, y - poleY) / (reach * 0.72)) ** 1.6;\r\n const axis = ((x - w / 2) * ca + (y - h / 2) * sa) / reach + 0.5;\r\n const isLightMode = !isDarkMode;\r\n const alphaBase = isLightMode ? 0.055 : 0.028;\r\n const alpha = (alphaBase + rng() * (isLightMode ? 0.04 : 0.025)) * (0.75 + axis * 0.55) * (1 + bloom * 0.4);\r\n\r\n const baseColor = mix(ink, tint, bloom * 0.85);\r\n // RTL: from Bottom-Right (w, h) to Top-Left (0, 0)\r\n // LTR: from Top-Left (0, 0) to Bottom-Right (w, h)\r\n const normDist = isRTL\r\n ? (w - x + h - y) / (w + h || 1)\r\n : (x + y) / (w + h || 1);\r\n\r\n const glyphSeed = (rng() * 0xffffff) | 0;\r\n const shimmerColor = getShimmerColor(glyphSeed, normDist, isDarkMode);\r\n\r\n let rotation = 0;\r\n let lineWidth = isLightMode ? 1.05 + rng() * 0.35 : 0.65 + rng() * 0.35;\r\n let size = 20;\r\n let drawFn = motifs[0];\r\n let alphaMul = 1;\r\n\r\n if (roll < 0.5) {\r\n rotation = wob(rng, 0.16);\r\n lineWidth = isLightMode ? 1.15 + rng() * 0.45 : 0.7 + rng() * 0.35;\r\n size = 20 + rng() * 16;\r\n drawFn = motifs[(rng() * motifs.length) | 0];\r\n } else if (roll < 0.82) {\r\n rotation = rng() * Math.PI * 2;\r\n lineWidth = isLightMode ? 0.95 + rng() * 0.4 : 0.6 + rng() * 0.4;\r\n size = 16 + rng() * 20;\r\n drawFn = scribbles[(rng() * scribbles.length) | 0];\r\n } else if (roll < 0.95 || !accent) {\r\n rotation = rng() * Math.PI * 2;\r\n lineWidth = isLightMode ? 0.85 + rng() * 0.35 : 0.55 + rng() * 0.35;\r\n size = 7 + rng() * 7;\r\n drawFn = specks[(rng() * specks.length) | 0];\r\n } else {\r\n rotation = wob(rng, 0.3);\r\n lineWidth = isLightMode ? 1.1 + rng() * 0.3 : 0.75 + rng() * 0.3;\r\n size = 15 + rng() * 9;\r\n drawFn = accent;\r\n alphaMul = 2.6;\r\n }\r\n\r\n glyphs.push({\r\n x,\r\n y,\r\n roll,\r\n rotation,\r\n lineWidth,\r\n alpha: alpha * alphaMul,\r\n baseColor,\r\n shimmerColor,\r\n drawFn,\r\n size,\r\n seed: glyphSeed,\r\n normDist,\r\n });\r\n }\r\n\r\n return glyphs;\r\n}\r\n\r\nfunction renderDoodles(\r\n ctx: CanvasRenderingContext2D,\r\n glyphs: DoodleGlyph[],\r\n w: number,\r\n h: number,\r\n shimmerProgress: number,\r\n) {\r\n ctx.clearRect(0, 0, w, h);\r\n ctx.lineCap = 'round';\r\n ctx.lineJoin = 'round';\r\n\r\n // Active smooth fluid shimmer wave (-0.2 to 1.4)\r\n const isShimmering = shimmerProgress >= 0 && shimmerProgress <= 1.4;\r\n const wavePos = isShimmering ? shimmerProgress * 1.4 - 0.2 : -999;\r\n const waveWidth = 0.30;\r\n\r\n for (const g of glyphs) {\r\n let alpha = g.alpha;\r\n let stroke = g.baseColor;\r\n let lw = g.lineWidth;\r\n\r\n if (isShimmering) {\r\n const diff = g.normDist - wavePos;\r\n\r\n // Ahead of wave: subtle dormant state\r\n if (diff > waveWidth) {\r\n alpha = g.alpha * 0.45;\r\n stroke = g.baseColor;\r\n lw = g.lineWidth;\r\n }\r\n // Behind wave (wake): permanently awake resting state\r\n else if (diff < -waveWidth) {\r\n alpha = g.alpha;\r\n stroke = g.baseColor;\r\n lw = g.lineWidth;\r\n }\r\n // In wavefront beam: soft, delicate rainbow/silver glint\r\n else {\r\n const surge = Math.cos((diff / waveWidth) * (Math.PI / 2)) ** 2;\r\n alpha = g.alpha + surge * 0.08;\r\n stroke = surge > 0.08 ? mix(g.baseColor, g.shimmerColor, surge * 0.65) : g.baseColor;\r\n lw = g.lineWidth * (1 + surge * 0.2);\r\n }\r\n }\r\n\r\n ctx.save();\r\n ctx.translate(g.x, g.y);\r\n ctx.rotate(g.rotation);\r\n ctx.globalAlpha = Math.min(alpha, 1.0);\r\n ctx.strokeStyle = stroke;\r\n ctx.fillStyle = stroke;\r\n ctx.lineWidth = lw;\r\n\r\n const glyphRng = mulberry32(g.seed);\r\n g.drawFn(ctx, g.size, glyphRng);\r\n ctx.restore();\r\n }\r\n}\r\n\r\nconst KikuDoodles = React.memo(function KikuDoodles({\r\n seed = '',\r\n theme,\r\n dir,\r\n}: {\r\n seed?: string;\r\n theme?: string;\r\n dir?: string;\r\n}) {\r\n const ref = useRef<HTMLCanvasElement>(null);\r\n const isAnimatingRef = useRef(false);\r\n const animFrameRef = useRef(0);\r\n const cachedGlyphsRef = useRef<DoodleGlyph[] | null>(null);\r\n const lastWidthRef = useRef<number>(0);\r\n\r\n useEffect(() => {\r\n const cv = ref.current;\r\n if (!cv) return;\r\n\r\n const numeric = hashSeed(seed || 'kiku');\r\n let timer = 0;\r\n\r\n const tick = (startTime: number, duration: number, glyphs: DoodleGlyph[], isRTL: boolean) => (now: number) => {\r\n const elapsed = now - startTime;\r\n const rawProgress = Math.min(1, elapsed / duration);\r\n const eased = (1 - Math.cos(rawProgress * Math.PI)) / 2;\r\n const progress = eased * 1.4;\r\n\r\n const w = cv.clientWidth;\r\n const h = cv.clientHeight;\r\n if (w && h) {\r\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\r\n const targetW = Math.round(w * dpr);\r\n const targetH = Math.round(h * dpr);\r\n if (cv.width !== targetW || cv.height !== targetH) {\r\n cv.width = targetW;\r\n cv.height = targetH;\r\n }\r\n const ctx = cv.getContext('2d');\r\n if (ctx) {\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n renderDoodles(ctx, glyphs, w, h, progress);\r\n }\r\n }\r\n\r\n if (rawProgress < 1) {\r\n animFrameRef.current = requestAnimationFrame(tick(startTime, duration, glyphs, isRTL));\r\n } else {\r\n isAnimatingRef.current = false;\r\n const w = cv.clientWidth;\r\n const h = cv.clientHeight;\r\n const ctx = cv.getContext('2d');\r\n if (ctx && w && h) {\r\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n renderDoodles(ctx, glyphs, w, h, -1);\r\n }\r\n }\r\n };\r\n\r\n const updateCanvas = () => {\r\n const w = cv.clientWidth;\r\n const h = cv.clientHeight;\r\n if (!w || !h) return;\r\n\r\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\r\n const ctx = cv.getContext('2d');\r\n if (!ctx) return;\r\n\r\n const cs = getComputedStyle(cv);\r\n const ink = cs.getPropertyValue('--hsk-doodle-ink').trim() || '31,31,31';\r\n const tint = cs.getPropertyValue('--hsk-doodle-tint').trim() || ink;\r\n const isRTL = dir === 'rtl' || cs.direction === 'rtl' || cv.closest('[dir=\"rtl\"]') !== null;\r\n\r\n const fullScreenH = typeof window !== 'undefined' ? Math.max(h, window.innerHeight || 0) : h;\r\n\r\n const glyphs = generateGlyphs(w, fullScreenH, ink, tint, numeric, isRTL, theme);\r\n cachedGlyphsRef.current = glyphs;\r\n lastWidthRef.current = w;\r\n\r\n const targetW = Math.round(w * dpr);\r\n const targetH = Math.round(h * dpr);\r\n if (cv.width !== targetW || cv.height !== targetH) {\r\n cv.width = targetW;\r\n cv.height = targetH;\r\n }\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n\r\n const reducedMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;\r\n\r\n if (reducedMotion) {\r\n renderDoodles(ctx, glyphs, w, h, -1);\r\n return;\r\n }\r\n\r\n cancelAnimationFrame(animFrameRef.current);\r\n isAnimatingRef.current = true;\r\n const duration = 1200;\r\n const startTime = performance.now();\r\n animFrameRef.current = requestAnimationFrame(tick(startTime, duration, glyphs, isRTL));\r\n };\r\n\r\n const handleResize = () => {\r\n clearTimeout(timer);\r\n timer = window.setTimeout(updateCanvas, 20);\r\n };\r\n\r\n updateCanvas();\r\n\r\n const ro = new ResizeObserver(handleResize);\r\n ro.observe(cv);\r\n const scheme = window.matchMedia?.('(prefers-color-scheme: dark)');\r\n const handleSchemeChange = () => {\r\n updateCanvas();\r\n };\r\n scheme?.addEventListener?.('change', handleSchemeChange);\r\n\r\n return () => {\r\n clearTimeout(timer);\r\n cancelAnimationFrame(animFrameRef.current);\r\n isAnimatingRef.current = false;\r\n ro.disconnect();\r\n scheme?.removeEventListener?.('change', handleSchemeChange);\r\n };\r\n }, [seed, theme, dir]);\r\n\r\n return <canvas className=\"hsk-cb-doodles\" ref={ref} aria-hidden=\"true\" />;\r\n});\r\n\r\nexport default KikuDoodles;\r\n","import React, { useState, useEffect, useCallback } from 'react';\r\nimport type { ScriptFont, AkropolysTheme } from '@akropolys/sdk';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport { useScriptFontFace, preloadScriptFont } from '../../../utils/hostFont';\r\nimport { cachedBaseFont } from '../../../utils/chromeWarm';\r\nimport { DEFAULT_UI_STRINGS, getLoadingMeta, type UIStringKey } from '../types';\r\nimport BUILTIN_LOCALES from '../locales.json';\r\n\r\nexport interface UseScriptFontOptions {\r\n shopperLanguage: string;\r\n theme?: 'light' | 'dark' | AkropolysTheme;\r\n}\r\n\r\nfunction getBuiltinLocale(lang: string): { strings: Record<string, string>; dir: string; bcp47: string } | null {\r\n if (!lang) return null;\r\n const l = lang.trim().toLowerCase();\r\n const map: Record<string, string> = {\r\n english: 'english',\r\n en: 'english',\r\n swahili: 'swahili',\r\n kiswahili: 'swahili',\r\n sw: 'swahili',\r\n french: 'french',\r\n français: 'french',\r\n francais: 'french',\r\n fr: 'french',\r\n spanish: 'spanish',\r\n español: 'spanish',\r\n espanol: 'spanish',\r\n es: 'spanish',\r\n arabic: 'arabic',\r\n 'العربية': 'arabic',\r\n ar: 'arabic',\r\n portuguese: 'portuguese',\r\n português: 'portuguese',\r\n pt: 'portuguese',\r\n hindi: 'hindi',\r\n 'हिन्दी': 'hindi',\r\n hi: 'hindi',\r\n chinese: 'chinese',\r\n '中文': 'chinese',\r\n zh: 'chinese',\r\n japanese: 'japanese',\r\n '日本語': 'japanese',\r\n ja: 'japanese',\r\n urdu: 'urdu',\r\n 'اردو': 'urdu',\r\n ur: 'urdu',\r\n };\r\n const key = map[l];\r\n if (!key || !(key in BUILTIN_LOCALES)) return null;\r\n const raw = (BUILTIN_LOCALES as Record<string, Record<string, string>>)[key];\r\n const isRtl = key === 'arabic' || key === 'urdu';\r\n const bcp = key === 'arabic' ? 'ar' :\r\n key === 'hindi' ? 'hi' :\r\n key === 'chinese' ? 'zh' :\r\n key === 'japanese' ? 'ja' :\r\n key === 'urdu' ? 'ur' :\r\n key === 'swahili' ? 'sw' :\r\n key === 'french' ? 'fr' :\r\n key === 'spanish' ? 'es' :\r\n key === 'portuguese' ? 'pt' : 'en';\r\n return {\r\n strings: raw,\r\n dir: isRtl ? 'rtl' : 'ltr',\r\n bcp47: bcp,\r\n };\r\n}\r\n\r\nfunction resolveFirstFamily(varRef: string): string {\r\n const name = /var\\(\\s*(--[\\w-]+)/.exec(varRef)?.[1];\r\n if (!name || typeof document === 'undefined') return '';\r\n for (const el of [document.documentElement, document.body]) {\r\n const value = el ? getComputedStyle(el).getPropertyValue(name).trim() : '';\r\n if (value) return value.split(',')[0].trim();\r\n }\r\n return '';\r\n}\r\n\r\nexport function useScriptFont({ shopperLanguage, theme }: UseScriptFontOptions) {\r\n const client = useAkropolysContext();\r\n const [chromeStrings, setChromeStrings] = useState<Record<string, string>>(() => {\r\n const builtin = getBuiltinLocale(shopperLanguage);\r\n return builtin?.strings || {};\r\n });\r\n const [chromeCurated, setChromeCurated] = useState<boolean>(true);\r\n const [chromeReady, setChromeReady] = useState<boolean>(() => {\r\n return !shopperLanguage || !!getBuiltinLocale(shopperLanguage);\r\n });\r\n\r\n const dirKey = shopperLanguage ? `akropolys_ui_dir_${shopperLanguage.toLowerCase()}` : '';\r\n const [isRTL, setIsRTL] = useState<boolean>(() => {\r\n const builtin = getBuiltinLocale(shopperLanguage);\r\n if (builtin) return builtin.dir === 'rtl';\r\n const meta = getLoadingMeta(shopperLanguage);\r\n if (meta?.rtl) return true;\r\n if (typeof window === 'undefined' || !dirKey) return false;\r\n try { return localStorage.getItem(dirKey) === 'rtl'; } catch { return false; }\r\n });\r\n const [speechLang, setSpeechLang] = useState(() => {\r\n return getBuiltinLocale(shopperLanguage)?.bcp47 || '';\r\n });\r\n const [scriptFont, setScriptFont] = useState<ScriptFont | null>(null);\r\n const [baseFont, setBaseFont] = useState<ScriptFont | null>(null);\r\n\r\n useEffect(() => {\r\n if (!shopperLanguage) {\r\n setSpeechLang('');\r\n setScriptFont(null);\r\n setChromeStrings({});\r\n setChromeReady(true);\r\n setIsRTL(false);\r\n return;\r\n }\r\n const builtin = getBuiltinLocale(shopperLanguage);\r\n const meta = getLoadingMeta(shopperLanguage);\r\n const lLower = shopperLanguage.trim().toLowerCase();\r\n const isUrdu = lLower === 'urdu' || lLower === 'ur' || shopperLanguage.trim() === 'اردو';\r\n const needsWebFont = isUrdu || !builtin;\r\n\r\n if (builtin) {\r\n setChromeStrings(builtin.strings);\r\n setIsRTL(builtin.dir === 'rtl');\r\n setSpeechLang(builtin.bcp47);\r\n setChromeReady(!needsWebFont);\r\n } else {\r\n if (meta?.rtl) setIsRTL(true);\r\n setChromeReady(false);\r\n }\r\n\r\n let cancelled = false;\r\n (async () => {\r\n try {\r\n const res = await client.getUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS);\r\n if (!cancelled && res?.complete) {\r\n setChromeCurated(res.curated !== false);\r\n setChromeStrings(prev => ({ ...res.strings, ...(builtin?.strings || {}) }));\r\n setIsRTL(res.dir === 'rtl');\r\n setSpeechLang(res.bcp47 || builtin?.bcp47 || '');\r\n try { localStorage.setItem(dirKey, res.dir); } catch { }\r\n if (res.font) {\r\n await preloadScriptFont(res.font, 1200);\r\n if (!cancelled) setScriptFont(res.font);\r\n }\r\n }\r\n } catch {\r\n /* Builtin or defaults */\r\n }\r\n if (!cancelled) setChromeReady(true);\r\n })();\r\n return () => { cancelled = true; };\r\n }, [shopperLanguage, dirKey, client]);\r\n\r\n useEffect(() => {\r\n let cancelled = false;\r\n (async () => {\r\n try {\r\n const f = await cachedBaseFont(client);\r\n if (!cancelled && f) setBaseFont(f);\r\n } catch {\r\n\r\n }\r\n })();\r\n return () => { cancelled = true; };\r\n }, [client]);\r\n\r\n useScriptFontFace(scriptFont);\r\n useScriptFontFace(baseFont);\r\n\r\n const fontStack = React.useMemo(() => {\r\n const declared = typeof theme === 'object' && theme?.fontFamily ? theme.fontFamily : '';\r\n const first = declared.split(',')[0].trim();\r\n const isVarRef = /^var\\(/i.test(first);\r\n const hostName = first.replace(/^['\"]|['\"]$/g, '');\r\n const resolved = isVarRef ? resolveFirstFamily(first) : '';\r\n const host = isVarRef\r\n ? (resolved ? `${resolved}, ` : '')\r\n : (hostName ? `\"${hostName}\", ` : '');\r\n\r\n if (scriptFont) {\r\n return `\"${scriptFont.family}\", ${host}\"Geist\", system-ui, sans-serif`;\r\n }\r\n\r\n const l = shopperLanguage ? shopperLanguage.trim().toLowerCase() : '';\r\n if (l === 'japanese' || l === 'ja' || l === '日本語') {\r\n return `${host}\"Geist\", \"Hiragino Sans\", \"Hiragino Kaku Gothic ProN\", \"Yu Gothic\", \"Meiryo\", system-ui, sans-serif`;\r\n }\r\n if (l === 'chinese' || l === 'zh' || l === '中文') {\r\n return `${host}\"Geist\", \"PingFang SC\", \"Microsoft YaHei\", \"Hiragino Sans GB\", system-ui, sans-serif`;\r\n }\r\n if (l === 'urdu' || l === 'ur' || l === 'اردو') {\r\n return `\"Noto Nastaliq Urdu\", ${host}\"IBM Plex Sans Arabic\", \"Geist\", system-ui, sans-serif`;\r\n }\r\n if (l === 'arabic' || l === 'ar' || l === 'العربية') {\r\n return `\"IBM Plex Sans Arabic\", ${host}\"Geist\", system-ui, sans-serif`;\r\n }\r\n if (l === 'hindi' || l === 'hi' || l === 'हिन्दी') {\r\n return `\"Hind\", ${host}\"Geist\", system-ui, sans-serif`;\r\n }\r\n\r\n return undefined;\r\n }, [scriptFont, shopperLanguage, typeof theme === 'object' && theme ? theme.fontFamily : undefined]);\r\n\r\n const isNonLatin = React.useMemo(() => {\r\n let latin = 0;\r\n let other = 0;\r\n for (const v of Object.values(chromeStrings)) {\r\n for (const ch of v) {\r\n const c = ch.codePointAt(0) ?? 0;\r\n if (c < 0x00c0) continue;\r\n if (!/\\p{L}/u.test(ch)) continue;\r\n if (c <= 0x024f) latin++;\r\n else other++;\r\n }\r\n }\r\n return other > latin;\r\n }, [chromeStrings]);\r\n\r\n const [fontEpoch, setFontEpoch] = useState(0);\r\n useEffect(() => {\r\n if (typeof document === 'undefined' || !(document as any).fonts?.ready) return;\r\n let live = true;\r\n (document as any).fonts.ready.then(() => {\r\n if (live) setFontEpoch(e => e + 1);\r\n });\r\n return () => { live = false; };\r\n }, [scriptFont]);\r\n\r\n const hostFontCovers = React.useMemo(() => {\r\n if (!isNonLatin || typeof document === 'undefined') return true;\r\n const declared = typeof theme === 'object' && theme?.fontFamily ? theme.fontFamily : '';\r\n const first = declared.split(',')[0].trim();\r\n if (!first) return false;\r\n let sample = '';\r\n for (const v of Object.values(chromeStrings)) {\r\n if (v) { sample = v; break; }\r\n }\r\n if (!sample) return true;\r\n const text = sample.replace(/\\s+/g, '');\r\n if (!text) return true;\r\n try {\r\n const canvas = document.createElement('canvas');\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return true;\r\n const hostFamily = first.startsWith('var(')\r\n ? getComputedStyle(document.documentElement).getPropertyValue(first.slice(4, -1).trim()).trim() || first\r\n : first;\r\n ctx.font = `16px ${hostFamily}, __akropolys_nonexistent_font__`;\r\n const withHost = ctx.measureText(text).width;\r\n ctx.font = '16px __akropolys_nonexistent_font__';\r\n const withoutHost = ctx.measureText(text).width;\r\n return Math.abs(withHost - withoutHost) > 1;\r\n } catch {\r\n return true;\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isNonLatin, chromeStrings, typeof theme === 'object' && theme ? theme.fontFamily : undefined, fontEpoch]);\r\n\r\n const t = useCallback((key: UIStringKey, vars?: Record<string, string>): string => {\r\n let s: string = chromeStrings[key] || DEFAULT_UI_STRINGS[key] || key;\r\n if (vars) {\r\n for (const [k, v] of Object.entries(vars)) s = s.split(`{${k}}`).join(v);\r\n }\r\n return s;\r\n }, [chromeStrings]);\r\n\r\n const tNode = useCallback((key: UIStringKey, vars: Record<string, string>) => {\r\n const s = chromeStrings[key] || DEFAULT_UI_STRINGS[key] || key;\r\n return s.split(/(\\{[a-zA-Z]+\\})/g).map((part, i) => {\r\n const m = part.match(/^\\{([a-zA-Z]+)\\}$/);\r\n if (m && vars[m[1]] !== undefined) return <bdi key={i}>{vars[m[1]]}</bdi>;\r\n return <React.Fragment key={i}>{part}</React.Fragment>;\r\n });\r\n }, [chromeStrings]);\r\n\r\n return {\r\n chromeStrings,\r\n chromeReady,\r\n chromeCurated,\r\n isRTL,\r\n speechLang,\r\n scriptFont,\r\n fontStack,\r\n isNonLatin,\r\n hostFontCovers,\r\n t,\r\n tNode,\r\n };\r\n}\r\n","{\n \"arabic\": {\n \"allSet\": \"أنت جاهز، {name}.\",\n \"asWritten\": \"كما هي مكتوبة\",\n \"captureAll\": \"التقاط الكل ({count})\",\n \"captureAndRemember\": \"kiku — التقاط وتذكر\",\n \"captureCurrentPage\": \"التقاط الصفحة الحالية\",\n \"cardClickAnswer\": \"الـ {name}\",\n \"cardClickQuery\": \"أخبرني المزيد عن {name}{price} — ما هي تفاصيله الرئيسية، ولمن هو الأنسب، وماذا يجب أن أعرف؟\",\n \"clearChat\": \"مسح الدردشة\",\n \"defaultPlaceholder\": \"اسألني أي شيء...\",\n \"deleteThis\": \"حذف هذا\",\n \"detailsTranslated\": \"تمت ترجمة التفاصيل. تبقى الأرقام والروابط كما هي تمامًا.\",\n \"displayCapture\": \"التقاط {name}\",\n \"displayCaptureAll\": \"التقاط الكل ({count} عناصر)\",\n \"displayDelete\": \"حذف هذا\",\n \"displayViewHistory\": \"ماذا حفظت؟\",\n \"entityLangIntro\": \"أرد بـ {lang}. يمكن عرض البطاقات كما هي أو ترجمتها.\",\n \"entityLangPlaceholder\": \"اختر إحدى البطاقتين أعلاه...\",\n \"errAccessRevoked\": \"تم إلغاء وصولك إلى المساعد من قبل المتجر.\",\n \"errAccountRequired\": \"الرجاء إنشاء حساب لمتابعة استخدام مساعد الدردشة.\",\n \"errShopperReplyLimit\": \"لقد وصلت إلى حد الردود المسموح به لحسابك في هذا الموقع.\",\n \"errStreamInterrupted\": \"تمت مقاطعة الرد. الرجاء المحاولة مرة أخرى.\",\n \"errTokenLimit\": \"لقد وصلت إلى حد الاستخدام الخاص بك. الرجاء تحديث حدود الفواتير في لوحة التحكم الخاصة بك للمتابعة.\",\n \"errTooManyRequests\": \"يتلقى المساعد حاليًا عددًا كبيرًا جدًا من الطلبات. الرجاء المحاولة مرة أخرى بعد لحظات قليلة.\",\n \"footerHint\": \"kiku · يبحث في الكتالوج بأكمله في الوقت الفعلي\",\n \"greetReturning\": \"أهلاً، {name}.\",\n \"greetReturningLead\": \"ماذا يمكنني أن أجد لك اليوم؟\",\n \"howShouldResultsLook\": \"كيف يجب أن تبدو النتائج؟\",\n \"inLanguage\": \"بـ {lang}\",\n \"keyAutoHide\": \"يختفي تلقائيًا في {seconds} ثوانٍ.\",\n \"keyCopied\": \"تم النسخ\",\n \"keyCopyId\": \"نسخ المعرّف\",\n \"keyCopySecret\": \"نسخ السر\",\n \"keyCreateNew\": \"أنا جديد — أنشئ واحدًا\",\n \"keyCreating\": \"جارٍ الإنشاء…\",\n \"keyDismiss\": \"تجاهل\",\n \"keyPastePlaceholder\": \"معرّفك العام…\",\n \"keyPastePrompt\": \"الصق معرّفك العام — أو أنشئ واحدًا\",\n \"keyPublicHint\": \"الصقه في أي موقع للحفظ في نفس الذاكرة.\",\n \"keyPublicTitle\": \"معرّفك العام\",\n \"keySecretHint\": \"احتفظ به خاصًا — استخدمه لفتح ذاكرتك.\",\n \"keySecretTitle\": \"سرك — يُعرض مرة واحدة فقط\",\n \"keyUseMine\": \"استخدم معرّفي\",\n \"kikuActionUnavailable\": \"عذرًا — هذا الإجراء غير متاح على هذا الموقع.\",\n \"kikuCaptureDbError\": \"فشل الالتقاط بسبب خطأ في قاعدة البيانات.\",\n \"kikuCaptureNoContext\": \"فشل الالتقاط لأنه لم يتم توفير سياق الصفحة أو المنتج بواسطة SDK.\",\n \"kikuCaptureNoUrl\": \"تعذر حفظ أي عناصر — لم يكن لأي منها عنوان URL صالح.\",\n \"kikuCaptureNoneSelected\": \"لم يتم تحديد أي عناصر لالتقاطها.\",\n \"kikuDeleteDbError\": \"فشل الحذف بسبب خطأ في قاعدة البيانات.\",\n \"kikuDeleteDone\": \"تمت إزالته من العناصر المحفوظة لديك.\",\n \"kikuDeleteNoContext\": \"فشل الحذف لأنه لم يتم توفير سياق الصفحة لتحديد ما يجب حذفه.\",\n \"kikuMemoryIntro\": \"كل ما التقطته عبر المواقع موجود في ذاكرتك الخاصة. افتحها باستخدام سرك:\",\n \"kikuMintNeeded\": \"لحفظ العناصر عبر المواقع، تحتاج إلى مفتاح kiku — سأقوم بإنشاء واحد لك. يُعرض مرة واحدة فقط، لذا احفظه في مكان آمن.\",\n \"kikuMintOffer\": \"يمكنني الاحتفاظ بهذا لك ومتابعته معك عبر المواقع — سأقوم بإنشاء مفتاح kiku لك. يُعرض مرة واحدة فقط، لذا احفظه في مكان آمن.\",\n \"kikuNeedKeyToUpdate\": \"أدخل مفتاح kiku الخاص بك حتى أتمكن من العثور على العناصر المحفوظة لديك وتحديثها.\",\n \"micDenied\": \"تم حظر الميكروفون. اسمح بالوصول إلى الميكروفون لهذا الموقع، ثم حاول مرة أخرى.\",\n \"micFailed\": \"لم أتمكن من سماع ذلك. حاول مرة أخرى.\",\n \"micInsecure\": \"يتطلب الصوت اتصالاً آمنًا (https).\",\n \"micLangUnsupported\": \"لا يمكن لهذا المتصفح نسخ هذه اللغة بعد. يرجى الكتابة بدلاً من ذلك.\",\n \"micMissing\": \"لم يتم العثور على ميكروفون.\",\n \"micNetwork\": \"تتطلب ميزة الصوت اتصالاً الآن. يرجى التحقق من اتصالك والمحاولة مرة أخرى.\",\n \"micNoSpeech\": \"لم أسمع شيئًا. يرجى المحاولة مرة أخرى، واقترب قليلاً من الميكروفون.\",\n \"namePlaceholder\": \"اكتب اسمك...\",\n \"nameStepAsk\": \"ماذا يجب أن أناديك؟\",\n \"nameStepLead\": \"يمكنني البحث عن أي شيء أو تصوره أو التقاطه لك — في هذا الموقع أو أي موقع آخر.\",\n \"nameStepTitle\": \"سررت بلقائك.\",\n \"namesAsWritten\": \"الأسماء والتفاصيل تمامًا كما هي مدرجة في الموقع.\",\n \"pillCompareTop2\": \"قارن أفضل 2\",\n \"pillCompareTop2Query\": \"قارن بين {a} و {b}\",\n \"pillFindAlternatives\": \"ابحث عن بدائل\",\n \"pillFindAlternativesQuery\": \"ما هي البدائل الجيدة لـ {name}؟\",\n \"pillMoreOn\": \"المزيد عن {name}\",\n \"pillMoreOnQuery\": \"أخبرني المزيد عن {name}\",\n \"pillRecommend\": \"أوصِ بشيء\",\n \"pillRecommendQuery\": \"ماذا توصي لي؟\",\n \"pillShowPopular\": \"عرض العناصر الشائعة\",\n \"pillShowPopularQuery\": \"ما هي منتجاتك الأكثر شعبية؟\",\n \"pillSimilarOptions\": \"خيارات مشابهة\",\n \"pillSimilarOptionsQuery\": \"أرني المزيد المشابه لـ {name}\",\n \"pillUnder\": \"أقل من {amount}\",\n \"pillUnderQuery\": \"أظهر لي خيارات بسعر أقل من {amount}\",\n \"pillWhichBest\": \"أيهما الأفضل؟\",\n \"pillWhichBestQuery\": \"أيهما توصي ولماذا؟\",\n \"replyingOriginal\": \"أردّ باللغة {lang}، والنتائج كما كتبها هذا الموقع. اسألني أي شيء.\",\n \"replyingTranslated\": \"أردّ باللغة {lang}، والنتائج مترجمة أيضًا. اسألني أي شيء.\",\n \"statusSent\": \"تم الإرسال\",\n \"statusStopped\": \"تم الإرسال · تم إيقاف الرد\",\n \"thinking\": \"جاري التفكير\",\n \"thoughtForSeconds\": \"فكرت لمدة {duration}\",\n \"thoughtProcess\": \"عملية التفكير\",\n \"vizDisclaimerImage\": \"تم الإنشاء باستخدام الذكاء الاصطناعي — قد تختلف الألوان والحجم والموضع عن المنتج الحقيقي.\",\n \"vizDisclaimerVideo\": \"تم الإنشاء باستخدام الذكاء الاصطناعي — قد تختلف الألوان والحجم والحركة عن المنتج الحقيقي.\",\n \"vizUnavailable\": \"تعذر تحميل المعاينة.\",\n \"voiceListening\": \"جاري الاستماع... اضغط على الميكروفون للإيقاف\",\n \"voiceSending\": \"تمام — جاري الإرسال...\",\n \"termsStepTitle\": \"الخصوصية وشروط الاستخدام\",\n \"termsStepSubtitle\": \"شفافية كاملة، وهوية مجهولة، وبدون جمع أي بيانات شخصية.\",\n \"termsPiiTitle\": \"عدم جمع البيانات الشخصية\",\n \"termsPiiDesc\": \"نحن لا نجمع أو نطلب أو نخزن أي معلومات تعريف شخصية (لا بريد إلكتروني، لا أرقام هواتف، ولا هويات حقيقية) من محادثاتك أو جلساتك الصوتية.\",\n \"termsSessionTitle\": \"معرّفات جلسة مجهولة\",\n \"termsSessionDesc\": \"تستخدم جلستك معرّفًا مجهولاً من جانب العميل فقط للحفاظ على السياق، ولا يتم ربطه بهويتك الحقيقية أبداً.\",\n \"termsMemoryTitle\": \"محادثات مؤقتة مقابل خزينة ميمي\",\n \"termsMemoryDesc\": \"المحادثات العادية مؤقتة — إغلاق النافذة أو مسح الدردشة ينهيها نهائيًا. العناصر التي تحفظها عبر \\\"@kiku\\\" مشفرة ويمكن فتحها في mimi.akropolys.cloud باستخدام مفتاحك السري.\",\n \"termsCookieTitle\": \"بيانات تتبع الموقع المضيف\",\n \"termsCookieDesc\": \"قد يقوم الموقع المضيف بجمع ملفات تعريف الارتباط والتحليلات وفقًا لسياسة ملفات تعريف الارتباط الخاصة به، وهي خارجة عن سيطرة kiku.\",\n \"termsAgreeButton\": \"الموافقة والمتابعة\",\n \"termsAgreeCounting\": \"الموافقة والمتابعة ({seconds} ث)\",\n \"termsPlaceholder\": \"يرجى مراجعة وقبول الخصوصية والشروط أعلاه...\",\n \"whatHaveYouSaved\": \"ماذا حفظت؟\",\n \"voiceHint\": \"تحدث فقط — سأجيب عندما تتوقف.\",\n \"voiceModeExit\": \"الخروج من الوضع بدون استخدام اليدين\",\n \"voiceModeStart\": \"محادثة بدون استخدام اليدين\",\n \"voiceMuted\": \"مكتوم\",\n \"voiceMutedHint\": \"اضغط على الميكروفون للتحدث مرة أخرى.\",\n \"voicePhaseListening\": \"استماع\",\n \"voicePhaseSpeaking\": \"تحدث\",\n \"voicePhaseThinking\": \"تفكير\",\n \"retry\": \"إعادة المحاولة\",\n \"edit\": \"تعديل\",\n \"copy\": \"نسخ\",\n \"copied\": \"تم النسخ\",\n \"msgFailed\": \"فشل الإرسال\"\n },\n \"chinese\": {\n \"allSet\": \"您已准备好,{name}。\",\n \"asWritten\": \"如原文所示\",\n \"captureAll\": \"捕获全部({count})\",\n \"captureAndRemember\": \"kiku — 捕获并记住\",\n \"captureCurrentPage\": \"捕获当前页面\",\n \"cardClickAnswer\": \"{name}\",\n \"cardClickQuery\": \"告诉我更多关于 {name}{price} — 关键细节是什么,最适合谁,我需要了解什么?\",\n \"clearChat\": \"清除聊天\",\n \"defaultPlaceholder\": \"随便问我任何事…\",\n \"deleteThis\": \"删除此项\",\n \"detailsTranslated\": \"详情已翻译。数字和链接保持原样。\",\n \"displayCapture\": \"捕获 {name}\",\n \"displayCaptureAll\": \"捕获全部({count} 项)\",\n \"displayDelete\": \"删除此项\",\n \"displayViewHistory\": \"我保存了什么?\",\n \"entityLangIntro\": \"我会用 {lang} 回复。结果卡片可以保持网站原文,也可以翻译。\",\n \"entityLangPlaceholder\": \"从上面的两张卡片中选择一个…\",\n \"errAccessRevoked\": \"您的访问权限已被商店撤销。\",\n \"errAccountRequired\": \"请创建账户以继续使用聊天助手。\",\n \"errShopperReplyLimit\": \"您已达到此站点对您账户的回复上限。\",\n \"errStreamInterrupted\": \"回复被中断。请再试一次。\",\n \"errTokenLimit\": \"您已达到使用上限。请在仪表板中更新计费上限以继续。\",\n \"errTooManyRequests\": \"助手当前请求过多。请稍后再试。\",\n \"footerHint\": \"kiku · 实时搜索整个目录\",\n \"greetReturning\": \"您好,{name}。\",\n \"greetReturningLead\": \"今天我能为您找到什么?\",\n \"howShouldResultsLook\": \"结果应该是什么样子?\",\n \"inLanguage\": \"使用 {lang}\",\n \"namePlaceholder\": \"输入您的名字…\",\n \"nameStepAsk\": \"我该怎么称呼您?\",\n \"nameStepLead\": \"我可以为您搜索、可视化或捕获任何内容——在此站点或其他任何站点。\",\n \"nameStepTitle\": \"很高兴见到您。\",\n \"namesAsWritten\": \"名称和详情完全按站点列出。\",\n \"pillCompareTop2\": \"比较前两项\",\n \"pillCompareTop2Query\": \"比较 {a} 和 {b}\",\n \"pillFindAlternatives\": \"寻找替代品\",\n \"pillFindAlternativesQuery\": \"有什么好的替代品可以替代 {name}?\",\n \"pillMoreOn\": \"更多关于 {name}\",\n \"pillMoreOnQuery\": \"告诉我更多关于 {name}\",\n \"pillRecommend\": \"推荐一些东西\",\n \"pillRecommendQuery\": \"您会推荐什么给我?\",\n \"pillShowPopular\": \"显示热门项目\",\n \"pillShowPopularQuery\": \"您最受欢迎的项目是什么?\",\n \"pillSimilarOptions\": \"相似选项\",\n \"pillSimilarOptionsQuery\": \"展示更多类似 {name} 的内容\",\n \"pillUnder\": \"低于 {amount}\",\n \"pillUnderQuery\": \"展示低于 {amount} 的选项\",\n \"pillWhichBest\": \"哪一个最好?\",\n \"pillWhichBestQuery\": \"您会推荐哪一个,为什么?\",\n \"replyingOriginal\": \"用 {lang} 回复,结果保持网站原文。随便问我任何事。\",\n \"replyingTranslated\": \"用 {lang} 回复,结果也已翻译。随便问我任何事。\",\n \"statusSent\": \"已发送\",\n \"statusStopped\": \"已发送 · 回复已停止\",\n \"thinking\": \"思考中\",\n \"thoughtForSeconds\": \"思考了 {duration}\",\n \"thoughtProcess\": \"思考过程\",\n \"termsStepTitle\": \"隐私与使用条款\",\n \"termsStepSubtitle\": \"透明、匿名,从设计之初即零个人身份信息。\",\n \"termsPiiTitle\": \"零个人身份信息收集\",\n \"termsPiiDesc\": \"我们绝不会从您的对话或语音中收集或存储任何个人身份信息(无邮箱、电话号码或真实姓名)。\",\n \"termsSessionTitle\": \"匿名会话凭证\",\n \"termsSessionDesc\": \"您的会话仅使用客户端生成的匿名标识符来维持上下文,绝不与您的真实身份关联。\",\n \"termsMemoryTitle\": \"即时会话 vs. Mimi 记忆库\",\n \"termsMemoryDesc\": \"普通对话完全即时处理——关闭或清除聊天即可彻底销毁。使用 \\\"@kiku\\\" 保存的内容经过加密,可在 mimi.akropolys.cloud 使用您的私钥随时解锁。\",\n \"termsCookieTitle\": \"宿主网站遥测\",\n \"termsCookieDesc\": \"嵌入 kiku 的宿主网站可能会根据其自身的 Cookie 政策收集浏览数据,不受 kiku 控制。\",\n \"termsAgreeButton\": \"同意并继续\",\n \"termsAgreeCounting\": \"同意并继续 ({seconds}秒)\",\n \"termsPlaceholder\": \"请查阅并同意上方的隐私与条款…\",\n \"whatHaveYouSaved\": \"我保存了什么?\",\n \"keyAutoHide\": \"将在 {seconds} 秒后自动隐藏。\",\n \"keyCopied\": \"已复制\",\n \"keyCopyId\": \"复制 ID\",\n \"keyCopySecret\": \"复制密钥\",\n \"keyCreateNew\": \"我是新用户 — 创建一个\",\n \"keyCreating\": \"正在创建…\",\n \"keyDismiss\": \"关闭\",\n \"keyPastePlaceholder\": \"您的公开 ID…\",\n \"keyPastePrompt\": \"粘贴您的公开 ID — 或创建一个\",\n \"keyPublicHint\": \"在任何网站上粘贴此 ID 即可保存到相同的记忆库中。\",\n \"keyPublicTitle\": \"您的公开 ID\",\n \"keySecretHint\": \"请妥善保管 — 用于解锁您的记忆库。\",\n \"keySecretTitle\": \"您的密钥 — 仅显示一次\",\n \"keyUseMine\": \"使用我的 ID\",\n \"kikuActionUnavailable\": \"抱歉 — 此站点暂不支持该操作。\",\n \"kikuCaptureDbError\": \"由于数据库错误,保存失败。\",\n \"kikuCaptureNoContext\": \"由于未提供页面或产品上下文,保存失败。\",\n \"kikuCaptureNoUrl\": \"无法保存任何项目 — 均无有效网址。\",\n \"kikuCaptureNoneSelected\": \"未选择要保存的项目。\",\n \"kikuDeleteDbError\": \"由于数据库错误,删除失败。\",\n \"kikuDeleteDone\": \"已从保存的项目中移除。\",\n \"kikuDeleteNoContext\": \"未提供页面上下文以确定要删除的内容。\",\n \"kikuMemoryIntro\": \"您在各站点保存的所有内容均存储在您的私有记忆库中。使用您的密钥解锁:\",\n \"kikuMintNeeded\": \"要在跨站点保存项目,您需要一个 kiku 密钥 — 我将为您生成一个。该密钥仅显示一次,请妥善保存。\",\n \"kikuMintOffer\": \"我可以为您保存并跟随您跨站点同步 — 我将为您生成一个 kiku 密钥。仅显示一次,请妥善保存。\",\n \"kikuNeedKeyToUpdate\": \"输入您的 kiku 密钥以便我查找并更新您保存的项目。\",\n \"micDenied\": \"麦克风已被阻止。请允许此站点访问麦克风,然后重试。\",\n \"micFailed\": \"未能听清。请重试。\",\n \"micInsecure\": \"语音功能需要安全连接 (HTTPS)。\",\n \"micLangUnsupported\": \"此浏览器暂不支持该语言的语音转录。请使用文字输入。\",\n \"micMissing\": \"未找到麦克风。\",\n \"micNetwork\": \"语音功能需要网络连接。请检查网络后重试。\",\n \"micNoSpeech\": \"未检测到声音。请靠近麦克风后重试。\",\n \"vizDisclaimerImage\": \"由人工智能生成 — 颜色、尺寸和位置可能与实物略有不同。\",\n \"vizDisclaimerVideo\": \"由人工智能生成 — 颜色、尺寸和动作可能与实物略有不同。\",\n \"vizUnavailable\": \"无法加载预览。\",\n \"voiceHint\": \"直接说话即可 — 您停顿后我会回答。\",\n \"voiceListening\": \"正在聆听… 点击麦克风停止\",\n \"voiceModeExit\": \"退出免提模式\",\n \"voiceModeStart\": \"免提对话\",\n \"voiceMuted\": \"静音\",\n \"voiceMutedHint\": \"点击麦克风重新开始说话。\",\n \"voicePhaseListening\": \"正在聆听\",\n \"voicePhaseSpeaking\": \"正在回答\",\n \"voicePhaseThinking\": \"正在思考\",\n \"voiceSending\": \"已收到 — 正在发送…\",\n \"retry\": \"重试\",\n \"edit\": \"编辑\",\n \"copy\": \"复制\",\n \"copied\": \"已复制\",\n \"msgFailed\": \"发送失败\"\n },\n \"english\": {\n \"allSet\": \"You're all set, {name}.\",\n \"asWritten\": \"As written\",\n \"captureAll\": \"Capture all ({count})\",\n \"captureAndRemember\": \"kiku — capture & remember\",\n \"captureCurrentPage\": \"Capture current page\",\n \"cardClickAnswer\": \"The {name}\",\n \"cardClickQuery\": \"Tell me more about the {name}{price} — what are its key details, who is it best suited for, and what should I know?\",\n \"clearChat\": \"Clear chat\",\n \"defaultPlaceholder\": \"Ask me anything…\",\n \"deleteThis\": \"Delete this\",\n \"detailsTranslated\": \"Details translated. Numbers and links stay exactly as listed.\",\n \"displayCapture\": \"capture {name}\",\n \"displayCaptureAll\": \"capture all ({count} items)\",\n \"displayDelete\": \"delete this\",\n \"displayViewHistory\": \"what have you saved?\",\n \"entityLangIntro\": \"I reply in {lang}. Result cards can stay as written, or be translated too.\",\n \"entityLangPlaceholder\": \"Pick one of the two cards above…\",\n \"errAccessRevoked\": \"Your access to the assistant has been revoked by the store.\",\n \"errAccountRequired\": \"Please create an account to continue using the chat assistant.\",\n \"errShopperReplyLimit\": \"You've reached this site's reply limit for your account.\",\n \"errStreamInterrupted\": \"The reply was interrupted. Please try again.\",\n \"errTokenLimit\": \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\",\n \"errTooManyRequests\": \"The assistant is currently receiving too many requests. Please try again in a few moments.\",\n \"footerHint\": \"kiku · searches the whole catalogue in real time\",\n \"greetReturning\": \"Hi, {name}.\",\n \"greetReturningLead\": \"What can I find for you today?\",\n \"howShouldResultsLook\": \"How should results look?\",\n \"inLanguage\": \"In {lang}\",\n \"keyAutoHide\": \"Hides automatically in {seconds}s.\",\n \"keyCopied\": \"Copied\",\n \"keyCopyId\": \"Copy id\",\n \"keyCopySecret\": \"Copy secret\",\n \"keyCreateNew\": \"I'm new — create one\",\n \"keyCreating\": \"Creating…\",\n \"keyDismiss\": \"Dismiss\",\n \"keyPastePlaceholder\": \"your public id…\",\n \"keyPastePrompt\": \"Paste your public id — or create one\",\n \"keyPublicHint\": \"Paste this on any site to save to the same memory.\",\n \"keyPublicTitle\": \"Your public id\",\n \"keySecretHint\": \"Keep it private — use it to unlock your memory.\",\n \"keySecretTitle\": \"Your secret — shown only once\",\n \"keyUseMine\": \"Use my id\",\n \"kikuActionUnavailable\": \"Sorry — that action isn't available on this site.\",\n \"kikuCaptureDbError\": \"Capture failed due to a database error.\",\n \"kikuCaptureNoContext\": \"Capture failed because no page or product context was provided by the SDK.\",\n \"kikuCaptureNoUrl\": \"Couldn’t save any items — none had a valid URL.\",\n \"kikuCaptureNoneSelected\": \"No items were selected to capture.\",\n \"kikuDeleteDbError\": \"Delete failed due to a database error.\",\n \"kikuDeleteDone\": \"Removed it from your saved items.\",\n \"kikuDeleteNoContext\": \"Delete failed because no page context was provided to identify what to delete.\",\n \"kikuMemoryIntro\": \"Everything you've captured across sites lives in your private memory. Unlock it with your secret:\",\n \"kikuMintNeeded\": \"To save items across sites you need a kiku key — I'll mint one for you. It's shown only once, so save it somewhere safe.\",\n \"kikuMintOffer\": \"I can keep this for you and have it follow you across sites — I'll mint you a kiku key. It's shown only once, so save it somewhere safe.\",\n \"kikuNeedKeyToUpdate\": \"Enter your kiku key so I can find and update your saved items.\",\n \"micDenied\": \"Microphone blocked. Allow mic access for this site, then try again.\",\n \"micFailed\": \"Couldn't hear that. Try again.\",\n \"micInsecure\": \"Voice needs a secure (https) connection.\",\n \"micLangUnsupported\": \"This browser cannot transcribe that language yet. Type instead.\",\n \"micMissing\": \"No microphone found.\",\n \"micNetwork\": \"Voice needs a connection right now. Check yours and try again.\",\n \"micNoSpeech\": \"Didn't catch anything. Try again, a little closer to the mic.\",\n \"namePlaceholder\": \"Type your name…\",\n \"nameStepAsk\": \"What should I call you?\",\n \"nameStepLead\": \"I can search, visualize, or capture anything for you — on this site or any other.\",\n \"nameStepTitle\": \"Nice to meet you.\",\n \"namesAsWritten\": \"Names and details exactly as the site lists them.\",\n \"pillCompareTop2\": \"Compare top 2\",\n \"pillCompareTop2Query\": \"Compare the {a} and {b}\",\n \"pillFindAlternatives\": \"Find alternatives\",\n \"pillFindAlternativesQuery\": \"What are good alternatives to the {name}?\",\n \"pillMoreOn\": \"More on {name}\",\n \"pillMoreOnQuery\": \"Tell me more about the {name}\",\n \"pillRecommend\": \"Recommend something\",\n \"pillRecommendQuery\": \"What do you recommend for me?\",\n \"pillShowPopular\": \"Show popular items\",\n \"pillShowPopularQuery\": \"What are your most popular items?\",\n \"pillSimilarOptions\": \"Similar options\",\n \"pillSimilarOptionsQuery\": \"Show me more like the {name}\",\n \"pillUnder\": \"Under {amount}\",\n \"pillUnderQuery\": \"Show me options under {amount}\",\n \"pillWhichBest\": \"Which is best?\",\n \"pillWhichBestQuery\": \"Which one would you recommend and why?\",\n \"replyingOriginal\": \"Replying in {lang}, results as this site wrote them. Ask me anything.\",\n \"replyingTranslated\": \"Replying in {lang}, results translated too. Ask me anything.\",\n \"statusSent\": \"Sent\",\n \"statusStopped\": \"Sent · reply stopped\",\n \"thinking\": \"Thinking\",\n \"thoughtForSeconds\": \"Thought for {duration}\",\n \"thoughtProcess\": \"Thought process\",\n \"vizDisclaimerImage\": \"Generated using Artificial Intelligence — colours, size and placement may differ from the real product.\",\n \"vizDisclaimerVideo\": \"Generated using Artificial Intelligence — colours, size and movement may differ from the real product.\",\n \"vizUnavailable\": \"The preview could not be loaded.\",\n \"voiceHint\": \"Just talk — I'll answer when you pause.\",\n \"voiceListening\": \"Listening… tap the mic to stop\",\n \"voiceModeExit\": \"Leave hands-free\",\n \"voiceModeStart\": \"Hands-free conversation\",\n \"voiceMuted\": \"Muted\",\n \"voiceMutedHint\": \"Tap the microphone to speak again.\",\n \"voicePhaseListening\": \"Listening\",\n \"voicePhaseSpeaking\": \"Speaking\",\n \"voicePhaseThinking\": \"Thinking\",\n \"voiceSending\": \"Got it — sending…\",\n \"termsStepTitle\": \"Privacy & Terms of Use\",\n \"termsStepSubtitle\": \"Transparent, anonymous, and zero-PII by design.\",\n \"termsPiiTitle\": \"Zero PII Collection\",\n \"termsPiiDesc\": \"We never collect or store personal identifying information (no emails, phone numbers, or real-world identities) from your chats or voice sessions.\",\n \"termsSessionTitle\": \"Anonymous Session Tokens\",\n \"termsSessionDesc\": \"Your session uses an anonymous client-side token solely to maintain context. It is never linked to your real identity.\",\n \"termsMemoryTitle\": \"Ephemeral Chats vs. Mimi Vault\",\n \"termsMemoryDesc\": \"Regular chats are ephemeral — closing the tab or clicking \\\"Clear Chat\\\" terminates them forever. Items you save with \\\"@kiku\\\" are encrypted and can be unlocked at mimi.akropolys.cloud with your Secret Access Key.\",\n \"termsCookieTitle\": \"Host Website Telemetry\",\n \"termsCookieDesc\": \"The host website where Kiku is embedded may collect cookies and analytics per their own cookie policy, outside Kiku's control.\",\n \"termsAgreeButton\": \"Agree & Continue\",\n \"termsAgreeCounting\": \"Agree & Continue ({seconds}s)\",\n \"termsPlaceholder\": \"Please review and accept our Privacy & Terms above…\",\n \"whatHaveYouSaved\": \"What have you saved?\",\n \"retry\": \"Retry\",\n \"edit\": \"Edit\",\n \"copy\": \"Copy\",\n \"copied\": \"Copied\",\n \"msgFailed\": \"Failed to send\"\n },\n \"french\": {\n \"allSet\": \"C'est tout bon, {name}.\",\n \"asWritten\": \"Tel quel\",\n \"captureAll\": \"Tout capturer ({count})\",\n \"captureAndRemember\": \"kiku — capturer et mémoriser\",\n \"captureCurrentPage\": \"Capturer la page actuelle\",\n \"cardClickAnswer\": \"Le {name}\",\n \"cardClickQuery\": \"Dites-m'en plus sur le {name}{price} : ses caractéristiques principales, à qui il convient le mieux et ce que je devrais savoir.\",\n \"clearChat\": \"Effacer le chat\",\n \"defaultPlaceholder\": \"Posez-moi n'importe quelle question…\",\n \"deleteThis\": \"Supprimer ceci\",\n \"detailsTranslated\": \"Détails traduits. Les chiffres et les liens restent exactement tels qu'ils sont.\",\n \"displayCapture\": \"capturer {name}\",\n \"displayCaptureAll\": \"tout capturer ({count} articles)\",\n \"displayDelete\": \"supprimer ceci\",\n \"displayViewHistory\": \"qu'avez-vous enregistré ?\",\n \"entityLangIntro\": \"Je réponds en {lang}. Les fiches peuvent rester telles qu'écrites ou être traduites.\",\n \"entityLangPlaceholder\": \"Choisissez l'une des deux fiches ci-dessus…\",\n \"errAccessRevoked\": \"Votre accès à l'assistant a été révoqué par le magasin.\",\n \"errAccountRequired\": \"Veuillez créer un compte pour continuer à utiliser l'assistant de chat.\",\n \"errShopperReplyLimit\": \"Vous avez atteint la limite de réponses de ce site pour votre compte.\",\n \"errStreamInterrupted\": \"La réponse a été interrompue. Veuillez réessayer.\",\n \"errTokenLimit\": \"Vous avez atteint votre limite d'utilisation. Veuillez mettre à jour vos limites de facturation dans votre tableau de bord pour continuer.\",\n \"errTooManyRequests\": \"L'assistant reçoit actuellement trop de requêtes. Veuillez réessayer dans quelques instants.\",\n \"footerHint\": \"kiku · recherche dans tout le catalogue en temps réel\",\n \"greetReturning\": \"Bonjour, {name}.\",\n \"greetReturningLead\": \"Que puis-je trouver pour vous aujourd'hui ?\",\n \"howShouldResultsLook\": \"Comment les résultats doivent-ils s'afficher ?\",\n \"inLanguage\": \"En {lang}\",\n \"keyAutoHide\": \"Se masque automatiquement dans {seconds}s.\",\n \"keyCopied\": \"Copié\",\n \"keyCopyId\": \"Copier l'identifiant\",\n \"keyCopySecret\": \"Copier le secret\",\n \"keyCreateNew\": \"Je suis nouveau — créez-en un\",\n \"keyCreating\": \"Création en cours…\",\n \"keyDismiss\": \"Ignorer\",\n \"keyPastePlaceholder\": \"votre identifiant public…\",\n \"keyPastePrompt\": \"Collez votre identifiant public — ou créez-en un\",\n \"keyPublicHint\": \"Collez ceci sur n'importe quel site pour enregistrer dans la même mémoire.\",\n \"keyPublicTitle\": \"Votre identifiant public\",\n \"keySecretHint\": \"Gardez-le privé — utilisez-le pour déverrouiller votre mémoire.\",\n \"keySecretTitle\": \"Votre secret — affiché une seule fois\",\n \"keyUseMine\": \"Utiliser mon identifiant\",\n \"kikuActionUnavailable\": \"Désolé — cette action n'est pas disponible sur ce site.\",\n \"kikuCaptureDbError\": \"La capture a échoué en raison d'une erreur de base de données.\",\n \"kikuCaptureNoContext\": \"La capture a échoué car aucun contexte de page ou de produit n'a été fourni par le SDK.\",\n \"kikuCaptureNoUrl\": \"Impossible d'enregistrer des articles — aucun n'avait d'URL valide.\",\n \"kikuCaptureNoneSelected\": \"Aucun article n'a été sélectionné pour la capture.\",\n \"kikuDeleteDbError\": \"La suppression a échoué en raison d'une erreur de base de données.\",\n \"kikuDeleteDone\": \"Je l'ai retiré de vos articles enregistrés.\",\n \"kikuDeleteNoContext\": \"La suppression a échoué car aucun contexte de page n'a été fourni pour identifier ce qu'il fallait supprimer.\",\n \"kikuMemoryIntro\": \"Tout ce que vous avez capturé sur les sites se trouve dans votre mémoire privée. Déverrouillez-la avec votre secret :\",\n \"kikuMintNeeded\": \"Pour enregistrer des articles sur différents sites, vous avez besoin d'une clé kiku — je vais en créer une pour vous. Elle n'est affichée qu'une seule fois, alors enregistrez-la en lieu sûr.\",\n \"kikuMintOffer\": \"Je peux garder ceci pour vous et le faire vous suivre sur les sites — je vais vous créer une clé kiku. Elle n'est affichée qu'une seule fois, alors enregistrez-la en lieu sûr.\",\n \"kikuNeedKeyToUpdate\": \"Entrez votre clé kiku afin que je puisse trouver et mettre à jour vos articles enregistrés.\",\n \"micDenied\": \"Microphone bloqué. Autorisez l'accès au micro pour ce site, puis réessayez.\",\n \"micFailed\": \"Je n'ai pas entendu. Réessayez.\",\n \"micInsecure\": \"La voix nécessite une connexion sécurisée (https).\",\n \"micLangUnsupported\": \"Ce navigateur ne peut pas encore transcrire cette langue. Veuillez taper à la place.\",\n \"micMissing\": \"Aucun microphone détecté.\",\n \"micNetwork\": \"La voix nécessite une connexion en ce moment. Vérifiez la vôtre et réessayez.\",\n \"micNoSpeech\": \"Je n'ai rien entendu. Réessayez, un peu plus près du micro.\",\n \"namePlaceholder\": \"Tapez votre nom…\",\n \"nameStepAsk\": \"Comment dois-je vous appeler ?\",\n \"nameStepLead\": \"Je peux chercher, visualiser ou enregistrer pour vous sur ce site ou ailleurs.\",\n \"nameStepTitle\": \"Enchanté de vous rencontrer.\",\n \"namesAsWritten\": \"Noms et détails exactement tels qu'ils sont listés sur le site.\",\n \"pillCompareTop2\": \"Comparer les 2 meilleurs\",\n \"pillCompareTop2Query\": \"Comparez le {a} et le {b}\",\n \"pillFindAlternatives\": \"Trouver des alternatives\",\n \"pillFindAlternativesQuery\": \"Quelles sont de bonnes alternatives au {name} ?\",\n \"pillMoreOn\": \"Plus sur {name}\",\n \"pillMoreOnQuery\": \"Dites-m'en plus sur le {name}\",\n \"pillRecommend\": \"Recommander quelque chose\",\n \"pillRecommendQuery\": \"Que me recommandez-vous ?\",\n \"pillShowPopular\": \"Afficher les articles populaires\",\n \"pillShowPopularQuery\": \"Quels sont vos articles les plus populaires ?\",\n \"pillSimilarOptions\": \"Options similaires\",\n \"pillSimilarOptionsQuery\": \"Montrez-m'en plus comme le {name}\",\n \"pillUnder\": \"Moins de {amount}\",\n \"pillUnderQuery\": \"Montrez-moi des options à moins de {amount}\",\n \"pillWhichBest\": \"Lequel est le meilleur ?\",\n \"pillWhichBestQuery\": \"Lequel recommanderiez-vous et pourquoi ?\",\n \"replyingOriginal\": \"Je réponds en {lang}, les résultats sont tels que le site les a écrits. Posez-moi n'importe quelle question.\",\n \"replyingTranslated\": \"Je réponds en {lang}, les résultats sont également traduits. Posez-moi n'importe quelle question.\",\n \"statusSent\": \"Envoyé\",\n \"statusStopped\": \"Envoyé · réponse arrêtée\",\n \"thinking\": \"Réflexion en cours\",\n \"thoughtForSeconds\": \"Réflexion pendant {duration}\",\n \"thoughtProcess\": \"Processus de réflexion\",\n \"vizDisclaimerImage\": \"Généré par Intelligence Artificielle — les couleurs, la taille et le placement peuvent différer du produit réel.\",\n \"vizDisclaimerVideo\": \"Généré par Intelligence Artificielle — les couleurs, la taille et le mouvement peuvent différer du produit réel.\",\n \"vizUnavailable\": \"L'aperçu n'a pas pu être chargé.\",\n \"voiceListening\": \"Écoute… touchez le micro pour arrêter\",\n \"voiceSending\": \"Bien reçu — envoi en cours…\",\n \"termsStepTitle\": \"Confidentialité et conditions d'utilisation\",\n \"termsStepSubtitle\": \"Transparent, anonyme et sans collecte de données personnelles.\",\n \"termsPiiTitle\": \"Zéro collecte de données personnelles\",\n \"termsPiiDesc\": \"Nous ne collectons ni ne stockons aucune information d'identification personnelle (ni e-mail, ni numéro de téléphone, ni identité réelle) depuis vos discussions ou sessions vocales.\",\n \"termsSessionTitle\": \"Jetons de session anonymes\",\n \"termsSessionDesc\": \"Votre session utilise un identifiant anonyme côté client uniquement pour maintenir le contexte, jamais lié à votre identité réelle.\",\n \"termsMemoryTitle\": \"Discussions éphémères vs Coffre Mimi\",\n \"termsMemoryDesc\": \"Les discussions normales sont éphémères — fermer ou effacer le chat les détruit pour toujours. Les éléments enregistrés avec « @kiku » sont chiffrés et accessibles sur mimi.akropolys.cloud avec votre clé secrète.\",\n \"termsCookieTitle\": \"Télémétrie du site hôte\",\n \"termsCookieDesc\": \"Le site hôte sur lequel kiku est intégré peut collecter des cookies et des données d'analyse selon sa propre politique de cookies, hors du contrôle de kiku.\",\n \"termsAgreeButton\": \"Accepter et continuer\",\n \"termsAgreeCounting\": \"Accepter et continuer ({seconds}s)\",\n \"termsPlaceholder\": \"Veuillez examiner et accepter la politique de confidentialité et les conditions ci-dessus…\",\n \"whatHaveYouSaved\": \"Qu'avez-vous enregistré ?\",\n \"voiceHint\": \"Parlez simplement — je répondrai dès que vous ferez une pause.\",\n \"voiceModeExit\": \"Quitter le mode mains libres\",\n \"voiceModeStart\": \"Conversation mains libres\",\n \"voiceMuted\": \"En sourdine\",\n \"voiceMutedHint\": \"Appuyez sur le micro pour parler à nouveau.\",\n \"voicePhaseListening\": \"Écoute\",\n \"voicePhaseSpeaking\": \"Parle\",\n \"voicePhaseThinking\": \"Réflexion\",\n \"retry\": \"Réessayer\",\n \"edit\": \"Modifier\",\n \"copy\": \"Copier\",\n \"copied\": \"Copié\",\n \"msgFailed\": \"Échec de l'envoi\"\n },\n \"hindi\": {\n \"allSet\": \"आप तैयार हैं, {name}.\",\n \"asWritten\": \"जैसा लिखा है\",\n \"captureAll\": \"सभी को कैप्चर करें ({count})\",\n \"captureAndRemember\": \"kiku — कैप्चर & याद रखें\",\n \"captureCurrentPage\": \"वर्तमान पृष्ठ को कैप्चर करें\",\n \"cardClickAnswer\": \"{name}\",\n \"cardClickQuery\": \"कृपया {name}{price} के बारे में अधिक बताइए — इसके मुख्य विवरण क्या हैं, यह किसके लिए सबसे उपयुक्त है, और मुझे क्या जानना चाहिए?\",\n \"clearChat\": \"चैट साफ़ करें\",\n \"defaultPlaceholder\": \"मुझसे कुछ भी पूछें…\",\n \"deleteThis\": \"इसे हटाएँ\",\n \"detailsTranslated\": \"विवरण अनुवादित। संख्याएँ और लिंक ठीक वैसे ही रहें।\",\n \"displayCapture\": \"कैप्चर {name}\",\n \"displayCaptureAll\": \"सभी को कैप्चर करें ({count} आइटम)\",\n \"displayDelete\": \"इसे हटाएँ\",\n \"displayViewHistory\": \"आपने क्या सहेजा है?\",\n \"entityLangIntro\": \"मैं {lang} में उत्तर दूँगा। कार्ड मूल रूप में रह सकते हैं या अनुवादित हो सकते हैं।\",\n \"entityLangPlaceholder\": \"ऊपर दो कार्डों में से एक चुनें…\",\n \"errAccessRevoked\": \"स्टोर द्वारा आपके सहायक तक पहुँच रद्द कर दी गई है।\",\n \"errAccountRequired\": \"चैट सहायक का उपयोग जारी रखने के लिए कृपया एक खाता बनाएँ।\",\n \"errShopperReplyLimit\": \"आपने इस साइट के लिए अपने खाते की उत्तर सीमा तक पहुँच बना ली है।\",\n \"errStreamInterrupted\": \"उत्तर बाधित हो गया। कृपया पुनः प्रयास करें।\",\n \"errTokenLimit\": \"आपने अपनी उपयोग सीमा तक पहुँच बना ली है। जारी रखने के लिए अपने डैशबोर्ड में बिलिंग सीमा अपडेट करें।\",\n \"errTooManyRequests\": \"सहायक वर्तमान में बहुत अधिक अनुरोध प्राप्त कर रहा है। कुछ क्षण बाद पुनः प्रयास करें।\",\n \"footerHint\": \"kiku · वास्तविक समय में पूरे कैटलॉग को खोजता है\",\n \"greetReturning\": \"नमस्ते, {name}.\",\n \"greetReturningLead\": \"आज मैं आपके लिए क्या खोजूँ?\",\n \"howShouldResultsLook\": \"परिणाम कैसे दिखें?\",\n \"inLanguage\": \"{lang} में\",\n \"keyAutoHide\": \"स्वतः {seconds}s में छिप जाएगा.\",\n \"keyCopied\": \"कॉपी किया गया\",\n \"keyCopyId\": \"आईडी कॉपी करें\",\n \"keyCopySecret\": \"सीक्रेट कॉपी करें\",\n \"keyCreateNew\": \"मैं नया हूँ — एक बनाएं\",\n \"keyCreating\": \"बना रहा हूँ…\",\n \"keyDismiss\": \"बंद करें\",\n \"keyPastePlaceholder\": \"आपका सार्वजनिक आईडी…\",\n \"keyPastePrompt\": \"अपना सार्वजनिक आईडी पेस्ट करें — या एक बनाएं\",\n \"keyPublicHint\": \"इसे किसी भी साइट पर पेस्ट करें ताकि वही मेमोरी में सहेजा जा सके।\",\n \"keyPublicTitle\": \"आपका सार्वजनिक आईडी\",\n \"keySecretHint\": \"इसे निजी रखें — अपने मेमोरी को अनलॉक करने के लिए उपयोग करें।\",\n \"keySecretTitle\": \"आपका सीक्रेट — केवल एक बार दिखाया गया\",\n \"keyUseMine\": \"मेरी आईडी उपयोग करें\",\n \"kikuActionUnavailable\": \"क्षमा करें — यह कार्रवाई इस साइट पर उपलब्ध नहीं है।\",\n \"kikuCaptureDbError\": \"डेटाबेस त्रुटि के कारण कैप्चर विफल रहा।\",\n \"kikuCaptureNoContext\": \"SDK द्वारा कोई पेज या प्रोडक्ट कॉन्टेक्स्ट प्रदान नहीं किया गया, इसलिए कैप्चर विफल रहा।\",\n \"kikuCaptureNoUrl\": \"कोई आइटम सहेजा नहीं जा सका — कोई भी वैध URL नहीं था।\",\n \"kikuCaptureNoneSelected\": \"कैप्चर करने के लिए कोई आइटम चयनित नहीं किया गया।\",\n \"kikuDeleteDbError\": \"डेटाबेस त्रुटि के कारण हटाना विफल रहा।\",\n \"kikuDeleteDone\": \"इसे आपके सहेजे गए आइटम्स से हटा दिया गया।\",\n \"kikuDeleteNoContext\": \"हटाने के लिए कोई पेज कॉन्टेक्स्ट प्रदान नहीं किया गया, इसलिए हटाना विफल रहा।\",\n \"kikuMemoryIntro\": \"आपने विभिन्न साइटों पर जो भी कैप्चर किया है, वह आपके निजी मेमोरी में रहता है। इसे अपने सीक्रेट से अनलॉक करें:\",\n \"kikuMintNeeded\": \"साइटों के बीच आइटम्स सहेजने के लिए आपको एक किकु कुंजी चाहिए — मैं आपके लिए एक बनाऊँगा। यह केवल एक बार दिखाया जाता है, इसलिए इसे सुरक्षित जगह पर रखें।\",\n \"kikuMintOffer\": \"मैं इसे आपके लिए रख सकता हूँ और साइटों के बीच आपके साथ ले जा सकता हूँ — मैं आपके लिए एक किकु कुंजी बनाऊँगा। यह केवल एक बार दिखाया जाता है, इसलिए इसे सुरक्षित जगह पर रखें।\",\n \"kikuNeedKeyToUpdate\": \"अपनी किकु कुंजी दर्ज करें ताकि मैं आपके सहेजे गए आइटम्स को खोज और अपडेट कर सकूँ।\",\n \"namePlaceholder\": \"अपना नाम टाइप करें…\",\n \"nameStepAsk\": \"मैं आपको क्या कहूँ?\",\n \"nameStepLead\": \"मैं आपके लिए कुछ भी खोज, विज़ुअलाइज़ या कैप्चर कर सकता हूँ — इस साइट पर या किसी अन्य पर।\",\n \"nameStepTitle\": \"आपसे मिलकर खुशी हुई।\",\n \"namesAsWritten\": \"नाम और विवरण ठीक उसी तरह जैसे साइट पर सूचीबद्ध हैं।\",\n \"pillCompareTop2\": \"शीर्ष 2 की तुलना करें\",\n \"pillCompareTop2Query\": \"{a} और {b} की तुलना करें\",\n \"pillFindAlternatives\": \"विकल्प खोजें\",\n \"pillFindAlternativesQuery\": \"{name} के अच्छे विकल्प क्या हैं?\",\n \"pillMoreOn\": \"{name} के बारे में अधिक\",\n \"pillMoreOnQuery\": \"कृपया {name} के बारे में अधिक बताइए\",\n \"pillRecommend\": \"कुछ सुझाएँ\",\n \"pillRecommendQuery\": \"मेरे लिए आप क्या सुझाएंगे?\",\n \"pillShowPopular\": \"लोकप्रिय आइटम दिखाएँ\",\n \"pillShowPopularQuery\": \"आपके सबसे लोकप्रिय आइटम कौन से हैं?\",\n \"pillSimilarOptions\": \"समान विकल्प\",\n \"pillSimilarOptionsQuery\": \"{name} जैसा और दिखाइए\",\n \"pillUnder\": \"{amount} से कम\",\n \"pillUnderQuery\": \"{amount} से कम विकल्प दिखाइए\",\n \"pillWhichBest\": \"कौन सबसे अच्छा है?\",\n \"pillWhichBestQuery\": \"आप कौन सा सुझाएंगे और क्यों?\",\n \"replyingOriginal\": \"{lang} में उत्तर दे रहा हूँ, परिणाम साइट के लिखे अनुसार। मुझसे कुछ भी पूछें।\",\n \"replyingTranslated\": \"{lang} में उत्तर दे रहा हूँ, परिणाम भी अनूदित हैं। मुझसे कुछ भी पूछें।\",\n \"statusSent\": \"भेजा गया\",\n \"statusStopped\": \"भेजा गया · उत्तर रोक दिया गया\",\n \"thinking\": \"सोच रहा हूँ\",\n \"thoughtForSeconds\": \"{duration} तक सोचा\",\n \"thoughtProcess\": \"विचार प्रक्रिया\",\n \"vizUnavailable\": \"पूर्वावलोकन लोड नहीं हो सका।\",\n \"termsStepTitle\": \"गोपनीयता और उपयोग की शर्तें\",\n \"termsStepSubtitle\": \"पारदर्शी, अज्ञात और शून्य व्यक्तिगत पहचान डेटा।\",\n \"termsPiiTitle\": \"शून्य व्यक्तिगत डेटा संग्रह\",\n \"termsPiiDesc\": \"हम आपकी बातचीत या वॉयस सत्रों से व्यक्तिगत पहचान योग्य जानकारी (कोई ईमेल, फ़ोन नंबर या वास्तविक पहचान नहीं) एकत्र या संग्रहीत नहीं करते हैं।\",\n \"termsSessionTitle\": \"अज्ञात सत्र टोकन\",\n \"termsSessionDesc\": \"आपका सत्र केवल संदर्भ बनाए रखने के लिए एक अनाम क्लाइंट टोकन का उपयोग करता है। यह आपकी वास्तविक पहचान से कभी नहीं जुड़ता।\",\n \"termsMemoryTitle\": \"अस्थायी चैट बनाम मिमी वॉल्ट\",\n \"termsMemoryDesc\": \"नियमित चैट अस्थायी हैं — चैट बंद करने या साफ़ करने पर वे हमेशा के लिए समाप्त हो जाती हैं। \\\"@kiku\\\" से सहेजे गए आइटम एन्क्रिप्टेड हैं और mimi.akropolys.cloud पर आपकी गुप्त कुंजी से खोले जा सकते हैं।\",\n \"termsCookieTitle\": \"होस्ट वेबसाइट टेलीमेट्री\",\n \"termsCookieDesc\": \"जिस वेबसाइट पर kiku एम्बेडेड है, वह अपनी स्वयं की कुकी नीति के अनुसार कुकीज़ और एनालिटिक्स एकत्र कर सकती है।\",\n \"termsAgreeButton\": \"सहमत हों और आगे बढ़ें\",\n \"termsAgreeCounting\": \"सहमत हों और आगे बढ़ें ({seconds}s)\",\n \"termsPlaceholder\": \"कृपया ऊपर दी गई गोपनीयता और शर्तों की समीक्षा करें और स्वीकार करें…\",\n \"whatHaveYouSaved\": \"आपने क्या सहेजा है?\",\n \"micDenied\": \"माइक्रोफ़ोन ब्लॉक है। इस साइट के लिए माइक एक्सेस की अनुमति दें, फिर पुनः प्रयास करें।\",\n \"micFailed\": \"सुनाई नहीं दिया। पुनः प्रयास करें।\",\n \"micInsecure\": \"वॉयस के लिए सुरक्षित (https) कनेक्शन आवश्यक है।\",\n \"micLangUnsupported\": \"यह ब्राउज़र अभी इस भाषा को ट्रांसक्राइब नहीं कर सकता। इसके बजाय टाइप करें।\",\n \"micMissing\": \"कोई माइक्रोफ़ोन नहीं मिला।\",\n \"micNetwork\": \"वॉयस के लिए इंटरनेट कनेक्शन आवश्यक है। अपना कनेक्शन जांचें और पुनः प्रयास करें।\",\n \"micNoSpeech\": \"कुछ सुनाई नहीं दिया। कृपया माइक के पास आकर दोबारा बोलें।\",\n \"vizDisclaimerImage\": \"कृत्रिम बुद्धिमत्ता (AI) द्वारा निर्मित — रंग, आकार और स्थिति वास्तविक उत्पाद से भिन्न हो सकते हैं।\",\n \"vizDisclaimerVideo\": \"कृत्रिम बुद्धिमत्ता (AI) द्वारा निर्मित — रंग, आकार और गति वास्तविक उत्पाद से भिन्न हो सकते हैं।\",\n \"voiceHint\": \"बस बोलें — जब आप रुकेंगे तो मैं उत्तर दूंगा।\",\n \"voiceListening\": \"सुन रहा है… रोकने के लिए माइक पर टैप करें\",\n \"voiceModeExit\": \"हैंड्स-फ्री से बाहर निकलें\",\n \"voiceModeStart\": \"हैंड्स-फ्री बातचीत\",\n \"voiceMuted\": \"म्यूट किया गया\",\n \"voiceMutedHint\": \"दोबारा बोलने के लिए माइक्रोफ़ोन पर टैप करें।\",\n \"voicePhaseListening\": \"सुन रहा है\",\n \"voicePhaseSpeaking\": \"बोल रहा है\",\n \"voicePhaseThinking\": \"सोच रहा है\",\n \"voiceSending\": \"समझ गया — भेजा जा रहा है…\",\n \"retry\": \"पुनः प्रयास करें\",\n \"edit\": \"संपादित करें\",\n \"copy\": \"कॉपी करें\",\n \"copied\": \"कॉपी किया गया\",\n \"msgFailed\": \"भेजने में विफल\"\n },\n \"japanese\": {\n \"allSet\": \"準備が完了しました、{name}さん。\",\n \"asWritten\": \"サイトの原文通り\",\n \"captureAll\": \"すべて保存 ({count})\",\n \"captureAndRemember\": \"kiku — 保存と記憶\",\n \"captureCurrentPage\": \"現在のページを保存\",\n \"cardClickAnswer\": \"{name}\",\n \"cardClickQuery\": \"{name}{price} について詳しく教えてください — 主な特徴、どんな人に向いているか、知っておくべきことは何ですか?\",\n \"clearChat\": \"チャットを消去\",\n \"defaultPlaceholder\": \"何でもお聞きください…\",\n \"deleteThis\": \"これを削除\",\n \"detailsTranslated\": \"詳細を翻訳。価格やリンクは原文のままです。\",\n \"displayCapture\": \"{name} を保存\",\n \"displayCaptureAll\": \"すべて保存({count}件)\",\n \"displayDelete\": \"これを削除\",\n \"displayViewHistory\": \"何を保存しましたか?\",\n \"entityLangIntro\": \"{lang}で回答します。カードは原文のまま、または翻訳して表示できます。\",\n \"entityLangPlaceholder\": \"上の2つのカードから1つ選んでください…\",\n \"errAccessRevoked\": \"ストアによってアシスタントへのアクセス権が取り消されました。\",\n \"errAccountRequired\": \"チャットアシスタントを引き続きご利用いただくには、アカウントを作成してください。\",\n \"errShopperReplyLimit\": \"このサイトでのあなたのアカウントの返答上限に達しました。\",\n \"errStreamInterrupted\": \"返答が中断されました。もう一度お試しください。\",\n \"errTokenLimit\": \"利用上限に達しました。ダッシュボードで利用上限を更新して続行してください。\",\n \"errTooManyRequests\": \"現在リクエストが集中しています。しばらくしてからもう一度お試しください。\",\n \"footerHint\": \"kiku · カタログ全体をリアルタイムで検索\",\n \"greetReturning\": \"こんにちは、{name}さん。\",\n \"greetReturningLead\": \"今日は何をお探しですか?\",\n \"howShouldResultsLook\": \"結果はどのように表示しますか?\",\n \"inLanguage\": \"{lang}で\",\n \"keyAutoHide\": \"{seconds}秒後に自動で閉じます。\",\n \"keyCopied\": \"コピーしました\",\n \"keyCopyId\": \"IDをコピー\",\n \"keyCopySecret\": \"シークレットをコピー\",\n \"keyCreateNew\": \"初めて利用 — 新規作成\",\n \"keyCreating\": \"作成中…\",\n \"keyDismiss\": \"閉じる\",\n \"keyPastePlaceholder\": \"公開IDを入力…\",\n \"keyPastePrompt\": \"公開IDを貼り付けるか、新規作成してください\",\n \"keyPublicHint\": \"どのサイトでもこれを貼り付けると、同じメモリーに保存できます。\",\n \"keyPublicTitle\": \"あなたの公開ID\",\n \"keySecretHint\": \"大切に保管してください — メモリーのロック解除に使用します。\",\n \"keySecretTitle\": \"あなたのシークレット — 1度だけ表示されます\",\n \"keyUseMine\": \"自分のIDを使用\",\n \"kikuActionUnavailable\": \"申し訳ありません。このサイトではその操作は利用できません。\",\n \"kikuCaptureDbError\": \"データベースエラーのため保存に失敗しました。\",\n \"kikuCaptureNoContext\": \"ページ情報が提供されなかったため保存に失敗しました。\",\n \"kikuCaptureNoUrl\": \"有効なURLがないため、アイテムを保存できませんでした。\",\n \"kikuCaptureNoneSelected\": \"保存するアイテムが選択されていません。\",\n \"kikuDeleteDbError\": \"データベースエラーのため削除に失敗しました。\",\n \"kikuDeleteDone\": \"保存したアイテムから削除しました。\",\n \"kikuDeleteNoContext\": \"削除対象を特定するためのページ情報がありませんでした。\",\n \"kikuMemoryIntro\": \"複数サイトで保存したすべてのアイテムはプライベートメモリーに保持されます。シークレットでロック解除:\",\n \"kikuMintNeeded\": \"サイトをまたいでアイテムを保存するにはkikuキーが必要です。新しく発行します。1度しか表示されないため、安全な場所に保存してください。\",\n \"kikuMintOffer\": \"アイテムを保持して他のサイトでも引き継ぐことができます — kikuキーを発行します。1度しか表示されないため安全に保存してください。\",\n \"kikuNeedKeyToUpdate\": \"保存したアイテムを更新・検索するにはkikuキーを入力してください。\",\n \"micDenied\": \"マイクがブロックされています。このサイトでのマイクアクセスを許可してから、もう一度お試しください。\",\n \"micFailed\": \"聞き取れませんでした。もう一度お話しください。\",\n \"micInsecure\": \"音声入力には保護された接続 (HTTPS) が必要です。\",\n \"micLangUnsupported\": \"お使いのブラウザはこの言語の音声認識にまだ対応していません。文字で入力してください。\",\n \"micMissing\": \"マイクが見つかりませんでした。\",\n \"micNetwork\": \"音声入力にはネットワーク接続が必要です。接続を確認してもう一度お試しください。\",\n \"micNoSpeech\": \"音声が検出されませんでした。マイクに近づいてもう一度お話しください。\",\n \"namePlaceholder\": \"お名前を入力…\",\n \"nameStepAsk\": \"何とお呼びすればよろしいですか?\",\n \"nameStepLead\": \"商品の検索・ビジュアル化・保存をお手伝いします。\",\n \"nameStepTitle\": \"はじめまして。\",\n \"namesAsWritten\": \"商品名や詳細はサイトの掲載通り。\",\n \"pillCompareTop2\": \"トップ2を比較\",\n \"pillCompareTop2Query\": \"{a} と {b} を比較して\",\n \"pillFindAlternatives\": \"代替品を探す\",\n \"pillFindAlternativesQuery\": \"{name} の良い代替品はありますか?\",\n \"pillMoreOn\": \"{name} についてもっと知る\",\n \"pillMoreOnQuery\": \"{name} についてもっと詳しく教えて\",\n \"pillRecommend\": \"おすすめを教えて\",\n \"pillRecommendQuery\": \"私に何をおすすめしますか?\",\n \"pillShowPopular\": \"人気商品を見る\",\n \"pillShowPopularQuery\": \"一番人気の商品はどれですか?\",\n \"pillSimilarOptions\": \"似ているオプション\",\n \"pillSimilarOptionsQuery\": \"{name} に似た商品をもっと見せて\",\n \"pillUnder\": \"{amount} 以下\",\n \"pillUnderQuery\": \"{amount} 以下の選択肢を見せて\",\n \"pillWhichBest\": \"どれが一番おすすめ?\",\n \"pillWhichBestQuery\": \"どれが一番おすすめですか?その理由も教えてください。\",\n \"replyingOriginal\": \"{lang}で回答(結果は原文のまま)。何でもお聞きください。\",\n \"replyingTranslated\": \"{lang}で回答(結果も翻訳)。何でもお聞きください。\",\n \"statusSent\": \"送信済み\",\n \"statusStopped\": \"送信済み · 返答を停止しました\",\n \"thinking\": \"思考中\",\n \"thoughtForSeconds\": \"{duration} 考えました\",\n \"thoughtProcess\": \"思考プロセス\",\n \"vizDisclaimerImage\": \"人工知能によって生成されました — 色、サイズ、配置は実際の商品と異なる場合があります。\",\n \"vizDisclaimerVideo\": \"人工知能によって生成されました — 色、サイズ、動きは実際の商品と異なる場合があります。\",\n \"vizUnavailable\": \"プレビューを読み込めませんでした。\",\n \"voiceHint\": \"お話しください — 話し終えたらお答えします。\",\n \"voiceListening\": \"聞き取り中… タップして停止\",\n \"voiceModeExit\": \"ハンズフリーを終了\",\n \"voiceModeStart\": \"ハンズフリー会話\",\n \"voiceMuted\": \"ミュート中\",\n \"voiceMutedHint\": \"マイクをタップしてもう一度お話しください。\",\n \"voicePhaseListening\": \"聞き取り中\",\n \"voicePhaseSpeaking\": \"発答中\",\n \"voicePhaseThinking\": \"考え中\",\n \"voiceSending\": \"受け取りました — 送信中…\",\n \"termsStepTitle\": \"プライバシーと利用規約\",\n \"termsStepSubtitle\": \"透明性、匿名性、そして個人を特定しない設計。\",\n \"termsPiiTitle\": \"個人を特定する情報の不収集\",\n \"termsPiiDesc\": \"チャットや音声セッションから個人を特定できる情報(メールアドレス、電話番号、実名など)を収集・保存することは一切ありません。\",\n \"termsSessionTitle\": \"匿名のセッション識別子\",\n \"termsSessionDesc\": \"コンテキストを維持するためにクライアント側で生成された匿名トークンのみを使用し、実際の身元と紐付けることはありません。\",\n \"termsMemoryTitle\": \"一時的なチャット vs Mimi Vault\",\n \"termsMemoryDesc\": \"通常のチャットは一時的なものです。タブを閉じるかチャットを消去すると完全に破棄されます。「@kiku」で保存したアイテムは暗号化され、mimi.akropolys.cloud でシークレットキーを使ってロック解除できます。\",\n \"termsCookieTitle\": \"ホストサイトのテレメトリ\",\n \"termsCookieDesc\": \"kikuが埋め込まれているホストサイトは、独自のクッキーポリシーに基づいてクッキーやアクセス解析を収集する場合があります(kikuの管理外)。\",\n \"termsAgreeButton\": \"同意して続行\",\n \"termsAgreeCounting\": \"同意して続行 ({seconds}秒)\",\n \"termsPlaceholder\": \"上記のプライバシーと規約をご確認いただき、同意してください…\",\n \"whatHaveYouSaved\": \"何を保存しましたか?\",\n \"retry\": \"再試行\",\n \"edit\": \"編集\",\n \"copy\": \"コピー\",\n \"copied\": \"コピー完了\",\n \"msgFailed\": \"送信に失敗しました\"\n },\n \"portuguese\": {\n \"allSet\": \"Tudo pronto, {name}.\",\n \"asWritten\": \"Como escrito\",\n \"captureAll\": \"Capturar tudo ({count})\",\n \"captureAndRemember\": \"kiku — capturar & lembrar\",\n \"captureCurrentPage\": \"Capturar página atual\",\n \"cardClickAnswer\": \"O {name}\",\n \"cardClickQuery\": \"Fale mais sobre o {name}{price} — quais são seus detalhes principais, para quem é mais indicado e o que devo saber?\",\n \"clearChat\": \"Limpar chat\",\n \"defaultPlaceholder\": \"Pergunte-me qualquer coisa…\",\n \"deleteThis\": \"Excluir isso\",\n \"detailsTranslated\": \"Detalhes traduzidos. Números e links permanecem exatamente como listados.\",\n \"displayCapture\": \"capturar {name}\",\n \"displayCaptureAll\": \"capturar tudo ({count} itens)\",\n \"displayDelete\": \"excluir isso\",\n \"displayViewHistory\": \"o que você salvou?\",\n \"entityLangIntro\": \"Respondo em {lang}. Os cartões podem ficar no original ou ser traduzidos.\",\n \"entityLangPlaceholder\": \"Escolha um dos dois cartões acima…\",\n \"errAccessRevoked\": \"Seu acesso ao assistente foi revogado pela loja.\",\n \"errAccountRequired\": \"Por favor, crie uma conta para continuar usando o assistente de chat.\",\n \"errShopperReplyLimit\": \"Você atingiu o limite de respostas deste site para sua conta.\",\n \"errStreamInterrupted\": \"A resposta foi interrompida. Por favor, tente novamente.\",\n \"errTokenLimit\": \"Você atingiu seu limite de uso. Atualize seus limites de cobrança no painel para continuar.\",\n \"errTooManyRequests\": \"O assistente está recebendo muitas solicitações no momento. Por favor, tente novamente em alguns instantes.\",\n \"footerHint\": \"kiku · pesquisa todo o catálogo em tempo real\",\n \"greetReturning\": \"Oi, {name}.\",\n \"greetReturningLead\": \"O que posso encontrar para você hoje?\",\n \"howShouldResultsLook\": \"Como os resultados devem aparecer?\",\n \"inLanguage\": \"Em {lang}\",\n \"keyAutoHide\": \"Esconde automaticamente em {seconds}s.\",\n \"keyCopied\": \"Copiado\",\n \"keyCopyId\": \"Copiar id\",\n \"keyCopySecret\": \"Copiar segredo\",\n \"keyCreateNew\": \"Sou novo — criar um\",\n \"keyCreating\": \"Criando…\",\n \"keyDismiss\": \"Fechar\",\n \"keyPastePlaceholder\": \"seu id público…\",\n \"keyPastePrompt\": \"Cole seu id público — ou crie um\",\n \"keyPublicHint\": \"Cole isso em qualquer site para salvar na mesma memória.\",\n \"keyPublicTitle\": \"Seu id público\",\n \"keySecretHint\": \"Mantenha privado — use para desbloquear sua memória.\",\n \"keySecretTitle\": \"Seu segredo — mostrado apenas uma vez\",\n \"keyUseMine\": \"Usar meu id\",\n \"kikuActionUnavailable\": \"Desculpe — essa ação não está disponível neste site.\",\n \"kikuCaptureDbError\": \"Falha ao capturar devido a um erro de banco de dados.\",\n \"kikuCaptureNoContext\": \"Falha ao capturar porque nenhum contexto de página ou produto foi fornecido pelo SDK.\",\n \"kikuCaptureNoUrl\": \"Não foi possível salvar nenhum item — nenhum tinha URL válido.\",\n \"kikuCaptureNoneSelected\": \"Nenhum item foi selecionado para captura.\",\n \"kikuDeleteDbError\": \"Falha ao excluir devido a um erro de banco de dados.\",\n \"kikuDeleteDone\": \"Removido dos seus itens salvos.\",\n \"kikuDeleteNoContext\": \"Falha ao excluir porque nenhum contexto de página foi fornecido para identificar o que excluir.\",\n \"kikuMemoryIntro\": \"Tudo que você capturou em sites está na sua memória privada. Desbloqueie-a com seu segredo:\",\n \"kikuMintNeeded\": \"Para salvar itens entre sites você precisa de uma chave kiku — vou gerar uma para você. Ela será mostrada apenas uma vez, então guarde-a em um local seguro.\",\n \"kikuMintOffer\": \"Posso guardar isso para você e fazer com que siga você entre sites — vou gerar uma chave kiku. Ela será mostrada apenas uma vez, então guarde-a em um local seguro.\",\n \"kikuNeedKeyToUpdate\": \"Insira sua chave kiku para que eu possa encontrar e atualizar seus itens salvos.\",\n \"namePlaceholder\": \"Digite seu nome…\",\n \"nameStepAsk\": \"Como devo chamar você?\",\n \"nameStepLead\": \"Posso pesquisar, visualizar ou salvar qualquer item neste ou em outro site.\",\n \"nameStepTitle\": \"Prazer em conhecê-lo.\",\n \"namesAsWritten\": \"Nomes e detalhes exatamente como o site os lista.\",\n \"pillCompareTop2\": \"Comparar os 2 melhores\",\n \"pillCompareTop2Query\": \"Compare o {a} e o {b}\",\n \"pillFindAlternatives\": \"Encontrar alternativas\",\n \"pillFindAlternativesQuery\": \"Quais são boas alternativas ao {name}?\",\n \"pillMoreOn\": \"Mais sobre {name}\",\n \"pillMoreOnQuery\": \"Fale mais sobre o {name}\",\n \"pillRecommend\": \"Recomendar algo\",\n \"pillRecommendQuery\": \"O que você recomenda para mim?\",\n \"pillShowPopular\": \"Mostrar itens populares\",\n \"pillShowPopularQuery\": \"Quais são os seus itens mais populares?\",\n \"pillSimilarOptions\": \"Opções semelhantes\",\n \"pillSimilarOptionsQuery\": \"Mostre-me mais opções semelhantes ao {name}\",\n \"pillUnder\": \"Abaixo de {amount}\",\n \"pillUnderQuery\": \"Mostre-me opções abaixo de {amount}\",\n \"pillWhichBest\": \"Qual é o melhor?\",\n \"pillWhichBestQuery\": \"Qual você recomendaria e por quê?\",\n \"replyingOriginal\": \"Respondendo em {lang}, resultados como o site escreveu. Pergunte-me qualquer coisa.\",\n \"replyingTranslated\": \"Respondendo em {lang}, resultados também traduzidos. Pergunte-me qualquer coisa.\",\n \"statusSent\": \"Enviado\",\n \"statusStopped\": \"Enviado · resposta interrompida\",\n \"thinking\": \"Pensando\",\n \"thoughtForSeconds\": \"Pensou por {duration}\",\n \"thoughtProcess\": \"Processo de pensamento\",\n \"vizUnavailable\": \"A visualização não pôde ser carregada.\",\n \"termsStepTitle\": \"Privacidade e Termos de Uso\",\n \"termsStepSubtitle\": \"Transparente, anônimo e sem coleta de dados pessoais.\",\n \"termsPiiTitle\": \"Zero Coleta de Dados Pessoais\",\n \"termsPiiDesc\": \"Nunca coletamos nem armazenamos informações de identificação pessoal (sem e-mails, telefones ou identidades reais) das suas conversas ou sessões de voz.\",\n \"termsSessionTitle\": \"Tokens de Sessão Anônimos\",\n \"termsSessionDesc\": \"Sua sessão usa um token anônimo no cliente apenas para manter o contexto. Nunca é vinculado à sua identidade real.\",\n \"termsMemoryTitle\": \"Conversas Efêmeras vs. Cofre Mimi\",\n \"termsMemoryDesc\": \"Conversas normais são efêmeras — fechar ou limpar o chat as apaga para sempre. Itens salvos com \\\"@kiku\\\" são criptografados e podem ser desbloqueados em mimi.akropolys.cloud com sua chave secreta.\",\n \"termsCookieTitle\": \"Telemetria do Site Hospedeiro\",\n \"termsCookieDesc\": \"O site onde o kiku está incorporado pode coletar cookies e análises de acordo com sua própria política de cookies, fora do controle do kiku.\",\n \"termsAgreeButton\": \"Concordar e Continuar\",\n \"termsAgreeCounting\": \"Concordar e Continuar ({seconds}s)\",\n \"termsPlaceholder\": \"Por favor, revise e aceite a privacidade e os termos acima…\",\n \"whatHaveYouSaved\": \"O que você salvou?\",\n \"micDenied\": \"Microfone bloqueado. Permita o acesso ao microfone neste site e tente novamente.\",\n \"micFailed\": \"Não foi possível ouvir. Tente novamente.\",\n \"micInsecure\": \"A voz precisa de uma conexão segura (https).\",\n \"micLangUnsupported\": \"Este navegador ainda não transcreve este idioma. Digite em vez disso.\",\n \"micMissing\": \"Nenhum microfone encontrado.\",\n \"micNetwork\": \"A voz precisa de uma conexão no momento. Verifique a sua e tente novamente.\",\n \"micNoSpeech\": \"Não ouvimos nada. Tente novamente, um pouco mais perto do microfone.\",\n \"vizDisclaimerImage\": \"Gerado com Inteligência Artificial — cores, tamanho e posição podem diferir do produto real.\",\n \"vizDisclaimerVideo\": \"Gerado com Inteligência Artificial — cores, tamanho e movimento podem diferir do produto real.\",\n \"voiceHint\": \"Basta falar — responderei quando você fizer uma pausa.\",\n \"voiceListening\": \"Ouvindo… toque no microfone para parar\",\n \"voiceModeExit\": \"Sair do modo mãos-livres\",\n \"voiceModeStart\": \"Conversa em mãos-livres\",\n \"voiceMuted\": \"Silenciado\",\n \"voiceMutedHint\": \"Toque no microfone para falar novamente.\",\n \"voicePhaseListening\": \"Ouvindo\",\n \"voicePhaseSpeaking\": \"Falando\",\n \"voicePhaseThinking\": \"Pensando\",\n \"voiceSending\": \"Entendido — enviando…\",\n \"retry\": \"Tentar novamente\",\n \"edit\": \"Editar\",\n \"copy\": \"Copiar\",\n \"copied\": \"Copiado\",\n \"msgFailed\": \"Falha ao enviar\"\n },\n \"spanish\": {\n \"allSet\": \"Todo listo, {name}.\",\n \"asWritten\": \"Tal como está escrito\",\n \"captureAll\": \"Capturar todo ({count})\",\n \"captureAndRemember\": \"kiku — capturar y recordar\",\n \"captureCurrentPage\": \"Capturar página actual\",\n \"cardClickAnswer\": \"El {name}\",\n \"cardClickQuery\": \"Cuéntame más sobre {name}{price} — ¿cuáles son sus detalles clave, para quién es más adecuado y qué debería saber?\",\n \"clearChat\": \"Borrar chat\",\n \"defaultPlaceholder\": \"Pregúntame lo que quieras…\",\n \"deleteThis\": \"Eliminar esto\",\n \"detailsTranslated\": \"Detalles traducidos. Los números y enlaces se mantienen exactamente como se muestran.\",\n \"displayCapture\": \"capturar {name}\",\n \"displayCaptureAll\": \"capturar todo ({count} elementos)\",\n \"displayDelete\": \"eliminar esto\",\n \"displayViewHistory\": \"¿qué has guardado?\",\n \"entityLangIntro\": \"Respondo en {lang}. Las tarjetas pueden mostrarse en versión original o traducirse.\",\n \"entityLangPlaceholder\": \"Elige una de las dos tarjetas de arriba…\",\n \"errAccessRevoked\": \"La tienda ha revocado su acceso al asistente.\",\n \"errAccountRequired\": \"Por favor, cree una cuenta para seguir usando el asistente de chat.\",\n \"errShopperReplyLimit\": \"Ha alcanzado el límite de respuestas de este sitio para su cuenta.\",\n \"errStreamInterrupted\": \"La respuesta fue interrumpida. Por favor, inténtelo de nuevo.\",\n \"errTokenLimit\": \"Ha alcanzado su límite de uso. Por favor, actualice sus límites de facturación en su panel de control para continuar.\",\n \"errTooManyRequests\": \"El asistente está recibiendo demasiadas solicitudes en este momento. Por favor, inténtelo de nuevo en unos instantes.\",\n \"footerHint\": \"kiku · busca en todo el catálogo en tiempo real\",\n \"greetReturning\": \"Hola, {name}.\",\n \"greetReturningLead\": \"¿Qué puedo encontrar para usted hoy?\",\n \"howShouldResultsLook\": \"¿Cómo deberían verse los resultados?\",\n \"inLanguage\": \"En {lang}\",\n \"keyAutoHide\": \"Se oculta automáticamente en {seconds}s.\",\n \"keyCopied\": \"Copiado\",\n \"keyCopyId\": \"Copiar ID\",\n \"keyCopySecret\": \"Copiar secreto\",\n \"keyCreateNew\": \"Soy nuevo/a, crear uno\",\n \"keyCreating\": \"Creando…\",\n \"keyDismiss\": \"Descartar\",\n \"keyPastePlaceholder\": \"tu ID público…\",\n \"keyPastePrompt\": \"Pega tu ID público — o crea uno\",\n \"keyPublicHint\": \"Pégalo en cualquier sitio para guardar en la misma memoria.\",\n \"keyPublicTitle\": \"Tu ID público\",\n \"keySecretHint\": \"Mantenlo privado — úsalo para desbloquear tu memoria.\",\n \"keySecretTitle\": \"Tu secreto — mostrado solo una vez\",\n \"keyUseMine\": \"Usar mi ID\",\n \"kikuActionUnavailable\": \"Lo siento, esa acción no está disponible en este sitio.\",\n \"kikuCaptureDbError\": \"La captura falló debido a un error de base de datos.\",\n \"kikuCaptureNoContext\": \"La captura falló porque el SDK no proporcionó contexto de página o producto.\",\n \"kikuCaptureNoUrl\": \"No se pudieron guardar elementos — ninguno tenía una URL válida.\",\n \"kikuCaptureNoneSelected\": \"No se seleccionaron elementos para capturar.\",\n \"kikuDeleteDbError\": \"La eliminación falló debido a un error de base de datos.\",\n \"kikuDeleteDone\": \"Lo he eliminado de tus elementos guardados.\",\n \"kikuDeleteNoContext\": \"La eliminación falló porque no se proporcionó contexto de página para identificar qué eliminar.\",\n \"kikuMemoryIntro\": \"Todo lo que has capturado en diferentes sitios vive en tu memoria privada. Desbloquéala con tu secreto:\",\n \"kikuMintNeeded\": \"Para guardar elementos en diferentes sitios necesitas una clave kiku — te crearé una. Se muestra solo una vez, así que guárdala en un lugar seguro.\",\n \"kikuMintOffer\": \"Puedo guardar esto por ti y hacer que te siga en diferentes sitios — te crearé una clave kiku. Se muestra solo una vez, así que guárdala en un lugar seguro.\",\n \"kikuNeedKeyToUpdate\": \"Introduce tu clave kiku para que pueda encontrar y actualizar tus elementos guardados.\",\n \"micDenied\": \"Micrófono bloqueado. Permite el acceso al micrófono para este sitio e inténtalo de nuevo.\",\n \"micFailed\": \"No pude oír eso. Inténtalo de nuevo.\",\n \"micInsecure\": \"La voz requiere una conexión segura (https).\",\n \"micLangUnsupported\": \"Este navegador aún no puede transcribir ese idioma. Escriba en su lugar.\",\n \"micMissing\": \"No se encontró ningún micrófono.\",\n \"micNetwork\": \"La voz necesita una conexión en este momento. Revise la suya e inténtelo de nuevo.\",\n \"micNoSpeech\": \"No he captado nada. Inténtelo de nuevo, un poco más cerca del micrófono.\",\n \"namePlaceholder\": \"Escriba su nombre…\",\n \"nameStepAsk\": \"¿Cómo debo llamarle?\",\n \"nameStepLead\": \"Puedo buscar, visualizar o guardar cualquier producto en este u otro sitio.\",\n \"nameStepTitle\": \"Encantado de conocerle.\",\n \"namesAsWritten\": \"Nombres y detalles exactamente como los enumera el sitio.\",\n \"pillCompareTop2\": \"Comparar los 2 mejores\",\n \"pillCompareTop2Query\": \"Compara {a} y {b}\",\n \"pillFindAlternatives\": \"Buscar alternativas\",\n \"pillFindAlternativesQuery\": \"¿Qué alternativas hay a {name}?\",\n \"pillMoreOn\": \"Más sobre {name}\",\n \"pillMoreOnQuery\": \"Cuéntame más sobre {name}\",\n \"pillRecommend\": \"Recomendar algo\",\n \"pillRecommendQuery\": \"¿Qué me recomiendas?\",\n \"pillShowPopular\": \"Mostrar artículos populares\",\n \"pillShowPopularQuery\": \"¿Cuáles son tus artículos más populares?\",\n \"pillSimilarOptions\": \"Opciones similares\",\n \"pillSimilarOptionsQuery\": \"Muéstrame más opciones como {name}\",\n \"pillUnder\": \"Menos de {amount}\",\n \"pillUnderQuery\": \"Muéstrame opciones por menos de {amount}\",\n \"pillWhichBest\": \"¿Cuál es el mejor?\",\n \"pillWhichBestQuery\": \"¿Cuál me recomendarías y por qué?\",\n \"replyingOriginal\": \"Respondiendo en {lang}, resultados tal como los escribió este sitio. Pregúnteme lo que quiera.\",\n \"replyingTranslated\": \"Respondiendo en {lang}, resultados también traducidos. Pregúnteme lo que quiera.\",\n \"statusSent\": \"Enviado\",\n \"statusStopped\": \"Enviado · respuesta detenida\",\n \"thinking\": \"Pensando\",\n \"thoughtForSeconds\": \"Pensado durante {duration}\",\n \"thoughtProcess\": \"Proceso de pensamiento\",\n \"vizDisclaimerImage\": \"Generado con Inteligencia Artificial: los colores, el tamaño y la ubicación pueden diferir del producto real.\",\n \"vizDisclaimerVideo\": \"Generado con Inteligencia Artificial: los colores, el tamaño y el movimiento pueden diferir del producto real.\",\n \"vizUnavailable\": \"No se pudo cargar la vista previa.\",\n \"voiceListening\": \"Escuchando… toque el micrófono para detener.\",\n \"voiceSending\": \"Entendido, enviando…\",\n \"termsStepTitle\": \"Privacidad y términos de uso\",\n \"termsStepSubtitle\": \"Transparente, anónimo y sin recolección de datos personales.\",\n \"termsPiiTitle\": \"Cero recolección de datos personales\",\n \"termsPiiDesc\": \"Nunca recopilamos ni almacenamos información de identificación personal (sin correos, números de teléfono ni identidades reales) de tus conversaciones o sesiones de voz.\",\n \"termsSessionTitle\": \"Tokens de sesión anónimos\",\n \"termsSessionDesc\": \"Tu sesión utiliza un token anónimo generado en el cliente únicamente para mantener el contexto. Nunca se vincula a tu identidad real.\",\n \"termsMemoryTitle\": \"Chats efímeros vs. Bóveda Mimi\",\n \"termsMemoryDesc\": \"Las conversaciones regulares son efímeras: cerrar o borrar el chat las elimina para siempre. Lo que guardas con «@kiku» está cifrado y se puede desbloquear en mimi.akropolys.cloud con tu clave secreta.\",\n \"termsCookieTitle\": \"Telemetría del sitio web anfitrión\",\n \"termsCookieDesc\": \"El sitio web donde está integrado kiku puede recopilar cookies y analíticas según su propia política de cookies, fuera del control de kiku.\",\n \"termsAgreeButton\": \"Aceptar y continuar\",\n \"termsAgreeCounting\": \"Aceptar y continuar ({seconds}s)\",\n \"termsPlaceholder\": \"Por favor, revisa y acepta nuestra privacidad y términos arriba…\",\n \"whatHaveYouSaved\": \"¿Qué ha guardado?\",\n \"voiceHint\": \"Solo habla — responderé cuando hagas una pausa.\",\n \"voiceModeExit\": \"Salir de manos libres\",\n \"voiceModeStart\": \"Conversación manos libres\",\n \"voiceMuted\": \"Silenciado\",\n \"voiceMutedHint\": \"Toca el micrófono para hablar de nuevo.\",\n \"voicePhaseListening\": \"Escuchando\",\n \"voicePhaseSpeaking\": \"Hablando\",\n \"voicePhaseThinking\": \"Pensando\",\n \"retry\": \"Reintentar\",\n \"edit\": \"Editar\",\n \"copy\": \"Copiar\",\n \"copied\": \"Copiado\",\n \"msgFailed\": \"Error al enviar\"\n },\n \"swahili\": {\n \"allSet\": \"Uko tayari, {name}.\",\n \"asWritten\": \"Kama ilivyoandikwa\",\n \"captureAll\": \"Chukua zote ({count})\",\n \"captureAndRemember\": \"kiku — chukua & kumbuka\",\n \"captureCurrentPage\": \"Chukua ukurasa wa sasa\",\n \"cardClickAnswer\": \"{name}\",\n \"cardClickQuery\": \"Nisaidie kujua zaidi kuhusu {name}{price} — ni maelezo yake muhimu, ni kwa nani inafaa zaidi, na ninapaswa kujua nini?\",\n \"clearChat\": \"Futa mazungumzo\",\n \"defaultPlaceholder\": \"Uliza chochote…\",\n \"deleteThis\": \"Futa hii\",\n \"detailsTranslated\": \"Maelezo yame tafsiriwa. Nambari na viungo vinabaki kama ilivyo.\",\n \"displayCapture\": \"chukua {name}\",\n \"displayCaptureAll\": \"chukua zote ({count} items)\",\n \"displayDelete\": \"futa hii\",\n \"displayViewHistory\": \"ulivyohifadhi?\",\n \"entityLangIntro\": \"Nitajibu kwa {lang}. Kadi zinaweza kubaki zilivyo au kutafsiriwa.\",\n \"entityLangPlaceholder\": \"Chagua moja ya kadi mbili zilizo juu…\",\n \"errAccessRevoked\": \"Ufikiaji wako kwa msaidizi umeondolewa na duka.\",\n \"errAccountRequired\": \"Tafadhali unda akaunti ili kuendelea kutumia msaidizi wa mazungumzo.\",\n \"errShopperReplyLimit\": \"Umefikia kikomo cha majibu cha tovuti hii kwa akaunti yako.\",\n \"errStreamInterrupted\": \"Jibu lilikatizwa. Tafadhali jaribu tena.\",\n \"errTokenLimit\": \"Umefikia kikomo cha matumizi yako. Tafadhali sasisha mipaka ya malipo kwenye dashbodi yako ili kuendelea.\",\n \"errTooManyRequests\": \"Msaidizi anapokea maombi mengi sana kwa sasa. Tafadhali jaribu tena baada ya muda mfupi.\",\n \"footerHint\": \"kiku · hutafuta katika katalogi nzima kwa wakati halisi\",\n \"greetReturning\": \"Habari, {name}.\",\n \"greetReturningLead\": \"Nini naweza kukutafuta leo?\",\n \"howShouldResultsLook\": \"Matokeo yanapaswa kuonekana vipi?\",\n \"inLanguage\": \"Kwa {lang}\",\n \"keyAutoHide\": \"Inaficha kiotomatiki baada ya {seconds}s.\",\n \"keyCopied\": \"Imekopiwa\",\n \"keyCopyId\": \"Nakili kitambulisho\",\n \"keyCopySecret\": \"Nakili siri\",\n \"keyCreateNew\": \"Mimi mpya — unda moja\",\n \"keyCreating\": \"Inaunda…\",\n \"keyDismiss\": \"Ondoa\",\n \"keyPastePlaceholder\": \"kitambulisho chako cha umma…\",\n \"keyPastePrompt\": \"Bandika kitambulisho chako cha umma — au unda moja\",\n \"keyPublicHint\": \"Bandika hii kwenye tovuti yoyote ili kuihifadhi katika kumbukumbu sawa.\",\n \"keyPublicTitle\": \"Kitambulisho chako cha umma\",\n \"keySecretHint\": \"Ikeepye kibinafsi — tumia kufungua kumbukumbu yako.\",\n \"keySecretTitle\": \"Siri yako — inaonyeshwa mara moja tu\",\n \"keyUseMine\": \"Tumia kitambulisho changu\",\n \"kikuActionUnavailable\": \"Samahani — kitendo hicho hakipatikani kwenye tovuti hii.\",\n \"kikuCaptureDbError\": \"Uchukuaji umeshindwa kutokana na hitilafu ya hifadhidata.\",\n \"kikuCaptureNoContext\": \"Uchukuaji umeshindwa kwa sababu hakuna muktadha wa ukurasa au bidhaa uliotolewa na SDK.\",\n \"kikuCaptureNoUrl\": \"Haikuweza kuhifadhi vitu vyovyote — hakuna kilichokuwa na URL halali.\",\n \"kikuCaptureNoneSelected\": \"Hakuna vitu vilivyochaguliwa kwa uchukuaji.\",\n \"kikuDeleteDbError\": \"Ufutaji umeshindwa kutokana na hitilafu ya hifadhidata.\",\n \"kikuDeleteDone\": \"Imeondolewa kutoka vitu vyako vilivyohifadhiwa.\",\n \"kikuDeleteNoContext\": \"Ufutaji umeshindwa kwa sababu hakuna muktadha wa ukurasa uliotolewa kutambua kinachofutwa.\",\n \"kikuMemoryIntro\": \"Kila kitu ulichukua kwenye tovuti mbalimbali kiko katika kumbukumbu yako ya kibinafsi. Kifungue kwa siri yako:\",\n \"kikuMintNeeded\": \"Ili kuhifadhi vitu kwenye tovuti mbalimbali unahitaji ufunguo wa kiku — nitaunda moja kwa ajili yako. Inaonyeshwa mara moja tu, hivyo uiweke mahali salama.\",\n \"kikuMintOffer\": \"Ninaweza kuhifadhi hii kwa ajili yako na iende nawe kwenye tovuti mbalimbali — nitaunda ufunguo wa kiku. Inaonyeshwa mara moja tu, hivyo uiweke mahali salama.\",\n \"kikuNeedKeyToUpdate\": \"Weka ufunguo wako wa kiku ili niweze kupata na kusasisha vitu vyako vilivyohifadhiwa.\",\n \"micDenied\": \"Kinanda cha sauti kimezuiwa. Ruhusu ufikiaji wa kinanda kwa tovuti hii, kisha jaribu tena.\",\n \"micFailed\": \"Sikuweza kusikia hilo. Jaribu tena.\",\n \"micInsecure\": \"Sauti inahitaji muunganisho salama (https).\",\n \"micLangUnsupported\": \"Kivinjari hiki hakiwezi kuandika lugha hiyo bado. Andika badala yake.\",\n \"micMissing\": \"Hakuna kipaza sauti kilichopatikana.\",\n \"micNetwork\": \"Sauti inahitaji muunganisho kwa sasa. Angalia yako na ujaribu tena.\",\n \"micNoSpeech\": \"Sijapata chochote. Jaribu tena, karibu zaidi na kipaza sauti.\",\n \"namePlaceholder\": \"Andika jina lako…\",\n \"nameStepAsk\": \"Ninapaswa kukuita nani?\",\n \"nameStepLead\": \"Ninaweza kutafuta, kuonyesha, au kunasa chochote kwa ajili yako — kwenye tovuti hii au nyingine yoyote.\",\n \"nameStepTitle\": \"Nafurahi kukutana nawe.\",\n \"namesAsWritten\": \"Majina na maelezo kama ilivyo kwenye tovuti.\",\n \"pillCompareTop2\": \"Linganisha bora 2\",\n \"pillCompareTop2Query\": \"Linganisha {a} na {b}\",\n \"pillFindAlternatives\": \"Tafuta mbadala\",\n \"pillFindAlternativesQuery\": \"Ni mbadala gani mazuri kwa {name}?\",\n \"pillMoreOn\": \"Zaidi kuhusu {name}\",\n \"pillMoreOnQuery\": \"Nisaidie kujua zaidi kuhusu {name}\",\n \"pillRecommend\": \"Pendekeza kitu\",\n \"pillRecommendQuery\": \"Unaweza kunipendekeza nini?\",\n \"pillShowPopular\": \"Onyesha vitu maarufu\",\n \"pillShowPopularQuery\": \"Ni bidhaa gani zimekuwa maarufu zaidi?\",\n \"pillSimilarOptions\": \"Chaguzi zinazofanana\",\n \"pillSimilarOptionsQuery\": \"Nionyeshe zaidi kama {name}\",\n \"pillUnder\": \"Chini ya {amount}\",\n \"pillUnderQuery\": \"Nionyeshe chaguo chini ya {amount}\",\n \"pillWhichBest\": \"Ni ipi bora?\",\n \"pillWhichBestQuery\": \"Ni ipi unayopendekeza na kwa nini?\",\n \"replyingOriginal\": \"Ninajibu kwa {lang}, matokeo kama ilivyoandikwa kwenye tovuti hii. Uliza chochote.\",\n \"replyingTranslated\": \"Ninajibu kwa {lang}, matokeo yamefasiriwa pia. Uliza chochote.\",\n \"statusSent\": \"Imetumwa\",\n \"statusStopped\": \"Imetumwa · majibu yametolewa\",\n \"thinking\": \"Inafikiri\",\n \"thoughtForSeconds\": \"Imefikiri kwa {duration}\",\n \"thoughtProcess\": \"Mchakato wa mawazo\",\n \"vizDisclaimerImage\": \"Imetengenezwa kwa kutumia Akili Bandia — rangi, ukubwa na upangaji huenda yakatofautiana na bidhaa halisi.\",\n \"vizDisclaimerVideo\": \"Imetengenezwa kwa kutumia Akili Bandia — rangi, ukubwa na mwendo huenda yakatofautiana na bidhaa halisi.\",\n \"vizUnavailable\": \"Hakuna uwezo wa kupakia onyesho la awali.\",\n \"voiceListening\": \"Inasikiliza… gonga kipaza sauti ili kusimama\",\n \"voiceSending\": \"Nimepokea — ninatuma…\",\n \"termsStepTitle\": \"Faragha na Masharti ya Matumizi\",\n \"termsStepSubtitle\": \"Wazi, bila utambulisho, na bila kukusanya taarifa binafsi.\",\n \"termsPiiTitle\": \"Hakuna Ukusanyaji wa Taarifa Binafsi\",\n \"termsPiiDesc\": \"Hatukusanyi wala kuhifadhi taarifa za utambulisho binafsi (hakuna barua pepe, nambari za simu, wala majina halisi) kutoka kwa mazungumzo yako au sauti.\",\n \"termsSessionTitle\": \"Vitambulisho Visivyojulikana vya Kipindi\",\n \"termsSessionDesc\": \"Kipindi chako kinatumia kitambulisho kisichojulikana upande wa mteja ili kuendeleza muktadha tu. Hakihusishwi na utambulisho wako halisi.\",\n \"termsMemoryTitle\": \"Mazungumzo ya Muda dhidi ya Hazina ya Mimi\",\n \"termsMemoryDesc\": \"Mazungumzo ya kawaida ni ya muda — kufunga au kufuta mazungumzo kunayaondoa kabisa. Vitu unavyohifadhi kwa \\\"@kiku\\\" vimelindwa na vinaweza kufunguliwa kwenye mimi.akropolys.cloud kwa ufunguo wako wa siri.\",\n \"termsCookieTitle\": \"Takwimu za Tovuti Mwenyeji\",\n \"termsCookieDesc\": \"Tovuti inayotumia kiku inaweza kukusanya vidakuzi na takwimu kulingana na sera yake ya vidakuzi, nje ya udhibiti wa kiku.\",\n \"termsAgreeButton\": \"Kubali na Uendelee\",\n \"termsAgreeCounting\": \"Kubali na Uendelee ({seconds}s)\",\n \"termsPlaceholder\": \"Tafadhali kagua na ukubali sera ya faragha na masharti hapo juu…\",\n \"whatHaveYouSaved\": \"Umehifadhi nini?\",\n \"voiceHint\": \"Ongea tu — nitajibu ukipumzika.\",\n \"voiceModeExit\": \"Ondoka kwenye hali ya bila mikono\",\n \"voiceModeStart\": \"Mazungumzo ya bila mikono\",\n \"voiceMuted\": \"Imezimwa sauti\",\n \"voiceMutedHint\": \"Gonga kipaza sauti ili kuongea tena.\",\n \"voicePhaseListening\": \"Inasikiliza\",\n \"voicePhaseSpeaking\": \"Inazungumza\",\n \"voicePhaseThinking\": \"Inafikiri\",\n \"retry\": \"Jaribu tena\",\n \"edit\": \"Hariri\",\n \"copy\": \"Nakili\",\n \"copied\": \"Imenakiliwa\",\n \"msgFailed\": \"Imeshindwa kutuma\"\n },\n \"urdu\": {\n \"allSet\": \"آپ بالکل تیار ہیں، {name}۔\",\n \"asWritten\": \"جیسا لکھا ہے\",\n \"captureAll\": \"سب محفوظ کریں ({count})\",\n \"captureAndRemember\": \"kiku — محفوظ کریں اور یاد رکھیں\",\n \"captureCurrentPage\": \"موجودہ صفحہ محفوظ کریں\",\n \"cardClickAnswer\": \"{name}\",\n \"cardClickQuery\": \"مجھے {name}{price} کے بارے میں مزید بتائیں — اس کی اہم خصوصیات کیا ہیں، یہ کس کے لیے بہترین ہے، اور مجھے کیا جاننا چاہیے؟\",\n \"clearChat\": \"چیٹ صاف کریں\",\n \"defaultPlaceholder\": \"مجھ سے کچھ بھی پوچھیں…\",\n \"deleteThis\": \"اسے حذف کریں\",\n \"detailsTranslated\": \"تفصیلات کا ترجمہ کر دیا گیا۔ قیمتیں اور لنکس ویسے ہی رہیں گے۔\",\n \"displayCapture\": \"{name} کو محفوظ کریں\",\n \"displayCaptureAll\": \"سب محفوظ کریں ({count} اشیاء)\",\n \"displayDelete\": \"اسے حذف کریں\",\n \"displayViewHistory\": \"آپ نے کیا محفوظ کیا ہے؟\",\n \"entityLangIntro\": \"میں {lang} میں جواب دیتا ہوں۔ کارڈز اصل زبان میں یا ترجمہ شدہ دیکھے جا سکتے ہیں۔\",\n \"entityLangPlaceholder\": \"اوپر دیے گئے دو کارڈز میں سے ایک منتخب کریں…\",\n \"errAccessRevoked\": \"اسٹور کی طرف سے اسسٹنٹ تک آپ کی رسائی منسوخ کر دی گئی ہے۔\",\n \"errAccountRequired\": \"چیٹ اسسٹنٹ کا استعمال جاری رکھنے کے لیے برائے مہربانی اکاؤنٹ بنائیں۔\",\n \"errShopperReplyLimit\": \"آپ اس سائٹ پر اپنے اکاؤنٹ کی جوابات کی حد تک پہنچ چکے ہیں۔\",\n \"errStreamInterrupted\": \"جواب میں خلل پڑ گیا۔ برائے مہربانی دوبارہ کوشش کریں۔\",\n \"errTokenLimit\": \"آپ کے استعمال کی حد ختم ہو چکی ہے۔ جاری رکھنے کے لیے اپنے ڈیش بورڈ میں بلنگ کی حد اپ ڈیٹ کریں۔\",\n \"errTooManyRequests\": \"اسسٹنٹ پر اس وقت بہت زیادہ درخواستیں آرہی ہیں۔ برائے مہربانی تھوڑی دیر بعد کوشش کریں۔\",\n \"footerHint\": \"kiku · حقیقی وقت میں مکمل کیٹلاگ تلاش کرتا ہے\",\n \"greetReturning\": \"خوش آمدید، {name}۔\",\n \"greetReturningLead\": \"آج میں آپ کے لیے کیا تلاش کر سکتا ہوں؟\",\n \"howShouldResultsLook\": \"نتائج کیسی دکھنی چاہئیں؟\",\n \"inLanguage\": \"{lang} میں\",\n \"keyAutoHide\": \"{seconds} سیکنڈ میں خود بخود چھپ جائے گا۔\",\n \"keyCopied\": \"کاپی ہو گیا\",\n \"keyCopyId\": \"آئی ڈی کاپی کریں\",\n \"keyCopySecret\": \"خفیہ کلید کاپی کریں\",\n \"keyCreateNew\": \"میں نیا ہوں — نئی بنائیں\",\n \"keyCreating\": \"بنایا جا رہا ہے…\",\n \"keyDismiss\": \"رد کریں\",\n \"keyPastePlaceholder\": \"آپ کی پبلک آئی ڈی…\",\n \"keyPastePrompt\": \"اپنی پبلک آئی ڈی چسپاں کریں — یا نئی بنائیں\",\n \"keyPublicHint\": \"اسی یادداشت میں محفوظ کرنے کے لیے اسے کسی بھی سائٹ پر چسپاں کریں۔\",\n \"keyPublicTitle\": \"آپ کی پبلک آئی ڈی\",\n \"keySecretHint\": \"اسے خفیہ رکھیں — اپنی یادداشت کو کھولنے کے لیے استعمال کریں۔\",\n \"keySecretTitle\": \"آپ کی خفیہ کلید — صرف ایک بار دکھائی جائے گی\",\n \"keyUseMine\": \"میری آئی ڈی استعمال کریں\",\n \"kikuActionUnavailable\": \"معذرت — یہ عمل اس سائٹ پر دستیاب نہیں ہے۔\",\n \"kikuCaptureDbError\": \"ڈیٹا بیس کی خرابی کی وجہ سے محفوظ کرنے میں ناکامی۔\",\n \"kikuCaptureNoContext\": \"صفحے کا سیاق و سباق نہ ملنے کی وجہ سے محفوظ کرنے میں ناکامی۔\",\n \"kikuCaptureNoUrl\": \"کوئی آئٹم محفوظ نہیں ہو سکا کیونکہ کسی کے پاس درست URL نہیں تھا۔\",\n \"kikuCaptureNoneSelected\": \"محفوظ کرنے کے لیے کوئی آئٹم منتخب نہیں کیا گیا۔\",\n \"kikuDeleteDbError\": \"ڈیٹا بیس کی خرابی کی وجہ سے حذف کرنے میں ناکامی۔\",\n \"kikuDeleteDone\": \"آپ کی محفوظ کردہ اشیاء سے ہٹا دیا گیا۔\",\n \"kikuDeleteNoContext\": \"حذف کرنے کے لیے صفحے کا سیاق و سباق فراہم نہیں کیا گیا۔\",\n \"kikuMemoryIntro\": \"سائٹس بھر میں محفوظ کردہ تمام چیزیں آپ کی نجی یادداشت میں ہیں۔ اپنی خفیہ کلید سے کھولیں:\",\n \"kikuMintNeeded\": \"سائٹس پر چیزیں محفوظ کرنے کے لیے آپ کو kiku کی ضرورت ہے — میں آپ کے لیے ایک کلید بناؤں گا۔ یہ صرف ایک بار دکھائی جاتی ہے، اسے محفوظ رکھیں۔\",\n \"kikuMintOffer\": \"میں اسے آپ کے لیے محفوظ رکھ سکتا ہوں — میں آپ کے لیے ایک kiku کلید بناؤں گا۔ یہ صرف ایک بار دکھائی جاتی ہے۔\",\n \"kikuNeedKeyToUpdate\": \"اپنی kiku کلید درج کریں تاکہ میں آپ کی محفوظ کردہ اشیاء تلاش اور اپ ڈیٹ کر سکوں۔\",\n \"micDenied\": \"مائیکروفون بلاک ہے۔ اس سائٹ کے لیے مائیک کی اجازت دیں اور دوبارہ کوشش کریں۔\",\n \"micFailed\": \"آواز سنائی نہیں دی۔ دوبارہ کوشش کریں۔\",\n \"micInsecure\": \"آواز کے لیے محفوظ (https) کنکشن درکار ہے۔\",\n \"micLangUnsupported\": \"یہ براؤزر ابھی اس زبان کو نہیں سمجھ سکتا۔ براہ کرم ٹائپ کریں۔\",\n \"micMissing\": \"کوئی مائیکروفون نہیں ملا۔\",\n \"micNetwork\": \"آواز کے لیے انٹرنیٹ کنکشن درکار ہے۔ اپنا کنکشن چیک کریں اور دوبارہ کوشش کریں۔\",\n \"micNoSpeech\": \"کچھ سنائی نہیں دیا۔ مائیک کے قریب آ کر دوبارہ بولیں۔\",\n \"namePlaceholder\": \"اپنا نام لکھیں…\",\n \"nameStepAsk\": \"میں آپ کو کس نام سے پکاروں؟\",\n \"nameStepLead\": \"میں آپ کے لیے اس سائٹ یا کسی دوسری سائٹ پر کچھ بھی تلاش، تصور یا محفوظ کر سکتا ہوں۔\",\n \"nameStepTitle\": \"آپ سے مل کر خوشی ہوئی۔\",\n \"namesAsWritten\": \"نام اور تفصیلات بالکل ویسے جیسے سائٹ پر درج ہیں۔\",\n \"pillCompareTop2\": \"بہترین 2 کا موازنہ کریں\",\n \"pillCompareTop2Query\": \"{a} اور {b} کا موازنہ کریں\",\n \"pillFindAlternatives\": \"متبادل تلاش کریں\",\n \"pillFindAlternativesQuery\": \"{name} کے اچھے متبادل کیا ہیں؟\",\n \"pillMoreOn\": \"{name} کے بارے میں مزید\",\n \"pillMoreOnQuery\": \"مجھے {name} کے بارے میں مزید بتائیں\",\n \"pillRecommend\": \"کچھ تجویز کریں\",\n \"pillRecommendQuery\": \"آپ میرے لیے کیا تجویز کرتے ہیں؟\",\n \"pillShowPopular\": \"مقبول اشیاء دکھائیں\",\n \"pillShowPopularQuery\": \"آپ کی سب سے مقبول اشیاء کون سی ہیں؟\",\n \"pillSimilarOptions\": \"ملتے جلتے اختیارات\",\n \"pillSimilarOptionsQuery\": \"مجھے {name} جیسی مزید چیزیں دکھائیں\",\n \"pillUnder\": \"{amount} سے کم\",\n \"pillUnderQuery\": \"{amount} سے کم قیمت والے اختیارات دکھائیں\",\n \"pillWhichBest\": \"کون سا بہترین ہے؟\",\n \"pillWhichBestQuery\": \"آپ کون سا تجویز کریں گے اور کیوں؟\",\n \"replyingOriginal\": \"میں {lang} میں جواب دے رہا ہوں، نتائج سائٹ کے مطابق ہیں۔ مجھ سے کچھ بھی پوچھیں۔\",\n \"replyingTranslated\": \"میں {lang} میں جواب دے رہا ہوں، نتائج کا ترجمہ بھی کیا گیا ہے۔ مجھ سے کچھ بھی پوچھیں۔\",\n \"statusSent\": \"بھیج دیا گیا\",\n \"statusStopped\": \"بھیج دیا گیا · جواب روک دیا گیا\",\n \"thinking\": \"سوچ رہا ہے\",\n \"thoughtForSeconds\": \"{duration} تک سوچا\",\n \"thoughtProcess\": \"سوچنے کا عمل\",\n \"vizDisclaimerImage\": \"مصنوعی ذہانت سے تیار کردہ — اصل پروڈکٹ سے رنگ، سائز اور جگہ مختلف ہو سکتی ہے۔\",\n \"vizDisclaimerVideo\": \"مصنوعی ذہانت سے تیار کردہ — اصل پروڈکٹ سے رنگ، سائز اور حرکت مختلف ہو سکتی ہے۔\",\n \"vizUnavailable\": \"پیش نظارہ لوڈ نہیں ہو سکا۔\",\n \"voiceHint\": \"بس بات کریں — جب آپ رکیں گے تو میں جواب دوں گا۔\",\n \"voiceListening\": \"سن رہا ہے… روکنے کے لیے مائیک پر ٹیپ کریں\",\n \"voiceModeExit\": \"ہینڈز فری سے نکلیں\",\n \"voiceModeStart\": \"ہینڈز فری گفتگو\",\n \"voiceMuted\": \"خاموش (میوٹ)\",\n \"voiceMutedHint\": \"دوبارہ بولنے کے لیے مائیکروفون پر ٹیپ کریں۔\",\n \"voicePhaseListening\": \"سن رہا ہے\",\n \"voicePhaseSpeaking\": \"بول رہا ہے\",\n \"voicePhaseThinking\": \"سوچ رہا ہے\",\n \"voiceSending\": \"سمجھ گیا — بھیج رہا ہے…\",\n \"termsStepTitle\": \"رازداری اور استعمال کی شرائط\",\n \"termsStepSubtitle\": \"شفاف، گمنام، اور بغیر کسی ذاتی شناختی ڈیٹا کے۔\",\n \"termsPiiTitle\": \"کوئی ذاتی شناختی ڈیٹا اکٹھا نہیں کیا جاتا\",\n \"termsPiiDesc\": \"ہم آپ کی چیٹس یا صوتی گفتگو سے کبھی بھی کوئی ذاتی شناختی معلومات (کوئی ای میل، فون نمبر، یا حقیقی نام) اکٹھا یا محفوظ نہیں کرتے۔\",\n \"termsSessionTitle\": \"گمنام سیشن ٹوکنز\",\n \"termsSessionDesc\": \"آپ کا سیشن صرف سیاق و سباق برقرار رکھنے کے لیے ایک گمنام ٹوکن استعمال کرتا ہے۔ یہ کبھی بھی آپ کی حقیقی شناخت سے نہیں جڑتا۔\",\n \"termsMemoryTitle\": \"عارضی چیٹس بمقابلہ میمی والٹ\",\n \"termsMemoryDesc\": \"عام چیٹس عارضی ہیں — ٹیب بند کرنے یا چیٹ صاف کرنے سے وہ ہمیشہ کے لیے ختم ہو جاتی ہیں۔ وہ چیزیں جو آپ \\\"@kiku\\\" سے محفوظ کرتے ہیں انکرپٹڈ ہوتی ہیں اور انہیں اپنی خفیہ کلید کے ذریعے mimi.akropolys.cloud پر کھولا جا سکتا ہے۔\",\n \"termsCookieTitle\": \"میزبان ویب سائٹ ٹیلی میٹری\",\n \"termsCookieDesc\": \"جس ویب سائٹ پر kiku شامل ہے وہ اپنی کوکی پالیسی کے تحت کوکیز اور اینالیٹکس جمع کر سکتی ہے، جو kiku کے کنٹرول سے باہر ہے۔\",\n \"termsAgreeButton\": \"متفق ہوں اور جاری رکھیں\",\n \"termsAgreeCounting\": \"متفق ہوں اور جاری رکھیں ({seconds}s)\",\n \"termsPlaceholder\": \"برائے مہربانی اوپر دی گئی رازداری اور شرائط کا جائزہ لیں اور قبول کریں…\",\n \"whatHaveYouSaved\": \"آپ نے کیا محفوظ کیا ہے؟\",\n \"retry\": \"دوبارہ کوشش کریں\",\n \"edit\": \"ترمیم کریں\",\n \"copy\": \"کاپی کریں\",\n \"copied\": \"کاپی ہو گیا\",\n \"msgFailed\": \"ارسال ناکام ہو گیا\"\n }\n}\n","import { useState, useRef, useEffect, useCallback } from 'react';\r\nimport type { ChatMessage } from '@akropolys/sdk';\r\n\r\ninterface UseChatScrollOptions {\r\n messages: ChatMessage[];\r\n loading: boolean;\r\n messageRefs: React.MutableRefObject<(HTMLDivElement | null)[]>;\r\n}\r\n\r\nexport function useChatScroll({ messages, loading, messageRefs }: UseChatScrollOptions) {\r\n const msgsContainerRef = useRef<HTMLDivElement>(null);\r\n const lastExternalScrollRef = useRef(0);\r\n const [showJumpToBottom, setShowJumpToBottom] = useState(false);\r\n const [scrollProgress, setScrollProgress] = useState(1);\r\n const [activeMsgIdx, setActiveMsgIdx] = useState(0);\r\n const resyncScrollRef = useRef<() => void>(() => {});\r\n const glideScrollRef = useRef<((to: number) => void) | null>(null);\r\n const touchScrollingRef = useRef(false);\r\n const stickToBottomRef = useRef(true);\r\n const [alertTick, setAlertTick] = useState(0);\r\n const awayEpochRef = useRef(0);\r\n const lastAlertKeyRef = useRef('');\r\n const dismissJumpAlertRef = useRef<() => void>(() => {});\r\n const resetAlertArmingRef = useRef<() => void>(() => {});\r\n\r\n useEffect(() => {\r\n const el = msgsContainerRef.current;\r\n if (!el) return;\r\n let idle: ReturnType<typeof setTimeout>;\r\n const settle = () => {\r\n clearTimeout(idle);\r\n idle = setTimeout(() => { touchScrollingRef.current = false; }, 150);\r\n };\r\n const onTouchStart = () => {\r\n clearTimeout(idle);\r\n touchScrollingRef.current = true;\r\n dismissJumpAlertRef.current();\r\n };\r\n const onScroll = () => { if (touchScrollingRef.current) settle(); };\r\n el.addEventListener('touchstart', onTouchStart, { passive: true });\r\n el.addEventListener('touchend', settle, { passive: true });\r\n el.addEventListener('touchcancel', settle, { passive: true });\r\n el.addEventListener('scroll', onScroll, { passive: true });\r\n return () => {\r\n clearTimeout(idle);\r\n el.removeEventListener('touchstart', onTouchStart);\r\n el.removeEventListener('touchend', settle);\r\n el.removeEventListener('touchcancel', settle);\r\n el.removeEventListener('scroll', onScroll);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n const el = msgsContainerRef.current;\r\n if (!el) return;\r\n const JUMP_THRESHOLD = 160;\r\n const STICK_ON = 8;\r\n let queued = 0;\r\n\r\n const measure = () => {\r\n queued = 0;\r\n const distance = el.scrollHeight - el.scrollTop - el.clientHeight;\r\n if (distance <= STICK_ON) {\r\n if (!stickToBottomRef.current) resetAlertArmingRef.current();\r\n stickToBottomRef.current = true;\r\n clearUnreadRef.current();\r\n }\r\n\r\n setShowJumpToBottom(distance > JUMP_THRESHOLD && !stickToBottomRef.current);\r\n\r\n const max = el.scrollHeight - el.clientHeight;\r\n setScrollProgress(max > 8 ? Math.min(1, Math.max(0, el.scrollTop / max)) : 1);\r\n\r\n const line = el.scrollTop + el.clientHeight * 0.33;\r\n let active = 0;\r\n for (let i = 0; i < messageRefs.current.length; i++) {\r\n const node = messageRefs.current[i];\r\n if (node && node.offsetTop - el.offsetTop <= line) active = i;\r\n }\r\n setActiveMsgIdx(active);\r\n };\r\n\r\n const onScroll = () => {\r\n if (queued) return;\r\n queued = requestAnimationFrame(measure);\r\n };\r\n\r\n measure();\r\n el.addEventListener('scroll', onScroll, { passive: true });\r\n const ro = new ResizeObserver(onScroll);\r\n ro.observe(el);\r\n return () => {\r\n if (queued) cancelAnimationFrame(queued);\r\n el.removeEventListener('scroll', onScroll);\r\n ro.disconnect();\r\n };\r\n }, [messages.length, messageRefs]);\r\n\r\n const notifyNewBelow = useCallback((turn: number) => {\r\n const key = `${turn}:${awayEpochRef.current}`;\r\n if (lastAlertKeyRef.current === key) return;\r\n lastAlertKeyRef.current = key;\r\n setAlertTick(t => t + 1);\r\n }, []);\r\n\r\n const [unreadBelow, setUnreadBelow] = useState(false);\r\n const unreadBelowRef = useRef(false);\r\n const markUnread = useCallback(() => {\r\n if (unreadBelowRef.current) return;\r\n unreadBelowRef.current = true;\r\n setUnreadBelow(true);\r\n }, []);\r\n const clearUnread = useCallback(() => {\r\n if (!unreadBelowRef.current) return;\r\n unreadBelowRef.current = false;\r\n setUnreadBelow(false);\r\n }, []);\r\n const clearUnreadRef = useRef<() => void>(() => {});\r\n clearUnreadRef.current = clearUnread;\r\n\r\n const [jumpAlert, setJumpAlert] = useState(false);\r\n const jumpAlertRef = useRef(false);\r\n const alertShownAtRef = useRef(0);\r\n const clearAlert = useCallback(() => {\r\n jumpAlertRef.current = false;\r\n setJumpAlert(false);\r\n }, []);\r\n const resetAlertArming = useCallback(() => {\r\n lastAlertKeyRef.current = '';\r\n clearAlert();\r\n clearUnread();\r\n }, [clearAlert, clearUnread]);\r\n const dismissJumpAlert = useCallback(() => {\r\n if (!jumpAlertRef.current) return;\r\n if (performance.now() - alertShownAtRef.current < 700) return;\r\n clearAlert();\r\n }, [clearAlert]);\r\n dismissJumpAlertRef.current = dismissJumpAlert;\r\n resetAlertArmingRef.current = resetAlertArming;\r\n\r\n useEffect(() => {\r\n if (alertTick === 0) return;\r\n jumpAlertRef.current = true;\r\n alertShownAtRef.current = performance.now();\r\n setJumpAlert(true);\r\n const t = setTimeout(clearAlert, 4200);\r\n return () => clearTimeout(t);\r\n }, [alertTick, clearAlert]);\r\n\r\n const jumpToMessage = useCallback((idx: number) => {\r\n const el = msgsContainerRef.current;\r\n const node = messageRefs.current[idx];\r\n if (!el || !node) return;\r\n const targetCenter = node.offsetTop - el.offsetTop - Math.max(0, (el.clientHeight - node.clientHeight) / 2);\r\n const to = Math.max(0, Math.min(el.scrollHeight - el.clientHeight, targetCenter));\r\n if (glideScrollRef.current) glideScrollRef.current(to);\r\n else el.scrollTo({ top: to, behavior: 'smooth' });\r\n }, [messageRefs]);\r\n\r\n const jumpToBottom = useCallback(() => {\r\n const el = msgsContainerRef.current;\r\n if (!el) return;\r\n stickToBottomRef.current = true;\r\n resetAlertArmingRef.current();\r\n const bottom = el.scrollHeight - el.clientHeight;\r\n if (glideScrollRef.current) glideScrollRef.current(bottom);\r\n else el.scrollTo({ top: bottom, behavior: 'smooth' });\r\n }, []);\r\n\r\n useEffect(() => {\r\n const container = msgsContainerRef.current;\r\n if (!container) return;\r\n const raf = requestAnimationFrame(() => {\r\n const before = container.scrollTop;\r\n if (!stickToBottomRef.current) {\r\n markUnread();\r\n notifyNewBelow(messages.length);\r\n } else {\r\n if (!touchScrollingRef.current) {\r\n const bottom = container.scrollHeight - container.clientHeight;\r\n if (glideScrollRef.current) { glideScrollRef.current(bottom); return; }\r\n container.scrollTop = container.scrollHeight;\r\n }\r\n }\r\n if (container.scrollTop !== before) resyncScrollRef.current();\r\n });\r\n return () => cancelAnimationFrame(raf);\r\n }, [messages, loading, messageRefs, notifyNewBelow, markUnread]);\r\n\r\n useEffect(() => {\r\n const el = msgsContainerRef.current;\r\n if (!el) return;\r\n\r\n if (typeof window !== 'undefined' && window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return;\r\n\r\n const LAMBDA = 7;\r\n const LINE_PX = 16;\r\n const step = 1 / (window.devicePixelRatio || 1);\r\n const snap = (v: number) => Math.round(v / step) * step;\r\n\r\n let target = el.scrollTop;\r\n let current = el.scrollTop;\r\n let written = el.scrollTop;\r\n let lastTime = 0;\r\n let rafId: number | null = null;\r\n\r\n const write = (v: number) => {\r\n if (v === written) return;\r\n el.scrollTop = v;\r\n written = el.scrollTop;\r\n };\r\n\r\n const resync = () => {\r\n if (rafId !== null) { cancelAnimationFrame(rafId); rafId = null; }\r\n el.classList.remove('hsk-scrolling');\r\n target = current = written = el.scrollTop;\r\n };\r\n resyncScrollRef.current = resync;\r\n\r\n glideScrollRef.current = (to: number) => {\r\n if (Math.abs(el.scrollTop - written) > 1) { target = current = written = el.scrollTop; }\r\n const next = Math.round(Math.max(0, Math.min(el.scrollHeight - el.clientHeight, to)));\r\n if (next === target) return;\r\n target = next;\r\n if (rafId === null) {\r\n lastTime = performance.now();\r\n rafId = requestAnimationFrame(update);\r\n }\r\n };\r\n\r\n const update = (now: number) => {\r\n const dt = Math.min((now - lastTime) / 1000, 0.05);\r\n lastTime = now;\r\n current += (target - current) * (1 - Math.exp(-LAMBDA * dt));\r\n if (Math.abs(target - current) < step) {\r\n current = target;\r\n write(Math.round(target));\r\n el.classList.remove('hsk-scrolling');\r\n rafId = null;\r\n return;\r\n }\r\n write(snap(current));\r\n rafId = requestAnimationFrame(update);\r\n };\r\n\r\n const handleWheel = (e: WheelEvent) => {\r\n if (e.ctrlKey) return;\r\n if (Math.abs(el.scrollTop - written) > 1) target = current = written = el.scrollTop;\r\n\r\n if (e.deltaY < 0) {\r\n if (stickToBottomRef.current) awayEpochRef.current += 1;\r\n stickToBottomRef.current = false;\r\n }\r\n\r\n dismissJumpAlertRef.current();\r\n\r\n const scale = e.deltaMode === 1 ? LINE_PX : e.deltaMode === 2 ? el.clientHeight : 1;\r\n const maxScroll = Math.max(0, el.scrollHeight - el.clientHeight);\r\n const next = Math.round(Math.max(0, Math.min(maxScroll, target + e.deltaY * scale)));\r\n\r\n if (next === target) { if (maxScroll > 0) e.preventDefault(); return; }\r\n e.preventDefault();\r\n target = next;\r\n\r\n if (rafId === null) {\r\n lastTime = performance.now();\r\n el.classList.add('hsk-scrolling');\r\n rafId = requestAnimationFrame(update);\r\n }\r\n };\r\n\r\n let lastTop = el.scrollTop;\r\n const handleScroll = () => {\r\n const external = Math.abs(el.scrollTop - written) > 1;\r\n if (external) {\r\n lastExternalScrollRef.current = performance.now();\r\n if (el.scrollTop < lastTop - 1 && stickToBottomRef.current) {\r\n awayEpochRef.current += 1;\r\n stickToBottomRef.current = false;\r\n }\r\n }\r\n lastTop = el.scrollTop;\r\n if (rafId !== null && external) {\r\n cancelAnimationFrame(rafId);\r\n rafId = null;\r\n el.classList.remove('hsk-scrolling');\r\n target = current = written = el.scrollTop;\r\n }\r\n };\r\n\r\n el.addEventListener('wheel', handleWheel, { passive: false });\r\n el.addEventListener('scroll', handleScroll, { passive: true });\r\n return () => {\r\n el.removeEventListener('scroll', handleScroll);\r\n el.removeEventListener('wheel', handleWheel);\r\n if (rafId !== null) cancelAnimationFrame(rafId);\r\n el.classList.remove('hsk-scrolling');\r\n resyncScrollRef.current = () => {};\r\n glideScrollRef.current = null;\r\n };\r\n }, []);\r\n\r\n return {\r\n msgsContainerRef,\r\n lastExternalScrollRef,\r\n showJumpToBottom,\r\n scrollProgress,\r\n activeMsgIdx,\r\n jumpAlert,\r\n unreadBelow,\r\n jumpToMessage,\r\n jumpToBottom,\r\n resetAlertArming,\r\n };\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ChatAction } from '@akropolys/sdk';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport { KIKU_KEY_REVEAL_SECONDS } from '../types';\r\n\r\nexport function useKikuKey(lastAction: ChatAction | null, retryLastMessage: () => Promise<void>) {\r\n const client = useAkropolysContext();\r\n const [keyInput, setKeyInput] = useState('');\r\n const [keyPhase, setKeyPhase] = useState<'idle' | 'prompt_key'>('idle');\r\n const [mintedKey, setMintedKey] = useState<string | null>(null);\r\n const [mintedPub, setMintedPub] = useState<string | null>(null);\r\n const [copied, setCopied] = useState<'secret' | 'pub' | null>(null);\r\n const [keyCountdown, setKeyCountdown] = useState(KIKU_KEY_REVEAL_SECONDS);\r\n const [minting, setMinting] = useState(false);\r\n\r\n const copyValue = useCallback(async (val: string, type: 'secret' | 'pub') => {\r\n try {\r\n await navigator.clipboard.writeText(val);\r\n setCopied(type);\r\n setTimeout(() => setCopied(null), 2000);\r\n } catch { }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!lastAction) return;\r\n if (lastAction.type === 'request_kiku_key') {\r\n setKeyPhase('prompt_key');\r\n setKeyInput('');\r\n }\r\n }, [lastAction]);\r\n\r\n useEffect(() => {\r\n if (!mintedKey) return;\r\n setKeyCountdown(KIKU_KEY_REVEAL_SECONDS);\r\n const t = setInterval(() => {\r\n setKeyCountdown(s => {\r\n if (s <= 1) {\r\n clearInterval(t);\r\n setMintedKey(null);\r\n setMintedPub(null);\r\n return 0;\r\n }\r\n return s - 1;\r\n });\r\n }, 1000);\r\n return () => clearInterval(t);\r\n }, [mintedKey]);\r\n\r\n const handleUseExistingKey = useCallback(async () => {\r\n const pub = keyInput.trim();\r\n if (!pub) return;\r\n client.setKikuPub(pub);\r\n setKeyInput('');\r\n setKeyPhase('idle');\r\n await retryLastMessage();\r\n }, [client, keyInput, retryLastMessage]);\r\n\r\n const handleCreateKey = useCallback(async () => {\r\n if (minting) return;\r\n setMinting(true);\r\n try {\r\n const { secret, publicId } = await client.mintKikuKey();\r\n setMintedKey(secret);\r\n setMintedPub(publicId);\r\n setKeyPhase('idle');\r\n await retryLastMessage();\r\n } catch { } finally {\r\n setMinting(false);\r\n }\r\n }, [client, minting, retryLastMessage]);\r\n\r\n return {\r\n keyInput,\r\n setKeyInput,\r\n keyPhase,\r\n setKeyPhase,\r\n mintedKey,\r\n setMintedKey,\r\n mintedPub,\r\n setMintedPub,\r\n copied,\r\n keyCountdown,\r\n minting,\r\n copyValue,\r\n handleUseExistingKey,\r\n handleCreateKey,\r\n };\r\n}\r\n","import { useCallback } from 'react';\r\nimport type { ChatSource, ChatAttachment, CaptureTarget } from '@akropolys/sdk';\r\nimport type { UIStringKey } from '../types';\r\n\r\nexport interface UseChatCommandsOptions {\r\n attachments: ChatAttachment[];\r\n setAttachments: React.Dispatch<React.SetStateAction<ChatAttachment[]>>;\r\n setInput: React.Dispatch<React.SetStateAction<string>>;\r\n send: (\r\n prompt: string,\r\n displayContent?: string,\r\n attachments?: ChatAttachment[],\r\n forcedIntent?: string,\r\n captureTargets?: CaptureTarget[]\r\n ) => Promise<any>;\r\n defaultCurrency: string;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n}\r\n\r\nexport function useChatCommands({\r\n attachments,\r\n setAttachments,\r\n setInput,\r\n send,\r\n defaultCurrency,\r\n t,\r\n}: UseChatCommandsOptions) {\r\n const handleKikuCapture = useCallback((product: ChatSource) => {\r\n const name = product.name || '';\r\n const display = `@kiku ${t('displayCapture', { name }).trim()}`;\r\n const q = name || 'capture current page';\r\n setInput('');\r\n const toSend = attachments;\r\n setAttachments([]);\r\n send(q, display, toSend.length > 0 ? toSend : undefined, 'capture');\r\n }, [attachments, send, setAttachments, setInput, t]);\r\n\r\n const handleKikuCaptureAll = useCallback((products: ChatSource[]) => {\r\n const targets: CaptureTarget[] = products\r\n .filter(p => p.id)\r\n .map(p => ({\r\n name: p.name || '',\r\n url: (p as any).url || '',\r\n image: p.image || '',\r\n price: p.price ? String(p.price) : '',\r\n currency: p.currency || defaultCurrency,\r\n }));\r\n const names = products.map(p => p.name).filter(Boolean).join(', ');\r\n const display = `@kiku ${t('displayCaptureAll', { count: String(products.length) })}`;\r\n setInput('');\r\n setAttachments([]);\r\n send(names || 'capture all', display, undefined, 'capture_all', targets);\r\n }, [defaultCurrency, send, setAttachments, setInput, t]);\r\n\r\n const handleKikuViewHistory = useCallback(() => {\r\n const display = `@kiku ${t('displayViewHistory')}`;\r\n setInput('');\r\n setAttachments([]);\r\n send('show my saved items', display, undefined, 'view_history');\r\n }, [send, setAttachments, setInput, t]);\r\n\r\n const handleKikuDelete = useCallback(() => {\r\n const display = `@kiku ${t('displayDelete')}`;\r\n setInput('');\r\n setAttachments([]);\r\n send('delete this', display, undefined, 'delete');\r\n }, [send, setAttachments, setInput, t]);\r\n\r\n return {\r\n handleKikuCapture,\r\n handleKikuCaptureAll,\r\n handleKikuViewHistory,\r\n handleKikuDelete,\r\n };\r\n}\r\n","import { useState, useCallback } from 'react';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport { stopSpeech } from '../../../utils/tts';\r\nimport { useVoiceSession } from '../../../utils/voiceSession';\r\nimport { useLiveVoice, type LiveState } from '../../../utils/liveVoice';\r\nimport { LIVE_VOICES, VOICE_STORAGE_KEY, isSecureOrigin, type VoicePhase } from '../types';\r\n\r\nconst toVoicePhase = (s: LiveState): VoicePhase =>\r\n s === 'connecting' || s === 'ended' ? 'idle' : s;\r\n\r\nexport interface UseVoiceControllerOptions {\r\n voiceLang?: string;\r\n speechLang: string;\r\n shopperLanguage: string;\r\n ttsVoice?: string;\r\n handleSendUtterance: (text: string) => void;\r\n appendSpokenExchange: (heard: string, said: string) => void;\r\n}\r\n\r\nexport function useVoiceController({\r\n voiceLang,\r\n speechLang,\r\n shopperLanguage,\r\n ttsVoice = 'Puck',\r\n handleSendUtterance,\r\n appendSpokenExchange,\r\n}: UseVoiceControllerOptions) {\r\n const client = useAkropolysContext();\r\n const [voiceMode, setVoiceMode] = useState<'off' | 'dictate' | 'converse'>('off');\r\n const [dictateState, setDictateState] = useState<'idle' | 'listening' | 'thinking'>('idle');\r\n const [voiceError, setVoiceError] = useState<string>('');\r\n const [voiceMuted, setVoiceMuted] = useState(false);\r\n const [voiceSecondsLeft, setVoiceSecondsLeft] = useState<number | null>(null);\r\n const [voiceBlocked, setVoiceBlocked] = useState(false);\r\n\r\n const [liveVoiceName, setLiveVoiceName] = useState<string>(() => {\r\n try {\r\n const stored = localStorage.getItem(VOICE_STORAGE_KEY);\r\n if (stored && LIVE_VOICES.some(v => v.name === stored)) return stored;\r\n } catch { }\r\n return ttsVoice || 'Puck';\r\n });\r\n\r\n const chooseVoice = useCallback((name: string) => {\r\n setLiveVoiceName(name);\r\n try { localStorage.setItem(VOICE_STORAGE_KEY, name); } catch { }\r\n }, []);\r\n\r\n const voice = useVoiceSession({\r\n lang: voiceLang || speechLang,\r\n onUtterance: (text) => {\r\n setDictateState('thinking');\r\n handleSendUtterance(text);\r\n },\r\n onError: (code) => {\r\n setVoiceMode('off');\r\n setDictateState('idle');\r\n if (code === 'not-allowed') setVoiceError('micDenied');\r\n else if (code === 'language-not-supported') setVoiceError('micLangUnsupported');\r\n else if (code === 'audio-capture') setVoiceError('micMissing');\r\n else if (code === 'network') setVoiceError('micNetwork');\r\n else setVoiceError('micFailed');\r\n },\r\n onBargeIn: () => { stopSpeech(); },\r\n });\r\n\r\n const apiUrl = (client as any)?.api?.apiUrl || (client as any)?.apiUrl || '';\r\n const siteId = (client as any)?.api?.siteId || (client as any)?.siteId || '';\r\n const token = (client as any)?.api?.apiToken || (client as any)?.apiToken || '';\r\n const kikuId = client?.getShopperId?.() || client?.getKikuPub?.() || undefined;\r\n\r\n const live = useLiveVoice({\r\n apiUrl,\r\n siteId,\r\n token,\r\n kikuId,\r\n language: shopperLanguage,\r\n voice: liveVoiceName,\r\n muted: voiceMuted,\r\n onExchange: (exchange) => {\r\n appendSpokenExchange(exchange.heard, exchange.said);\r\n },\r\n onError: (err) => {\r\n if (err === 'shopper_reply_limit' || err === 'access_revoked' || err === 'account_required') {\r\n setVoiceBlocked(true);\r\n live.stop();\r\n setVoiceMode('off');\r\n return;\r\n }\r\n setVoiceMode('off');\r\n if (err === 'not-allowed') setVoiceError('micDenied');\r\n else if (err === 'audio-capture') setVoiceError('micMissing');\r\n else if (err === 'limit') setVoiceError('voiceLimitReached');\r\n else if (err === 'siteLimit') setVoiceError('voiceSiteLimit');\r\n else if (err === 'connection' || err === 'network') setVoiceError('micNetwork');\r\n else setVoiceError('voiceUnavailable');\r\n },\r\n onRefused: (code) => {\r\n if (code === 'shopper_reply_limit' || code === 'access_revoked' || code === 'account_required') {\r\n setVoiceBlocked(true);\r\n }\r\n setVoiceMode('off');\r\n setVoiceError('voiceUnavailable');\r\n },\r\n });\r\n\r\n const canConverse = typeof window !== 'undefined' &&\r\n !!(window as any).WebSocket &&\r\n !!(window.AudioContext || (window as any).webkitAudioContext) &&\r\n !!navigator.mediaDevices?.getUserMedia;\r\n\r\n const startVoice = useCallback(async (mode: 'dictate' | 'converse') => {\r\n if (!isSecureOrigin()) { setVoiceError('micInsecure'); return; }\r\n setVoiceError('');\r\n setVoiceMode(mode);\r\n if (mode === 'dictate') {\r\n setDictateState('listening');\r\n await voice.start();\r\n } else {\r\n live.start();\r\n }\r\n }, [live, voice]);\r\n\r\n const stopVoice = useCallback(() => {\r\n setVoiceMode('off');\r\n setDictateState('idle');\r\n voice.stop();\r\n live.stop();\r\n }, [live, voice]);\r\n\r\n const voicePhase: VoicePhase =\r\n voiceMode === 'converse' ? toVoicePhase(live.state)\r\n : voiceMode === 'dictate' ? (dictateState === 'listening' ? (voice.hearing ? 'speaking' : 'listening') : dictateState)\r\n : 'idle';\r\n\r\n const voiceConnecting = voiceMode === 'converse' && (live.phase === 'connecting' || live.state === 'connecting');\r\n\r\n return {\r\n voiceMode,\r\n voicePhase,\r\n voiceConnecting,\r\n voiceError,\r\n setVoiceError,\r\n voiceMuted,\r\n setVoiceMuted,\r\n voiceSecondsLeft,\r\n voiceBlocked,\r\n liveVoiceName,\r\n chooseVoice,\r\n canConverse,\r\n startVoice,\r\n stopVoice,\r\n voice,\r\n live,\r\n };\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from 'react';\r\n\r\nexport type LiveState = 'idle' | 'connecting' | 'listening' | 'thinking' | 'speaking' | 'ended';\r\n\r\nexport interface LiveSource {\r\n id?: string;\r\n url?: string;\r\n name: string;\r\n price?: string;\r\n currency?: string;\r\n image?: string;\r\n brand?: string;\r\n availability?: string;\r\n}\r\n\r\nexport interface LiveVoiceOptions {\r\n apiUrl: string;\r\n siteId: string;\r\n\r\n token: string;\r\n kikuId?: string;\r\n\r\n language?: string;\r\n voice?: string;\r\n\r\n onExchange?: (exchange: { heard: string; said: string }) => void;\r\n onRefused?: (code: string) => void;\r\n onError?: (code: string) => void;\r\n\r\n muted?: boolean;\r\n}\r\n\r\nconst INPUT_RATE = 16000;\r\n\r\nconst WORKLET_SRC = `\r\nclass KikuCapture extends AudioWorkletProcessor {\r\n constructor() {\r\n super();\r\n this._ratio = sampleRate / ${INPUT_RATE};\r\n this._chunk = ${Math.round(INPUT_RATE * 0.04)};\r\n this._acc = new Int16Array(this._chunk);\r\n this._n = 0;\r\n this._pos = 0;\r\n }\r\n process(inputs) {\r\n const ch = inputs[0] && inputs[0][0];\r\n if (!ch) return true;\r\n while (this._pos < ch.length) {\r\n const i = this._pos | 0;\r\n const frac = this._pos - i;\r\n const a = ch[i];\r\n const b = i + 1 < ch.length ? ch[i + 1] : a;\r\n const s = a + (b - a) * frac;\r\n const c = s < -1 ? -1 : s > 1 ? 1 : s;\r\n this._acc[this._n++] = c < 0 ? c * 0x8000 : c * 0x7fff;\r\n if (this._n === this._chunk) {\r\n this.port.postMessage(this._acc.buffer, [this._acc.buffer]);\r\n this._acc = new Int16Array(this._chunk);\r\n this._n = 0;\r\n }\r\n this._pos += this._ratio;\r\n }\r\n this._pos -= ch.length;\r\n return true;\r\n }\r\n}\r\nregisterProcessor('kiku-capture', KikuCapture);\r\n`;\r\n\r\nfunction toBase64(buf: ArrayBuffer): string {\r\n const bytes = new Uint8Array(buf);\r\n let s = '';\r\n for (let i = 0; i < bytes.length; i += 0x8000) {\r\n s += String.fromCharCode.apply(null, Array.from(bytes.subarray(i, i + 0x8000)));\r\n }\r\n return btoa(s);\r\n}\r\n\r\nfunction fromBase64(b64: string): Float32Array {\r\n const bin = atob(b64);\r\n const len = bin.length;\r\n const bytes = new Uint8Array(len);\r\n for (let i = 0; i < len; i++) bytes[i] = bin.charCodeAt(i);\r\n const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\r\n const numSamples = len >> 1;\r\n const float32 = new Float32Array(numSamples);\r\n for (let i = 0; i < numSamples; i++) {\r\n float32[i] = dataView.getInt16(i * 2, true) / 32768;\r\n }\r\n return float32;\r\n}\r\n\r\nexport function useLiveVoice(opts: LiveVoiceOptions) {\r\n const [state, setState] = useState<LiveState>('idle');\r\n const [hearing, setHearing] = useState(false);\r\n const [sources, setSources] = useState<LiveSource[]>([]);\r\n const [secondsLeft, setSecondsLeft] = useState<number | null>(null);\r\n\r\n const wsRef = useRef<WebSocket | null>(null);\r\n const ctxRef = useRef<AudioContext | null>(null);\r\n const streamRef = useRef<MediaStream | null>(null);\r\n const nodeRef = useRef<AudioWorkletNode | null>(null);\r\n const analyserRef = useRef<AnalyserNode | null>(null);\r\n\r\n const playAtRef = useRef(0);\r\n const sourcesRef = useRef<Set<AudioBufferSourceNode>>(new Set());\r\n const outAnalyserRef = useRef<AnalyserNode | null>(null);\r\n const outGainRef = useRef<GainNode | null>(null);\r\n const outRateRef = useRef(24000);\r\n\r\n const optsRef = useRef(opts);\r\n useEffect(() => { optsRef.current = opts; }, [opts]);\r\n\r\n const readyRef = useRef(false);\r\n const armCaptureRef = useRef<(() => void) | null>(null);\r\n\r\n const turnHeardRef = useRef('');\r\n const turnSaidRef = useRef('');\r\n\r\n const flushExchange = useCallback(() => {\r\n const heard = turnHeardRef.current.trim();\r\n const said = turnSaidRef.current.trim();\r\n turnHeardRef.current = '';\r\n turnSaidRef.current = '';\r\n if (!heard && !said) return;\r\n optsRef.current.onExchange?.({ heard, said });\r\n }, []);\r\n\r\n const chirp = useCallback(() => {\r\n // Silent - no synthetic beeps during live voice\r\n }, []);\r\n\r\n const beginCapture = useCallback(() => {\r\n if (!readyRef.current) return;\r\n if (ctxRef.current && ctxRef.current.state === 'suspended') {\r\n ctxRef.current.resume().catch(() => {});\r\n }\r\n const arm = armCaptureRef.current;\r\n if (!arm) return;\r\n armCaptureRef.current = null;\r\n arm();\r\n }, []);\r\n\r\n const micLevel = useCallback(() => {\r\n const a = analyserRef.current;\r\n if (!a) return 0;\r\n const d = new Uint8Array(a.fftSize);\r\n a.getByteTimeDomainData(d);\r\n let sum = 0;\r\n for (let i = 0; i < d.length; i++) { const v = (d[i] - 128) / 128; sum += v * v; }\r\n return Math.min(1, Math.sqrt(sum / d.length) * 4);\r\n }, []);\r\n\r\n const outbound = state === 'speaking' || state === 'thinking';\r\n\r\n const micSpectrum = useCallback((out: Uint8Array) => {\r\n const a = outbound ? outAnalyserRef.current : analyserRef.current;\r\n if (!a || out.length !== a.frequencyBinCount) return false;\r\n a.getByteFrequencyData(out as Uint8Array<ArrayBuffer>);\r\n return true;\r\n }, [outbound]);\r\n\r\n const spectrumBins = useCallback(\r\n () => (outbound ? outAnalyserRef.current : analyserRef.current)?.frequencyBinCount ?? 0,\r\n [outbound]\r\n );\r\n\r\n \r\n const flushPlayback = useCallback(() => {\r\n playAtRef.current = 0;\r\n const g = outGainRef.current;\r\n const ctx = ctxRef.current;\r\n if (g && ctx && ctx.state !== 'closed') {\r\n const now = ctx.currentTime;\r\n g.gain.cancelScheduledValues(now);\r\n g.gain.setValueAtTime(g.gain.value, now);\r\n // Smooth 80ms fade down to 0: zero Dirac delta voltage snap!\r\n g.gain.linearRampToValueAtTime(0, now + 0.08);\r\n\r\n setTimeout(() => {\r\n for (const src of sourcesRef.current) {\r\n try { src.onended = null; src.stop(); } catch { }\r\n }\r\n sourcesRef.current.clear();\r\n if (g && ctxRef.current && ctxRef.current.state !== 'closed') {\r\n g.gain.setValueAtTime(1, ctxRef.current.currentTime);\r\n }\r\n }, 100);\r\n } else {\r\n for (const src of sourcesRef.current) {\r\n try { src.onended = null; src.stop(); } catch { }\r\n }\r\n sourcesRef.current.clear();\r\n }\r\n }, []);\r\n\r\n const enqueue = useCallback((chunk: Float32Array) => {\r\n const ctx = ctxRef.current;\r\n const out = outAnalyserRef.current;\r\n if (!ctx || !out || chunk.length === 0) return;\r\n if (ctx.state === 'suspended') {\r\n ctx.resume().catch(() => {});\r\n }\r\n\r\n const rate = outRateRef.current;\r\n const buf = ctx.createBuffer(1, chunk.length, rate);\r\n buf.getChannelData(0).set(chunk);\r\n\r\n const src = ctx.createBufferSource();\r\n src.buffer = buf;\r\n src.connect(out);\r\n\r\n const now = ctx.currentTime;\r\n // Direct sample-accurate continuous chain:\r\n const at = playAtRef.current > now ? playAtRef.current : now + 0.03;\r\n src.start(at);\r\n playAtRef.current = at + buf.duration;\r\n\r\n sourcesRef.current.add(src);\r\n src.onended = () => {\r\n sourcesRef.current.delete(src);\r\n if (sourcesRef.current.size === 0) {\r\n playAtRef.current = 0;\r\n setState(s => (s === 'speaking' ? 'listening' : s));\r\n }\r\n };\r\n setState(s => (s === 'speaking' || s === 'idle' || s === 'ended' ? s : 'speaking'));\r\n }, []);\r\n\r\n const stopHold = useCallback(() => {\r\n // Silent - no drone\r\n }, []);\r\n\r\n const startHold = useCallback(() => {\r\n // Silent - clean natural voice only\r\n }, []);\r\n\r\n const teardown = useCallback((finalState: LiveState) => {\r\n flushExchange();\r\n wsRef.current = null;\r\n readyRef.current = false;\r\n armCaptureRef.current = null;\r\n stopHold();\r\n flushPlayback();\r\n nodeRef.current?.disconnect();\r\n nodeRef.current = null;\r\n streamRef.current?.getTracks().forEach(t => t.stop());\r\n streamRef.current = null;\r\n analyserRef.current = null;\r\n outAnalyserRef.current = null;\r\n outGainRef.current = null;\r\n ctxRef.current?.close().catch(() => { });\r\n ctxRef.current = null;\r\n setState(finalState);\r\n setHearing(false);\r\n setSources([]);\r\n }, [flushExchange, flushPlayback, stopHold]);\r\n\r\n const stop = useCallback(() => {\r\n try { wsRef.current?.send(JSON.stringify({ type: 'close' })); } catch { }\r\n try { wsRef.current?.close(); } catch { }\r\n teardown('idle');\r\n }, [teardown]);\r\n\r\n const attachWsHandlers = useCallback((ws: WebSocket) => {\r\n let abandoned = false;\r\n ws.onmessage = ev => {\r\n let f: any;\r\n try { f = JSON.parse(ev.data); } catch { return; }\r\n switch (f.type) {\r\n case 'ready':\r\n if (f.sampleRate) outRateRef.current = f.sampleRate;\r\n if (typeof f.secondsLeft === 'number') setSecondsLeft(f.secondsLeft);\r\n readyRef.current = true;\r\n setState('listening');\r\n beginCapture();\r\n break;\r\n case 'audio':\r\n stopHold();\r\n if (f.audio) enqueue(fromBase64(f.audio));\r\n break;\r\n case 'hearing':\r\n setHearing(true);\r\n break;\r\n case 'thinking':\r\n setHearing(false);\r\n setState('thinking');\r\n startHold();\r\n break;\r\n case 'heard':\r\n turnHeardRef.current += f.text;\r\n break;\r\n case 'said':\r\n turnSaidRef.current += f.text;\r\n break;\r\n case 'interrupted':\r\n stopHold();\r\n flushPlayback();\r\n setHearing(false);\r\n setState('listening');\r\n break;\r\n case 'turn_complete':\r\n stopHold();\r\n setHearing(false);\r\n flushExchange();\r\n break;\r\n case 'sources':\r\n if (Array.isArray(f.sources) && f.sources.length) setSources(f.sources);\r\n break;\r\n case 'seconds':\r\n if (typeof f.secondsLeft === 'number') setSecondsLeft(f.secondsLeft);\r\n break;\r\n case 'refused':\r\n optsRef.current.onRefused?.(f.code || 'guest');\r\n stop();\r\n break;\r\n case 'error':\r\n optsRef.current.onError?.(f.code || 'unavailable');\r\n stop();\r\n break;\r\n }\r\n };\r\n\r\n ws.onclose = ev => {\r\n if (wsRef.current !== ws) return;\r\n if (ev.code === 4402) {\r\n abandoned = true;\r\n optsRef.current.onError?.(ev.reason === 'site' ? 'siteLimit' : 'limit');\r\n }\r\n teardown('ended');\r\n };\r\n ws.onerror = () => { if (!abandoned && wsRef.current === ws) optsRef.current.onError?.('connection'); };\r\n }, [beginCapture, enqueue, flushExchange, flushPlayback, startHold, stopHold, stop, teardown]);\r\n\r\n const hotReconnect = useCallback((newVoice?: string) => {\r\n const oldWs = wsRef.current;\r\n readyRef.current = false;\r\n setState('connecting');\r\n flushPlayback();\r\n stopHold();\r\n if (oldWs) {\r\n try { oldWs.send(JSON.stringify({ type: 'close' })); } catch { }\r\n try { oldWs.close(); } catch { }\r\n }\r\n const o = optsRef.current;\r\n const base = o.apiUrl.replace(/\\/+$/, '');\r\n const url = new URL(base + '/voice/live', window.location.href);\r\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\r\n url.searchParams.set('siteId', o.siteId);\r\n if (o.kikuId) url.searchParams.set('kikuId', o.kikuId);\r\n if (o.language) url.searchParams.set('language', o.language);\r\n if (newVoice || o.voice) url.searchParams.set('voice', (newVoice || o.voice)!);\r\n\r\n const ws = new WebSocket(url.toString(), ['akropolys.token.' + o.token]);\r\n wsRef.current = ws;\r\n attachWsHandlers(ws);\r\n }, [attachWsHandlers, flushPlayback, stopHold]);\r\n\r\n const currentVoiceRef = useRef(opts.voice);\r\n useEffect(() => {\r\n if (currentVoiceRef.current !== opts.voice) {\r\n currentVoiceRef.current = opts.voice;\r\n if (wsRef.current && (state === 'listening' || state === 'thinking' || state === 'speaking')) {\r\n hotReconnect(opts.voice);\r\n }\r\n }\r\n }, [opts.voice, state, hotReconnect]);\r\n\r\n const start = useCallback(async () => {\r\n if (wsRef.current) return;\r\n setState('connecting');\r\n const o = optsRef.current;\r\n\r\n const AC: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\r\n if (AC) {\r\n if (!ctxRef.current || ctxRef.current.state === 'closed') {\r\n ctxRef.current = new AC({ latencyHint: 'interactive' });\r\n }\r\n if (ctxRef.current.state === 'suspended') {\r\n ctxRef.current.resume().catch(() => {});\r\n }\r\n }\r\n\r\n const base = o.apiUrl.replace(/\\/+$/, '');\r\n const url = new URL(base + '/voice/live', window.location.href);\r\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\r\n url.searchParams.set('siteId', o.siteId);\r\n if (o.kikuId) url.searchParams.set('kikuId', o.kikuId);\r\n if (o.language) url.searchParams.set('language', o.language);\r\n if (o.voice) url.searchParams.set('voice', o.voice);\r\n\r\n const ws = new WebSocket(url.toString(), ['akropolys.token.' + o.token]);\r\n wsRef.current = ws;\r\n attachWsHandlers(ws);\r\n\r\n let stream: MediaStream;\r\n try {\r\n if (!navigator.mediaDevices?.getUserMedia) throw { name: 'NotAllowedError' };\r\n stream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n autoGainControl: true,\r\n },\r\n });\r\n } catch (e: any) {\r\n abandoned = true;\r\n try { ws.close(); } catch { }\r\n wsRef.current = null;\r\n setState('idle');\r\n o.onError?.(e?.name === 'NotAllowedError' ? 'not-allowed' : 'audio-capture');\r\n return;\r\n }\r\n if (wsRef.current !== ws) {\r\n stream.getTracks().forEach(t => t.stop());\r\n return;\r\n }\r\n streamRef.current = stream;\r\n for (const track of stream.getAudioTracks()) {\r\n track.enabled = !optsRef.current.muted;\r\n }\r\n\r\n const ctx = ctxRef.current && ctxRef.current.state !== 'closed' ? ctxRef.current : (AC ? new AC({ latencyHint: 'interactive' }) : null);\r\n if (!ctx) return;\r\n ctxRef.current = ctx;\r\n if (ctx.state === 'suspended') {\r\n ctx.resume().catch(() => {});\r\n }\r\n\r\n const inAnalyser = ctx.createAnalyser();\r\n inAnalyser.fftSize = 1024;\r\n inAnalyser.smoothingTimeConstant = 0.25;\r\n analyserRef.current = inAnalyser;\r\n\r\n const outGain = ctx.createGain();\r\n outGain.gain.value = 1;\r\n outGain.connect(ctx.destination);\r\n outGainRef.current = outGain;\r\n\r\n const outAnalyser = ctx.createAnalyser();\r\n outAnalyser.fftSize = 1024;\r\n outAnalyser.smoothingTimeConstant = 0.25;\r\n outAnalyser.connect(outGain);\r\n outAnalyserRef.current = outAnalyser;\r\n\r\n try {\r\n const blobUrl = URL.createObjectURL(new Blob([WORKLET_SRC], { type: 'application/javascript' }));\r\n await ctx.audioWorklet.addModule(blobUrl);\r\n URL.revokeObjectURL(blobUrl);\r\n if (wsRef.current !== ws) {\r\n stream.getTracks().forEach(t => t.stop());\r\n ctx.close().catch(() => {});\r\n return;\r\n }\r\n\r\n const node = new AudioWorkletNode(ctx, 'kiku-capture');\r\n nodeRef.current = node;\r\n node.port.onmessage = e => {\r\n const curWs = wsRef.current;\r\n if (!curWs || curWs.readyState !== WebSocket.OPEN) return;\r\n curWs.send(JSON.stringify({ type: 'audio', audio: toBase64(e.data) }));\r\n };\r\n const srcNode = ctx.createMediaStreamSource(stream);\r\n armCaptureRef.current = () => {\r\n srcNode.connect(inAnalyser);\r\n srcNode.connect(node);\r\n };\r\n beginCapture();\r\n } catch {\r\n optsRef.current.onError?.('audio-worklet');\r\n stop();\r\n }\r\n }, [beginCapture, enqueue, flushExchange, flushPlayback, startHold, stopHold, stop, teardown]);\r\n\r\n useEffect(() => () => { stop(); }, [stop]);\r\n\r\n useEffect(() => {\r\n const stream = streamRef.current;\r\n if (!stream) return;\r\n for (const track of stream.getAudioTracks()) track.enabled = !opts.muted;\r\n }, [opts.muted, state]);\r\n\r\n return { state, phase: state, hearing, sources, secondsLeft, micLevel, micSpectrum, spectrumBins, start, stop };\r\n}\r\n","import React from 'react';\nimport { useT } from './types';\nimport { ChevronLeftIcon, CloseIcon } from './icons';\nimport { THEMES, type ThemeId } from './themes';\nimport { KikuAvatar, type KikuState } from '../KikuAvatar';\nimport { cn } from '../../utils/cn';\n\nexport interface ChatTopbarProps {\n title: string;\n hasMessages: boolean;\n avatarState?: KikuState;\n unread?: boolean;\n awayFromBottom?: boolean;\n themeMenuOpen?: boolean;\n themeMenuClosing?: boolean;\n isNarrow?: boolean;\n currentTheme?: ThemeId;\n onJumpToLatest?: () => void;\n onReset: () => void;\n onClose: () => void;\n onToggleThemeMenu?: () => void;\n onSelectTheme?: (theme: ThemeId) => void;\n}\n\nconst RadarIcon = ({ size = 15 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2Z\"/>\n <path d=\"M12 6a6 6 0 1 0 6 6 6 6 0 0 0-6-6Z\"/>\n <circle cx=\"12\" cy=\"12\" r=\"2\"/>\n </svg>\n);\n\nexport function ChatTopbar({\n title,\n hasMessages,\n avatarState = 'idle',\n unread = false,\n awayFromBottom = false,\n themeMenuOpen = false,\n themeMenuClosing = false,\n isNarrow = false,\n currentTheme = 'dark',\n onJumpToLatest,\n onReset,\n onClose,\n onToggleThemeMenu,\n onSelectTheme,\n}: ChatTopbarProps) {\n const tr = useT();\n const [isImpacting, setIsImpacting] = React.useState(false);\n const [impactColor, setImpactColor] = React.useState<string>('#134e3d');\n const [impactGlow, setImpactGlow] = React.useState<string>('rgba(19, 78, 61, 0.45)');\n const triggerRef = React.useRef<(() => void) | undefined>(undefined);\n const longPressTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n const isLongPressRef = React.useRef(false);\n const touchStartTimeRef = React.useRef(0);\n\n\n\n const startPress = React.useCallback(() => {\n isLongPressRef.current = false;\n touchStartTimeRef.current = Date.now();\n longPressTimerRef.current = setTimeout(() => {\n isLongPressRef.current = true;\n if (typeof navigator !== 'undefined' && navigator.vibrate) {\n try { navigator.vibrate(25); } catch {}\n }\n onToggleThemeMenu?.();\n }, 350);\n }, [onToggleThemeMenu]);\n\n const endPress = React.useCallback(() => {\n if (longPressTimerRef.current) {\n clearTimeout(longPressTimerRef.current);\n longPressTimerRef.current = null;\n }\n }, []);\n\n const cancelPress = React.useCallback(() => {\n if (longPressTimerRef.current) {\n clearTimeout(longPressTimerRef.current);\n longPressTimerRef.current = null;\n }\n }, []);\n\n const handleClick = React.useCallback((e: React.MouseEvent) => {\n if (isLongPressRef.current) {\n isLongPressRef.current = false;\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (awayFromBottom) {\n onJumpToLatest?.();\n } else if (isNarrow) {\n onToggleThemeMenu?.();\n } else {\n triggerRef.current?.();\n }\n }, [awayFromBottom, isNarrow, onJumpToLatest, onToggleThemeMenu]);\n\n const handleImpact = React.useCallback((splat: number, color: string, glow: string) => {\n if (splat > 0.04) {\n setIsImpacting(true);\n setImpactColor(color);\n setImpactGlow(glow);\n } else {\n setIsImpacting(false);\n }\n }, []);\n\n return (\n <div className=\"hsk-cb-topbar\">\n {/* Left Column: Back button on mobile, clean spacer on desktop */}\n <div className=\"hsk-cb-topbar-left\" style={{ minWidth: '34px' }}>\n {isNarrow && (\n <button\n type=\"button\"\n className=\"hsk-cb-back\"\n onClick={onClose}\n aria-label={tr('back')}\n >\n <span className=\"hsk-cb-back-icon\"><ChevronLeftIcon /></span>\n </button>\n )}\n </div>\n\n {/* Center Column: Avatar & Name */}\n <div\n className={cn(\"hsk-cb-topbar-mark\", isNarrow && themeMenuOpen && \"is-oozing\")}\n data-impacting={isImpacting ? 'true' : 'false'}\n style={{\n '--hsk-contact-color': impactColor,\n '--hsk-contact-glow': impactGlow,\n } as React.CSSProperties}\n data-unread={unread ? 'true' : 'false'}\n onTouchStart={startPress}\n onTouchEnd={endPress}\n onTouchMove={cancelPress}\n onTouchCancel={cancelPress}\n onClick={handleClick}\n role=\"button\"\n tabIndex={0}\n aria-label={awayFromBottom ? tr('jumpToLatest') : 'kiku (tap for scouts and themes)'}\n >\n <KikuAvatar\n state={avatarState}\n size={34}\n theme={currentTheme}\n alert={unread}\n onImpact={handleImpact}\n triggerRef={triggerRef}\n />\n <span className=\"hsk-cb-topbar-name\">{title}</span>\n </div>\n\n {/* Right Column: Actions (desktop exit button) */}\n <div className=\"hsk-cb-topbar-actions\" style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>\n {hasMessages && (\n <button className=\"hsk-cb-topbar-btn\" onClick={onReset}>\n {tr('clearChat')}\n </button>\n )}\n\n {/* Desktop: Exit button */}\n {!isNarrow && (\n <button\n type=\"button\"\n className=\"hsk-cb-squircle-btn hsk-cb-exit-btn\"\n onClick={onClose}\n title=\"Close\"\n aria-label=\"Close Chat\"\n >\n <CloseIcon />\n </button>\n )}\n </div>\n\n {/* Mobile Tray: Ooze menu above 2x2 theme grid */}\n {isNarrow && themeMenuOpen && (\n <div\n className={cn(\"hsk-cb-topbar-ooze-menu\", themeMenuClosing && \"is-closing\")}\n role=\"dialog\"\n aria-label=\"Scouts and theme selector\"\n style={{\n position: 'absolute',\n top: '100%',\n marginTop: '8px',\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: 1000,\n }}\n onPointerDown={(e) => e.stopPropagation()}\n onClick={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <div className=\"hsk-cb-theme-2x2-grid\" style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 6 }}>\n {THEMES.map(({ id, label, Icon }) => (\n <button\n key={id}\n type=\"button\"\n className={cn(\"hsk-cb-theme-grid-item\", currentTheme === id && \"is-active\")}\n onClick={(e) => { e.stopPropagation(); onSelectTheme?.(id); }}\n >\n <Icon />\n <span>{label}</span>\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n}\n","import React, { useEffect, useRef } from 'react';\r\n\r\nexport type KikuState = 'idle' | 'thinking' | 'visualizing' | 'speaking' | 'failed' | 'curious' | 'welcoming' | 'guiding' | 'happy' | 'focused';\r\n\r\ntype Shape = { bw: number; bh: number; tr: number; br: number; bow: number };\r\ntype Mood = { lid: number; warm: number; breath: number; wob: number };\r\n\r\nconst BODY: Record<string, Shape> = {\r\n idle: { bw: 50, bh: 60, tr: 1, br: 0.42, bow: 3 },\r\n thinking: { bw: 46, bh: 46, tr: 1, br: 1, bow: 2 },\r\n visualizing: { bw: 64, bh: 42, tr: 0.42,br: 0.42, bow: 2 },\r\n speaking: { bw: 44, bh: 54, tr: 0.9, br: 0.9, bow: 3 },\r\n failed: { bw: 53, bh: 45, tr: 0.95,br: 0.55, bow: 4 },\r\n curious: { bw: 48, bh: 52, tr: 0.9, br: 0.7, bow: 3 },\r\n welcoming: { bw: 50, bh: 58, tr: 1, br: 0.5, bow: 2 },\r\n guiding: { bw: 46, bh: 50, tr: 0.8, br: 0.8, bow: 2 },\r\n happy: { bw: 52, bh: 56, tr: 1, br: 0.4, bow: 4 },\r\n focused: { bw: 48, bh: 52, tr: 0.9, br: 0.7, bow: 2 },\r\n};\r\n\r\nconst MOOD: Record<string, Mood> = {\r\n idle: { lid: 1, warm: 0, breath: 2100, wob: 1 },\r\n thinking: { lid: 1, warm: 0.2, breath: 1700, wob: 1.6 },\r\n visualizing: { lid: 1, warm: 0.9, breath: 1200, wob: 2.2 },\r\n speaking: { lid: 1, warm: 0.35, breath: 900, wob: 1.8 },\r\n failed: { lid: 0.28, warm: 0, breath: 3000, wob: 0.6 },\r\n curious: { lid: 1, warm: 0.15, breath: 1800, wob: 1.4 },\r\n welcoming: { lid: 1, warm: 0.25, breath: 1600, wob: 1.2 },\r\n guiding: { lid: 1, warm: 0.2, breath: 1500, wob: 1.3 },\r\n happy: { lid: 1, warm: 0.4, breath: 1200, wob: 1.5 },\r\n focused: { lid: 1, warm: 0.2, breath: 1500, wob: 1.2 },\r\n};\r\n\r\nconst HOP: [number, number, number][] = [\r\n [0, 0, 0],\r\n [0.09, 0.54, 0], // crouch — the wind-up sells the height that follows\r\n [0.19, -0.36, 32], // launch, stretched thin\r\n [0.31, -0.22, 58],\r\n [0.42, -0.12, 68], // apex, and a beat of hang time\r\n [0.54, 0.04, 28],\r\n [0.63, 0.96, 0], // impact: flat as it gets\r\n [0.71, 0.18, 0],\r\n [0.79, -0.16, 20], // rebound — smaller, faster, the Duolingo tell\r\n [0.88, 0.34, 0],\r\n [0.95, -0.05, 4],\r\n [1, 0, 0],\r\n];\r\n\r\nfunction hopAt(f: number): [number, number] {\r\n let i = 1;\r\n while (i < HOP.length - 1 && HOP[i][0] < f) i++;\r\n const [t0, s0, l0] = HOP[i - 1];\r\n const [t1, s1, l1] = HOP[i];\r\n const u = t1 === t0 ? 0 : (f - t0) / (t1 - t0);\r\n const e = u * u * (3 - 2 * u);\r\n return [s0 + (s1 - s0) * e, l0 + (l1 - l0) * e];\r\n}\r\n\r\nconst SLOTS = 6;\r\nconst KEYS = ['bw', 'bh', 'tr', 'br', 'bow', 'lid', 'warm', 'wob', 'gx', 'gy'] as const;\r\ntype Key = typeof KEYS[number];\r\n\r\nconst clamp = (v: number, a: number, b: number) => Math.max(a, Math.min(b, v));\r\n\r\nfunction side(x: number, y0: number, y1: number, bow: number) {\r\n const f = (n: number) => n.toFixed(2);\r\n const ym = (y0 + y1) / 2;\r\n const xb = x + bow;\r\n const a = (ym - y0) * 0.55;\r\n const b = (y1 - ym) * 0.55;\r\n return (\r\n `C${f(x)} ${f(y0 + a)} ${f(xb)} ${f(ym - a)} ${f(xb)} ${f(ym)}` +\r\n `C${f(xb)} ${f(ym + b)} ${f(x)} ${f(y1 - b)} ${f(x)} ${f(y1)}`\r\n );\r\n}\r\n\r\nfunction bodyPath(bw: number, bh: number, tr: number, br: number, bow: number) {\r\n const rt = clamp(bw * tr, 8, bh * 0.96);\r\n const rb = clamp(bw * br, 8, bh * 0.96);\r\n const p = (x: number, y: number) => `${x.toFixed(2)} ${y.toFixed(2)}`;\r\n const k = 0.46; // continuous corners, never a quarter circle\r\n const ft = clamp((bw - rt) / bw, 0, 1);\r\n const fb = clamp((bw - rb) / bw, 0, 1);\r\n return (\r\n `M${p(-bw, -bh + rt)}` +\r\n `C${p(-bw, -bh + rt * k)} ${p(-bw + rt * k, -bh)} ${p(-bw + rt, -bh)}` +\r\n `C${p(-bw * 0.3 * ft, -bh - 2 * ft)} ${p(bw * 0.3 * ft, -bh - 2 * ft)} ${p(bw - rt, -bh)}` +\r\n `C${p(bw - rt * k, -bh)} ${p(bw, -bh + rt * k)} ${p(bw, -bh + rt)}` +\r\n side(bw, -bh + rt, bh - rb, bow) +\r\n `C${p(bw, bh - rb * k)} ${p(bw - rb * k, bh)} ${p(bw - rb, bh)}` +\r\n `C${p(bw * 0.3 * fb, bh + 2 * fb)} ${p(-bw * 0.3 * fb, bh + 2 * fb)} ${p(-bw + rb, bh)}` +\r\n `C${p(-bw + rb * k, bh)} ${p(-bw, bh - rb * k)} ${p(-bw, bh - rb)}` +\r\n side(-bw, bh - rb, -bh + rt, -bow) +\r\n 'Z'\r\n );\r\n}\r\n\r\nconst NEUTRALS = [\r\n { name: 'Graphite', color: '#4B5058', light: '#A8AEB6', glow: 'rgba(75, 80, 88, 0.26)' },\r\n { name: 'Mist', color: '#78868F', light: '#BFC9CF', glow: 'rgba(120, 134, 143, 0.26)' },\r\n { name: 'Sandstone', color: '#8A7E71', light: '#CBC1B5', glow: 'rgba(138, 126, 113, 0.26)' },\r\n { name: 'Pewter', color: '#5F6670', light: '#B3BAC3', glow: 'rgba(95, 102, 112, 0.26)' },\r\n];\r\n\r\nconst POPS = [\r\n { name: 'Aegean', color: '#2E6FB7', light: '#9CC1E6', glow: 'rgba(46, 111, 183, 0.30)' },\r\n { name: 'Fern', color: '#3C8C60', light: '#A2CFB4', glow: 'rgba(60, 140, 96, 0.30)' },\r\n { name: 'Marigold', color: '#C48A22', light: '#EBD095', glow: 'rgba(196, 138, 34, 0.30)' },\r\n { name: 'Coral', color: '#C15A4E', light: '#E9AEA3', glow: 'rgba(193, 90, 78, 0.30)' },\r\n { name: 'Iris', color: '#5F5CC4', light: '#B6B4E8', glow: 'rgba(95, 92, 196, 0.30)' },\r\n];\r\n\r\nexport const RARE_SHADES = [...NEUTRALS, ...POPS];\r\n\r\nfunction pickShade(current: typeof RARE_SHADES[number]) {\r\n const wasPop = POPS.includes(current as any);\r\n const pool = !wasPop && Math.random() < 0.26 ? POPS : NEUTRALS;\r\n const options = pool.filter(s => s !== current);\r\n return options[Math.floor(Math.random() * options.length)];\r\n}\r\n\r\ntype RGB = [number, number, number];\r\n\r\nfunction toRGB(hex: string): RGB {\r\n const n = parseInt(hex.slice(1), 16);\r\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\r\n}\r\n\r\nfunction rgbCSS(c: RGB) {\r\n return `rgb(${Math.round(c[0])}, ${Math.round(c[1])}, ${Math.round(c[2])})`;\r\n}\r\n\r\nfunction mix(base: RGB, tint: RGB, amount: number): RGB {\r\n return [\r\n base[0] + (tint[0] - base[0]) * amount,\r\n base[1] + (tint[1] - base[1]) * amount,\r\n base[2] + (tint[2] - base[2]) * amount,\r\n ];\r\n}\r\n\r\nconst MARBLE_PAPER: RGB[] = [\r\n [255, 253, 248],\r\n [247, 240, 231],\r\n [231, 218, 202],\r\n [198, 178, 156],\r\n];\r\nconst MARBLE_TINT = [0.05, 0.15, 0.42, 0.74];\r\nconst MARBLE_FLOOD = [0.52, 0.72, 0.9, 1];\r\n\r\nconst ALERT_SHADE = { color: '#E2581D', light: '#FFBE96', glow: 'rgba(226, 88, 29, 0.34)' };\r\n\r\nexport interface KikuAvatarProps {\r\n state?: KikuState;\r\n size?: number;\r\n alert?: boolean;\r\n theme?: string;\r\n feminine?: boolean;\r\n accessories?: {\r\n flower?: boolean;\r\n eyelashes?: boolean;\r\n blush?: boolean;\r\n };\r\n onImpact?: (splat: number, color: string, glow: string) => void;\r\n triggerRef?: React.MutableRefObject<(() => void) | undefined>;\r\n}\r\n\r\nexport function KikuAvatar({\r\n state = 'idle',\r\n size = 40,\r\n alert = false,\r\n theme,\r\n feminine,\r\n accessories,\r\n onImpact,\r\n triggerRef,\r\n}: KikuAvatarProps) {\r\n const stateRef = useRef<KikuState>(state);\r\n stateRef.current = state;\r\n const alertRef = useRef(alert);\r\n alertRef.current = alert;\r\n\r\n const isFeminine = theme === 'blush' || feminine === true || Boolean(accessories?.flower || accessories?.eyelashes || accessories?.blush);\r\n const showFlower = accessories?.flower ?? isFeminine;\r\n const showLashes = accessories?.eyelashes ?? isFeminine;\r\n const showBlush = accessories?.blush ?? isFeminine;\r\n\r\n const bodyRef = useRef<SVGPathElement>(null);\r\n const maskRef = useRef<SVGPathElement>(null);\r\n const figRef = useRef<SVGGElement>(null);\r\n const decorRef = useRef<SVGGElement>(null);\r\n const flowerGRef = useRef<SVGGElement>(null);\r\n const cheeksGRef = useRef<SVGGElement>(null);\r\n const lashesGRef = useRef<SVGGElement>(null);\r\n const lashLRef = useRef<SVGPathElement>(null);\r\n const lashRRef = useRef<SVGPathElement>(null);\r\n const warmRef = useRef<SVGRectElement>(null);\r\n const contactRef = useRef<SVGRectElement>(null);\r\n const stop1Ref = useRef<SVGStopElement>(null);\r\n const stop2Ref = useRef<SVGStopElement>(null);\r\n const stop3Ref = useRef<SVGStopElement>(null);\r\n const marbleRefs = useRef<(SVGStopElement | null)[]>([]);\r\n const slotRefs = useRef<(SVGRectElement | null)[]>([]);\r\n const slotGRef = useRef<SVGGElement>(null);\r\n const uid = useRef(`kiku-${Math.random().toString(36).slice(2, 8)}`).current;\r\n const onImpactRef = useRef(onImpact);\r\n onImpactRef.current = onImpact;\r\n\r\n useEffect(() => {\r\n const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n const at: Record<string, number> = {};\r\n const vel: Record<string, number> = {};\r\n KEYS.forEach(k => {\r\n at[k] = (BODY.idle as any)[k] ?? (MOOD.idle as any)[k] ?? 0;\r\n vel[k] = 0;\r\n });\r\n const slotAt = Array.from({ length: SLOTS }, () => ({ x: 0, y: 0, w: 0, h: 0, rx: 0, a: 0 }));\r\n const slotVel = Array.from({ length: SLOTS }, () => ({ x: 0, y: 0, w: 0, h: 0, rx: 0, a: 0 }));\r\n\r\n let blinkAt = 1800, blinkPhase = -1, wander = 0, wanderAt = 2600, raf = 0, gooOn = false;\r\n let hopDue = 9000 + Math.random() * 8000, hopPhase = -1;\r\n\r\n let lean = 0, leanVel = 0, leanWant = 0, leanAt = 4200;\r\n let peek = 0, peekVel = 0, peekWant = 0, peekAt = 12000;\r\n\r\n let shade = NEUTRALS[0];\r\n let deep: RGB = toRGB(shade.color);\r\n let pale: RGB = toRGB(shade.light);\r\n let deepWant: RGB = [...deep] as RGB;\r\n let paleWant: RGB = [...pale] as RGB;\r\n\r\n const DOUBLE_MS = 2600;\r\n let lastHopAt = -Infinity;\r\n let pendingEncore = false;\r\n let singlesSince = 0;\r\n let queuedHop = false;\r\n let now = 0;\r\n let puff = 0, puffVel = 0, wasAlert = false, nagDue = 0;\r\n\r\n const startHop = (t: number) => {\r\n if (t - lastHopAt < DOUBLE_MS) {\r\n shade = pickShade(shade);\r\n deepWant = toRGB(shade.color);\r\n paleWant = toRGB(shade.light);\r\n lastHopAt = -Infinity; // a third hop starts a fresh pair\r\n } else {\r\n lastHopAt = t;\r\n }\r\n };\r\n\r\n const layout = (t: number, lid: number, gx: number, gy: number) => {\r\n const phase = stateRef.current;\r\n const out = Array.from({ length: SLOTS }, () => ({ x: 0, y: 0, w: 0, h: 0, rx: 0, a: 0 }));\r\n const eye = (i: number, cx: number, dy = 0) => {\r\n const h = Math.max(4, 54 * Math.max(0.06, lid));\r\n out[i] = { x: cx + gx, y: -4 + gy + dy, w: 21, h, rx: 10.5, a: 1 };\r\n };\r\n if (phase === 'thinking') {\r\n const n = 4;\r\n const cycle = (t % 2800) / 2800;\r\n const fuse = Math.pow(Math.sin(cycle * Math.PI * 2) * 0.5 + 0.5, 3); // 1 = gathered\r\n for (let i = 0; i < n; i++) {\r\n const a = t / 700 + (i / n) * Math.PI * 2;\r\n const R = (26 - (i % 2) * 5) * (1 - 0.94 * fuse); // uneven orbits, so it never reads as a spinner\r\n const s = 16 + fuse * 6 + Math.sin(t / 420 + i) * 1.4; // stay above the goo threshold when apart\r\n out[i] = { x: Math.cos(a) * R, y: Math.sin(a) * R * 0.86 + 2, w: s, h: s, rx: s / 2, a: 1 };\r\n }\r\n } else if (phase === 'visualizing') {\r\n out[0] = { x: 0, y: -2, w: 78, h: 26, rx: 13, a: 1 };\r\n } else if (phase === 'speaking') {\r\n const n = 5;\r\n for (let i = 0; i < n; i++) {\r\n const h = 12 + Math.abs(Math.sin(t / 150 + i * 0.9)) * 26;\r\n out[i] = { x: (i - (n - 1) / 2) * 15, y: -2, w: 9, h, rx: 4.5, a: 1 };\r\n }\r\n } else if (phase === 'failed') {\r\n eye(0, -22, 8); eye(1, 22, 8);\r\n } else {\r\n eye(0, -22); eye(1, 22);\r\n }\r\n return out;\r\n };\r\n\r\n if (triggerRef) {\r\n triggerRef.current = () => {\r\n if (hopPhase >= 0) {\r\n queuedHop = true;\r\n shade = pickShade(shade);\r\n deepWant = toRGB(shade.color);\r\n paleWant = toRGB(shade.light);\r\n lastHopAt = -Infinity;\r\n return;\r\n }\r\n hopPhase = 0;\r\n startHop(now);\r\n hopDue = now + 4000;\r\n };\r\n }\r\n\r\n const frame = (t: number) => {\r\n now = t;\r\n const phase = stateRef.current;\r\n const shape = BODY[phase] ?? BODY.idle, mood = MOOD[phase] ?? MOOD.idle;\r\n const facing = phase === 'idle' || phase === 'failed';\r\n\r\n if (facing && !reduced) {\r\n if (t > wanderAt) { wander = (Math.random() - 0.5) * 2; wanderAt = t + 1800 + Math.random() * 3600; }\r\n (at as any).wantGx = wander * 5;\r\n }\r\n const puffWant = alertRef.current ? 1 : 0;\r\n puffVel = (puffVel + (puffWant - puff) * 0.1) * 0.88;\r\n puff += puffVel;\r\n const breath = alertRef.current && !reduced ? Math.sin(t / 480) * 0.055 * puff : 0;\r\n\r\n const want: Record<string, number> = {\r\n bw: shape.bw * (1 + puff * 0.34 + breath), bh: shape.bh * (1 + puff * 0.2 + breath),\r\n tr: shape.tr, br: shape.br, bow: shape.bow,\r\n warm: mood.warm, wob: mood.wob, lid: mood.lid,\r\n gx: facing && !reduced ? wander * 5 : 0,\r\n gy: facing && !reduced ? Math.sin(t / 2600) * 2 : 0,\r\n };\r\n\r\n if (!reduced && facing) {\r\n if (blinkPhase < 0 && t > blinkAt) blinkPhase = 0;\r\n if (blinkPhase >= 0) {\r\n blinkPhase += 1 / 7;\r\n want.lid = mood.lid * Math.abs(blinkPhase - 0.5) * 2;\r\n if (blinkPhase >= 1) {\r\n blinkPhase = -1;\r\n want.lid = mood.lid;\r\n blinkAt = t + (Math.random() < 0.22 ? 340 : 2600 + Math.random() * 4200);\r\n }\r\n }\r\n }\r\n\r\n KEYS.forEach(k => {\r\n const key = k as Key;\r\n if (reduced) { at[key] = want[key]; return; }\r\n const stiff = key === 'lid' ? 0.42 : 0.11;\r\n const damp = key === 'lid' ? 0.55 : 0.78;\r\n vel[key] = (vel[key] + (want[key] - at[key]) * stiff) * damp;\r\n at[key] += vel[key];\r\n });\r\n\r\n let squash = 0, lift = 0;\r\n if (!reduced && alertRef.current && hopPhase < 0 && t > nagDue) {\r\n hopPhase = 0;\r\n nagDue = t + 2100;\r\n hopDue = t + 4000;\r\n }\r\n if (!reduced && phase === 'idle') {\r\n if (hopPhase < 0 && t > hopDue) {\r\n hopPhase = 0;\r\n if (pendingEncore) {\r\n pendingEncore = false;\r\n singlesSince = 0;\r\n shade = pickShade(shade);\r\n deepWant = toRGB(shade.color);\r\n paleWant = toRGB(shade.light);\r\n lastHopAt = -Infinity;\r\n } else {\r\n singlesSince++;\r\n startHop(t);\r\n }\r\n }\r\n } else if (hopPhase < 0) {\r\n hopDue = t + 3000 + Math.random() * 3000;\r\n }\r\n\r\n if (hopPhase >= 0) {\r\n hopPhase += 1 / 96;\r\n [squash, lift] = hopAt(hopPhase);\r\n if (hopPhase >= 1) {\r\n hopPhase = -1; squash = 0; lift = 0;\r\n if (queuedHop) {\r\n queuedHop = false;\r\n singlesSince = 0;\r\n hopDue = t + 150;\r\n } else if (!pendingEncore && singlesSince >= 2) {\r\n pendingEncore = true;\r\n hopDue = t + 240;\r\n } else {\r\n hopDue = t + 5000 + Math.random() * 5000;\r\n }\r\n }\r\n }\r\n const splat = Math.max(0, squash);\r\n\r\n if (alertRef.current !== wasAlert) {\r\n wasAlert = alertRef.current;\r\n const to = alertRef.current ? ALERT_SHADE : shade;\r\n deepWant = toRGB(to.color);\r\n paleWant = toRGB(to.light);\r\n if (alertRef.current && !reduced) {\r\n if (hopPhase < 0) hopPhase = 0;\r\n nagDue = t + 2600;\r\n }\r\n }\r\n\r\n const currentShade = alertRef.current ? ALERT_SHADE : shade;\r\n\r\n if (!reduced) {\r\n for (let i = 0; i < 3; i++) {\r\n deep[i] += (deepWant[i] - deep[i]) * 0.055;\r\n pale[i] += (paleWant[i] - pale[i]) * 0.055;\r\n }\r\n } else {\r\n deep = [...deepWant] as RGB;\r\n pale = [...paleWant] as RGB;\r\n }\r\n const deepCSS = rgbCSS(deep), paleCSS = rgbCSS(pale);\r\n stop1Ref.current?.setAttribute('stop-color', deepCSS);\r\n stop2Ref.current?.setAttribute('stop-color', paleCSS);\r\n stop3Ref.current?.setAttribute('stop-color', paleCSS);\r\n\r\n for (let i = 0; i < 4; i++) {\r\n const amount = MARBLE_TINT[i] + (MARBLE_FLOOD[i] - MARBLE_TINT[i]) * puff;\r\n marbleRefs.current[i]?.style.setProperty(\r\n 'stop-color',\r\n rgbCSS(mix(MARBLE_PAPER[i], deep, amount)),\r\n );\r\n }\r\n\r\n const baseWash = 0.34 + Math.sin(t / 1200) * 0.06;\r\n const contactOpacity = splat > 0.02 ? Math.min(0.72, baseWash + splat * 0.34) : baseWash;\r\n contactRef.current?.setAttribute('opacity', contactOpacity.toFixed(3));\r\n\r\n if (splat > 0.04) {\r\n onImpactRef.current?.(splat, currentShade.color, currentShade.glow);\r\n } else if (lastSplat > 0.04) {\r\n onImpactRef.current?.(0, currentShade.color, currentShade.glow);\r\n }\r\n lastSplat = splat;\r\n\r\n const wobble = reduced ? 0 : Math.sin(t / 1900) * 0.9 * at.wob;\r\n const bwF = at.bw * (1 + squash * 0.55) + wobble * 0.4;\r\n const bhF = at.bh * (1 - squash * 0.62);\r\n const d = bodyPath(\r\n bwF, bhF,\r\n clamp(at.tr + splat * 0.5, 0, 1.2),\r\n clamp(at.br + splat * 0.9, 0, 1),\r\n at.bow + wobble + splat * 5,\r\n );\r\n bodyRef.current?.setAttribute('d', d);\r\n maskRef.current?.setAttribute('d', d);\r\n\r\n const wantGoo = phase === 'thinking';\r\n if (wantGoo !== gooOn) {\r\n gooOn = wantGoo;\r\n slotGRef.current?.setAttribute('filter', wantGoo ? `url(#${uid}-goo)` : 'none');\r\n }\r\n\r\n const targets = layout(t, at.lid * (1 - splat * 0.85), at.gx, at.gy);\r\n for (let i = 0; i < SLOTS; i++) {\r\n const T = targets[i] as any, A = slotAt[i] as any, V = slotVel[i] as any;\r\n for (const k of ['x', 'y', 'w', 'h', 'rx', 'a']) {\r\n if (reduced) { A[k] = T[k]; continue; }\r\n V[k] = (V[k] + (T[k] - A[k]) * 0.16) * 0.74;\r\n A[k] += V[k];\r\n }\r\n const e = slotRefs.current[i];\r\n if (!e) continue;\r\n e.setAttribute('x', (A.x - A.w / 2).toFixed(2));\r\n e.setAttribute('y', (A.y - A.h / 2).toFixed(2));\r\n e.setAttribute('width', Math.max(0, A.w).toFixed(2));\r\n e.setAttribute('height', Math.max(0, A.h).toFixed(2));\r\n e.setAttribute('rx', Math.max(0, Math.min(A.rx, A.w / 2, A.h / 2)).toFixed(2));\r\n e.setAttribute('opacity', clamp(A.a, 0, 1).toFixed(2));\r\n }\r\n\r\n const breathe = reduced ? 0 : Math.sin(t / mood.breath) * 1.5;\r\n\r\n if (!reduced && facing && hopPhase < 0) {\r\n if (t > leanAt) {\r\n leanWant = (Math.random() < 0.5 ? -1 : 1) * (0.35 + Math.random() * 0.65);\r\n leanAt = t + 2600 + Math.random() * 4200;\r\n }\r\n if (t > peekAt) {\r\n peekWant = peekWant > 0.1 ? 0 : 1;\r\n peekAt = t + (peekWant > 0.1 ? 900 : 9000 + Math.random() * 11000);\r\n }\r\n } else {\r\n leanWant = 0;\r\n peekWant = 0;\r\n }\r\n leanVel = (leanVel + (leanWant - lean) * 0.028) * 0.9;\r\n lean += leanVel;\r\n peekVel = (peekVel + (peekWant - peek) * 0.06) * 0.82;\r\n peek += peekVel;\r\n\r\n const planted = at.bh - bhF;\r\n const tilt = lean * 3.4 + peek * 4.5;\r\n const shift = lean * 2.2 + peek * 3;\r\n const dip = peek * 2.4;\r\n figRef.current?.setAttribute(\r\n 'transform',\r\n `translate(${shift.toFixed(2)} ${(breathe + planted - lift + dip).toFixed(2)}) rotate(${tilt.toFixed(2)} 0 60)`,\r\n );\r\n\r\n if (decorRef.current) {\r\n decorRef.current.setAttribute(\r\n 'transform',\r\n `translate(${shift.toFixed(2)} ${(breathe + planted - lift + dip).toFixed(2)}) rotate(${tilt.toFixed(2)} 0 60)`,\r\n );\r\n }\r\n\r\n if (showFlower && flowerGRef.current) {\r\n const flowerX = -bwF * 0.62;\r\n const flowerY = -bhF * 0.70;\r\n const flowerTilt = -16 + (reduced ? 0 : Math.sin(t / 1400) * 3) + tilt * 0.4;\r\n flowerGRef.current.setAttribute(\r\n 'transform',\r\n `translate(${flowerX.toFixed(2)}, ${flowerY.toFixed(2)}) rotate(${flowerTilt.toFixed(2)})`\r\n );\r\n }\r\n\r\n if (showBlush && cheeksGRef.current) {\r\n const cheekY = 12 + at.gy * 0.5;\r\n cheeksGRef.current.setAttribute('transform', `translate(0, ${cheekY.toFixed(2)})`);\r\n }\r\n\r\n if (showLashes && lashesGRef.current) {\r\n const isEyeFacing = phase !== 'thinking' && phase !== 'visualizing' && phase !== 'speaking';\r\n lashesGRef.current.setAttribute('opacity', isEyeFacing ? clamp(at.lid * 1.3, 0, 1).toFixed(2) : '0');\r\n\r\n // rooted on each eye's own top-outer curve, so they track blinks and gaze\r\n // instead of floating at fixed coordinates\r\n const lashes = (A: { x: number; y: number; w: number; h: number }, side: number) => {\r\n const R = Math.max(1, Math.min(A.w, A.h) / 2);\r\n const cy = A.y - A.h / 2 + R;\r\n let d = '';\r\n for (const [deg, len] of [[20, 7], [48, 8], [76, 6.5]]) {\r\n const th = (deg * Math.PI) / 180;\r\n const sx = A.x + side * Math.sin(th) * R;\r\n const sy = cy - Math.cos(th) * R;\r\n const ex = A.x + side * Math.sin(th) * (R + len);\r\n const ey = cy - Math.cos(th) * (R + len) - 1.5;\r\n const cxp = A.x + side * Math.sin(th - 0.22) * (R + len * 0.65);\r\n const cyp = cy - Math.cos(th - 0.22) * (R + len * 0.65);\r\n d += ` M ${sx.toFixed(2)} ${sy.toFixed(2)} Q ${cxp.toFixed(2)} ${cyp.toFixed(2)} ${ex.toFixed(2)} ${ey.toFixed(2)}`;\r\n }\r\n return d.trim();\r\n };\r\n lashLRef.current?.setAttribute('d', lashes(slotAt[0] as any, -1));\r\n lashRRef.current?.setAttribute('d', lashes(slotAt[1] as any, 1));\r\n }\r\n\r\n raf = requestAnimationFrame(frame);\r\n };\r\n\r\n let lastSplat = 0;\r\n\r\n raf = requestAnimationFrame(frame);\r\n return () => cancelAnimationFrame(raf);\r\n }, [showFlower, showLashes, showBlush, isFeminine]);\r\n\r\n return (\r\n <svg className=\"hsk-kiku-avatar\" width={size} height={size} viewBox=\"-100 -100 200 200\" aria-hidden=\"true\" style={{ display: 'block', overflow: 'visible' }}>\r\n <defs>\r\n <linearGradient id={`${uid}-marble`} x1=\".2\" y1=\"0\" x2=\".42\" y2=\"1\">\r\n {[0, 40, 82, 100].map((offset, i) => (\r\n <stop\r\n key={offset}\r\n ref={el => { marbleRefs.current[i] = el; }}\r\n offset={`${offset}%`}\r\n style={{ stopColor: `var(--hsk-marble-${i + 1}, #FAF7F2)` }}\r\n />\r\n ))}\r\n </linearGradient>\r\n <linearGradient id={`${uid}-contact`} x1=\"0\" y1=\"1\" x2=\"0\" y2=\"0\">\r\n {}\r\n <stop ref={stop1Ref} offset=\"0%\" stopColor={NEUTRALS[0].color} stopOpacity=\"0.9\" />\r\n <stop ref={stop2Ref} offset=\"45%\" stopColor={NEUTRALS[0].light} stopOpacity=\"0.5\" />\r\n <stop ref={stop3Ref} offset=\"100%\" stopColor={NEUTRALS[0].light} stopOpacity=\"0\" />\r\n </linearGradient>\r\n <radialGradient id={`${uid}-sheen`} cx=\".34\" cy=\".2\" r=\".55\">\r\n <stop offset=\"0%\" stopColor=\"#FFFFFF\" style={{ stopOpacity: 'var(--hsk-marble-sheen, .9)' }} />\r\n <stop offset=\"100%\" stopColor=\"#FFFFFF\" stopOpacity=\"0\" />\r\n </radialGradient>\r\n <linearGradient id={`${uid}-hibiscus-petal`} x1=\"0\" y1=\"1\" x2=\"0\" y2=\"0\">\r\n <stop offset=\"0%\" stopColor=\"#FF3366\" />\r\n <stop offset=\"65%\" stopColor=\"#FF758F\" />\r\n <stop offset=\"100%\" stopColor=\"#FFAAA6\" />\r\n </linearGradient>\r\n <radialGradient id={`${uid}-blush-cheek`} cx=\"50%\" cy=\"50%\" r=\"50%\">\r\n <stop offset=\"0%\" stopColor=\"#FB7185\" stopOpacity=\"0.48\" />\r\n <stop offset=\"100%\" stopColor=\"#FB7185\" stopOpacity=\"0\" />\r\n </radialGradient>\r\n <clipPath id={`${uid}-skin`}><use href={`#${uid}-body`} /></clipPath>\r\n <filter id={`${uid}-goo`} x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\r\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"4\" result=\"b\" />\r\n <feColorMatrix in=\"b\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7\" />\r\n </filter>\r\n <mask id={`${uid}-cut`}>\r\n <path ref={maskRef} d=\"\" fill=\"#FFFFFF\" />\r\n <g ref={slotGRef}>\r\n {Array.from({ length: SLOTS }, (_, i) => (\r\n <rect key={i} ref={el => { slotRefs.current[i] = el; }} fill=\"#000000\" />\r\n ))}\r\n </g>\r\n </mask>\r\n </defs>\r\n \r\n {/* Base Body & Cutouts */}\r\n <g ref={figRef} mask={`url(#${uid}-cut)`}>\r\n <path id={`${uid}-body`} ref={bodyRef} d=\"\" fill={`url(#${uid}-marble)`} />\r\n <g clipPath={`url(#${uid}-skin)`}>\r\n <ellipse cx=\"-14\" cy=\"-40\" rx=\"46\" ry=\"34\" fill={`url(#${uid}-sheen)`} />\r\n <rect ref={contactRef} x=\"-100\" y=\"-20\" width=\"200\" height=\"100\" fill={`url(#${uid}-contact)`} opacity=\"0.45\" />\r\n </g>\r\n </g>\r\n\r\n {/* Feminine Blush Decor Overlay (syncs with figure transform) */}\r\n <g ref={decorRef} style={{ pointerEvents: 'none' }}>\r\n {/* Cheek Blush */}\r\n {showBlush && (\r\n <g ref={cheeksGRef}>\r\n <ellipse cx=\"-28\" cy=\"0\" rx=\"10\" ry=\"5.5\" fill={`url(#${uid}-blush-cheek)`} />\r\n <ellipse cx=\"28\" cy=\"0\" rx=\"10\" ry=\"5.5\" fill={`url(#${uid}-blush-cheek)`} />\r\n </g>\r\n )}\r\n\r\n {/* Fluttery Eyelashes */}\r\n {showLashes && (\r\n <g ref={lashesGRef}>\r\n <path ref={lashLRef} stroke=\"#3D1424\" strokeWidth=\"1.7\" strokeLinecap=\"round\" fill=\"none\" />\r\n <path ref={lashRRef} stroke=\"#3D1424\" strokeWidth=\"1.7\" strokeLinecap=\"round\" fill=\"none\" />\r\n </g>\r\n )}\r\n\r\n {/* Tropical Hawaiian Hibiscus Flower */}\r\n {showFlower && (\r\n <g ref={flowerGRef} className=\"hsk-avatar-flower\">\r\n {/* Mint Green Leaf */}\r\n <path d=\"M 0 0 C -12 -7 -15 5 0 0 Z\" fill=\"#10B981\" transform=\"translate(6, 4) rotate(-35)\" />\r\n {/* 5 Petals */}\r\n {[0, 72, 144, 216, 288].map(deg => (\r\n <path\r\n key={deg}\r\n d=\"M 0 0 C -6 -13 6 -13 0 0 Z\"\r\n fill={`url(#${uid}-hibiscus-petal)`}\r\n stroke=\"#FF2A5F\"\r\n strokeWidth=\"0.6\"\r\n transform={`rotate(${deg - 18})`}\r\n />\r\n ))}\r\n {/* Curved Pistil / Stamen */}\r\n <path d=\"M 0 0 Q 3 -10 9 -14\" stroke=\"#F59E0B\" strokeWidth=\"1.6\" strokeLinecap=\"round\" fill=\"none\" />\r\n {/* Golden Yellow Pollen Grains */}\r\n <circle cx=\"9\" cy=\"-14\" r=\"1.3\" fill=\"#FDE047\" />\r\n <circle cx=\"7\" cy=\"-12\" r=\"1.1\" fill=\"#FDE047\" />\r\n <circle cx=\"6.5\" cy=\"-15\" r=\"1.1\" fill=\"#FDE047\" />\r\n {/* Crimson Center Hub */}\r\n <circle cx=\"0\" cy=\"0\" r=\"2.2\" fill=\"#881337\" />\r\n </g>\r\n )}\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\nexport default KikuAvatar;\r\n","import React from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport type { KikuState } from '../KikuAvatar';\r\nimport { ChromeLoading } from './components/ListeningWave';\r\nimport { LANGUAGE_CHOICES, endonymFor, type UIStringKey } from './types';\r\nimport { CascadeText } from './components/CascadeText';\r\nimport { InkBloomSkeleton } from './components/InkBloomSkeleton';\r\nimport { splitPlaceholder } from './components/AnimatedPlaceholder';\r\nimport { ShieldIcon, KeyOutlineIcon, VaultIcon, GlobeIcon } from './icons';\r\n\r\nfunction countShimmerUnits(node: React.ReactNode): number {\r\n if (typeof node === 'string') return splitPlaceholder(node).length;\r\n if (Array.isArray(node)) return node.reduce<number>((n, c) => n + countShimmerUnits(c), 0);\r\n if (React.isValidElement(node)) return countShimmerUnits((node.props as any)?.children);\r\n return 0;\r\n}\r\n\r\n// walks the whole tree so interpolated nodes (tNode's <bdi>) shimmer like plain text\r\nfunction shimmerTree(\r\n node: React.ReactNode,\r\n cursor: { i: number },\r\n last: number,\r\n baseIdx: number,\r\n): React.ReactNode {\r\n if (typeof node === 'string') {\r\n return splitPlaceholder(node).map(unit => {\r\n const i = cursor.i++;\r\n return (\r\n <span\r\n key={i}\r\n className=\"hsk-cb-shimmer-char\"\r\n style={{\r\n '--hsk-char-idx': baseIdx + i,\r\n '--hsk-ph-hue': `${Math.round((i / last) * 300)}`,\r\n } as React.CSSProperties}\r\n >\r\n {unit}\r\n </span>\r\n );\r\n });\r\n }\r\n if (Array.isArray(node)) {\r\n return node.map((child, k) => (\r\n <React.Fragment key={k}>{shimmerTree(child, cursor, last, baseIdx)}</React.Fragment>\r\n ));\r\n }\r\n if (React.isValidElement(node)) {\r\n return React.cloneElement(node as any, {\r\n children: shimmerTree((node.props as any)?.children, cursor, last, baseIdx),\r\n });\r\n }\r\n return node;\r\n}\r\n\r\nfunction ShimmerText({ text, baseIdx = 0 }: { text: React.ReactNode; baseIdx?: number }) {\r\n const last = Math.max(countShimmerUnits(text) - 1, 1);\r\n return <>{shimmerTree(text, { i: 0 }, last, baseIdx)}</>;\r\n}\r\n\r\nexport interface OnboardingViewProps {\r\n inOnboarding: boolean;\r\n justCompleted: boolean;\r\n onboardingMood?: KikuState;\r\n awaitingLang: boolean;\r\n awaitingName: boolean;\r\n awaitingEntityLang: boolean;\r\n awaitingConsent: boolean;\r\n termsAgreed: boolean;\r\n shopperLanguage: string;\r\n shopperName: string;\r\n entityLangPref: string;\r\n chromeReady: boolean;\r\n activeChips: string[];\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n tNode: (key: UIStringKey, vars: Record<string, string>) => React.ReactNode;\r\n chooseLanguage: (lang: string) => void;\r\n chooseEntityLang: (mode: 'translated' | 'original') => void;\r\n agreeTerms: () => void;\r\n handleSend: (text: string) => void;\r\n}\r\n\r\nexport function OnboardingView({\r\n inOnboarding,\r\n justCompleted,\r\n onboardingMood,\r\n awaitingLang,\r\n awaitingName,\r\n awaitingEntityLang,\r\n awaitingConsent,\r\n termsAgreed,\r\n shopperLanguage,\r\n shopperName,\r\n entityLangPref,\r\n chromeReady,\r\n activeChips,\r\n t,\r\n tNode,\r\n chooseLanguage,\r\n chooseEntityLang,\r\n agreeTerms,\r\n handleSend,\r\n}: OnboardingViewProps) {\r\n const currentStep = awaitingLang ? '1' : awaitingName ? '2' : awaitingEntityLang ? '3' : awaitingConsent ? '4' : null;\r\n const displayShopperLang = endonymFor(shopperLanguage) || shopperLanguage;\r\n const [countdown, setCountdown] = React.useState(30);\r\n\r\n React.useEffect(() => {\r\n if (!awaitingConsent) {\r\n setCountdown(30);\r\n return;\r\n }\r\n const timer = setInterval(() => {\r\n setCountdown(prev => {\r\n if (prev <= 1) {\r\n clearInterval(timer);\r\n return 0;\r\n }\r\n return prev - 1;\r\n });\r\n }, 1000);\r\n return () => clearInterval(timer);\r\n }, [awaitingConsent]);\r\n\r\n return (\r\n <div className=\"hsk-cb-empty\">\r\n <div className=\"hsk-cb-onboarding-card\">\r\n {currentStep && (\r\n <div className=\"hsk-cb-onboarding-head\">\r\n <span className=\"hsk-cb-step-badge\" dir=\"ltr\">\r\n {currentStep} / 4\r\n </span>\r\n </div>\r\n )}\r\n {awaitingLang ? (\r\n <div className=\"hsk-cb-hello-wrap\" key=\"step-lang\">\r\n <h2 className=\"hsk-cb-hello hsk-cascade\">\r\n <CascadeText baseMs={0}>What language should we chat in?</CascadeText>\r\n </h2>\r\n <div className=\"hsk-cb-lang-chips\">\r\n {LANGUAGE_CHOICES.map((l, i) => (\r\n <button\r\n key={l.value}\r\n type=\"button\"\r\n className=\"hsk-cb-lang-chip\"\r\n style={{ '--hsk-pill-idx': i } as React.CSSProperties}\r\n lang={l.tag}\r\n dir={l.rtl ? 'rtl' : 'ltr'}\r\n onClick={() => chooseLanguage(l.value)}\r\n >\r\n {l.native}\r\n </button>\r\n ))}\r\n <span\r\n className=\"hsk-cb-lang-chips-hint\"\r\n style={{ '--hsk-pill-idx': LANGUAGE_CHOICES.length } as React.CSSProperties}\r\n >\r\n or type any other\r\n </span>\r\n </div>\r\n </div>\r\n ) : awaitingName ? (\r\n <div className=\"hsk-cb-hello-wrap\" key=\"step-name\">\r\n {chromeReady ? (\r\n <>\r\n <h2 className=\"hsk-cb-hello hsk-cascade\">\r\n <CascadeText baseMs={0}>{t('nameStepTitle')}</CascadeText>\r\n </h2>\r\n <p className=\"hsk-cb-hello-lead hsk-cascade\">\r\n <CascadeText baseMs={30}>{t('nameStepLead')}</CascadeText>\r\n </p>\r\n <p className=\"hsk-cb-hello-ask hsk-cascade\">\r\n <CascadeText baseMs={60}>{t('nameStepAsk')}</CascadeText>\r\n </p>\r\n </>\r\n ) : (\r\n <InkBloomSkeleton />\r\n )}\r\n </div>\r\n ) : awaitingEntityLang ? (\r\n <div className=\"hsk-cb-hello-wrap\" key=\"step-entity-lang\">\r\n {chromeReady ? (\r\n <>\r\n <h2 className=\"hsk-cb-hello hsk-cascade\">\r\n <CascadeText baseMs={0}>{t('howShouldResultsLook')}</CascadeText>\r\n </h2>\r\n <p className=\"hsk-cb-hello-lead hsk-cascade\">\r\n <CascadeText baseMs={30}>{tNode('entityLangIntro', { lang: displayShopperLang })}</CascadeText>\r\n </p>\r\n </>\r\n ) : (\r\n <InkBloomSkeleton lines={2} />\r\n )}\r\n {chromeReady && (\r\n <div className=\"hsk-cb-entlang-opts\" role=\"radiogroup\" aria-label={t('howShouldResultsLook')}>\r\n {(['translated', 'original'] as const).map((mode, i) => (\r\n <button\r\n key={mode}\r\n type=\"button\"\r\n role=\"radio\"\r\n aria-checked={entityLangPref === mode}\r\n className={cn(\"hsk-cb-entlang-opt\", entityLangPref === mode && \"is-selected\")}\r\n style={{ '--hsk-opt-idx': i } as React.CSSProperties}\r\n onClick={() => chooseEntityLang(mode)}\r\n >\r\n <span className=\"hsk-cb-entlang-radio\" aria-hidden=\"true\">\r\n <span className=\"hsk-cb-entlang-radio-dot\" />\r\n </span>\r\n <span className=\"hsk-cb-entlang-opt-text\">\r\n <span className=\"hsk-cb-entlang-opt-title\">\r\n <ShimmerText\r\n text={\r\n mode === 'translated'\r\n ? tNode('inLanguage', { lang: displayShopperLang })\r\n : t('asWritten')\r\n }\r\n baseIdx={0}\r\n />\r\n </span>\r\n <span className=\"hsk-cb-entlang-opt-note\">\r\n <ShimmerText\r\n text={\r\n mode === 'translated'\r\n ? t('detailsTranslated')\r\n : t('namesAsWritten')\r\n }\r\n baseIdx={15}\r\n />\r\n </span>\r\n </span>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n ) : awaitingConsent ? (\r\n <div className=\"hsk-cb-hello-wrap\" key=\"step-terms\">\r\n {chromeReady && (\r\n <>\r\n <h2 className=\"hsk-cb-hello hsk-cascade\">\r\n <CascadeText baseMs={0}>{t('termsStepTitle')}</CascadeText>\r\n </h2>\r\n <p className=\"hsk-cb-hello-lead hsk-cascade\">\r\n <CascadeText baseMs={30}>{t('termsStepSubtitle')}</CascadeText>\r\n </p>\r\n <div className=\"hsk-cb-terms-sanctuary\">\r\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 0 } as React.CSSProperties}>\r\n <div className=\"hsk-cb-terms-head\">\r\n <span className=\"hsk-cb-terms-numeral\">I</span>\r\n <h3 className=\"hsk-cb-terms-title\">{t('termsPiiTitle')}</h3>\r\n </div>\r\n <p className=\"hsk-cb-terms-desc\">{t('termsPiiDesc')}</p>\r\n </div>\r\n\r\n <div className=\"hsk-cb-terms-divider\" />\r\n\r\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 1 } as React.CSSProperties}>\r\n <div className=\"hsk-cb-terms-head\">\r\n <span className=\"hsk-cb-terms-numeral\">II</span>\r\n <h3 className=\"hsk-cb-terms-title\">{t('termsSessionTitle')}</h3>\r\n </div>\r\n <p className=\"hsk-cb-terms-desc\">{t('termsSessionDesc')}</p>\r\n </div>\r\n\r\n <div className=\"hsk-cb-terms-divider\" />\r\n\r\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 2 } as React.CSSProperties}>\r\n <div className=\"hsk-cb-terms-head\">\r\n <span className=\"hsk-cb-terms-numeral\">III</span>\r\n <h3 className=\"hsk-cb-terms-title\">{t('termsMemoryTitle')}</h3>\r\n </div>\r\n <p className=\"hsk-cb-terms-desc\">{t('termsMemoryDesc')}</p>\r\n </div>\r\n\r\n <div className=\"hsk-cb-terms-divider\" />\r\n\r\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 3 } as React.CSSProperties}>\r\n <div className=\"hsk-cb-terms-head\">\r\n <span className=\"hsk-cb-terms-numeral\">IV</span>\r\n <h3 className=\"hsk-cb-terms-title\">{t('termsCookieTitle')}</h3>\r\n </div>\r\n <p className=\"hsk-cb-terms-desc\">{t('termsCookieDesc')}</p>\r\n </div>\r\n </div>\r\n\r\n <div className=\"hsk-cb-terms-action-wrap\">\r\n <button\r\n type=\"button\"\r\n className={cn(\r\n \"hsk-cb-terms-agree-btn\",\r\n countdown === 0 && \"is-active\"\r\n )}\r\n disabled={countdown > 0}\r\n onClick={agreeTerms}\r\n >\r\n {countdown > 0\r\n ? t('termsAgreeCounting', { seconds: String(countdown) })\r\n : t('termsAgreeButton')}\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n ) : justCompleted ? (\r\n <div className=\"hsk-cb-hello-wrap\" key=\"step-completed\">\r\n {chromeReady && (\r\n <>\r\n <h2 className=\"hsk-cb-hello hsk-cascade\">\r\n <CascadeText baseMs={0}>{tNode('allSet', { name: shopperName })}</CascadeText>\r\n </h2>\r\n <p className=\"hsk-cb-hello-lead hsk-cascade\">\r\n <CascadeText baseMs={30}>\r\n {entityLangPref === 'translated'\r\n ? tNode('replyingTranslated', { lang: displayShopperLang })\r\n : tNode('replyingOriginal', { lang: displayShopperLang })}\r\n </CascadeText>\r\n </p>\r\n </>\r\n )}\r\n </div>\r\n ) : shopperName ? (\r\n <div className=\"hsk-cb-hello-wrap\" key=\"step-returning\">\r\n <h2 className=\"hsk-cb-hello hsk-cascade\">\r\n <CascadeText baseMs={0}>{tNode('greetReturning', { name: shopperName })}</CascadeText>\r\n </h2>\r\n <p className=\"hsk-cb-hello-lead hsk-cascade\">\r\n <CascadeText baseMs={30}>{t('greetReturningLead')}</CascadeText>\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"hsk-cb-hello-wrap\" key=\"step-initial\">\r\n <h2 className=\"hsk-cb-hello hsk-cascade\">\r\n <CascadeText baseMs={0}>Hi, I'm <b>kiku</b>.</CascadeText>\r\n </h2>\r\n <p className=\"hsk-cb-hello-lead hsk-cascade\">\r\n <CascadeText baseMs={30}>Ask me to search, visualize, or capture anything — I look across the whole site in real time.</CascadeText>\r\n </p>\r\n </div>\r\n )}\r\n {!inOnboarding && (activeChips?.length ?? 0) > 0 && (\r\n <div className=\"hsk-cb-chips\">\r\n {activeChips.map((chip, i) => (\r\n <button\r\n key={chip}\r\n className=\"hsk-cb-chip\"\r\n style={{ '--hsk-pill-idx': i } as React.CSSProperties}\r\n onClick={() => handleSend(chip)}\r\n >\r\n {chip}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\nconst HSK_WORD_STAGGER_MS = 12;\r\n\r\nexport interface CascadeTextProps {\r\n children: React.ReactNode;\r\n baseMs?: number;\r\n}\r\n\r\nfunction plainText(node: React.ReactNode): string {\r\n if (node === null || node === undefined || typeof node === 'boolean') return '';\r\n if (typeof node === 'string' || typeof node === 'number') return String(node);\r\n if (Array.isArray(node)) return node.map(plainText).join('');\r\n if (React.isValidElement(node)) return plainText((node.props as { children?: React.ReactNode }).children);\r\n return '';\r\n}\r\n\r\nfunction segmentText(text: string): string[] {\r\n if (/^\\s+$/.test(text)) return [text];\r\n if (/\\s/.test(text)) {\r\n const chunks = text.split(/(\\s+)/).filter(Boolean);\r\n const out: string[] = [];\r\n for (const chunk of chunks) {\r\n if (/^\\s+$/.test(chunk)) {\r\n out.push(chunk);\r\n } else {\r\n out.push(...segmentText(chunk));\r\n }\r\n }\r\n return out;\r\n }\r\n if (text.length > 3 && typeof Intl !== 'undefined' && (Intl as any).Segmenter) {\r\n try {\r\n const seg = new (Intl as any).Segmenter(undefined, { granularity: 'word' });\r\n const segments = Array.from(seg.segment(text)).map((s: any) => s.segment);\r\n if (segments.length > 1) {\r\n return segments;\r\n }\r\n } catch {\r\n // fallback\r\n }\r\n }\r\n return [text];\r\n}\r\n\r\nfunction cascade(node: React.ReactNode, count: { i: number }, baseMs: number, keyPrefix: string): React.ReactNode {\r\n if (node === null || node === undefined || typeof node === 'boolean') return null;\r\n\r\n if (typeof node === 'string' || typeof node === 'number') {\r\n return segmentText(String(node))\r\n .map((chunk, ci) => {\r\n if (/^\\s+$/.test(chunk)) {\r\n return chunk;\r\n }\r\n const delay = baseMs + count.i * HSK_WORD_STAGGER_MS;\r\n count.i += 1;\r\n return (\r\n <span className=\"hsk-cascade__w\" key={`${keyPrefix}-w${ci}`} style={{ animationDelay: `${delay}ms` }}>\r\n {chunk}\r\n </span>\r\n );\r\n });\r\n }\r\n\r\n if (Array.isArray(node)) return node.map((child, i) => cascade(child, count, baseMs, `${keyPrefix}-${i}`));\r\n\r\n if (React.isValidElement(node)) {\r\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\r\n return React.cloneElement(el, { key: `${keyPrefix}-el` }, cascade(el.props.children, count, baseMs, `${keyPrefix}-c`));\r\n }\r\n\r\n return node;\r\n}\r\n\r\nexport function CascadeText({ children, baseMs = 0 }: CascadeTextProps) {\r\n const text = plainText(children);\r\n let hash = 0;\r\n for (let i = 0; i < text.length; i++) {\r\n hash = ((hash << 5) - hash + text.charCodeAt(i)) | 0;\r\n }\r\n const prefix = `c${Math.abs(hash)}`;\r\n\r\n return (\r\n <>\r\n <span className=\"hsk-sr-only\">{text}</span>\r\n <span aria-hidden=\"true\">{cascade(children, { i: 0 }, baseMs, prefix)}</span>\r\n </>\r\n );\r\n}\r\n","import React from 'react';\n\nexport interface InkBloomSkeletonProps {\n lines?: number;\n className?: string;\n}\n\nexport function InkBloomSkeleton({ lines = 3, className = '' }: InkBloomSkeletonProps) {\n return (\n <div className={`hsk-cb-ink-skeleton ${className}`} aria-hidden=\"true\" role=\"status\">\n <div className=\"hsk-cb-ink-line hsk-cb-ink-line--title\" />\n <div className=\"hsk-cb-ink-line hsk-cb-ink-line--lead1\" />\n {lines >= 2 && <div className=\"hsk-cb-ink-line hsk-cb-ink-line--lead2\" />}\n {lines >= 3 && <div className=\"hsk-cb-ink-line hsk-cb-ink-line--ask\" />}\n </div>\n );\n}\r\n","import React from 'react';\r\n\r\nexport interface AnimatedPlaceholderProps {\r\n text?: string;\r\n placeholder?: string;\r\n visible?: boolean;\r\n replay?: number;\r\n replaySeed?: number;\r\n staggerMs?: number;\r\n}\r\n\r\nexport const HSK_STAGGER_MS = 16;\r\n\r\nconst HSK_FIELD_BASE_MS = 110;\r\n\r\nconst JOINING_SCRIPT = /[-ۿ܀-ݏ߀-߿ࡠ-ࣿﭐ-﷿ﹰ-]/;\r\n\r\ntype GraphemeSegmenter = {\r\n segment(input: string): Iterable<{ segment: string }>;\r\n};\r\ntype IntlWithSegmenter = typeof Intl & {\r\n Segmenter?: new (locale?: string, options?: { granularity: string }) => GraphemeSegmenter;\r\n};\r\n\r\nexport function splitPlaceholder(text: string): string[] {\r\n if (!text) return [];\r\n\r\n if (JOINING_SCRIPT.test(text)) return text.split(/(\\s+)/).filter(Boolean);\r\n\r\n const I = typeof Intl !== 'undefined' ? (Intl as IntlWithSegmenter) : undefined;\r\n if (I?.Segmenter) {\r\n const seg = new I.Segmenter(undefined, { granularity: 'grapheme' });\r\n return Array.from(seg.segment(text), s => s.segment);\r\n }\r\n\r\n return text.split(/(\\s+)/).filter(Boolean);\r\n}\r\n\r\nexport function AnimatedPlaceholder({\r\n text,\r\n placeholder,\r\n visible = true,\r\n replay = 0,\r\n replaySeed,\r\n staggerMs = HSK_STAGGER_MS,\r\n}: AnimatedPlaceholderProps) {\r\n if (!visible) return null;\r\n const content = text || placeholder || '';\r\n if (!content) return null;\r\n const seed = replaySeed !== undefined ? replaySeed : replay;\r\n\r\n const units = splitPlaceholder(content);\r\n const last = Math.max(units.length - 1, 1);\r\n\r\n return (\r\n <div className=\"hsk-animated-placeholder\" dir=\"auto\" aria-hidden=\"true\">\r\n {units.map((unit, i) => (\r\n <span\r\n key={`${content}|${seed}|${i}`}\r\n className=\"hsk-animated-placeholder__char\"\r\n style={{\r\n animationDelay: `${HSK_FIELD_BASE_MS + i * staggerMs}ms`,\r\n '--hsk-ph-hue': `${Math.round((i / last) * 300)}`,\r\n } as React.CSSProperties}\r\n >\r\n {unit}\r\n </span>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\nimport type { ChatMessage, ChatSource, ChatAction } from '@akropolys/sdk';\r\nimport { cn } from '../../../utils/cn';\r\nimport { renderMarkdown } from '../../../utils/markdown';\r\nimport { LiveTable } from '../../LiveTable';\r\nimport { ThinkingBlock, parseThinking } from './ThinkingBlock';\r\nimport { SourcesCarousel } from './SourcesCarousel';\r\nimport { SmartContextPills } from './SmartContextPills';\r\nimport {\r\n MicIcon,\r\n ExternalIcon,\r\n RetryIcon,\r\n EditIcon,\r\n CopyIcon,\r\n CheckIcon,\r\n} from '../icons';\r\nimport type { UIStringKey } from '../types';\r\n\r\nconst MarkdownBlock = React.memo(\r\n ({ content, streaming }: { content: string; streaming: boolean }) => <>{renderMarkdown(content, streaming)}</>,\r\n (a, b) => a.content === b.content && a.streaming === b.streaming\r\n);\r\nMarkdownBlock.displayName = 'MarkdownBlock';\r\n\r\nexport interface MessageItemProps {\r\n msg: ChatMessage;\r\n idx: number;\r\n isLast: boolean;\r\n isLastUser: boolean;\r\n isRunEnd: boolean;\r\n runMid: boolean;\r\n runCont: boolean;\r\n isNarrow: boolean;\r\n loading: boolean;\r\n streaming: boolean;\r\n stopped: boolean;\r\n interrupted: boolean;\r\n sources: ChatSource[];\r\n referencedIds: string[];\r\n discussedSources: ChatSource[];\r\n lastIntent: string | null;\r\n lastAction: ChatAction | null;\r\n defaultCurrency: string;\r\n vizState: Record<string, 'ok' | 'err'>;\r\n setVizState: React.Dispatch<React.SetStateAction<Record<string, 'ok' | 'err'>>>;\r\n setLightboxSrc: (src: string | null) => void;\r\n setMarkupSrc: (src: string | null) => void;\r\n handleSend: (text?: string) => Promise<void>;\r\n handleSourceClick: (src: ChatSource) => void;\r\n onRetry?: (msg: ChatMessage) => void;\r\n onEdit?: (msg: ChatMessage) => void;\r\n onLongPress?: (msg: ChatMessage, rect: { top: number; left: number; width: number; height: number }, isUser: boolean) => void;\r\n hasError?: boolean;\r\n retrying?: boolean;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n messageRef: (el: HTMLDivElement | null) => void;\r\n}\r\n\r\nexport function MessageItem({\r\n msg,\r\n idx,\r\n isLast,\r\n isLastUser,\r\n isRunEnd,\r\n runMid,\r\n runCont,\r\n isNarrow,\r\n loading,\r\n streaming,\r\n stopped,\r\n interrupted,\r\n sources,\r\n referencedIds,\r\n discussedSources,\r\n lastIntent,\r\n lastAction,\r\n defaultCurrency,\r\n vizState,\r\n setVizState,\r\n setLightboxSrc,\r\n setMarkupSrc,\r\n handleSend,\r\n handleSourceClick,\r\n onRetry,\r\n onEdit,\r\n onLongPress,\r\n hasError,\r\n retrying,\r\n t,\r\n messageRef,\r\n}: MessageItemProps) {\r\n const isUser = msg.role === 'user';\r\n const displayContent = msg.content;\r\n const [copied, setCopied] = React.useState(false);\r\n\r\n const touchStartPos = React.useRef<{ x: number; y: number } | null>(null);\r\n const longPressTimer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const startLongPress = React.useCallback((targetEl: HTMLElement) => {\r\n if (longPressTimer.current) clearTimeout(longPressTimer.current);\r\n longPressTimer.current = setTimeout(() => {\r\n if (onLongPress) {\r\n if (typeof navigator !== 'undefined' && navigator.vibrate) {\r\n try { navigator.vibrate(25); } catch {}\r\n }\r\n const r = targetEl.getBoundingClientRect();\r\n onLongPress(msg, { top: r.top, left: r.left, width: r.width, height: r.height }, isUser);\r\n }\r\n longPressTimer.current = null;\r\n }, 420);\r\n }, [msg, isUser, onLongPress]);\r\n\r\n const handleTouchStart = React.useCallback((e: React.TouchEvent<HTMLElement>) => {\r\n if (e.touches.length !== 1) return;\r\n const touch = e.touches[0];\r\n touchStartPos.current = { x: touch.clientX, y: touch.clientY };\r\n startLongPress(e.currentTarget);\r\n }, [startLongPress]);\r\n\r\n const handleTouchMove = React.useCallback((e: React.TouchEvent<HTMLElement>) => {\r\n if (!touchStartPos.current || !longPressTimer.current) return;\r\n const touch = e.touches[0];\r\n const dist = Math.hypot(touch.clientX - touchStartPos.current.x, touch.clientY - touchStartPos.current.y);\r\n if (dist > 8) {\r\n clearTimeout(longPressTimer.current);\r\n longPressTimer.current = null;\r\n }\r\n }, []);\r\n\r\n const handleTouchEnd = React.useCallback(() => {\r\n if (longPressTimer.current) {\r\n clearTimeout(longPressTimer.current);\r\n longPressTimer.current = null;\r\n }\r\n touchStartPos.current = null;\r\n }, []);\r\n\r\n const handleContextMenu = React.useCallback((e: React.MouseEvent<HTMLElement>) => {\r\n if (!onLongPress) return;\r\n e.preventDefault();\r\n const r = e.currentTarget.getBoundingClientRect();\r\n onLongPress(msg, { top: r.top, left: r.left, width: r.width, height: r.height }, isUser);\r\n }, [msg, isUser, onLongPress]);\r\n\r\n React.useEffect(() => {\r\n return () => {\r\n if (longPressTimer.current) clearTimeout(longPressTimer.current);\r\n };\r\n }, []);\r\n\r\n const handleCopy = React.useCallback((text: string) => {\r\n if (!text) return;\r\n try {\r\n navigator.clipboard.writeText(text);\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 2000);\r\n } catch {}\r\n }, []);\r\n\r\n const parsed = React.useMemo(() => parseThinking(displayContent), [displayContent]);\r\n const thinking = msg.thinking || parsed.thinking;\r\n const CALC_DISCLAIMER_REGEX = /(?:^|\\n+)(?:[>*_~`\\s]*)(?:This is a calculation from live figures,?\\s*not a guarantee\\s*[—–-]\\s*the market can move against it\\.?)(?:[>*_~`\\s]*)/gi;\r\n const hasCalcDisclaimer = CALC_DISCLAIMER_REGEX.test(parsed.content);\r\n const cleanContent = hasCalcDisclaimer ? parsed.content.replace(CALC_DISCLAIMER_REGEX, '').trimEnd() : parsed.content;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'hsk-cb-msg-group',\r\n runMid && 'hsk-cb-msg-group--run-mid',\r\n runCont && 'hsk-cb-msg-group--run-cont',\r\n )}\r\n ref={messageRef}\r\n >\r\n {isUser ? (\r\n <div className={`hsk-cb-user-msg${isLastUser ? ' hsk-sent' : ''}`}>\r\n {msg.images && msg.images.length > 0 && (\r\n <div className=\"hsk-cb-user-imgs\" data-count={Math.min(msg.images.length, 4)}>\r\n {msg.images.slice(0, 4).map((img, i) => (\r\n <button\r\n key={i}\r\n type=\"button\"\r\n className=\"hsk-cb-user-img-cell\"\r\n onClick={() => setLightboxSrc(img)}\r\n >\r\n <img src={img} alt={`attachment ${i + 1}`} className=\"hsk-cb-user-img-thumb\" />\r\n {i === 3 && msg.images!.length > 4 && (\r\n <span className=\"hsk-cb-user-img-more\">+{msg.images!.length - 3}</span>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n {msg.content && (\r\n <div\r\n className={cn(\r\n 'hsk-cb-user-bubble',\r\n isRunEnd && 'hsk-cb-user-bubble--tail',\r\n msg.spoken && 'hsk-cb-user-bubble--spoken',\r\n hasError && 'hsk-cb-user-bubble--error',\r\n )}\r\n onTouchStart={handleTouchStart}\r\n onTouchMove={handleTouchMove}\r\n onTouchEnd={handleTouchEnd}\r\n onTouchCancel={handleTouchEnd}\r\n onContextMenu={handleContextMenu}\r\n >\r\n {msg.spoken && <MicIcon className=\"hsk-cb-spoken-mark\" size={10} />}\r\n {/^@kiku\\b/i.test(msg.content) ? (\r\n <>\r\n <span className=\"hsk-kiku-badge\">@kiku</span>\r\n {msg.content.replace(/^@kiku\\s*/i, '')}\r\n </>\r\n ) : msg.content}\r\n </div>\r\n )}\r\n <div className=\"hsk-cb-user-footer\">\r\n <div className={cn('hsk-cb-msg-actions', hasError && 'hsk-cb-msg-actions--failed')}>\r\n {onRetry && (hasError || isLastUser) && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-msg-action hsk-cb-msg-action--retry\"\r\n onClick={() => onRetry(msg)}\r\n aria-label={t('retry')}\r\n >\r\n <RetryIcon className={retrying ? 'hsk-retry-icon--spinning' : ''} size={11} />\r\n <span className=\"hsk-cb-msg-action-label\">{t('retry')}</span>\r\n </button>\r\n )}\r\n {onEdit && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-msg-action hsk-cb-msg-action--edit\"\r\n onClick={() => onEdit(msg)}\r\n aria-label={t('edit')}\r\n >\r\n <EditIcon size={11} />\r\n <span className=\"hsk-cb-msg-action-label\">{t('edit')}</span>\r\n </button>\r\n )}\r\n <button\r\n type=\"button\"\r\n className={cn('hsk-cb-msg-action hsk-cb-msg-action--copy', copied && 'hsk-cb-msg-action--copied')}\r\n onClick={() => handleCopy(msg.content)}\r\n aria-label={copied ? t('copied') : t('copy')}\r\n >\r\n {copied ? <CheckIcon size={11} /> : <CopyIcon size={11} />}\r\n <span className=\"hsk-cb-msg-action-label\">{copied ? t('copied') : t('copy')}</span>\r\n </button>\r\n </div>\r\n {isLastUser && !hasError && (\r\n <span className=\"hsk-cb-sent-status\">\r\n {stopped || interrupted ? t('statusStopped') : t('statusSent')}\r\n </span>\r\n )}\r\n {hasError && (\r\n <span className=\"hsk-cb-failed-notice\">\r\n <span className=\"hsk-cb-failed-dot\" />\r\n {t('msgFailed')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n ) : (\r\n <div className={cn('hsk-cb-ai-msg', isNarrow && 'hsk-cb-ai-msg--inline')}>\r\n <div\r\n className=\"hsk-cb-ai-body\"\r\n onTouchStart={handleTouchStart}\r\n onTouchMove={handleTouchMove}\r\n onTouchEnd={handleTouchEnd}\r\n onTouchCancel={handleTouchEnd}\r\n onContextMenu={handleContextMenu}\r\n >\r\n {(() => {\r\n const isComplete = msg.thoughtForSeconds != null || cleanContent.length > 0 || !(isLast && (streaming || loading));\r\n return (\r\n <>\r\n {!msg.spoken && (thinking || msg.thoughtForSeconds != null || (isLast && (streaming || loading))) && (\r\n <ThinkingBlock text={thinking} isComplete={isComplete} seconds={msg.thoughtForSeconds} />\r\n )}\r\n {cleanContent && (\r\n <div className=\"hsk-cb-ai-content\">\r\n <MarkdownBlock content={cleanContent} streaming={isLast && streaming} />\r\n </div>\r\n )}\r\n {hasCalcDisclaimer && (\r\n <div className=\"hsk-cb-calc-disclaimer\">\r\n {t('calcDisclaimer')}\r\n </div>\r\n )}\r\n </>\r\n );\r\n })()}\r\n\r\n {msg.visualizing && (\r\n <div className=\"hsk-cb-viz hsk-cb-viz--loading\">\r\n <span className=\"hsk-cb-viz-spinner\" />\r\n <span>{msg.visualizingText || t('vizWorking')}</span>\r\n </div>\r\n )}\r\n {msg.visualization && (\r\n <div className=\"hsk-cb-viz\">\r\n <div className=\"hsk-cb-viz-imgwrap\">\r\n {msg.visualizationType === 'video' || msg.visualization.includes('/videos/') ? (\r\n <video\r\n src={msg.visualization}\r\n controls\r\n autoPlay\r\n loop\r\n muted\r\n playsInline\r\n className=\"hsk-markdown-video\"\r\n style={{ display: 'block', maxHeight: '400px', objectFit: 'contain', width: '100%' }}\r\n />\r\n ) : (\r\n <img\r\n src={msg.visualization}\r\n alt=\"Product visualized in your photo\"\r\n className=\"hsk-markdown-img\"\r\n style={vizState[msg.visualization] === 'err' ? { display: 'none' } : undefined}\r\n onLoad={() => setVizState(p => ({ ...p, [msg.visualization!]: 'ok' }))}\r\n onError={() => setVizState(p => ({ ...p, [msg.visualization!]: 'err' }))}\r\n />\r\n )}\r\n {vizState[msg.visualization] === 'err' && (\r\n <div className=\"hsk-cb-viz-broken\">{t('vizUnavailable')}</div>\r\n )}\r\n {isLast && !streaming && vizState[msg.visualization] === 'ok' && (msg.visualizationType !== 'video' && !msg.visualization.includes('/videos/')) && (\r\n <button className=\"hsk-cb-viz-mark\" onClick={() => setMarkupSrc(msg.visualization!)}>\r\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\r\n <path d=\"M12 20h9\" /><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z\" />\r\n </svg>\r\n {t('vizMarkEdit')}\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"hsk-cb-viz-disclaimer\">\r\n {msg.visualizationType === 'video' || msg.visualization.includes('/videos/')\r\n ? t('vizDisclaimerVideo')\r\n : t('vizDisclaimerImage')}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {!isUser && (msg.knowledgeImages?.length ?? 0) > 0 && (\r\n <div className=\"hsk-cb-kimgs\">\r\n {msg.knowledgeImages!.map((ref) => (\r\n <div key={ref.entryId} className=\"hsk-cb-kimg-group\">\r\n <div className=\"hsk-cb-kimg-grid\">\r\n {ref.images.map((img, i) => (\r\n <img\r\n key={i}\r\n src={img.url}\r\n alt={img.note || ref.title || 'Reference image'}\r\n className=\"hsk-cb-kimg\"\r\n loading=\"lazy\"\r\n onClick={() => setLightboxSrc(img.url)}\r\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\r\n />\r\n ))}\r\n </div>\r\n {(ref.title || ref.images[0]?.note) && (\r\n <div className=\"hsk-cb-kimg-caption\">{ref.title || ref.images[0]?.note}</div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {!isUser && <LiveTable keys={msg.liveKeys} />}\r\n\r\n {!isUser && (msg.staleNotices?.length ?? 0) > 0 && (\r\n <div className=\"hsk-cb-stale\" role=\"status\">\r\n <div className=\"hsk-cb-stale-title\">{t('staleTitle')}</div>\r\n {msg.staleNotices!.map((n, i) => (\r\n <div key={i} className=\"hsk-cb-stale-item\">\r\n {n.state === 'removed'\r\n ? t('staleRemoved', { title: n.title })\r\n : t('staleUnavailable', { title: n.title })}\r\n {n.reason && <span className=\"hsk-cb-stale-reason\"> {n.reason}</span>}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {(() => {\r\n const msgReferencedIds = isLast ? referencedIds : (msg.referencedIds ?? []);\r\n const msgSources = isLast ? sources : (msg.sources ?? []);\r\n const msgIntent = isLast ? lastIntent : msg.intent;\r\n const hiddenIntent = msgIntent === 'compare' || msgIntent === 'capture' ||\r\n msgIntent === 'capture_all' || msgIntent === 'delete' || msgIntent === 'view_history';\r\n const showCarousel = msgReferencedIds.length > 0 && !hiddenIntent &&\r\n (!isLast || lastAction?.type !== 'request_kiku_key');\r\n return showCarousel && (\r\n <SourcesCarousel\r\n sources={msgSources}\r\n defaultCurrency={defaultCurrency}\r\n onSelectSource={handleSourceClick}\r\n onImageClick={setLightboxSrc}\r\n referencedIds={msgReferencedIds}\r\n compact={!!msg.visualization}\r\n />\r\n );\r\n })()}\r\n\r\n {isLast && !loading && !streaming && lastAction?.type === 'open_memory' && lastAction.url && (\r\n <a\r\n className=\"hsk-cb-memory-pill\"\r\n href={String(lastAction.url)}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n >\r\n {t('openMemory')}\r\n <ExternalIcon />\r\n </a>\r\n )}\r\n\r\n {isLast && !loading && lastAction?.url && lastAction.type !== 'open_memory' && (\r\n <div className=\"hsk-action-pills\">\r\n <a className=\"hsk-action-pill\" href={lastAction.url}>\r\n {String(lastAction.type || 'continue').replace(/_/g, ' ')} →\r\n </a>\r\n </div>\r\n )}\r\n\r\n {isLast && !loading && (\r\n <SmartContextPills\r\n intent={lastIntent}\r\n sources={discussedSources}\r\n onSend={handleSend}\r\n loading={loading}\r\n defaultCurrency={defaultCurrency}\r\n />\r\n )}\r\n\r\n {!isUser && !streaming && cleanContent && (\r\n <div className=\"hsk-cb-ai-footer\">\r\n <div className={cn('hsk-cb-msg-actions', (hasError || cleanContent.includes(\"We're experiencing high demand right now\")) && 'hsk-cb-msg-actions--failed')}>\r\n <button\r\n type=\"button\"\r\n className={cn('hsk-cb-msg-action hsk-cb-msg-action--copy', copied && 'hsk-cb-msg-action--copied')}\r\n onClick={() => handleCopy(cleanContent)}\r\n aria-label={copied ? t('copied') : t('copy')}\r\n >\r\n {copied ? <CheckIcon size={11} /> : <CopyIcon size={11} />}\r\n <span className=\"hsk-cb-msg-action-label\">{copied ? t('copied') : t('copy')}</span>\r\n </button>\r\n {isLast && (hasError || cleanContent.includes(\"We're experiencing high demand right now\")) && onRetry && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-msg-action hsk-cb-msg-action--retry\"\r\n onClick={() => onRetry(msg)}\r\n aria-label={t('retry')}\r\n >\r\n <RetryIcon className={retrying ? 'hsk-retry-icon--spinning' : ''} size={11} />\r\n <span className=\"hsk-cb-msg-action-label\">{t('retry')}</span>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import React, { useEffect, useState } from 'react';\r\nimport {\r\n describeAge,\r\n getLiveValue,\r\n isFresh,\r\n isStale,\r\n labelFor,\r\n formatLiveValue,\r\n subscribeLiveValues,\r\n LIVE_FLASH_MS,\r\n type LiveValue,\r\n} from '@akropolys/sdk';\r\n\r\nfunction useLiveValues(keys: string[]): (LiveValue | undefined)[] {\r\n const [, bump] = useState(0);\r\n const joined = JSON.stringify(keys);\r\n\r\n useEffect(() => subscribeLiveValues(k => {\r\n if (keys.includes(k)) bump(n => n + 1);\r\n }), [joined]);\r\n\r\n useEffect(() => {\r\n const id = setInterval(() => bump(n => n + 1), 1000);\r\n return () => clearInterval(id);\r\n }, []);\r\n\r\n return keys.map(getLiveValue);\r\n}\r\n\r\nfunction LiveQuoteCard({ record, now }: { record: LiveValue; now: number }) {\r\n const stale = isStale(record, now);\r\n\r\n const fields = record.fields;\r\n const rawTitle = fields.event || fields.question || fields.title || record.key;\r\n const shortTitle = rawTitle.length > 38 ? rawTitle.slice(0, 36) + '…' : rawTitle;\r\n\r\n const hasYesPrice = !!fields.yes_price || !!fields.yesPrice;\r\n const hasNoPrice = !!fields.no_price || !!fields.noPrice;\r\n\r\n const quotePills: { label: string; value: string; rawKey: string }[] = [];\r\n\r\n if (hasYesPrice) {\r\n quotePills.push({ label: 'Yes', value: formatLiveValue('yes_price', fields.yes_price || fields.yesPrice), rawKey: 'yes_price' });\r\n } else if (fields.yes_pct || fields.yesPct) {\r\n quotePills.push({ label: 'Yes', value: formatLiveValue('yes_pct', fields.yes_pct || fields.yesPct), rawKey: 'yes_pct' });\r\n }\r\n\r\n if (hasNoPrice) {\r\n quotePills.push({ label: 'No', value: formatLiveValue('no_price', fields.no_price || fields.noPrice), rawKey: 'no_price' });\r\n } else if (fields.no_pct || fields.noPct) {\r\n quotePills.push({ label: 'No', value: formatLiveValue('no_pct', fields.no_pct || fields.noPct), rawKey: 'no_pct' });\r\n }\r\n\r\n if (fields.bid) quotePills.push({ label: 'Bid', value: formatLiveValue('bid', fields.bid), rawKey: 'bid' });\r\n if (fields.ask) quotePills.push({ label: 'Ask', value: formatLiveValue('ask', fields.ask), rawKey: 'ask' });\r\n if (fields.spread) quotePills.push({ label: 'Spread', value: formatLiveValue('spread', fields.spread), rawKey: 'spread' });\r\n if (!hasYesPrice && !hasNoPrice && !fields.bid && fields.price) {\r\n quotePills.push({ label: 'Price', value: formatLiveValue('price', fields.price), rawKey: 'price' });\r\n }\r\n\r\n if (fields.home_spread || fields.spread_line) quotePills.push({ label: 'Spread', value: formatLiveValue('spread', fields.home_spread || fields.spread_line), rawKey: 'spread' });\r\n if (fields.moneyline || fields.ml) quotePills.push({ label: 'ML', value: formatLiveValue('ml', fields.moneyline || fields.ml), rawKey: 'moneyline' });\r\n if (fields.over_under || fields.total) quotePills.push({ label: 'O/U', value: formatLiveValue('total', fields.over_under || fields.total), rawKey: 'over_under' });\r\n\r\n if (fields['1_home'] || fields.home_odd || fields['1']) {\r\n quotePills.push({ label: '1', value: formatLiveValue('odds', fields['1_home'] || fields.home_odd || fields['1']), rawKey: '1_home' });\r\n }\r\n if (fields['X_draw'] || fields.neutral_odd || fields.draw_odd || fields['X']) {\r\n quotePills.push({ label: 'X', value: formatLiveValue('odds', fields['X_draw'] || fields.neutral_odd || fields.draw_odd || fields['X']), rawKey: 'X_draw' });\r\n }\r\n if (fields['2_away'] || fields.away_odd || fields['2']) {\r\n quotePills.push({ label: '2', value: formatLiveValue('odds', fields['2_away'] || fields.away_odd || fields['2']), rawKey: '2_away' });\r\n }\r\n\r\n const volVal = fields.volume || fields.vol || fields['24h_volume'] || fields.turnover;\r\n if (volVal) {\r\n quotePills.push({ label: 'Vol', value: formatLiveValue('volume', volVal), rawKey: 'volume' });\r\n }\r\n\r\n const closeDate = fields.close_date || fields.expiry || fields.expires_at || fields.settle_date;\r\n const formattedClose = closeDate ? formatLiveValue('close_date', closeDate) : null;\r\n\r\n return (\r\n <div className={`hsk-live-card${stale ? ' is-stale' : ''}`} role=\"region\" aria-label=\"Live quote\">\r\n <div className=\"hsk-live-card__top\">\r\n <div className=\"hsk-live-card__badge\">\r\n <span className={`hsk-live-dot${stale ? ' is-stale' : ''}`} aria-hidden=\"true\" />\r\n <span className=\"hsk-live-card__age\">\r\n {stale ? `Paused · ${describeAge(now - record.at)}` : `Live · ${describeAge(now - record.at)}`}\r\n </span>\r\n </div>\r\n {formattedClose && <span className=\"hsk-live-card__close\">Closes {formattedClose}</span>}\r\n </div>\r\n\r\n <div className=\"hsk-live-card__body\">\r\n <span className=\"hsk-live-card__title\" title={rawTitle}>{shortTitle}</span>\r\n </div>\r\n\r\n <div className=\"hsk-live-card__pills\">\r\n {quotePills.map(p => {\r\n const flash = isFresh(record, p.rawKey, now);\r\n return (\r\n <div\r\n key={p.rawKey}\r\n className={`hsk-live-pill${flash ? ' is-changed' : ''}`}\r\n style={flash ? { animationDuration: `${LIVE_FLASH_MS}ms` } : undefined}\r\n >\r\n <span className=\"hsk-live-pill__label\">{p.label}</span>\r\n <span className=\"hsk-live-pill__value\">{p.value}</span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport function LiveTable({ keys }: { keys?: string[] }) {\r\n const seen = new Set<string>();\r\n const ordered = (keys ?? []).filter(k => (seen.has(k) ? false : (seen.add(k), true)));\r\n\r\n const records = useLiveValues(ordered);\r\n const present = ordered.filter((_, i) => records[i]);\r\n if (present.length === 0) return null;\r\n\r\n const shown = records.filter((r): r is LiveValue => !!r);\r\n const now = Date.now();\r\n\r\n return (\r\n <div className=\"hsk-live-wrap\" role=\"group\" aria-label=\"Live market data\">\r\n <div className=\"hsk-live-carousel\">\r\n {shown.map(r => (\r\n <LiveQuoteCard key={r.key} record={r} now={now} />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import React, { useState, useEffect, useRef } from 'react';\r\nimport { cn } from '../../../utils/cn';\r\nimport { useT } from '../types';\r\n\r\nexport function parseThinking(text: string): { thinking: string; content: string; isComplete: boolean } {\r\n const openMatch = text.match(/<\\s*thinking\\s*>/i);\r\n if (!openMatch) {\r\n return { thinking: '', content: text, isComplete: true };\r\n }\r\n\r\n const openIdx = openMatch.index ?? 0;\r\n const openTagLength = openMatch[0].length;\r\n const start = openIdx + openTagLength;\r\n\r\n const contentBefore = text.slice(0, openIdx);\r\n const textAfterOpen = text.slice(start);\r\n\r\n const closeMatch = textAfterOpen.match(/<\\/\\s*thinking\\s*>/i);\r\n if (!closeMatch) {\r\n return {\r\n thinking: textAfterOpen,\r\n content: contentBefore,\r\n isComplete: false\r\n };\r\n }\r\n\r\n const closeIdx = closeMatch.index ?? 0;\r\n const closeTagLength = closeMatch[0].length;\r\n\r\n return {\r\n thinking: textAfterOpen.slice(0, closeIdx),\r\n content: contentBefore + textAfterOpen.slice(closeIdx + closeTagLength),\r\n isComplete: true\r\n };\r\n}\r\n\r\nexport function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }: { text: string; isComplete: boolean; seconds?: number }) {\r\n const tr = useT();\r\n const startRef = useRef(Date.now());\r\n const [seconds, setSeconds] = useState<number | null>(() => (isComplete ? null : 0));\r\n const [isOpen, setIsOpen] = useState(!isComplete);\r\n\r\n useEffect(() => {\r\n if (isComplete) {\r\n if (seconds !== null) {\r\n setSeconds(Math.max(1, Math.round((Date.now() - startRef.current) / 1000)));\r\n setIsOpen(false);\r\n }\r\n return;\r\n }\r\n setIsOpen(true);\r\n const t = setInterval(() => {\r\n setSeconds(Math.round((Date.now() - startRef.current) / 1000));\r\n }, 1000);\r\n return () => clearInterval(t);\r\n }, [isComplete]);\r\n\r\n const finalSeconds = fixedSeconds ?? seconds;\r\n const label = isComplete\r\n ? (finalSeconds !== null && finalSeconds !== undefined\r\n ? tr('thoughtForSeconds', { duration: `${finalSeconds}s` })\r\n : tr('thoughtProcess'))\r\n : `${tr('thinking')}${seconds ? ` · ${seconds}s` : '…'}`;\r\n const expandable = !!text;\r\n\r\n return (\r\n <div className={cn('hsk-cb-think', !isComplete && 'hsk-cb-think--live')}>\r\n <button\r\n type=\"button\"\r\n className={cn('hsk-cb-think-head', !expandable && 'hsk-cb-think-head--static')}\r\n onClick={expandable ? () => setIsOpen(o => !o) : undefined}\r\n aria-expanded={expandable ? isOpen : undefined}\r\n >\r\n <span>{label}</span>\r\n {expandable && <span className={cn('hsk-cb-think-chevron', isOpen && 'hsk-cb-think-chevron--open')}>▶</span>}\r\n </button>\r\n {expandable && isOpen && <div className=\"hsk-cb-think-body\">{text}</div>}\r\n </div>\r\n );\r\n}\r\n","import React, { useState, useRef, useEffect, useCallback } from 'react';\r\nimport type { ChatSource } from '@akropolys/sdk';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport { cn } from '../../../utils/cn';\r\nimport { SparkleIcon, ChevronLeftIcon, ChevronRightIcon } from '../icons';\r\n\r\nexport interface SourcesCarouselProps {\r\n sources: ChatSource[];\r\n defaultCurrency: string;\r\n onSelectSource?: (src: ChatSource) => void;\r\n onImageClick?: (src: string) => void;\r\n referencedIds?: string[];\r\n compact?: boolean;\r\n}\r\n\r\nexport function SourceImg({ src, alt, onImageClick }: { src: string; alt?: string; onImageClick?: (src: string) => void }) {\r\n const [failed, setFailed] = useState(false);\r\n if (failed) {\r\n return (\r\n <div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--hsk-chat-source-bg, rgba(0,0,0,.04))', color: 'var(--hsk-chat-muted, #888)' }}>\r\n <SparkleIcon />\r\n </div>\r\n );\r\n }\r\n return (\r\n <img\r\n src={src}\r\n alt={alt ?? ''}\r\n onError={() => setFailed(true)}\r\n onClick={onImageClick ? (e) => { e.stopPropagation(); onImageClick(src); } : undefined}\r\n />\r\n );\r\n}\r\n\r\nexport function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClick, referencedIds = [], compact = false }: SourcesCarouselProps) {\r\n const client = useAkropolysContext();\r\n const isProperty = client?.vertical === 'property';\r\n const railRef = useRef<HTMLDivElement>(null);\r\n const [showPrev, setShowPrev] = useState(false);\r\n const [showNext, setShowNext] = useState(false);\r\n const [activeIndex, setActiveIndex] = useState(0);\r\n\r\n const display = sources.filter(s => s.id && referencedIds.includes(s.id));\r\n\r\n const measure = useCallback(() => {\r\n const el = railRef.current;\r\n if (!el || display.length === 0) return;\r\n const travelled = Math.abs(el.scrollLeft);\r\n const maxScroll = el.scrollWidth - el.clientWidth;\r\n setShowPrev(travelled > 10);\r\n setShowNext(maxScroll > 4 && travelled < maxScroll - 12);\r\n\r\n const cardWidth = 190;\r\n const idx = Math.round(travelled / cardWidth);\r\n setActiveIndex(Math.min(Math.max(0, idx), display.length - 1));\r\n }, [display.length]);\r\n\r\n useEffect(() => {\r\n measure();\r\n const el = railRef.current;\r\n if (!el) return;\r\n const ro = new ResizeObserver(measure);\r\n ro.observe(el);\r\n el.addEventListener('scroll', measure, { passive: true });\r\n return () => { ro.disconnect(); el.removeEventListener('scroll', measure); };\r\n }, [measure, sources]);\r\n\r\n const railStep = (dir: 1 | -1) => {\r\n const el = railRef.current;\r\n if (!el) return;\r\n const rtl = getComputedStyle(el).direction === 'rtl';\r\n el.scrollBy({ left: 190 * dir * (rtl ? -1 : 1), behavior: 'smooth' });\r\n };\r\n\r\n const scrollNext = () => railStep(1);\r\n const scrollPrev = () => railStep(-1);\r\n\r\n if (display.length === 0) return null;\r\n\r\n return (\r\n <div className={cn(\"hsk-cb-sources-wrap\", compact && \"hsk-cb-sources-wrap--compact\")}>\r\n {showPrev && (\r\n <>\r\n <div className=\"hsk-cb-sources-fade-left\" />\r\n <button className=\"hsk-cb-sources-prev\" onClick={scrollPrev} aria-label=\"Previous\">\r\n <ChevronLeftIcon />\r\n </button>\r\n </>\r\n )}\r\n\r\n <div className=\"hsk-cb-sources\" ref={railRef}>\r\n {display.map((src, si) => {\r\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\r\n return (\r\n <div\r\n key={src.id ?? si}\r\n className={cn(\"hsk-cb-source\", isReferenced && \"hsk-cb-source--referenced\")}\r\n style={{ animationDelay: `${si * 50}ms` }}\r\n onClick={() => onSelectSource?.(src)}\r\n >\r\n {src.image ? (\r\n <div className=\"hsk-cb-src-imgwrap\" style={{ position: 'relative' }}>\r\n <SourceImg src={src.image} alt={src.name} onImageClick={onImageClick} />\r\n {isProperty && (\r\n <div style={{\r\n position: 'absolute',\r\n top: '6px',\r\n right: '6px',\r\n background: 'rgba(14, 14, 15, 0.75)',\r\n backdropFilter: 'blur(4px)',\r\n borderRadius: '50%',\r\n width: '24px',\r\n height: '24px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: '#fbbf24',\r\n boxShadow: '0 2px 4px rgba(0,0,0,0.2)'\r\n }}>\r\n <SparkleIcon size={12} />\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"hsk-cb-src-imgwrap-empty\" style={{ position: 'relative' }}>\r\n <SparkleIcon />\r\n </div>\r\n )}\r\n <div className=\"hsk-cb-src-info\">\r\n <div className=\"hsk-cb-src-name\">{src.name}</div>\r\n {src.price && (\r\n <div className=\"hsk-cb-src-price\">\r\n {(src.currency || defaultCurrency) ? `${src.currency || defaultCurrency} ` : '$'}\r\n {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n\r\n {showNext && (\r\n <>\r\n <div className=\"hsk-cb-sources-fade-right\" />\r\n <button className=\"hsk-cb-sources-next\" onClick={scrollNext} aria-label=\"See more\">\r\n <ChevronRightIcon />\r\n </button>\r\n </>\r\n )}\r\n\r\n {display.length > 1 && (\r\n <div className=\"hsk-cb-carousel-dots\">\r\n {display.map((_, i) => (\r\n <div\r\n key={i}\r\n className={cn(\"hsk-cb-dot-item\", i === activeIndex && \"hsk-cb-dot-item--active\")}\r\n onClick={() => {\r\n const el = railRef.current;\r\n if (el) {\r\n const rtl = getComputedStyle(el).direction === 'rtl';\r\n el.scrollTo({ left: i * 190 * (rtl ? -1 : 1), behavior: 'smooth' });\r\n }\r\n }}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\nimport type { ChatSource } from '@akropolys/sdk';\r\nimport { useT } from '../types';\r\n\r\nexport interface SmartContextPillsProps {\r\n intent: string | null;\r\n sources: ChatSource[];\r\n onSend: (text: string) => void;\r\n loading: boolean;\r\n defaultCurrency?: string;\r\n}\r\n\r\nexport function SmartContextPills({\r\n intent,\r\n sources,\r\n onSend,\r\n loading,\r\n defaultCurrency = '',\r\n}: SmartContextPillsProps) {\r\n const tr = useT();\r\n if (!intent) return null;\r\n\r\n const pills: { label: string; query: string; emoji: string }[] = [];\r\n\r\n const cheapest =\r\n sources.length > 0\r\n ? sources.reduce((min, s) => {\r\n const p = parseFloat(String(s.price ?? '').replace(/[^0-9.]/g, ''));\r\n const m = parseFloat(String(min.price ?? '').replace(/[^0-9.]/g, ''));\r\n return !isNaN(p) && (isNaN(m) || p < m) ? s : min;\r\n }, sources[0])\r\n : null;\r\n\r\n const firstName = sources[0]?.name ?? '';\r\n const firstTwo = sources.slice(0, 2).map(s => s.name);\r\n\r\n const priceCeiling = (): string | null => {\r\n const nums = sources\r\n .map(s => parseFloat(String(s.price ?? '').replace(/[^0-9.]/g, '')))\r\n .filter(n => !isNaN(n) && n > 0);\r\n if (nums.length === 0) return null;\r\n const max = Math.max(...nums);\r\n const mag = Math.pow(10, Math.floor(Math.log10(max)));\r\n const rounded = Math.ceil(max / mag) * mag;\r\n const raw = String(sources.find(s => s.price)?.price ?? '');\r\n const symbol = raw.replace(/[0-9.,\\s]/g, '') || defaultCurrency;\r\n return `${symbol} ${rounded.toLocaleString()}`.trim();\r\n };\r\n\r\n if (intent === 'search' && sources.length > 0) {\r\n if (firstTwo.length >= 2) {\r\n pills.push({\r\n emoji: '⚖️',\r\n label: tr('pillCompareTop2'),\r\n query: tr('pillCompareTop2Query', { a: firstTwo[0], b: firstTwo[1] }),\r\n });\r\n }\r\n if (cheapest?.name) {\r\n const short = cheapest.name.split(' ').slice(0, 3).join(' ');\r\n pills.push({\r\n emoji: '💡',\r\n label: tr('pillMoreOn', { name: short }),\r\n query: tr('pillMoreOnQuery', { name: cheapest.name }),\r\n });\r\n }\r\n const ceiling = priceCeiling();\r\n if (ceiling) {\r\n pills.push({\r\n emoji: '💰',\r\n label: tr('pillUnder', { amount: ceiling }),\r\n query: tr('pillUnderQuery', { amount: ceiling }),\r\n });\r\n }\r\n } else if (intent === 'compare' && sources.length > 0) {\r\n if (firstName) {\r\n pills.push({\r\n emoji: '🔍',\r\n label: tr('pillSimilarOptions'),\r\n query: tr('pillSimilarOptionsQuery', { name: firstName }),\r\n });\r\n }\r\n pills.push({ emoji: '💡', label: tr('pillWhichBest'), query: tr('pillWhichBestQuery') });\r\n } else if (intent === 'specs' && sources.length > 0) {\r\n if (firstName) {\r\n pills.push({\r\n emoji: '🔄',\r\n label: tr('pillFindAlternatives'),\r\n query: tr('pillFindAlternativesQuery', { name: firstName }),\r\n });\r\n }\r\n } else if (intent === 'general') {\r\n pills.push({ emoji: '🔍', label: tr('pillShowPopular'), query: tr('pillShowPopularQuery') });\r\n pills.push({ emoji: '💡', label: tr('pillRecommend'), query: tr('pillRecommendQuery') });\r\n }\r\n\r\n if (pills.length === 0) return null;\r\n\r\n return (\r\n <div className=\"hsk-action-pills\">\r\n {pills.map(pill => (\r\n <button\r\n key={pill.query}\r\n className=\"hsk-action-pill\"\r\n onClick={() => onSend(pill.query)}\r\n disabled={loading}\r\n >\r\n <span className=\"hsk-pill-emoji\">{pill.emoji}</span>\r\n {pill.label}\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\nimport { SparkleIcon } from '../icons';\r\nimport type { UIStringKey } from '../types';\r\n\r\nexport interface PromptKeyCardProps {\r\n keyInput: string;\r\n setKeyInput: (val: string) => void;\r\n minting: boolean;\r\n handleUseExistingKey: () => void;\r\n handleCreateKey: () => void;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n}\r\n\r\nexport function PromptKeyCard({\r\n keyInput,\r\n setKeyInput,\r\n minting,\r\n handleUseExistingKey,\r\n handleCreateKey,\r\n t,\r\n}: PromptKeyCardProps) {\r\n return (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n <div className=\"hsk-cb-ai-text\">\r\n <div className=\"hsk-cb-phone-form\">\r\n <label className=\"hsk-cb-phone-label\">{t('keyPastePrompt')}</label>\r\n <input\r\n type=\"text\"\r\n className=\"hsk-cb-phone-input\"\r\n placeholder={t('keyPastePlaceholder')}\r\n value={keyInput}\r\n onChange={e => setKeyInput(e.target.value)}\r\n onKeyDown={e => e.key === 'Enter' && handleUseExistingKey()}\r\n autoFocus\r\n />\r\n <div style={{ display: 'flex', gap: 8 }}>\r\n <button className=\"hsk-cb-phone-submit\" onClick={handleUseExistingKey} disabled={!keyInput.trim()}>\r\n {t('keyUseMine')}\r\n </button>\r\n <button className=\"hsk-cb-phone-submit\" onClick={handleCreateKey} disabled={minting}>\r\n {minting ? t('keyCreating') : t('keyCreateNew')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport interface MintedKeyCardProps {\r\n mintedKey: string;\r\n mintedPub: string | null;\r\n copied: string | null;\r\n keyCountdown: number;\r\n onDismiss: () => void;\r\n copyValue: (val: string, type: 'secret' | 'pub') => void;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n}\r\n\r\nexport function MintedKeyCard({\r\n mintedKey,\r\n mintedPub,\r\n copied,\r\n keyCountdown,\r\n onDismiss,\r\n copyValue,\r\n t,\r\n}: MintedKeyCardProps) {\r\n return (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n <div className=\"hsk-cb-ai-text\">\r\n <div style={{ padding: '4px 0', display: 'flex', flexDirection: 'column', gap: 12 }}>\r\n <div>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }}>\r\n <span style={{ fontSize: 12, fontWeight: 600 }}>{t('keySecretTitle')}</span>\r\n <button\r\n className=\"hsk-cb-phone-submit\"\r\n style={{ padding: '2px 8px', fontSize: 11, background: 'transparent', border: 0 }}\r\n onClick={onDismiss}\r\n >\r\n {t('keyDismiss')} ✕\r\n </button>\r\n </div>\r\n <code style={{ display: 'block', fontSize: 13, fontWeight: 700, marginBottom: 8, wordBreak: 'break-all' }}>{mintedKey}</code>\r\n <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>\r\n <button className=\"hsk-cb-phone-submit\" style={{ padding: '4px 10px', border: 0 }} onClick={() => copyValue(mintedKey, 'secret')}>\r\n {copied === 'secret' ? t('keyCopied') : t('keyCopySecret')}\r\n </button>\r\n <span style={{ fontSize: 11, opacity: 0.7, flex: '1 1 180px' }}>\r\n {t('keySecretHint')}\r\n </span>\r\n </div>\r\n </div>\r\n {mintedPub && (\r\n <div>\r\n <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 4 }}>{t('keyPublicTitle')}</div>\r\n <code style={{ display: 'block', fontSize: 12, fontWeight: 600, marginBottom: 6, wordBreak: 'break-all', opacity: 0.85 }}>{mintedPub}</code>\r\n <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>\r\n <button className=\"hsk-cb-phone-submit\" style={{ padding: '4px 10px', border: 0 }} onClick={() => copyValue(mintedPub, 'pub')}>\r\n {copied === 'pub' ? t('keyCopied') : t('keyCopyId')}\r\n </button>\r\n <span style={{ fontSize: 11, opacity: 0.7, flex: '1 1 180px' }}>\r\n {t('keyPublicHint')}\r\n </span>\r\n </div>\r\n </div>\r\n )}\r\n <div style={{ fontSize: 11, opacity: 0.6 }}>{t('keyAutoHide', { seconds: String(keyCountdown) })}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\nimport type { ChatMessage, ChatSource, ChatAction } from '@akropolys/sdk';\r\nimport { cn } from '../../utils/cn';\r\nimport { ContinueIcon } from './icons';\r\nimport { getFriendlyError, type UIStringKey } from './types';\r\nimport { MessageItem } from './components/MessageItem';\r\nimport { PromptKeyCard, MintedKeyCard } from './components/MemoryKeyCards';\r\n\r\nexport interface ChatMessagesProps {\r\n displayMessages: ChatMessage[];\r\n messageRefs: React.MutableRefObject<(HTMLDivElement | null)[]>;\r\n isNarrow: boolean;\r\n loading: boolean;\r\n streaming: boolean;\r\n sources: ChatSource[];\r\n referencedIds: string[];\r\n discussedSources: ChatSource[];\r\n lastIntent: string | null;\r\n lastAction: ChatAction | null;\r\n defaultCurrency: string;\r\n stopped: boolean;\r\n interrupted: boolean;\r\n halted: boolean;\r\n haltedEmpty: boolean;\r\n error: string | null;\r\n errorCode: string | null;\r\n keyPhase: string;\r\n keyInput: string;\r\n setKeyInput: (val: string) => void;\r\n mintedKey: string | null;\r\n setMintedKey: (val: string | null) => void;\r\n mintedPub: string | null;\r\n setMintedPub: (val: string | null) => void;\r\n minting: boolean;\r\n copied: string | null;\r\n keyCountdown: number;\r\n handleUseExistingKey: () => void;\r\n handleCreateKey: () => void;\r\n copyValue: (val: string, type: 'secret' | 'pub') => void;\r\n queuedMessage: ChatMessage | null;\r\n sendQueuedNow: () => void;\r\n setLightboxSrc: (src: string | null) => void;\r\n setMarkupSrc: (src: string | null) => void;\r\n handleSend: (text?: string) => Promise<void>;\r\n handleSourceClick: (src: ChatSource) => void;\r\n onRetry?: (msg: ChatMessage) => void;\r\n onEdit?: (msg: ChatMessage) => void;\r\n onLongPress?: (msg: ChatMessage, rect: { top: number; left: number; width: number; height: number }, isUser: boolean) => void;\r\n retrying?: boolean;\r\n continueGenerating: () => void;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n bottomRef: React.RefObject<HTMLDivElement | null>;\r\n vizState: Record<string, 'ok' | 'err'>;\r\n setVizState: React.Dispatch<React.SetStateAction<Record<string, 'ok' | 'err'>>>;\r\n messages: ChatMessage[];\r\n}\r\n\r\nexport function ChatMessages({\r\n displayMessages,\r\n messageRefs,\r\n isNarrow,\r\n loading,\r\n streaming,\r\n sources,\r\n referencedIds,\r\n discussedSources,\r\n lastIntent,\r\n lastAction,\r\n defaultCurrency,\r\n stopped,\r\n interrupted,\r\n halted,\r\n haltedEmpty,\r\n error,\r\n errorCode,\r\n keyPhase,\r\n keyInput,\r\n setKeyInput,\r\n mintedKey,\r\n setMintedKey,\r\n mintedPub,\r\n setMintedPub,\r\n minting,\r\n copied,\r\n keyCountdown,\r\n handleUseExistingKey,\r\n handleCreateKey,\r\n copyValue,\r\n queuedMessage,\r\n sendQueuedNow,\r\n setLightboxSrc,\r\n setMarkupSrc,\r\n handleSend,\r\n handleSourceClick,\r\n onRetry,\r\n onEdit,\r\n onLongPress,\r\n retrying,\r\n continueGenerating,\r\n t,\r\n bottomRef,\r\n vizState,\r\n setVizState,\r\n messages,\r\n}: ChatMessagesProps) {\r\n return (\r\n <>\r\n {(() => {\r\n let lastUserIdx = -1;\r\n for (let i = displayMessages.length - 1; i >= 0; i--) {\r\n if (displayMessages[i]?.role === 'user') {\r\n lastUserIdx = i;\r\n break;\r\n }\r\n }\r\n return displayMessages.map((msg: ChatMessage, idx: number) => {\r\n const isLast = idx === displayMessages.length - 1;\r\n const isUser = msg.role === 'user';\r\n const isLastUser = isUser && idx === lastUserIdx;\r\n const isRunEnd = isUser && displayMessages[idx + 1]?.role !== 'user';\r\n const runMid = isUser && !isRunEnd;\r\n const runCont = isUser && displayMessages[idx - 1]?.role === 'user';\r\n const key = (msg as any).id || `${msg.role}-${idx}`;\r\n const hasError = (isLastUser && Boolean(error)) ||\r\n (!isUser && isLast && Boolean(error)) ||\r\n (!isUser && Boolean(msg.content?.includes(\"We're experiencing high demand right now\")));\r\n\r\n return (\r\n <MessageItem\r\n key={key}\r\n msg={msg}\r\n idx={idx}\r\n isLast={isLast}\r\n isLastUser={isLastUser}\r\n isRunEnd={isRunEnd}\r\n runMid={runMid}\r\n runCont={runCont}\r\n isNarrow={isNarrow}\r\n loading={loading}\r\n streaming={streaming}\r\n stopped={stopped}\r\n interrupted={interrupted}\r\n sources={sources}\r\n referencedIds={referencedIds}\r\n discussedSources={discussedSources}\r\n lastIntent={lastIntent}\r\n lastAction={lastAction}\r\n defaultCurrency={defaultCurrency}\r\n vizState={vizState}\r\n setVizState={setVizState}\r\n setLightboxSrc={setLightboxSrc}\r\n setMarkupSrc={setMarkupSrc}\r\n handleSend={handleSend}\r\n handleSourceClick={handleSourceClick}\r\n onRetry={onRetry}\r\n onEdit={onEdit}\r\n onLongPress={onLongPress}\r\n hasError={hasError}\r\n retrying={retrying}\r\n t={t}\r\n messageRef={(el) => { messageRefs.current[idx] = el; }}\r\n />\r\n );\r\n });\r\n })()}\r\n\r\n {halted && messages.length > 0 && (\r\n <div className={cn(\"hsk-cb-stopped\", haltedEmpty && \"hsk-cb-stopped--empty\")}>\r\n {haltedEmpty && (\r\n <span className=\"hsk-cb-stopped-dots\" aria-hidden=\"true\">\r\n <i /><i /><i />\r\n </span>\r\n )}\r\n <span className=\"hsk-cb-stopped-label\">\r\n {stopped ? t('stoppedByYou') : t('stoppedInterrupted')}\r\n </span>\r\n <button className=\"hsk-cb-continue\" onClick={continueGenerating}>\r\n <ContinueIcon />\r\n {t(messages[messages.length - 1]?.role === 'assistant' ? 'continueGenerating' : 'generateResponse')}\r\n </button>\r\n </div>\r\n )}\r\n\r\n {error && <div className=\"hsk-cb-error\">{getFriendlyError({ code: errorCode ?? undefined, message: error }, t)}</div>}\r\n\r\n {keyPhase === 'prompt_key' && (\r\n <PromptKeyCard\r\n keyInput={keyInput}\r\n setKeyInput={setKeyInput}\r\n minting={minting}\r\n handleUseExistingKey={handleUseExistingKey}\r\n handleCreateKey={handleCreateKey}\r\n t={t}\r\n />\r\n )}\r\n\r\n {mintedKey && (\r\n <MintedKeyCard\r\n mintedKey={mintedKey}\r\n mintedPub={mintedPub}\r\n copied={copied}\r\n keyCountdown={keyCountdown}\r\n onDismiss={() => { setMintedKey(null); setMintedPub(null); }}\r\n copyValue={copyValue}\r\n t={t}\r\n />\r\n )}\r\n\r\n {queuedMessage && (\r\n <div className={cn(\r\n 'hsk-cb-msg-group',\r\n displayMessages[displayMessages.length - 1]?.role === 'user' && 'hsk-cb-msg-group--run-cont',\r\n )}>\r\n <div className=\"hsk-cb-user-msg\">\r\n <div className=\"hsk-cb-user-bubble hsk-cb-user-bubble--tail hsk-cb-user-bubble--queued\">\r\n {queuedMessage.content}\r\n </div>\r\n <button type=\"button\" className=\"hsk-cb-queued-status\" onClick={sendQueuedNow}>\r\n <span className=\"hsk-cb-queued-dot\" />\r\n {t('queuedWaiting')}\r\n <span className=\"hsk-cb-queued-now\">{t('queuedSendNow')}</span>\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={bottomRef as any} style={{ height: 1 }} />\r\n </>\r\n );\r\n}\r\n","import React, { useState, useRef, useEffect } from 'react';\r\nimport type { ChatSource, ChatAttachment } from '@akropolys/sdk';\r\nimport { cn } from '../../utils/cn';\r\nimport {\r\n SparkleIcon,\r\n BookmarkIcon,\r\n HistoryIcon,\r\n TrashIcon,\r\n PaperclipIcon,\r\n WaveformIcon,\r\n MicIcon,\r\n MicOffIcon,\r\n StopIcon,\r\n ArrowUpIcon,\r\n PlusIcon,\r\n XIcon,\r\n} from './icons';\r\nimport { ListeningWave } from './components/ListeningWave';\r\nimport { AnimatedPlaceholder, HSK_STAGGER_MS, splitPlaceholder } from './components/AnimatedPlaceholder';\r\nimport type { UIStringKey, VoicePhase } from './types';\r\n\r\nexport interface ChatComposerProps {\r\n gooId: string;\r\n input: string;\r\n setInput: React.Dispatch<React.SetStateAction<string>>;\r\n showKikuPicker: boolean;\r\n setShowKikuPicker: (show: boolean) => void;\r\n showAtPicker: boolean;\r\n setShowAtPicker: (show: boolean) => void;\r\n captureAllowed: boolean;\r\n discussedSources: ChatSource[];\r\n defaultCurrency: string;\r\n handleSelectExtension: (ext: string) => void;\r\n handleKikuCapture: (product: ChatSource) => void;\r\n handleKikuCaptureAll: (products: ChatSource[]) => void;\r\n handleKikuViewHistory: () => void;\r\n handleKikuDelete: () => void;\r\n attachments: ChatAttachment[];\r\n removeAttachment: (idx: number) => void;\r\n chromeLoading: boolean;\r\n imageInputRef: React.RefObject<HTMLInputElement | null>;\r\n handleImageFiles: (files: FileList | null) => void;\r\n enableVision: boolean;\r\n enableVoice: boolean;\r\n canConverse: boolean;\r\n voiceMode: 'off' | 'dictate' | 'converse';\r\n startVoice: (mode: 'dictate' | 'converse') => void;\r\n stopVoice: () => void;\r\n voiceBlocked: boolean;\r\n textareaRef: React.RefObject<HTMLTextAreaElement | null>;\r\n classNames?: { input?: string; sendButton?: string };\r\n handleInput: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\r\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\r\n voice: {\r\n active: boolean;\r\n supported: boolean;\r\n spectrumBins: () => number;\r\n micSpectrum: (out: Uint8Array) => boolean;\r\n };\r\n voicePhase: VoicePhase;\r\n activePlaceholder: string;\r\n loading: boolean;\r\n streaming: boolean;\r\n stop: () => void;\r\n handleSend: (text?: string) => Promise<void>;\r\n voiceError: string;\r\n setVoiceError?: (err: string) => void;\r\n shopperLanguage: string;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n rail?: React.ReactNode;\r\n}\r\n\r\nexport function ChatComposer({\r\n gooId,\r\n input,\r\n setInput,\r\n showKikuPicker,\r\n setShowKikuPicker,\r\n showAtPicker,\r\n setShowAtPicker,\r\n captureAllowed,\r\n discussedSources,\r\n defaultCurrency,\r\n handleSelectExtension,\r\n handleKikuCapture,\r\n handleKikuCaptureAll,\r\n handleKikuViewHistory,\r\n handleKikuDelete,\r\n attachments,\r\n removeAttachment,\r\n chromeLoading,\r\n imageInputRef,\r\n handleImageFiles,\r\n enableVision,\r\n enableVoice,\r\n canConverse,\r\n voiceMode,\r\n startVoice,\r\n stopVoice,\r\n voiceBlocked,\r\n textareaRef,\r\n classNames = {},\r\n handleInput,\r\n handleKeyDown,\r\n voice,\r\n voicePhase,\r\n activePlaceholder,\r\n loading,\r\n streaming,\r\n stop,\r\n handleSend,\r\n voiceError,\r\n setVoiceError,\r\n shopperLanguage,\r\n t,\r\n rail,\r\n}: ChatComposerProps) {\r\n const [placeholderReplay, setPlaceholderReplay] = React.useState(0);\r\n const [toolsOpen, setToolsOpen] = React.useState(false);\r\n\r\n React.useEffect(() => {\r\n if (!voiceError) return;\r\n const timer = setTimeout(() => {\r\n setVoiceError?.('');\r\n }, 6000);\r\n return () => clearTimeout(timer);\r\n }, [voiceError, setVoiceError]);\r\n\r\n React.useEffect(() => {\r\n if (!toolsOpen) return;\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') setToolsOpen(false);\r\n };\r\n window.addEventListener('keydown', onKey);\r\n return () => window.removeEventListener('keydown', onKey);\r\n }, [toolsOpen]);\r\n\r\n const placeholderText = activePlaceholder || 'Ask me anything…';\r\n const placeholderSweepMs =\r\n Math.max(splitPlaceholder(placeholderText).length - 1, 0) * HSK_STAGGER_MS;\r\n\r\n // the kite tears through the seam, the seam heals, a fresh kite glides in\r\n const [launching, setLaunching] = useState(false);\r\n const launchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const launch = () => {\r\n if (launchTimer.current) clearTimeout(launchTimer.current);\r\n setLaunching(true);\r\n launchTimer.current = setTimeout(() => {\r\n setLaunching(false);\r\n launchTimer.current = null;\r\n }, 550);\r\n };\r\n useEffect(() => () => { if (launchTimer.current) clearTimeout(launchTimer.current); }, []);\r\n\r\n return (\r\n <div className=\"hsk-cb-input-wrap\">\r\n {toolsOpen && (\r\n <>\r\n <div className=\"hsk-cb-toolsheet-scrim\" onClick={() => setToolsOpen(false)} />\r\n <div className=\"hsk-cb-toolsheet-wrap\">\r\n <div className=\"hsk-cb-toolsheet\" role=\"menu\">\r\n {enableVision && (\r\n <button\r\n className=\"hsk-cb-toolsheet-item\"\r\n role=\"menuitem\"\r\n onClick={() => { setToolsOpen(false); imageInputRef.current?.click(); }}\r\n disabled={loading}\r\n >\r\n <PaperclipIcon />\r\n <span>{t('attachImage')}</span>\r\n </button>\r\n )}\r\n {enableVoice && canConverse && (\r\n <button\r\n className=\"hsk-cb-toolsheet-item\"\r\n role=\"menuitem\"\r\n onClick={() => { setToolsOpen(false); voiceMode === 'converse' ? stopVoice() : startVoice('converse'); }}\r\n disabled={loading || chromeLoading || voiceBlocked}\r\n >\r\n <WaveformIcon active={voiceMode === 'converse'} />\r\n <span>{voiceMode === 'converse' ? t('voiceModeExit') : t('voiceModeStart')}</span>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </>\r\n )}\r\n <div className=\"hsk-cb-input-card\">\r\n {(/^@kiku\\b/i.test(input) || showKikuPicker || showAtPicker) && (\r\n <div className=\"hsk-cb-docked-header\">\r\n <span className=\"hsk-cb-docked-sub\">{t('captureAndRemember')}</span>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-close\"\r\n onClick={() => {\r\n setInput(prev => prev.replace(/^@kiku\\s*/i, ''));\r\n setShowKikuPicker(false);\r\n setShowAtPicker(false);\r\n }}\r\n aria-label=\"Close mode\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n )}\r\n\r\n {(showKikuPicker || showAtPicker) && (\r\n <div className=\"hsk-cb-docked-options\" onMouseDown={e => e.preventDefault()}>\r\n {showAtPicker && captureAllowed && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => handleSelectExtension('@kiku')}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><SparkleIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">kiku</span>\r\n <span className=\"hsk-cb-docked-option-desc\">capture & remember</span>\r\n </button>\r\n )}\r\n\r\n {showKikuPicker && captureAllowed && (\r\n <>\r\n {discussedSources.map((src, i) => (\r\n <button\r\n key={src.id ?? i}\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuCapture(src); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\">\r\n {src.image ? <img src={src.image} alt=\"\" /> : <BookmarkIcon />}\r\n </span>\r\n <span className=\"hsk-cb-docked-option-title\">{src.name}</span>\r\n {src.price && (\r\n <span className=\"hsk-cb-docked-option-price\">\r\n {src.currency ?? defaultCurrency} {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </span>\r\n )}\r\n </button>\r\n ))}\r\n {discussedSources.length > 1 && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuCaptureAll(discussedSources); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><BookmarkIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">{t('captureAll', { count: String(discussedSources.length) })}</span>\r\n </button>\r\n )}\r\n {discussedSources.length === 0 && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuCapture({ name: 'current page', id: undefined }); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><BookmarkIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">{t('captureCurrentPage')}</span>\r\n </button>\r\n )}\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuViewHistory(); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><HistoryIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">{t('whatHaveYouSaved')}</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuDelete(); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><TrashIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">{t('deleteThis')}</span>\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n\r\n {attachments.length > 0 && (\r\n <div className=\"hsk-cb-img-strip\">\r\n {attachments.map((att, i) => (\r\n <div key={i} className=\"hsk-cb-img-thumb-wrap\">\r\n <img src={att.data} alt={`attachment ${i + 1}`} className=\"hsk-cb-img-thumb\" />\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-img-thumb-remove\"\r\n onClick={() => removeAttachment(i)}\r\n aria-label=\"Remove image\"\r\n >\r\n <XIcon size={10} />\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div\r\n className={cn(\"hsk-cb-input-box\", chromeLoading && \"hsk-cb-input-box--waiting\")}\r\n data-cascade={placeholderReplay % 2 ? 'b' : 'a'}\r\n data-tools={toolsOpen ? 'open' : 'closed'}\r\n style={{ '--hsk-text-sweep': `${placeholderSweepMs}ms` } as React.CSSProperties}\r\n >\r\n <input\r\n ref={imageInputRef as any}\r\n type=\"file\"\r\n accept=\"image/*\"\r\n className=\"hsk-sr-only\"\r\n onChange={e => {\r\n handleImageFiles(e.target.files);\r\n e.target.value = '';\r\n }}\r\n />\r\n {(enableVision || (enableVoice && canConverse)) && (\r\n <button\r\n className={cn('hsk-cb-tools-toggle', toolsOpen && 'hsk-cb-tools-toggle--open')}\r\n onClick={() => setToolsOpen(o => !o)}\r\n disabled={loading || chromeLoading}\r\n aria-label={toolsOpen ? 'Close options' : 'More options'}\r\n aria-expanded={toolsOpen}\r\n >\r\n <PlusIcon />\r\n </button>\r\n )}\r\n <>\r\n {enableVision && (\r\n <button\r\n className=\"hsk-cb-attach-btn\"\r\n onClick={() => imageInputRef.current?.click()}\r\n disabled={loading}\r\n aria-label=\"Attach image\"\r\n title=\"Attach image\"\r\n >\r\n <PaperclipIcon />\r\n </button>\r\n )}\r\n {enableVoice && canConverse && (\r\n <button\r\n className={cn(\"hsk-cb-voice-mode-btn\", voiceBlocked && \"hsk-cb-voice-mode-btn--blocked\")}\r\n onClick={() => voiceBlocked ? setVoiceError?.(t('errAccountRequired')) : startVoice('converse')}\r\n disabled={loading || chromeLoading}\r\n aria-label=\"Voice conversation\"\r\n title=\"Voice conversation\"\r\n >\r\n <WaveformIcon />\r\n </button>\r\n )}\r\n </>\r\n <div className=\"hsk-cb-field\">\r\n <textarea\r\n ref={textareaRef as any}\r\n value={input}\r\n onChange={handleInput}\r\n onKeyDown={handleKeyDown}\r\n rows={1}\r\n placeholder=\"\"\r\n className={cn(\"hsk-cb-textarea\", classNames.input)}\r\n aria-label={activePlaceholder}\r\n disabled={loading && !streaming}\r\n />\r\n <AnimatedPlaceholder\r\n placeholder={activePlaceholder}\r\n visible={!input}\r\n staggerMs={HSK_STAGGER_MS}\r\n replaySeed={placeholderReplay}\r\n />\r\n </div>\r\n {enableVoice && (\r\n <button\r\n className={cn(\"hsk-cb-mic-btn\", (voiceMode === 'converse' || voiceMode === 'dictate') && \"hsk-cb-mic-btn--active\", voiceBlocked && \"hsk-cb-mic-btn--blocked\")}\r\n onClick={() => {\r\n if (voiceMode !== 'off') {\r\n stopVoice();\r\n } else if (canConverse) {\r\n startVoice('converse');\r\n } else {\r\n startVoice('dictate');\r\n }\r\n }}\r\n disabled={loading || chromeLoading}\r\n aria-label={voiceMode === 'off' ? 'Start voice mode' : 'Stop voice'}\r\n title={voiceMode === 'off' ? (canConverse ? 'Voice conversation' : 'Voice input') : 'Stop'}\r\n >\r\n {voiceMode === 'off' ? <MicIcon /> : <MicOffIcon />}\r\n </button>\r\n )}\r\n {(loading || streaming) && !launching ? (\r\n <button\r\n className={cn(\"hsk-cb-send\", \"hsk-cb-send--stop\", classNames.sendButton)}\r\n onClick={stop}\r\n aria-label=\"Stop generating\"\r\n title=\"Stop generating\"\r\n >\r\n <StopIcon />\r\n </button>\r\n ) : (\r\n <button\r\n className={cn(\"hsk-cb-send\", launching && \"is-launching\", classNames.sendButton)}\r\n onClick={() => { launch(); handleSend(); }}\r\n disabled={chromeLoading || (!input.trim() && attachments.length === 0)}\r\n aria-label=\"Send message\"\r\n >\r\n <svg width=\"0\" height=\"0\" aria-hidden=\"true\" focusable=\"false\" style={{ position: 'absolute' }}>\r\n <defs>\r\n <filter id={gooId}>\r\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"1.6\" result=\"blur\" />\r\n <feColorMatrix in=\"blur\" type=\"matrix\"\r\n values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 16 -7\" result=\"goo\" />\r\n <feBlend in=\"SourceGraphic\" in2=\"goo\" />\r\n </filter>\r\n </defs>\r\n </svg>\r\n <span className=\"hsk-cb-send-sheath\" aria-hidden=\"true\" />\r\n <span className=\"hsk-cb-send-stage\" style={{ filter: `url(#${gooId})` }}>\r\n <span className=\"hsk-cb-send-seam\" aria-hidden=\"true\" />\r\n <span className=\"hsk-cb-send-kite\">\r\n <ArrowUpIcon />\r\n </span>\r\n </span>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n {voiceBlocked ? (\r\n <div className=\"hsk-cb-voice-error\" role=\"status\" onClick={() => setVoiceError?.('')}>\r\n <span>{t('errAccountRequired')}</span>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-voice-error-dismiss\"\r\n onClick={(e) => { e.stopPropagation(); setVoiceError?.(''); }}\r\n aria-label=\"Dismiss error\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n ) : voiceError && (\r\n <div className=\"hsk-cb-voice-error\" role=\"status\" onClick={() => setVoiceError?.('')}>\r\n <span>{t(voiceError as UIStringKey)}</span>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-voice-error-dismiss\"\r\n onClick={(e) => { e.stopPropagation(); setVoiceError?.(''); }}\r\n aria-label=\"Dismiss error\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n )}\r\n <div className=\"hsk-cb-hint\">{shopperLanguage ? t('footerHint') : 'kiku · searches the whole catalogue in real time'}</div>\r\n </div>\r\n );\r\n}\r\n","import React, { useEffect, useRef } from 'react';\r\nimport type { VoicePhase } from '../utils/voiceSession';\r\n\r\nexport interface VoiceCanvasProps {\r\n phase: VoicePhase;\r\n\r\n level: () => number;\r\n\r\n spectrum?: (out: Uint8Array) => boolean;\r\n\r\n bins?: () => number;\r\n className?: string;\r\n}\r\n\r\ntype RGB = [number, number, number];\r\n\r\nfunction parseColor(css: string, fallback: RGB): RGB {\r\n const m = css.match(/-?[\\d.]+/g);\r\n if (!m || m.length < 3) return fallback;\r\n return [Number(m[0]), Number(m[1]), Number(m[2])];\r\n}\r\n\r\nfunction mix(a: RGB, b: RGB, t: number): RGB {\r\n return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];\r\n}\r\n\r\nfunction rgba(c: RGB, alpha: number): string {\r\n return `rgba(${c[0] | 0}, ${c[1] | 0}, ${c[2] | 0}, ${alpha})`;\r\n}\r\n\r\nconst BANDS = 24;\r\nconst SPECTRUM_FRACTION = 0.42;\r\n\r\nexport function VoiceCanvas({ phase, level, spectrum, bins, className }: VoiceCanvasProps) {\r\n const canvasRef = useRef<HTMLCanvasElement>(null);\r\n const phaseRef = useRef(phase);\r\n const levelRef = useRef(level);\r\n const spectrumRef = useRef(spectrum);\r\n const binsRef = useRef(bins);\r\n useEffect(() => { phaseRef.current = phase; }, [phase]);\r\n useEffect(() => { levelRef.current = level; }, [level]);\r\n useEffect(() => { spectrumRef.current = spectrum; }, [spectrum]);\r\n useEffect(() => { binsRef.current = bins; }, [bins]);\r\n\r\n useEffect(() => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) return;\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n\r\n const style = getComputedStyle(canvas);\r\n const accent = parseColor(style.getPropertyValue('--hsk-primary') || '', [255, 106, 51]);\r\n const ink = parseColor(style.getPropertyValue('--hsk-chat-text') || '', [31, 31, 31]);\r\n\r\n let raf = 0;\r\n let w = 0;\r\n let h = 0;\r\n\r\n const resize = () => {\r\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\r\n const rect = canvas.getBoundingClientRect();\r\n w = Math.max(1, rect.width);\r\n h = Math.max(1, rect.height);\r\n canvas.width = Math.round(w * dpr);\r\n canvas.height = Math.round(h * dpr);\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n };\r\n resize();\r\n const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(resize) : null;\r\n ro?.observe(canvas);\r\n window.addEventListener('resize', resize);\r\n\r\n const reduced = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false;\r\n\r\n const bands = new Float32Array(BANDS);\r\n let strokes: CanvasGradient[] = [];\r\n let glow: CanvasGradient | null = null;\r\n let strokesFor = -1;\r\n let freqBuf: Uint8Array | null = null;\r\n let amp = 0;\r\n let sweep = 0;\r\n const start = performance.now();\r\n\r\n const follow = (cur: number, target: number, attack: number, release: number) =>\r\n cur + (target - cur) * (target > cur ? attack : release);\r\n\r\n const readSpectrum = () => {\r\n const read = spectrumRef.current;\r\n const n = binsRef.current?.() ?? 0;\r\n if (!read || !n) return false;\r\n if (!freqBuf || freqBuf.length !== n) freqBuf = new Uint8Array(n);\r\n if (!read(freqBuf)) return false;\r\n\r\n const usable = Math.max(BANDS, Math.floor(n * SPECTRUM_FRACTION));\r\n const per = usable / BANDS;\r\n for (let b = 0; b < BANDS; b++) {\r\n const from = Math.floor(b * per);\r\n const to = Math.max(from + 1, Math.floor((b + 1) * per));\r\n let sum = 0;\r\n for (let i = from; i < to; i++) sum += freqBuf[i];\r\n const v = sum / (to - from) / 255;\r\n bands[b] = follow(bands[b], v, reduced ? 0.2 : 0.55, reduced ? 0.06 : 0.14);\r\n }\r\n return true;\r\n };\r\n\r\n const synthesizeBands = (t: number, energy: number) => {\r\n for (let b = 0; b < BANDS; b++) {\r\n const m = b / (BANDS - 1);\r\n const shape = Math.pow(1 - m, 1.6) * (0.75 + 0.25 * Math.sin(t * 3.1 + b * 0.7));\r\n bands[b] = follow(bands[b], shape * energy, 0.3, 0.12);\r\n }\r\n };\r\n\r\n const bandAt = (m: number) => {\r\n const x = Math.min(BANDS - 1, Math.max(0, m * (BANDS - 1)));\r\n const i = Math.floor(x);\r\n const f = x - i;\r\n const a = bands[i];\r\n const b = bands[Math.min(BANDS - 1, i + 1)];\r\n return a + (b - a) * f * f * (3 - 2 * f);\r\n };\r\n\r\n const draw = (now: number) => {\r\n raf = requestAnimationFrame(draw);\r\n const t = (now - start) / 1000;\r\n const p = phaseRef.current;\r\n\r\n const live = Math.min(1, levelRef.current());\r\n const floor = p === 'speaking' ? 0.42 : p === 'listening' ? 0.3 : p === 'thinking' ? 0.28 : 0.12;\r\n amp = follow(amp, Math.max(floor, live), reduced ? 0.1 : 0.5, reduced ? 0.05 : 0.11);\r\n\r\n if (!readSpectrum()) synthesizeBands(t, Math.max(0.25, amp));\r\n\r\n ctx.clearRect(0, 0, w, h);\r\n const cy = h / 2;\r\n\r\n sweep = p === 'thinking' ? (sweep + 0.012) % 1.6 : 0;\r\n\r\n const layers = 3;\r\n if (strokesFor !== w) {\r\n strokes = [];\r\n for (let l = 0; l < layers; l++) {\r\n const depth = l / (layers - 1 || 1);\r\n const hue = mix(accent, ink, depth * 0.5);\r\n const g = ctx.createLinearGradient(0, 0, w, 0);\r\n g.addColorStop(0, rgba(hue, 0));\r\n g.addColorStop(0.5, rgba(hue, 0.9 - depth * 0.35));\r\n g.addColorStop(1, rgba(hue, 0));\r\n strokes.push(g);\r\n }\r\n glow = ctx.createLinearGradient(0, 0, w, 0);\r\n glow.addColorStop(0, rgba(accent, 0));\r\n glow.addColorStop(0.5, rgba(accent, 0.14));\r\n glow.addColorStop(1, rgba(accent, 0));\r\n strokesFor = w;\r\n }\r\n const maxAmp = h * 0.32;\r\n const step = Math.max(4, w / 130);\r\n\r\n for (let l = 0; l < layers; l++) {\r\n const depth = l / (layers - 1 || 1);\r\n const lag = l * 0.055;\r\n const scale = 1 - depth * 0.22;\r\n\r\n ctx.beginPath();\r\n let px = 0;\r\n let py = cy;\r\n for (let x = 0; x <= w; x += step) {\r\n const u = x / w;\r\n const envelope = Math.pow(Math.sin(Math.PI * u), 0.85);\r\n const focus = p === 'thinking'\r\n ? Math.exp(-Math.pow((u - (sweep - 0.3)) * 4.5, 2))\r\n : 1;\r\n\r\n const band = bandAt(Math.abs(u - 0.5) * 2);\r\n const tl = t - lag;\r\n const ripple =\r\n Math.sin(u * Math.PI * 2 * 2.1 + tl * 7.4) * 0.66 +\r\n Math.sin(u * Math.PI * 2 * 3.7 - tl * 5.6) * 0.26 +\r\n Math.sin(u * Math.PI * 2 * 5.9 + tl * 9.1) * 0.08;\r\n\r\n const y =\r\n cy +\r\n envelope * focus * scale * maxAmp * amp * (0.6 + band * 1.1) * ripple +\r\n Math.sin(u * Math.PI * 2 * 0.6 + (t - lag) * 2.2) * envelope * h * 0.01;\r\n\r\n if (x === 0) {\r\n ctx.moveTo(x, y);\r\n } else {\r\n ctx.quadraticCurveTo(px, py, (px + x) / 2, (py + y) / 2);\r\n }\r\n px = x;\r\n py = y;\r\n }\r\n ctx.quadraticCurveTo(px, py, w, py);\r\n\r\n ctx.lineCap = 'round';\r\n ctx.lineJoin = 'round';\r\n const width = (l === 0 ? 3 : 1.6) * (1 + amp * 0.6);\r\n if (l === 0) {\r\n ctx.strokeStyle = glow!;\r\n ctx.lineWidth = width * 5;\r\n ctx.stroke();\r\n }\r\n ctx.strokeStyle = strokes[l];\r\n ctx.lineWidth = width;\r\n ctx.stroke();\r\n }\r\n };\r\n\r\n raf = requestAnimationFrame(draw);\r\n return () => {\r\n cancelAnimationFrame(raf);\r\n ro?.disconnect();\r\n window.removeEventListener('resize', resize);\r\n };\r\n }, []);\r\n\r\n return <canvas ref={canvasRef} className={className} aria-hidden=\"true\" />;\r\n}\r\n","import React from 'react';\r\nimport type { ChatSource } from '@akropolys/sdk';\r\nimport { cn } from '../../utils/cn';\r\nimport { SparkleIcon, CloseIcon, MicIcon, MicOffIcon } from './icons';\r\nimport { LIVE_VOICES, type UIStringKey, type VoicePhase } from './types';\r\nimport { VoiceCanvas } from '../VoiceCanvas';\r\nimport KikuDoodles from '../KikuDoodles';\r\n\r\nexport interface VoiceOverlayProps {\r\n siteId: string;\r\n themeAttr?: 'light' | 'dark' | string;\r\n stopVoice: () => void;\r\n chooseVoice: (name: string) => void;\r\n liveVoiceName: string;\r\n voiceSecondsLeft: number | null;\r\n voiceConnecting: boolean;\r\n voicePhase: VoicePhase;\r\n live: {\r\n micLevel: () => number;\r\n micSpectrum: (out: Uint8Array) => boolean;\r\n spectrumBins: () => number;\r\n };\r\n voiceMuted: boolean;\r\n setVoiceMuted: React.Dispatch<React.SetStateAction<boolean>>;\r\n shownSources: ChatSource[];\r\n onSelectSource?: (src: ChatSource) => void;\r\n defaultCurrency: string;\r\n voiceError: string;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n}\r\n\r\nexport function VoiceOverlay({\r\n siteId,\r\n themeAttr,\r\n stopVoice,\r\n chooseVoice,\r\n liveVoiceName,\r\n voiceSecondsLeft,\r\n voiceConnecting,\r\n voicePhase,\r\n live,\r\n voiceMuted,\r\n setVoiceMuted,\r\n shownSources,\r\n onSelectSource,\r\n defaultCurrency,\r\n voiceError,\r\n t,\r\n}: VoiceOverlayProps) {\r\n return (\r\n <div className=\"hsk-voice-overlay\" role=\"dialog\" aria-label={t('voiceModeStart')}>\r\n <KikuDoodles seed={siteId} theme={themeAttr} />\r\n\r\n <button\r\n className=\"hsk-voice-exit\"\r\n onClick={stopVoice}\r\n aria-label={t('voiceModeExit')}\r\n title={t('voiceModeExit')}\r\n >\r\n <CloseIcon />\r\n </button>\r\n\r\n <div className=\"hsk-voice-picker\" role=\"radiogroup\" aria-label={t('voicePickerLabel')}>\r\n {LIVE_VOICES.map((v, i) => (\r\n <button\r\n key={v.name}\r\n type=\"button\"\r\n role=\"radio\"\r\n aria-checked={liveVoiceName === v.name}\r\n className={cn('hsk-voice-pill', liveVoiceName === v.name && 'hsk-voice-pill--on')}\r\n style={{ animationDelay: `${i * 60}ms` }}\r\n onClick={() => chooseVoice(v.name)}\r\n aria-label={`${v.label}, ${v.gender}`}\r\n >\r\n {v.label}\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {voiceSecondsLeft !== null && (\r\n <div\r\n className={cn('hsk-voice-allowance', voiceSecondsLeft <= 5 && 'hsk-voice-allowance--low')}\r\n role=\"timer\"\r\n aria-live=\"off\"\r\n >\r\n {Math.max(0, Math.ceil(voiceSecondsLeft))}s\r\n </div>\r\n )}\r\n\r\n <div className={cn('hsk-voice-stage', voiceConnecting && 'hsk-voice-stage--connecting')}>\r\n <VoiceCanvas\r\n className=\"hsk-voice-canvas\"\r\n phase={voicePhase}\r\n level={live.micLevel}\r\n spectrum={live.micSpectrum}\r\n bins={live.spectrumBins}\r\n />\r\n </div>\r\n\r\n {voiceConnecting ? (\r\n <div className=\"hsk-voice-connecting\" role=\"status\">\r\n <span className=\"hsk-voice-connecting-dot\" />\r\n <span>{t('voiceConnecting')}</span>\r\n </div>\r\n ) : (\r\n <div className=\"hsk-voice-caption\" aria-live=\"polite\">\r\n <span className={cn('hsk-voice-phase', `hsk-voice-phase--${voicePhase}`)}>\r\n {voiceMuted ? t('voiceMuted')\r\n : voicePhase === 'speaking' ? t('voicePhaseSpeaking')\r\n : voicePhase === 'thinking' ? t('voicePhaseThinking')\r\n : t('voicePhaseListening')}\r\n </span>\r\n {voiceMuted && <span className=\"hsk-voice-heard\">{t('voiceMutedHint')}</span>}\r\n {!voiceMuted && voicePhase === 'listening' && (\r\n <span className=\"hsk-voice-hint-sub\">{t('voiceHint')}</span>\r\n )}\r\n </div>\r\n )}\r\n\r\n {shownSources.length > 0 && (\r\n <div className=\"hsk-voice-items\">\r\n {shownSources.slice(0, 4).map((src, i) => (\r\n <button\r\n key={src.id ?? i}\r\n type=\"button\"\r\n className=\"hsk-voice-item\"\r\n style={{ animationDelay: `${i * 70}ms` }}\r\n onClick={() => onSelectSource?.(src)}\r\n >\r\n {src.image\r\n ? <img src={src.image} alt=\"\" className=\"hsk-voice-item-img\" loading=\"lazy\" />\r\n : <span className=\"hsk-voice-item-img hsk-voice-item-img--empty\"><SparkleIcon /></span>}\r\n <span className=\"hsk-voice-item-name\">{src.name}</span>\r\n {src.price && (\r\n <span className=\"hsk-voice-item-price\">\r\n {src.currency ?? defaultCurrency}{' '}\r\n {parseFloat(String(src.price).replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </span>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {voiceError && <div className=\"hsk-voice-error\">{t(voiceError as UIStringKey)}</div>}\r\n\r\n <div className=\"hsk-voice-controls\">\r\n <button\r\n className={cn('hsk-voice-control', voiceMuted && 'hsk-voice-control--muted')}\r\n onClick={() => setVoiceMuted(m => !m)}\r\n aria-label={voiceMuted ? t('voicePhaseListening') : t('voiceModeExit')}\r\n title={voiceMuted ? t('voicePhaseListening') : t('voiceModeExit')}\r\n >\r\n <span key={voiceMuted ? 'off' : 'on'} className=\"hsk-voice-control-icon\">\r\n {voiceMuted ? <MicOffIcon /> : <MicIcon />}\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\nimport { CloseIcon } from '../icons';\r\n\r\nexport interface LightboxModalProps {\r\n src: string | null;\r\n onClose: () => void;\r\n}\r\n\r\nexport function LightboxModal({ src, onClose }: LightboxModalProps) {\r\n if (!src) return null;\r\n return (\r\n <div className=\"hsk-lightbox\" onClick={onClose}>\r\n <button className=\"hsk-lightbox-close\" onClick={onClose} aria-label=\"Close image\">\r\n <CloseIcon />\r\n </button>\r\n <img src={src} alt=\"\" className=\"hsk-lightbox-img\" onClick={e => e.stopPropagation()} />\r\n </div>\r\n );\r\n}\r\n","import React, { useRef, useEffect } from 'react';\r\nimport { cn } from '../../../utils/cn';\r\nimport { useT } from '../types';\r\n\r\nexport interface ConversationTimelineProps {\r\n items: { idx: number; text: string }[];\r\n activeIdx: number;\r\n progress: number;\r\n onJump: (idx: number) => void;\r\n side?: 'left' | 'right';\r\n}\r\n\r\nexport function ConversationTimeline({\r\n items,\r\n activeIdx,\r\n progress,\r\n onJump,\r\n side = 'right',\r\n}: ConversationTimelineProps) {\r\n const tr = useT();\r\n const containerRef = useRef<HTMLElement>(null);\r\n const trackRef = useRef<HTMLDivElement>(null);\r\n const itemRefs = useRef<(HTMLButtonElement | null)[]>([]);\r\n const cursorRef = useRef<HTMLSpanElement>(null);\r\n\r\n let anchor = 0;\r\n for (let i = 0; i < items.length; i++) {\r\n if (items[i].idx <= activeIdx) anchor = i;\r\n }\r\n\r\n useEffect(() => {\r\n const node = itemRefs.current[anchor];\r\n const cursor = cursorRef.current;\r\n const track = trackRef.current;\r\n const container = containerRef.current;\r\n if (!node) return;\r\n\r\n if (cursor) {\r\n cursor.style.transform = `translateY(${node.offsetTop + node.offsetHeight / 2}px)`;\r\n }\r\n\r\n if (track && container) {\r\n const containerHeight = container.clientHeight;\r\n const trackHeight = track.scrollHeight;\r\n if (trackHeight > containerHeight && containerHeight > 0) {\r\n const nodeCenter = node.offsetTop + node.offsetHeight / 2;\r\n const targetY = containerHeight / 2 - nodeCenter;\r\n track.style.transform = `translateY(${targetY}px)`;\r\n } else {\r\n track.style.transform = 'none';\r\n }\r\n }\r\n }, [anchor, items.length]);\r\n\r\n if (items.length < 2) return null;\r\n\r\n return (\r\n <nav\r\n ref={containerRef}\r\n className={cn(\"hsk-cb-timeline\", side === 'left' ? \"hsk-cb-timeline--left\" : \"hsk-cb-timeline--right\")}\r\n aria-label={tr('timelineLabel')}\r\n >\r\n <div\r\n ref={trackRef}\r\n className=\"hsk-cb-timeline-track\"\r\n style={{ '--hsk-tl-progress': progress } as React.CSSProperties}\r\n >\r\n <span className=\"hsk-cb-tl-cursor\" ref={cursorRef} aria-hidden=\"true\" />\r\n {items.map((item, i) => (\r\n <button\r\n key={item.idx}\r\n ref={(el) => { itemRefs.current[i] = el; }}\r\n type=\"button\"\r\n className={cn('hsk-cb-tl-item', i === anchor && 'hsk-cb-tl-item--on')}\r\n style={{ '--hsk-tl-d': Math.min(Math.abs(i - anchor), 4) } as React.CSSProperties}\r\n onClick={() => onJump(item.idx)}\r\n title={item.text}\r\n >\r\n <span className=\"hsk-cb-tl-dot\" />\r\n <span className=\"hsk-cb-tl-label\">{item.text}</span>\r\n </button>\r\n ))}\r\n </div>\r\n </nav>\r\n );\r\n}\r\n","import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport type { ChatMessage } from '@akropolys/sdk';\nimport { cn } from '../../../utils/cn';\nimport {\n PinIcon,\n RetryIcon,\n EditIcon,\n CopyIcon,\n CheckIcon,\n} from '../icons';\nimport type { UIStringKey } from '../types';\n\nexport interface TapbackMenuProps {\n msg: ChatMessage;\n rect: { top: number; left: number; width: number; height: number };\n containerRect?: { top: number; left: number; width: number; height: number };\n isUser: boolean;\n canRetry?: boolean;\n canEdit?: boolean;\n onPin: (msg: ChatMessage) => void;\n onRetry?: (msg: ChatMessage) => void;\n onEdit?: (msg: ChatMessage) => void;\n onCopy: (text: string) => void;\n onClose: () => void;\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\n}\n\nexport function TapbackMenu({\n msg,\n rect,\n containerRect,\n isUser,\n canRetry,\n canEdit,\n onPin,\n onRetry,\n onEdit,\n onCopy,\n onClose,\n t,\n}: TapbackMenuProps) {\n const [copied, setCopied] = useState(false);\n const menuRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [onClose]);\n\n const handleCopyAction = useCallback(() => {\n onCopy(msg.content || '');\n setCopied(true);\n setTimeout(() => {\n onClose();\n }, 450);\n }, [msg.content, onCopy, onClose]);\n\n const handlePinAction = useCallback(() => {\n onPin(msg);\n onClose();\n }, [msg, onPin, onClose]);\n\n const handleRetryAction = useCallback(() => {\n if (onRetry) onRetry(msg);\n onClose();\n }, [msg, onRetry, onClose]);\n\n const handleEditAction = useCallback(() => {\n if (onEdit) onEdit(msg);\n onClose();\n }, [msg, onEdit, onClose]);\n\n const [measuredWidth, setMeasuredWidth] = useState(0);\n\n useEffect(() => {\n if (menuRef.current) {\n const w = menuRef.current.offsetWidth;\n if (w && Math.abs(w - measuredWidth) > 2) {\n setMeasuredWidth(w);\n }\n }\n }, [measuredWidth]);\n\n const cTop = containerRect?.top ?? 0;\n const cLeft = containerRect?.left ?? 0;\n const cWidth = containerRect?.width ?? (typeof window !== 'undefined' ? window.innerWidth : 390);\n\n const bTop = rect.top - cTop;\n const bLeft = rect.left - cLeft;\n const bWidth = rect.width;\n const bHeight = rect.height;\n\n // Capsule width based on enabled tools\n let btnCount = 2; // Pin + Copy\n if (canRetry && onRetry) btnCount++;\n if (isUser && canEdit && onEdit) btnCount++;\n const estimatedWidth = btnCount === 2 ? 140 : btnCount === 3 ? 195 : 252;\n const capsuleWidth = measuredWidth || estimatedWidth;\n const capsuleHeight = 38;\n\n // Always position above if space permits (bTop >= 58), else below\n const placeAbove = bTop >= 58;\n const capsuleTop = placeAbove\n ? Math.max(8, bTop - capsuleHeight - 16)\n : Math.min(bTop + bHeight + 16, (containerRect?.height ?? 800) - capsuleHeight - 8);\n\n // Target X where the anchor bubble touches the message bubble corner:\n // For user: top-right corner (18px from its right edge)\n // For model: top-left corner (20px from its left edge)\n const targetX = isUser\n ? Math.max(28, bLeft + bWidth - 18)\n : Math.min(cWidth - 28, bLeft + 20);\n\n // Position capsule so the upward bubble column (at 18px from capsule edge) aligns directly with targetX:\n let capsuleLeft = isUser\n ? targetX - capsuleWidth + 18\n : targetX - 18;\n\n // Clamp capsule within container bounds\n capsuleLeft = Math.max(10, Math.min(capsuleLeft, cWidth - capsuleWidth - 10));\n\n // Compute exact tail offset inside capsule so it aligns with targetX\n const tailOffset = Math.max(18, Math.min(targetX - capsuleLeft, capsuleWidth - 18));\n\n // Anchor droplet in the message bubble's exact color to seem like an organic extension!\n const anchorColor = isUser\n ? 'var(--hsk-user-bubble-bg, var(--hsk-primary, #007aff))'\n : 'var(--hsk-chat-source-bg, var(--hsk-bubble-bg, rgba(255, 255, 255, 0.12)))';\n\n let toolIdx = 0;\n\n return (\n <div className=\"hsk-tapback-overlay\" onClick={onClose}>\n <div\n ref={menuRef}\n className={cn(\n \"hsk-tapback-group\",\n placeAbove ? \"is-above\" : \"is-below\",\n isUser ? \"is-user\" : \"is-ai\"\n )}\n style={{\n top: `${capsuleTop}px`,\n left: `${capsuleLeft}px`,\n '--tail-x': `${tailOffset}px`,\n '--hsk-anchor-color': anchorColor,\n } as React.CSSProperties}\n onClick={e => e.stopPropagation()}\n >\n {/* Floating Tool Capsule */}\n <div className=\"hsk-tapback-capsule\">\n <button\n type=\"button\"\n className=\"hsk-tapback-tool-btn hsk-tapback-tool-btn--pin\"\n onClick={handlePinAction}\n aria-label=\"Pin to Kiku Memory\"\n style={{ '--tool-idx': toolIdx++ } as React.CSSProperties}\n >\n <PinIcon size={14} />\n <span>Pin</span>\n </button>\n\n {canRetry && onRetry && (\n <button\n type=\"button\"\n className=\"hsk-tapback-tool-btn hsk-tapback-tool-btn--retry\"\n onClick={handleRetryAction}\n aria-label={t('retry')}\n style={{ '--tool-idx': toolIdx++ } as React.CSSProperties}\n >\n <RetryIcon size={14} />\n <span>{t('retry')}</span>\n </button>\n )}\n\n {isUser && canEdit && onEdit && (\n <button\n type=\"button\"\n className=\"hsk-tapback-tool-btn hsk-tapback-tool-btn--edit\"\n onClick={handleEditAction}\n aria-label={t('edit')}\n style={{ '--tool-idx': toolIdx++ } as React.CSSProperties}\n >\n <EditIcon size={14} />\n <span>{t('edit')}</span>\n </button>\n )}\n\n <button\n type=\"button\"\n className={cn(\"hsk-tapback-tool-btn hsk-tapback-tool-btn--copy\", copied && \"is-copied\")}\n onClick={handleCopyAction}\n aria-label={copied ? t('copied') : t('copy')}\n style={{ '--tool-idx': toolIdx++ } as React.CSSProperties}\n >\n {copied ? <CheckIcon size={14} /> : <CopyIcon size={14} />}\n <span>{copied ? t('copied') : t('copy')}</span>\n </button>\n </div>\n\n {/* Upward-flowing connector bubbles:\n - Dot 3 (top): 20px, melted into capsule\n - Dot 2 (middle): 11px, frosted glass\n - Dot 1 (bottom): 6px, in the exact message bubble color, touching the bubble! */}\n <div\n className={cn(\"hsk-tapback-tail\", placeAbove ? \"is-above\" : \"is-below\")}\n style={{ left: `${tailOffset}px` }}\n >\n <span className=\"hsk-tapback-dot hsk-tapback-dot--top\">\n <span className=\"hsk-tapback-dot-bridge\" />\n </span>\n <span className=\"hsk-tapback-dot hsk-tapback-dot--mid\" />\n <span className=\"hsk-tapback-dot hsk-tapback-dot--anchor\" />\n </div>\n </div>\n </div>\n );\n}\n","import React, { useState, useEffect, useRef } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { getShadowContainer } from '../utils/shadowRoot';\r\nimport { useSearch, useKiku, useAkropolysContext } from '@akropolys/sdk';\r\nimport { renderMarkdown } from '../utils/markdown';\r\nimport { SearchResult, Product, AkropolysTheme } from '@akropolys/sdk';\r\nimport { cn } from '../utils/cn';\r\nimport { ArrowUpIcon } from '../utils/icons';\r\n\r\nexport interface SparkleProps {\r\n productName: string;\r\n limit?: number;\r\n onResult?: (results: SearchResult[]) => void;\r\n\r\n backdropColor?: string;\r\n \r\n backdropBlur?: string | number;\r\n \r\n className?: string;\r\n\r\n onNavigate?: (result: SearchResult) => boolean | void;\r\n theme?: AkropolysTheme;\r\n classNames?: {\r\n button?: string;\r\n backdrop?: string;\r\n card?: string;\r\n item?: string;\r\n };\r\n product?: Product;\r\n children?: React.ReactNode;\r\n}\r\n\r\ninterface ModalProps extends Pick<SparkleProps, 'productName' | 'limit' | 'backdropColor' | 'backdropBlur' | 'onNavigate' | 'onResult' | 'theme' | 'classNames' | 'product'> {\r\n onClose: () => void;\r\n}\r\n\r\nconst SparkleIcon = ({ className, size = 16 }: { className?: string; size?: number }) => (\r\n <svg\r\n className={cn(\"hsk-brand-mark\", className)}\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 100 100\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n aria-label=\"kiku\"\r\n >\r\n <g transform=\"translate(22.7 19) scale(0.62)\" fill=\"currentColor\" fillRule=\"evenodd\">\r\n <path d=\"M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z\" />\r\n <circle cx=\"55\" cy=\"82\" r=\"3.4\" />\r\n </g>\r\n </svg>\r\n);\r\n\r\nconst CloseIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\ninterface ModalProps extends Pick<SparkleProps, 'productName' | 'limit' | 'backdropColor' | 'backdropBlur' | 'onNavigate' | 'onResult' | 'theme' | 'classNames' | 'product'> {\r\n onClose: () => void;\r\n}\r\n\r\nconst getFriendlyError = (err: any) => {\r\n let str = '';\r\n if (typeof err === 'string') str = err;\r\n else if (err && typeof err === 'object' && err.message) str = err.message;\r\n else try { str = JSON.stringify(err); } catch { str = String(err); }\r\n\r\n if (str.toLowerCase().includes('token limit')) {\r\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(str);\r\n return parsed.error || parsed.message || str;\r\n } catch {\r\n return str;\r\n }\r\n};\r\n\r\nfunction SparkleModal({\r\n productName,\r\n limit,\r\n backdropColor,\r\n backdropBlur,\r\n onClose,\r\n onNavigate,\r\n onResult,\r\n theme,\r\n classNames = {},\r\n product: initialProduct,\r\n}: ModalProps) {\r\n const client = useAkropolysContext();\r\n const [fetchedProduct, setFetchedProduct] = useState<Product | null>(null);\r\n const displayProduct = initialProduct || fetchedProduct;\r\n const { results, loading: searchLoading, search } = useSearch({ type: 'vector' });\r\n const { messages, sources, loading: chatLoading, error: chatError, send } = useKiku();\r\n const [chatInput, setChatInput] = useState('');\r\n const [isMobile, setIsMobile] = useState(false);\r\n const [showSpecs, setShowSpecs] = useState(false);\r\n const [collapseSimilar, setCollapseSimilar] = useState(false);\r\n const chatBottomRef = useRef<HTMLDivElement>(null);\r\n const chatTextareaRef = useRef<HTMLTextAreaElement>(null);\r\n\r\n \r\n useEffect(() => {\r\n if (!initialProduct && !fetchedProduct) {\r\n client.api.searchVector(productName, 1)\r\n .then(res => {\r\n if (res.results && res.results.length > 0) {\r\n setFetchedProduct(res.results[0].entity);\r\n }\r\n })\r\n .catch(err => console.error('[Akropolys] Failed to fetch product details', err));\r\n }\r\n search(productName, limit);\r\n }, [productName, initialProduct, fetchedProduct, client, limit, search]);\r\n\r\n \r\n useEffect(() => {\r\n const handleResize = () => setIsMobile(window.innerWidth <= 768);\r\n handleResize();\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('resize', handleResize);\r\n return () => window.removeEventListener('resize', handleResize);\r\n }\r\n }, []);\r\n\r\n \r\n useEffect(() => { if (results.length > 0) onResult?.(results); }, [results, onResult]);\r\n\r\n \r\n useEffect(() => {\r\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\r\n document.addEventListener('keydown', h);\r\n return () => document.removeEventListener('keydown', h);\r\n }, [onClose]);\r\n\r\n const overlayRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n const prevOverflow = document.body.style.overflow;\r\n const prevPosition = document.body.style.position;\r\n const prevWidth = document.body.style.width;\r\n\r\n document.body.style.overflow = 'hidden';\r\n document.body.style.position = 'fixed';\r\n document.body.style.width = '100%';\r\n\r\n const handleScrollLock = () => {\r\n window.scrollTo(0, 0);\r\n if (overlayRef.current) overlayRef.current.scrollTop = 0;\r\n };\r\n\r\n window.addEventListener('scroll', handleScrollLock, { passive: true });\r\n\r\n return () => {\r\n document.body.style.overflow = prevOverflow;\r\n document.body.style.position = prevPosition;\r\n document.body.style.width = prevWidth;\r\n window.removeEventListener('scroll', handleScrollLock);\r\n };\r\n }, []);\r\n\r\n const chatBodyRef = useRef<HTMLDivElement>(null);\r\n\r\n \r\n useEffect(() => {\r\n if (chatBodyRef.current) {\r\n chatBodyRef.current.scrollTop = chatBodyRef.current.scrollHeight;\r\n }\r\n }, [messages, chatLoading]);\r\n\r\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '16px');\r\n const bg = backdropColor ?? undefined;\r\n\r\n const handleNav = (r: SearchResult) => {\r\n const prevent = onNavigate?.(r);\r\n if (prevent !== false) {\r\n onClose();\r\n if (r.entity.url) window.location.href = r.entity.url;\r\n }\r\n };\r\n\r\n const handleSend = async (text?: string) => {\r\n const q = (text ?? chatInput).trim();\r\n if (!q || chatLoading) return;\r\n setChatInput('');\r\n if (chatTextareaRef.current) {\r\n chatTextareaRef.current.style.height = 'auto';\r\n }\r\n\r\n if (messages.length === 0 && displayProduct) {\r\n const contextQuery = `[Context: Shopper is viewing \"${displayProduct.name}\". Price: ${displayProduct.price}. Description: ${displayProduct.description || ''}]\\n\\nQuestion: ${q}`;\r\n await send(contextQuery, q);\r\n } else {\r\n await send(q);\r\n }\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\r\n if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { e.preventDefault(); handleSend(); }\r\n };\r\n\r\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n setChatInput(e.target.value);\r\n const t = e.target;\r\n t.style.height = 'auto';\r\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\r\n };\r\n\r\n const customStyles = {\r\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\r\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\r\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\r\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\r\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\r\n } as React.CSSProperties;\r\n\r\n const displayMessages = messages.length === 0 && displayProduct\r\n ? [\r\n {\r\n role: 'assistant' as const,\r\n content: `Hi! I can help you with **${displayProduct.name}**. Ask me about its specifications, features, compare it with other options, or find alternatives!`,\r\n },\r\n ]\r\n : messages;\r\n\r\n if (isMobile) {\r\n return (\r\n <div\r\n ref={overlayRef}\r\n className={cn(\"hsk-sp-backdrop hsk-sp-mobile-view\", classNames.backdrop)}\r\n onClick={onClose}\r\n style={{\r\n backdropFilter: `blur(${blurVal})`,\r\n WebkitBackdropFilter: `blur(${blurVal})`,\r\n background: bg ?? undefined,\r\n ...customStyles,\r\n }}\r\n >\r\n <div className={cn(\"hsk-sp-card hsk-sp-fullscreen hsk-sp-mobile-card\", classNames.card)} onClick={e => e.stopPropagation()}>\r\n {}\r\n <div className=\"hsk-sp-header\">\r\n <span className=\"hsk-sp-header-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </span>\r\n <div className=\"hsk-sp-header-body\">\r\n <div className=\"hsk-sp-header-title-row\">\r\n <div className=\"hsk-sp-header-title\">{displayProduct?.name || productName}</div>\r\n {displayProduct && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-sp-header-specs-btn\"\r\n onClick={() => setShowSpecs(true)}\r\n >\r\n Specs\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"hsk-sp-header-sub\">kiku</div>\r\n </div>\r\n <button className=\"hsk-sp-close\" onClick={onClose} aria-label=\"Close\">\r\n <CloseIcon />\r\n </button>\r\n </div>\r\n\r\n {searchLoading && <div className=\"hsk-sp-bar\" />}\r\n\r\n {}\r\n <div className=\"hsk-sp-mobile-chat-container\">\r\n <div className=\"hsk-cb-msgs\">\r\n {displayMessages.map((msg, idx) => {\r\n const isUser = msg.role === 'user';\r\n return (\r\n <div key={idx} className=\"hsk-cb-msg-group\">\r\n {isUser ? (\r\n <div className=\"hsk-cb-user-msg\">\r\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\r\n </div>\r\n ) : (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\r\n\r\n {}\r\n {idx === 0 && displayProduct && (\r\n <div className=\"hsk-sp-mobile-attachment-deck\">\r\n {}\r\n <div className=\"hsk-sp-mobile-main-card\">\r\n <div className=\"hsk-sp-mobile-main-card-img\">\r\n {displayProduct.images?.[0] ? (\r\n <img src={displayProduct.images[0]} alt={displayProduct.name} />\r\n ) : (\r\n <span>ðŸ›</span>\r\n )}\r\n </div>\r\n <div className=\"hsk-sp-mobile-main-card-info\">\r\n <div className=\"hsk-sp-mobile-main-card-brand\">\r\n {displayProduct.brand || displayProduct.category || 'Product'}\r\n </div>\r\n <div className=\"hsk-sp-mobile-main-card-name\">{displayProduct.name}</div>\r\n <div className=\"hsk-sp-mobile-main-card-price\">\r\n {displayProduct.currency ?? 'KES'} {parseFloat(displayProduct.price?.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </div>\r\n </div>\r\n {((displayProduct.specs && Object.keys(displayProduct.specs).length > 0) || displayProduct.description) && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-sp-mobile-main-card-specs-btn\"\r\n onClick={() => setShowSpecs(true)}\r\n >\r\n Specs\r\n </button>\r\n )}\r\n </div>\r\n\r\n {}\r\n {(() => {\r\n const similarProducts = results.filter(\r\n r => {\r\n const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());\r\n const isSameSlug = r.entity.slug && displayProduct?.slug && r.entity.slug.toLowerCase() === displayProduct.slug.toLowerCase();\r\n return !isSameName && !isSameSlug;\r\n }\r\n );\r\n\r\n if (similarProducts.length === 0) return null;\r\n\r\n return (\r\n <div className=\"hsk-sp-mobile-similar-carousel-inline\">\r\n <div className=\"hsk-sp-mobile-similar-carousel-title\">Similar Products</div>\r\n <div className=\"hsk-sp-mobile-similar-carousel-list\">\r\n {similarProducts.map((r) => {\r\n const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, '') || '0');\r\n const currency = r.entity.currency ?? 'KES';\r\n return (\r\n <div\r\n key={r.id}\r\n className=\"hsk-sp-mobile-similar-carousel-item\"\r\n onClick={() => handleNav(r)}\r\n >\r\n <div className=\"hsk-sp-mobile-similar-carousel-img\">\r\n {r.entity.images?.[0] ? (\r\n <img src={r.entity.images[0]} alt={r.entity.name} />\r\n ) : (\r\n <span>ðŸ›</span>\r\n )}\r\n </div>\r\n <div className=\"hsk-sp-mobile-similar-carousel-meta\">\r\n <div className=\"hsk-sp-mobile-similar-carousel-name\" title={r.entity.name}>\r\n {r.entity.name}\r\n </div>\r\n <div className=\"hsk-sp-mobile-similar-carousel-price\">\r\n {currency} {price.toLocaleString()}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n })()}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n\r\n {chatLoading && (\r\n <div className=\"hsk-cb-typing-row\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-typing\">\r\n <div className=\"hsk-cb-dot\" />\r\n <div className=\"hsk-cb-dot\" />\r\n <div className=\"hsk-cb-dot\" />\r\n </div>\r\n </div>\r\n )}\r\n\r\n {chatError && <div className=\"hsk-cb-error\">{getFriendlyError(chatError)}</div>}\r\n <div ref={chatBottomRef} style={{ height: 1 }} />\r\n </div>\r\n\r\n <div className=\"hsk-cb-input-wrap\">\r\n <div className=\"hsk-cb-input-box\">\r\n <textarea\r\n ref={chatTextareaRef}\r\n className=\"hsk-cb-textarea\"\r\n value={chatInput}\r\n onChange={handleInput}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"Ask about this product, specs, or comparison...\"\r\n rows={1}\r\n disabled={chatLoading}\r\n />\r\n <button\r\n className=\"hsk-cb-send\"\r\n onClick={() => handleSend()}\r\n disabled={!chatInput.trim() || chatLoading}\r\n aria-label=\"Send message\"\r\n >\r\n <ArrowUpIcon />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {}\r\n {showSpecs && displayProduct && (\r\n <div className=\"hsk-sp-mobile-specs-overlay\" onClick={() => setShowSpecs(false)}>\r\n <div className=\"hsk-sp-mobile-specs-drawer\" onClick={e => e.stopPropagation()}>\r\n <div className=\"hsk-sp-mobile-specs-header\">\r\n <h3>Specifications</h3>\r\n <button type=\"button\" onClick={() => setShowSpecs(false)}>Close</button>\r\n </div>\r\n <div className=\"hsk-sp-mobile-specs-body\">\r\n <h4 className=\"hsk-sp-mobile-specs-title\">{displayProduct.name}</h4>\r\n {displayProduct.description && (\r\n <div className=\"hsk-sp-mobile-specs-desc\">\r\n <h5>Description</h5>\r\n <p>{displayProduct.description}</p>\r\n </div>\r\n )}\r\n {displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && (\r\n <div className=\"hsk-sp-mobile-specs-list\">\r\n <h5>Details</h5>\r\n {Object.entries(displayProduct.specs).map(([key, val]) => (\r\n <div key={key} className=\"hsk-sp-mobile-spec-row\">\r\n <span className=\"hsk-sp-mobile-spec-label\">{key}</span>\r\n <span className=\"hsk-sp-mobile-spec-value\">{val}</span>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={cn(\"hsk-sp-backdrop\", classNames.backdrop)}\r\n onClick={onClose}\r\n style={{\r\n backdropFilter: `blur(${blurVal})`,\r\n WebkitBackdropFilter: `blur(${blurVal})`,\r\n background: bg ?? undefined,\r\n ...customStyles,\r\n }}\r\n >\r\n <div className={cn(\"hsk-sp-card hsk-sp-fullscreen\", classNames.card)} onClick={e => e.stopPropagation()}>\r\n <div className=\"hsk-sp-header\">\r\n <span className=\"hsk-sp-header-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </span>\r\n <div className=\"hsk-sp-header-body\">\r\n <div className=\"hsk-sp-header-title\">{displayProduct?.name || productName}</div>\r\n <div className=\"hsk-sp-header-sub\">Ask questions, compare specs, or check similar products</div>\r\n </div>\r\n <button className=\"hsk-sp-close\" onClick={onClose} aria-label=\"Close\">\r\n <CloseIcon />\r\n </button>\r\n </div>\r\n\r\n {searchLoading && <div className=\"hsk-sp-bar\" />}\r\n\r\n {}\r\n <div className=\"hsk-sp-body\">\r\n {}\r\n <div className=\"hsk-sp-details-pane\">\r\n {displayProduct && (\r\n <div className=\"hsk-sp-product-profile-container\">\r\n <div className=\"hsk-sp-product-profile\">\r\n <div className=\"hsk-sp-details-imgwrap\">\r\n {displayProduct.images?.[0] ? (\r\n <img src={displayProduct.images[0]} alt={displayProduct.name} />\r\n ) : (\r\n <span className=\"hsk-sp-img-placeholder\">ðŸ›</span>\r\n )}\r\n </div>\r\n <div className=\"hsk-sp-details-meta\">\r\n {displayProduct.brand && <span className=\"hsk-sp-item-brand\">{displayProduct.brand}</span>}\r\n {displayProduct.category && <span className=\"hsk-sp-item-cat\">{displayProduct.category}</span>}\r\n <h2 className=\"hsk-sp-details-name\">{displayProduct.name}</h2>\r\n <div className=\"hsk-sp-item-price-row\">\r\n <span className=\"hsk-sp-item-currency\">{displayProduct.currency ?? 'KES'}</span>\r\n <span className=\"hsk-sp-item-price\">{parseFloat(displayProduct.price?.replace(/[^0-9.]/g, '') || '0').toLocaleString()}</span>\r\n {displayProduct.originalPrice && (\r\n <span className=\"hsk-sp-item-original-price\">\r\n {parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\r\n </span>\r\n )}\r\n {displayProduct.discount && (\r\n <span className=\"hsk-sp-item-discount\">({displayProduct.discount})</span>\r\n )}\r\n </div>\r\n\r\n <div className=\"hsk-sp-item-meta-badges\">\r\n {displayProduct.rating && (\r\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-rating\">\r\n ★ {parseFloat(displayProduct.rating.toString()).toFixed(1)} {displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ''}\r\n </span>\r\n )}\r\n {displayProduct.availability && (\r\n <span className={`hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes('in') ? 'in-stock' : 'out-stock'}`}>\r\n {displayProduct.availability}\r\n </span>\r\n )}\r\n {displayProduct.stock && !displayProduct.availability && (\r\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-stock\">\r\n Stock: {displayProduct.stock}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && (\r\n <div className=\"hsk-sp-specs-horizontal\">\r\n {Object.entries(displayProduct.specs).map(([key, val]) => (\r\n <div key={key} className=\"hsk-sp-spec-item-horizontal\">\r\n <span className=\"hsk-sp-spec-label-horizontal\">{key}:</span>\r\n <span className=\"hsk-sp-spec-value-horizontal\" title={val}>{val}</span>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {displayProduct.description && (\r\n <div className=\"hsk-sp-details-desc\">\r\n <h4>Description</h4>\r\n <p>{displayProduct.description}</p>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {}\r\n <div className=\"hsk-sp-similar-section\">\r\n <h3>Similar Products</h3>\r\n <div className=\"hsk-sp-results\">\r\n {(() => {\r\n const similarProducts = results.filter(\r\n r => {\r\n const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());\r\n const isSameSlug = r.entity.slug && displayProduct?.slug && r.entity.slug.toLowerCase() === displayProduct.slug.toLowerCase();\r\n return !isSameName && !isSameSlug;\r\n }\r\n );\r\n\r\n if (!searchLoading && similarProducts.length === 0) {\r\n return <div className=\"hsk-sp-empty\">No similar products found.</div>;\r\n }\r\n\r\n return similarProducts.map((r, i) => {\r\n const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, '') || '0');\r\n const currency = r.entity.currency ?? 'KES';\r\n return (\r\n <div\r\n key={r.id}\r\n className={cn(\"hsk-sp-item\", classNames.item)}\r\n style={{ animationDelay: `${i * 55}ms`, cursor: 'pointer' }}\r\n onClick={() => handleNav(r)}\r\n >\r\n <div className=\"hsk-sp-img-wrap\">\r\n {r.entity.images?.[0] ? (\r\n <img src={r.entity.images[0]} alt={r.entity.name} />\r\n ) : (\r\n <span className=\"hsk-sp-img-placeholder\">ðŸ›</span>\r\n )}\r\n </div>\r\n <div className=\"hsk-sp-item-body\">\r\n <div>\r\n {r.entity.category && (\r\n <div className=\"hsk-sp-item-cat\">{r.entity.category}</div>\r\n )}\r\n <div className=\"hsk-sp-item-name\" title={r.entity.name}>{r.entity.name}</div>\r\n </div>\r\n <div className=\"hsk-sp-item-price-row\">\r\n <span className=\"hsk-sp-item-currency\">{currency}</span>\r\n <span className=\"hsk-sp-item-price\">{price.toLocaleString()}</span>\r\n </div>\r\n <div className=\"hsk-sp-actions\">\r\n <button\r\n className=\"hsk-sp-action hsk-sp-action-primary\"\r\n onClick={(e) => { e.stopPropagation(); handleNav(r); }}\r\n >\r\n View\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n });\r\n })()}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {}\r\n <div className=\"hsk-sp-chat-pane\">\r\n <div className=\"hsk-cb-msgs\">\r\n {displayMessages.map((msg, idx) => {\r\n const isUser = msg.role === 'user';\r\n return (\r\n <div key={idx} className=\"hsk-cb-msg-group\">\r\n {isUser ? (\r\n <div className=\"hsk-cb-user-msg\">\r\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\r\n </div>\r\n ) : (\r\n <div className=\"hsk-cb-ai-msg\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-ai-body\">\r\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n })}\r\n\r\n {chatLoading && (\r\n <div className=\"hsk-cb-typing-row\">\r\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\r\n <SparkleIcon />\r\n </div>\r\n <div className=\"hsk-cb-typing\">\r\n <div className=\"hsk-cb-dot\" />\r\n <div className=\"hsk-cb-dot\" />\r\n <div className=\"hsk-cb-dot\" />\r\n </div>\r\n </div>\r\n )}\r\n\r\n {chatError && <div className=\"hsk-cb-error\">{getFriendlyError(chatError)}</div>}\r\n <div ref={chatBottomRef} style={{ height: 1 }} />\r\n </div>\r\n\r\n <div className=\"hsk-cb-input-wrap\">\r\n <div className=\"hsk-cb-input-box\">\r\n <textarea\r\n ref={chatTextareaRef}\r\n className=\"hsk-cb-textarea\"\r\n value={chatInput}\r\n onChange={handleInput}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"Ask about this product, specs, or comparison...\"\r\n rows={1}\r\n disabled={chatLoading}\r\n />\r\n <button\r\n className=\"hsk-cb-send\"\r\n onClick={() => handleSend()}\r\n disabled={!chatInput.trim() || chatLoading}\r\n aria-label=\"Send message\"\r\n >\r\n <ArrowUpIcon />\r\n </button>\r\n </div>\r\n <div className=\"hsk-cb-hint\">Akropolys · instant product knowledge</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div className=\"hsk-sp-footer\">\r\n <span className=\"hsk-sp-esc\">Esc to close</span>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport function Sparkle({\r\n productName,\r\n limit = 8,\r\n onResult,\r\n backdropColor,\r\n backdropBlur,\r\n className,\r\n onNavigate,\r\n theme,\r\n classNames = {},\r\n product,\r\n children,\r\n}: SparkleProps) {\r\n const [open, setOpen] = useState(false);\r\n const [mounted, setMounted] = useState(false);\r\n\r\n useEffect(() => { setMounted(true); }, []);\r\n\r\n const customStyles = {\r\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\r\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\r\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\r\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\r\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\r\n } as React.CSSProperties;\r\n\r\n return (\r\n <>\r\n <button\r\n className={cn(\"hsk-sp-btn\", classNames.button, className)}\r\n onClick={() => setOpen(true)}\r\n style={customStyles}\r\n title=\"Find similar products\"\r\n aria-label=\"Find similar products\"\r\n >\r\n {children || <SparkleIcon />}\r\n </button>\r\n {open && mounted && createPortal(\r\n <SparkleModal\r\n productName={productName}\r\n limit={limit}\r\n onResult={onResult}\r\n backdropColor={backdropColor}\r\n backdropBlur={backdropBlur}\r\n onClose={() => setOpen(false)}\r\n onNavigate={onNavigate}\r\n theme={theme}\r\n classNames={classNames}\r\n product={product}\r\n />,\r\n getShadowContainer() ?? document.body\r\n )}\r\n </>\r\n );\r\n}\r\n\r\n","import React, { useEffect, useState, useRef } from 'react';\r\nimport { createRoot } from 'react-dom/client';\r\nimport { AkropolysProvider, getAkropolysClient, ChatSource } from '@akropolys/sdk';\r\nimport { KikuButton } from './components/KikuButton';\r\n\r\nexport interface ShopifyProduct {\r\n id?: number | string;\r\n title?: string;\r\n name?: string;\r\n handle?: string;\r\n url?: string;\r\n price?: number | string;\r\n compare_at_price?: number | string;\r\n price_min?: number | string;\r\n featured_image?: string;\r\n images?: string[] | { src: string }[];\r\n image?: string;\r\n type?: string;\r\n product_type?: string;\r\n category?: string;\r\n vendor?: string;\r\n brand?: string;\r\n tags?: string[] | string;\r\n description?: string;\r\n body_html?: string;\r\n variants?: Array<{\r\n id: number | string;\r\n title?: string;\r\n price?: number | string;\r\n sku?: string;\r\n available?: boolean;\r\n }>;\r\n available?: boolean;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface StandaloneConfig {\r\n siteId?: string;\r\n apiToken?: string;\r\n apiUrl?: string;\r\n vertical?: string;\r\n shopperId?: string;\r\n theme?: 'dark' | 'light' | any;\r\n buttonLabel?: string;\r\n title?: string;\r\n placeholder?: string;\r\n defaultCurrency?: string;\r\n chips?: string[];\r\n enableVoice?: boolean;\r\n voiceLang?: string;\r\n enableVision?: boolean;\r\n visionCategoryHint?: string;\r\n enableAudioResponse?: boolean;\r\n ttsVoice?: string;\r\n autoSpeakResponses?: boolean;\r\n position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'inline' | 'hidden' | 'custom';\r\n containerId?: string;\r\n containerSelector?: string;\r\n dockable?: boolean;\r\n product?: ShopifyProduct;\r\n onAddToCart?: (items: ChatSource[]) => void;\r\n onAction?: (action: any) => void;\r\n [key: string]: any;\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n AkropolysConfig?: StandaloneConfig;\r\n Kiku?: {\r\n version: string;\r\n open: () => void;\r\n close: () => void;\r\n toggle: () => void;\r\n ingest: (product: ShopifyProduct) => Promise<void>;\r\n resetPosition: () => void;\r\n getClient: () => any;\r\n config: StandaloneConfig;\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Normalizes a Shopify product object into Akropolys entity format.\r\n */\r\nexport function normalizeShopifyProduct(p: ShopifyProduct): Record<string, any> {\r\n if (!p || typeof p !== 'object') return {};\r\n\r\n const id = String(p.id ?? p.handle ?? p.url ?? '');\r\n const title = p.title || p.name || '';\r\n \r\n let priceStr: string | undefined;\r\n if (typeof p.price === 'number') {\r\n priceStr = p.price >= 100 && Number.isInteger(p.price) \r\n ? (p.price / 100).toFixed(2) \r\n : p.price.toString();\r\n } else if (typeof p.price === 'string') {\r\n priceStr = p.price;\r\n }\r\n\r\n let image = p.featured_image || p.image;\r\n if (!image && Array.isArray(p.images) && p.images.length > 0) {\r\n const first = p.images[0];\r\n image = typeof first === 'string' ? first : first?.src;\r\n }\r\n if (typeof image === 'string' && image.startsWith('//')) {\r\n image = 'https:' + image;\r\n }\r\n\r\n let url = p.url || '';\r\n if (!url && p.handle) {\r\n url = `/products/${p.handle}`;\r\n }\r\n if (url && typeof window !== 'undefined' && !url.startsWith('http')) {\r\n try {\r\n url = new URL(url, window.location.origin).href;\r\n } catch {\r\n // keep relative if URL parsing fails\r\n }\r\n }\r\n\r\n const category = p.type || p.product_type || p.category || '';\r\n const brand = p.vendor || p.brand || '';\r\n \r\n const tags = Array.isArray(p.tags) \r\n ? p.tags \r\n : typeof p.tags === 'string' \r\n ? p.tags.split(',').map(t => t.trim()).filter(Boolean)\r\n : [];\r\n\r\n const rawDescription = p.description || p.body_html || '';\r\n const cleanDescription = typeof rawDescription === 'string' \r\n ? rawDescription.replace(/<[^>]*>?/gm, '').trim()\r\n : '';\r\n\r\n const defaultVariant = Array.isArray(p.variants) && p.variants.length > 0 ? p.variants[0] : null;\r\n const variantId = defaultVariant ? defaultVariant.id : undefined;\r\n\r\n return {\r\n id,\r\n name: title,\r\n title,\r\n price: priceStr,\r\n image,\r\n url: url || (typeof window !== 'undefined' ? window.location.href : ''),\r\n category,\r\n brand,\r\n tags,\r\n description: cleanDescription,\r\n availability: p.available !== false ? 'in_stock' : 'out_of_stock',\r\n variant_id: variantId ? String(variantId) : undefined,\r\n shopify_product_id: p.id ? String(p.id) : undefined,\r\n handle: p.handle || undefined,\r\n };\r\n}\r\n\r\n/**\r\n * Native Shopify Cart Integration.\r\n */\r\nexport function shopifyAddToCart(items: ChatSource[]): Promise<any> {\r\n if (!items || items.length === 0) return Promise.resolve();\r\n\r\n const cartItems = items.map(item => {\r\n const variantId = item.fields?.variant_id || item.fields?.shopify_variant_id || item.id;\r\n return {\r\n id: variantId,\r\n quantity: 1,\r\n };\r\n });\r\n\r\n return fetch('/cart/add.js', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json',\r\n },\r\n body: JSON.stringify({ items: cartItems }),\r\n })\r\n .then(async res => {\r\n if (!res.ok) {\r\n console.warn('[Akropolys Shopify] /cart/add.js returned error status:', res.status);\r\n }\r\n const data = await res.json().catch(() => null);\r\n \r\n if (typeof document !== 'undefined') {\r\n document.dispatchEvent(new CustomEvent('cart:updated', { bubbles: true, detail: { items: data } }));\r\n document.dispatchEvent(new CustomEvent('cart:refresh', { bubbles: true, detail: { items: data } }));\r\n document.dispatchEvent(new CustomEvent('cart:build', { bubbles: true }));\r\n window.dispatchEvent(new CustomEvent('cart:updated', { detail: { items: data } }));\r\n }\r\n return data;\r\n })\r\n .catch(err => {\r\n console.warn('[Akropolys Shopify] Add to cart network error:', err);\r\n });\r\n}\r\n\r\n/**\r\n * Native Shopify Get Cart.\r\n */\r\nexport function shopifyGetCart(): Promise<any> {\r\n return fetch('/cart.js', {\r\n headers: { 'Accept': 'application/json' },\r\n })\r\n .then(res => (res.ok ? res.json() : null))\r\n .catch(() => null);\r\n}\r\n\r\n/**\r\n * Draggable and Dockable container for Kiku floating launcher button.\r\n */\r\nfunction DraggableDockWrapper({\r\n children,\r\n position = 'bottom-right',\r\n dockable = true,\r\n isInline = false,\r\n}: {\r\n children: React.ReactNode;\r\n position?: StandaloneConfig['position'];\r\n dockable?: boolean;\r\n isInline?: boolean;\r\n}) {\r\n if (isInline || position === 'inline' || position === 'custom' || position === 'hidden' || dockable === false) {\r\n return (\r\n <div className=\"akropolys-kiku-inline-wrapper\" style={{ display: 'inline-flex', alignItems: 'center' }}>\r\n {children}\r\n </div>\r\n );\r\n }\r\n\r\n const [coords, setCoords] = useState<{ x: number; y: number } | null>(null);\r\n const [isDragging, setIsDragging] = useState(false);\r\n const dragStartRef = useRef<{ startX: number; startY: number; initX: number; initY: number; moved: boolean } | null>(null);\r\n const wrapperRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const computeDefault = () => {\r\n const margin = 20;\r\n const btnWidth = 140;\r\n const btnHeight = 44;\r\n let defX = window.innerWidth - btnWidth - margin;\r\n let defY = window.innerHeight - btnHeight - margin;\r\n\r\n if (position === 'bottom-left') {\r\n defX = margin;\r\n defY = window.innerHeight - btnHeight - margin;\r\n } else if (position === 'top-right') {\r\n defX = window.innerWidth - btnWidth - margin;\r\n defY = margin;\r\n } else if (position === 'top-left') {\r\n defX = margin;\r\n defY = margin;\r\n }\r\n\r\n try {\r\n const saved = localStorage.getItem('akropolys_dock_pos');\r\n if (saved) {\r\n const parsed = JSON.parse(saved);\r\n if (typeof parsed.x === 'number' && typeof parsed.y === 'number') {\r\n const clampedX = Math.max(10, Math.min(window.innerWidth - 60, parsed.x));\r\n const clampedY = Math.max(10, Math.min(window.innerHeight - 60, parsed.y));\r\n return { x: clampedX, y: clampedY };\r\n }\r\n }\r\n } catch {}\r\n\r\n return { x: Math.max(10, defX), y: Math.max(10, defY) };\r\n };\r\n\r\n setCoords(computeDefault());\r\n\r\n const onResize = () => {\r\n setCoords(prev => {\r\n if (!prev) return computeDefault();\r\n const clampedX = Math.max(10, Math.min(window.innerWidth - 60, prev.x));\r\n const clampedY = Math.max(10, Math.min(window.innerHeight - 60, prev.y));\r\n return { x: clampedX, y: clampedY };\r\n });\r\n };\r\n\r\n window.addEventListener('resize', onResize);\r\n return () => window.removeEventListener('resize', onResize);\r\n }, [position]);\r\n\r\n const onPointerDown = (e: React.PointerEvent) => {\r\n if (!wrapperRef.current) return;\r\n const rect = wrapperRef.current.getBoundingClientRect();\r\n dragStartRef.current = {\r\n startX: e.clientX,\r\n startY: e.clientY,\r\n initX: rect.left,\r\n initY: rect.top,\r\n moved: false,\r\n };\r\n try {\r\n (e.target as HTMLElement).setPointerCapture?.(e.pointerId);\r\n } catch {}\r\n };\r\n\r\n const onPointerMove = (e: React.PointerEvent) => {\r\n if (!dragStartRef.current) return;\r\n const dx = e.clientX - dragStartRef.current.startX;\r\n const dy = e.clientY - dragStartRef.current.startY;\r\n if (!dragStartRef.current.moved && Math.hypot(dx, dy) > 6) {\r\n dragStartRef.current.moved = true;\r\n setIsDragging(true);\r\n }\r\n if (dragStartRef.current.moved) {\r\n const width = wrapperRef.current?.offsetWidth || 140;\r\n const height = wrapperRef.current?.offsetHeight || 44;\r\n const newX = Math.max(8, Math.min(window.innerWidth - width - 8, dragStartRef.current.initX + dx));\r\n const newY = Math.max(8, Math.min(window.innerHeight - height - 8, dragStartRef.current.initY + dy));\r\n setCoords({ x: newX, y: newY });\r\n }\r\n };\r\n\r\n const onPointerUp = () => {\r\n if (!dragStartRef.current) return;\r\n const hadMoved = dragStartRef.current.moved;\r\n dragStartRef.current = null;\r\n setIsDragging(false);\r\n\r\n if (hadMoved && coords) {\r\n try {\r\n localStorage.setItem('akropolys_dock_pos', JSON.stringify(coords));\r\n } catch {}\r\n\r\n const clickCapturer = (ev: MouseEvent) => {\r\n ev.stopPropagation();\r\n ev.preventDefault();\r\n window.removeEventListener('click', clickCapturer, true);\r\n };\r\n window.addEventListener('click', clickCapturer, true);\r\n setTimeout(() => window.removeEventListener('click', clickCapturer, true), 120);\r\n }\r\n };\r\n\r\n if (!coords) return null;\r\n\r\n return (\r\n <div\r\n ref={wrapperRef}\r\n className=\"akropolys-kiku-dock-wrapper\"\r\n onPointerDown={onPointerDown}\r\n onPointerMove={onPointerMove}\r\n onPointerUp={onPointerUp}\r\n onPointerCancel={onPointerUp}\r\n title=\"Drag to dock anywhere\"\r\n style={{\r\n position: 'fixed',\r\n left: `${coords.x}px`,\r\n top: `${coords.y}px`,\r\n zIndex: 2147483640,\r\n touchAction: 'none',\r\n cursor: isDragging ? 'grabbing' : 'grab',\r\n transition: isDragging ? 'none' : 'transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease',\r\n transform: isDragging ? 'scale(1.05)' : 'scale(1)',\r\n userSelect: 'none',\r\n WebkitUserSelect: 'none',\r\n }}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nfunction StandaloneKikuApp({ config, isInline }: { config: StandaloneConfig; isInline: boolean }) {\r\n useEffect(() => {\r\n const client = getAkropolysClient();\r\n if (!client) return;\r\n\r\n let prod = config.product;\r\n if (!prod && typeof (window as any).meta?.product === 'object') {\r\n prod = (window as any).meta.product;\r\n }\r\n\r\n if (prod) {\r\n const normalized = normalizeShopifyProduct(prod);\r\n if (normalized.id || normalized.url) {\r\n client.ingest(normalized).catch((err) => {\r\n console.debug('[Akropolys Shopify] Auto-ingest notice:', err);\r\n });\r\n }\r\n }\r\n }, [config.product]);\r\n\r\n const defaultOnAddToCart = (items: ChatSource[]) => {\r\n if (config.onAddToCart) {\r\n config.onAddToCart(items);\r\n return;\r\n }\r\n shopifyAddToCart(items);\r\n };\r\n\r\n return (\r\n <AkropolysProvider\r\n siteId={config.siteId}\r\n apiUrl={config.apiUrl}\r\n apiToken={config.apiToken}\r\n vertical={config.vertical || 'commerce'}\r\n shopperId={config.shopperId}\r\n onAddToCart={defaultOnAddToCart}\r\n onAction={config.onAction}\r\n getCart={shopifyGetCart}\r\n >\r\n <DraggableDockWrapper\r\n position={config.position}\r\n dockable={config.dockable !== false}\r\n isInline={isInline}\r\n >\r\n <KikuButton\r\n label={config.buttonLabel || 'Ask Kiku'}\r\n title={config.title || 'kiku'}\r\n placeholder={config.placeholder}\r\n defaultCurrency={config.defaultCurrency || '$'}\r\n chips={config.chips}\r\n theme={config.theme || 'dark'}\r\n enableVoice={config.enableVoice !== false}\r\n voiceLang={config.voiceLang}\r\n enableVision={config.enableVision !== false}\r\n visionCategoryHint={config.visionCategoryHint}\r\n enableAudioResponse={config.enableAudioResponse !== false}\r\n ttsVoice={config.ttsVoice || 'Puck'}\r\n autoSpeakResponses={config.autoSpeakResponses !== false}\r\n />\r\n </DraggableDockWrapper>\r\n </AkropolysProvider>\r\n );\r\n}\r\n\r\n/**\r\n * Attaches global click listeners for any element with [data-kiku-open] or [data-kiku-toggle]\r\n */\r\nfunction setupGlobalTriggers() {\r\n if (typeof document === 'undefined') return;\r\n\r\n document.addEventListener('click', (e) => {\r\n const target = e.target as HTMLElement | null;\r\n const trigger = target?.closest('[data-kiku-open], [data-kiku-toggle], .kiku-trigger');\r\n if (trigger) {\r\n e.preventDefault();\r\n window.Kiku?.open();\r\n }\r\n });\r\n}\r\n\r\nexport function initKiku(customConfig?: StandaloneConfig): void {\r\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\r\n\r\n let scriptConfig: Partial<StandaloneConfig> = {};\r\n const scriptTag = document.getElementById('akropolys-kiku-script') as HTMLScriptElement | null;\r\n if (scriptTag) {\r\n const ds = scriptTag.dataset;\r\n scriptConfig = {\r\n siteId: ds.siteId,\r\n apiToken: ds.apiToken,\r\n apiUrl: ds.apiUrl,\r\n theme: ds.theme as any,\r\n buttonLabel: ds.buttonLabel,\r\n position: ds.position as any,\r\n containerId: ds.containerId,\r\n containerSelector: ds.containerSelector,\r\n dockable: ds.dockable !== 'false',\r\n enableVoice: ds.enableVoice === 'true' || ds.enableVoice === '1',\r\n enableVision: ds.enableVision === 'true' || ds.enableVision === '1',\r\n };\r\n }\r\n\r\n const mergedConfig: StandaloneConfig = {\r\n ...scriptConfig,\r\n ...(window.AkropolysConfig || {}),\r\n ...(customConfig || {}),\r\n };\r\n\r\n if (!mergedConfig.siteId || !mergedConfig.apiToken) {\r\n console.warn(\r\n '[Akropolys] Missing siteId or apiToken. Configure window.AkropolysConfig = { siteId: \"...\", apiToken: \"...\" }'\r\n );\r\n }\r\n\r\n // Determine container and mounting mode\r\n let container: HTMLElement | null = null;\r\n let isInline = false;\r\n\r\n if (mergedConfig.containerSelector) {\r\n container = document.querySelector(mergedConfig.containerSelector);\r\n if (container) isInline = true;\r\n }\r\n if (!container && mergedConfig.containerId) {\r\n container = document.getElementById(mergedConfig.containerId);\r\n if (container) isInline = true;\r\n }\r\n if (!container) {\r\n container = document.getElementById('kiku-mount') || document.querySelector('[data-kiku-mount]');\r\n if (container) isInline = true;\r\n }\r\n\r\n // If no custom inline container was provided and not positioned inline, create floating host\r\n if (!container) {\r\n container = document.createElement('div');\r\n container.id = 'akropolys-kiku-host';\r\n document.body.appendChild(container);\r\n }\r\n\r\n const root = createRoot(container);\r\n root.render(<StandaloneKikuApp config={mergedConfig} isInline={isInline} />);\r\n\r\n setupGlobalTriggers();\r\n\r\n window.Kiku = {\r\n version: '1.7.19',\r\n open: () => {\r\n const btn = document.querySelector('.hsk-cb-btn') as HTMLButtonElement | null;\r\n btn?.click();\r\n },\r\n close: () => {\r\n const closeBtn = document.querySelector('.hsk-cb-topbar-btn[aria-label=\"Close\"]') as HTMLButtonElement | null;\r\n closeBtn?.click();\r\n },\r\n toggle: () => {\r\n const modal = document.querySelector('.hsk-cb-overlay');\r\n if (modal) {\r\n window.Kiku?.close();\r\n } else {\r\n window.Kiku?.open();\r\n }\r\n },\r\n resetPosition: () => {\r\n try {\r\n localStorage.removeItem('akropolys_dock_pos');\r\n window.location.reload();\r\n } catch {}\r\n },\r\n ingest: async (product: ShopifyProduct) => {\r\n const client = getAkropolysClient();\r\n if (client && product) {\r\n const normalized = normalizeShopifyProduct(product);\r\n await client.ingest(normalized);\r\n }\r\n },\r\n getClient: () => getAkropolysClient(),\r\n config: mergedConfig,\r\n };\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n const shouldAutoInit = () => {\r\n return Boolean(\r\n window.AkropolysConfig ||\r\n document.getElementById('akropolys-kiku-script') ||\r\n document.getElementById('kiku-mount') ||\r\n document.querySelector('[data-kiku-mount]')\r\n );\r\n };\r\n\r\n const autoRun = () => {\r\n if (shouldAutoInit()) initKiku();\r\n };\r\n\r\n if (document.readyState === 'loading') {\r\n document.addEventListener('DOMContentLoaded', autoRun);\r\n } else {\r\n setTimeout(autoRun, 0);\r\n }\r\n}\r\n"],"mappings":"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","names":["useState","useEffect","useRef","useSearch","useAkropolysContext","r","f","n","clsx","cn","inputs","clsx","Fragment","jsx","jsxs","SearchIcon","SearchBar","placeholder","limit","debounceMs","onSelect","className","inputClassName","dropdownClassName","renderResult","theme","classNames","query","setQuery","useState","open","setOpen","results","loading","search","clear","useSearch","client","useAkropolysContext","wrap","useRef","ignoreNextQueryChange","useEffect","h","e","handleSelect","r","handleCommitSearch","showDrop","customStyles","cn","i","thumb","useState","useRef","useEffect","useKiku","useAkropolysContext","resolveDisplayFields","React","Fragment","jsx","jsxs","SPACING_DOUBLE_REGEX","SPACING_PUNCT_REGEX","SPACING_OPEN_PAREN_REGEX","SPACING_CLOSE_PAREN_REGEX","SPACING_UNIT_REGEX","TOKEN_SPLIT_REGEX","IMAGE_PARSE_REGEX","LINK_PARSE_REGEX","SAFE_IMG_REGEX","SAFE_LINK_REGEX","MEMORY_LINK_FILTER_REGEX","MEMORY_URL_FILTER_REGEX","normalizeSpacing","text","parseInline","keyPrefix","part","index","key","imageMatch","alt","url","e","linkMatch","linkText","isTableLine","line","inTable","t","splitTableCells","rowLine","c","TableWrapper","children","ref","scrollState","setScrollState","isDragging","setIsDragging","dragRef","checkScroll","el","rtl","travelled","atStart","atEnd","ro","onMouseDown","onMouseMove","walk","onMouseUp","renderMarkdown","content","streaming","buildMarkdown","lines","last","blocks","currentTextNodes","bubbleIndex","flushTextBubble","i","standaloneImageMatch","headerMatch","level","Tag","listItems","itemText","headerCells","rawBodyRows","alignments","isHeader","cell","trimmed","startColon","endColon","cells","colCount","r","finalAlignments","numericCount","val","headerRow","cIdx","bodyRows","rIdx","jsx","jsxs","ArrowUpIcon","resolveTheme","theme","vars","useCallback","useEffect","useRef","useCallback","useEffect","useRef","useState","ctx","analyser","duckGain","timeData","generation","speaking","smoothed","usingFallback","audio","AC","duckSpeech","level","fadeMs","g","now","speechLevel","t","sum","i","v","rms","stopSpeech","generation","speaking","duckGain","ctx","cleanTextForSpeech","text","SENTENCE_END","CHUNK_TARGET","chunkForSpeech","target","pieces","chunks","buf","piece","cut","c","playBuffer","a","gen","resolve","src","watchdog","speak","client","voice","language","bcp47","onStart","onEnd","onError","onRefused","onSecondsLeft","usingFallback","clean","audio","fallbackWebSpeech","synth","t","started","pending","i","result","decoded","e","pickVoice","tag","voices","want","base","candidates","v","loose","utterance","DEFAULT_SILENCE_MS","SPEECH_MARGIN","BARGE_IN_MS","ECHO_REJECT","DUCK_LEVEL","DUCK_FADE_MS","CONFIRM_MS","CONFIRM_FRAMES","MOD_WINDOW","W_ENERGY","W_MODULATION","W_BAND","DUCK_SCORE","useVoiceSession","lang","onUtterance","onError","onBargeIn","silenceMs","paused","active","setActive","useState","hearing","setHearing","interim","setInterim","supported","setSupported","recognitionRef","useRef","streamRef","audioCtxRef","analyserRef","rafRef","dataRef","levelRef","floorRef","lastLoudRef","loudSinceRef","transcriptRef","consumedRef","resultLenRef","activeRef","pausedRef","wantRestartRef","stoppingRef","onUtteranceRef","onErrorRef","onBargeInRef","useEffect","micLevel","useCallback","micSpectrum","out","a","spectrumBins","envRef","freqRef","duckedRef","duckAtRef","bargeEvidenceRef","voiceLikeness","rms","analyser","env","modulation","mean","v","variance","band","freq","per","lo","hi","inBand","total","i","energy","commit","text","r","monitor","data","sum","lvl","now","echo","speechLevel","duckSpeech","startRecognition","SR","recognition","event","code","stopRecognition","stop","t","start","stream","AC","ctx","e","id","alive","hearingSomething","jsx","jsxs","MicIcon","active","VoiceButton","onTranscript","onInterim","lang","className","disabled","onError","onTranscriptRef","useRef","useEffect","stopRef","handleUtterance","useCallback","text","voice","useVoiceSession","useRef","useState","approxBytesOfDataURL","dataURL","i","b64","downscaleImage","file","original","resolve","reject","reader","bitmap","scale","w","h","canvas","cx","keepPNG","out","useAkropolysContext","jsx","jsxs","CameraIcon","SpinnerIcon","fileToBase64","file","downscaleImage","VisualSearch","onResults","onError","categoryHint","className","disabled","client","inputRef","useRef","loading","setLoading","useState","handleFile","base64","res","e","Fragment","jsx","jsxs","SparkleIcon","SpeakerIcon","active","SourceCard","source","defaultCurrency","onSelect","isReferenced","cn","ChatWidget","title","placeholder","emptyStateText","emptyStateSuggestions","className","theme","classNames","onSelectSource","enableVoice","enableVision","visionCategoryHint","enableAudioResponse","ttsVoice","autoSpeakResponses","client","useAkropolysContext","messages","sources","referencedIds","chatLoading","streaming","error","send","reset","useKiku","input","setInput","useState","visualLoading","setVisualLoading","bottomRef","useRef","textareaRef","audioEnabled","setAudioEnabled","speakingMsgIndex","setSpeakingMsgIndex","prevStreamingRef","userInitiatedVoiceRef","loading","chatHistory","setChatHistory","lastSyncedCount","useEffect","newMsgs","prev","next","hookIdx","historyIdx","wasStreaming","spoken","lastMsgIndex","lastMsg","speak","handleSend","q","stopSpeech","handleKey","e","handleInput","t","handleSpeakToggle","idx","text","handleVisualResults","res","preview","userMsg","dna","content","results","assistantMsg","r","fields","d","resolveDisplayFields","customStyles","resolveTheme","msg","renderMarkdown","tag","ti","src","si","featured","general","parsed","VisualSearch","err","VoiceButton","ArrowUpIcon","useState","useEffect","useCallback","createPortal","cssText_default","CONTAINER_ID","container","shadow","applyStyles","root","sheet","cssText_default","style","getShadowContainer","useAkropolysContext","BASE_FONT","cachedBaseFont","client","hit","p","warmChrome","shopperLanguage","defaults","useEffect","MOUNTED","formatFor","url","ext","safeUrl","u","RANGE_SEGMENT","safeRange","r","parts","s","p","safeWeight","w","useMountedFaces","key","css","h","i","id","el","left","scriptFontCSS","font","f","useScriptFontFace","faces","preloadScriptFont","timeoutMs","fonts","loads","resolve","useHostFontFace","theme","family","urls","normal","bold","variable","weights","weight","raw","fmt","React","DEFAULT_CHIPS","LANGUAGE_CHOICES","endonymFor","lang","typed","l","hit","x","isRTLText","s","ch","code","LANGUAGE_METAS","formatLangName","str","trimmed","getLoadingMeta","k","v","rawName","nativeName","rtl","LIVE_VOICES","VOICE_STORAGE_KEY","DEFAULT_UI_STRINGS","UIStringsContext","key","vars","useT","extractName","raw","words","q","w","name","SERVER_ERROR_STRINGS","getFriendlyError","err","tr","code","SERVER_ERROR_STRINGS","str","lower","isSecureOrigin","KIKU_KEY_REVEAL_SECONDS","React","useState","useEffect","useRef","useCallback","useId","Fragment","jsx","jsxs","KikuIcon","className","size","tight","cn","SparkleIcon","StopIcon","ExternalIcon","jsxs","jsx","ContinueIcon","CloseIcon","ChevronLeftIcon","ChevronRightIcon","HistoryIcon","BookmarkIcon","TrashIcon","PlusIcon","jsx","PaperclipIcon","RetryIcon","className","size","jsxs","cn","EditIcon","CopyIcon","CheckIcon","MicIcon","MicOffIcon","WaveformIcon","active","ArrowUpIcon","SunIcon","MoonIcon","WoodIcon","HeartIcon","CoffeeIcon","StarIcon","XIcon","size","jsxs","jsx","PinIcon","className","filled","cn","THEMES","SunIcon","MoonIcon","WoodIcon","HeartIcon","CoffeeIcon","StarIcon","DEFAULT_DARK","DEFAULT_LIGHT","isThemeId","value","themeDef","id","useKiku","useScouts","subscribeLiveStream","useAkropolysContext","useEffect","useRef","rubberBand","offset","dimension","coeff","createSpring","stiffness","damping","onFrame","onRest","value","velocity","target","raf","last","tick","now","dt","steps","h","i","a","start","v","t","v0","useDragToDismiss","panel","scroller","onDismiss","quiescent","enabled","dismissRef","el","dragging","startY","startX","pointerId","lastY","lastT","decided","exiting","spring","host","atTop","s","onDown","e","onMove","dy","dx","raw","onUp","useEffect","useRef","useState","dist","a","b","pathLength","pts","n","i","bbox","minX","minY","maxX","maxY","p","clamp1000","v","norm","w","h","overlaps","ay0","ax0","ay1","ax1","by0","bx0","by1","bx1","iw","ih","smaller","union","classifyStroke","box","diag","len","endGap","straightness","buildMarkRegions","actions","width","height","strokes","texts","c","used","out","cur","j","jsx","jsxs","COLORS","MAX_EXPORT_DIM","MarkupEditor","src","onCancel","onSend","t","img","setImg","useState","loadError","setLoadError","tool","setTool","color","setColor","actions","setActions","pendingText","setPendingText","textValue","setTextValue","instruction","setInstruction","exportError","setExportError","canvasRef","useRef","drawingRef","textInputRef","useEffect","el","dims","scale","markLayer","paint","live","canvas","ctx","layer","lctx","all","a","p","i","toCanvasPoint","e","rect","strokeSize","textSize","onPointerDown","onPointerMove","onPointerUp","done","prev","commitText","handleSend","clean","cctx","dataUrl","drawn","buildMarkRegions","hasMarks","c","useCallback","useEffect","useId","useRef","useState","useScouts","useAkropolysContext","useEffect","useRef","Fragment","jsx","jsxs","SPECIES","bw","bh","_bw","SPECIES_IDS","s","speciesFor","id","avatar","chosen","h","i","MOOD","squircle","p","x","y","ScoutCharacter","scoutId","mood","size","layer","sp","moodRef","figRef","bodyRef","earRef","eyeLRef","eyeRRef","shineLRef","shineRRef","mouthRef","reduced","at","vel","seed","phase","blinkAt","blinkPhase","wander","wanderAt","hopDue","hopPhase","raf","spring","k","want","stiff","damp","frame","t","m","alive","lid","lift","breath","eye","shine","dir","el","sh","speciesName","speciesNick","jsx","jsxs","Digit","d","delay","n","AnimatedNumber","value","decimals","prefix","suffix","className","chars","digitsTotal","c","seen","i","fromRight","useEffect","useState","createPortal","jsx","jsxs","pinSupported","moodOf","scout","progress","num","v","n","start","target","pct","ScoutPin","scouts","themeAttr","onClose","pip","setPip","useState","useEffect","win","cancelled","style","cssText_default","live","s","createPortal","ScoutCharacter","speciesNick","Fragment","jsx","jsxs","MIN_MINUTES","MAX_MINUTES","readable","m","h","rest","RadarIcon","size","moodOf","scout","label","inst","head","speciesName","ScoutRail","className","themeAttr","onAsk","onNew","openProp","onOpenChange","client","useAkropolysContext","scouts","balance","setAvatar","cancelScout","useScouts","openState","setOpenState","useState","open","setOpen","useCallback","v","closing","setClosing","closeTimer","useRef","wrapRef","minutes","setMinutes","priceUSD","setPriceUSD","picked","setPicked","swapping","setSwapping","roster","setRoster","pinned","setPinned","dragging","setDragging","typing","setTyping","draft","setDraft","gooId","useId","idle","s","paidAvatars","waiting","visible","activeCount","hasScouts","sharing","pct","runway","close","useEffect","onDown","e","path","onKey","stale","t","q","beginDrag","commitTyped","cn","ScoutPin","pinSupported","sc","ScoutCharacter","SPECIES_IDS","id","AnimatedNumber","i","React","useEffect","useRef","jsx","hashSeed","s","h","i","mulberry32","seed","a","t","smooth","makeNoise","rng","lat","at","x","y","xi","yi","xf","yf","b","c","d","poisson","w","r","cell","gw","gh","grid","pts","active","place","fits","cx","cy","gy","gx","j","dx","dy","ai","px","py","placed","k","ang","rad","wob","motifs","ctx","cap","q","eave","belly","n","dir","l","drupes","ox","oy","side","ax","ay","off","lift","scribbles","nx","ny","turns","rr","lean","len","step","specks","o","accents","rgb","p","mix","A","B","getShimmerColor","normDist","isDarkMode","generateGlyphs","ink","tint","isRTL","themeId","accent","noise","area","raw","fa","fb","reach","angle","ca","sa","poleX","poleY","glyphs","maxDist","ir","ig","ib","roll","bloom","axis","isLightMode","alpha","baseColor","glyphSeed","shimmerColor","rotation","lineWidth","size","drawFn","alphaMul","renderDoodles","shimmerProgress","isShimmering","wavePos","waveWidth","g","stroke","lw","diff","surge","glyphRng","KikuDoodles","theme","ref","isAnimatingRef","animFrameRef","cachedGlyphsRef","lastWidthRef","cv","numeric","timer","tick","startTime","duration","now","elapsed","rawProgress","progress","dpr","targetW","targetH","updateCanvas","cs","fullScreenH","handleResize","ro","scheme","handleSchemeChange","KikuDoodles_default","React","useState","useEffect","useCallback","useAkropolysContext","locales_default","jsx","getBuiltinLocale","lang","l","key","locales_default","resolveFirstFamily","varRef","name","el","value","useScriptFont","shopperLanguage","theme","client","useAkropolysContext","chromeStrings","setChromeStrings","useState","chromeCurated","setChromeCurated","chromeReady","setChromeReady","dirKey","isRTL","setIsRTL","builtin","getLoadingMeta","speechLang","setSpeechLang","scriptFont","setScriptFont","baseFont","setBaseFont","useEffect","meta","lLower","needsWebFont","cancelled","res","DEFAULT_UI_STRINGS","prev","preloadScriptFont","f","cachedBaseFont","useScriptFontFace","fontStack","React","first","isVarRef","hostName","resolved","host","isNonLatin","latin","other","v","ch","c","fontEpoch","setFontEpoch","live","e","hostFontCovers","sample","text","ctx","hostFamily","withHost","withoutHost","t","useCallback","vars","s","k","tNode","part","i","m","useState","useRef","useEffect","useCallback","useChatScroll","messages","loading","messageRefs","msgsContainerRef","lastExternalScrollRef","showJumpToBottom","setShowJumpToBottom","scrollProgress","setScrollProgress","activeMsgIdx","setActiveMsgIdx","resyncScrollRef","glideScrollRef","touchScrollingRef","stickToBottomRef","alertTick","setAlertTick","awayEpochRef","lastAlertKeyRef","dismissJumpAlertRef","resetAlertArmingRef","el","idle","settle","onTouchStart","onScroll","JUMP_THRESHOLD","STICK_ON","queued","measure","distance","clearUnreadRef","max","line","active","i","node","ro","notifyNewBelow","turn","key","t","unreadBelow","setUnreadBelow","unreadBelowRef","markUnread","clearUnread","jumpAlert","setJumpAlert","jumpAlertRef","alertShownAtRef","clearAlert","resetAlertArming","dismissJumpAlert","jumpToMessage","idx","targetCenter","to","jumpToBottom","bottom","container","raf","before","LAMBDA","LINE_PX","step","snap","v","target","current","written","lastTime","rafId","write","resync","next","update","now","dt","handleWheel","e","scale","maxScroll","lastTop","handleScroll","external","useState","useEffect","useCallback","useAkropolysContext","useKikuKey","lastAction","retryLastMessage","client","useAkropolysContext","keyInput","setKeyInput","useState","keyPhase","setKeyPhase","mintedKey","setMintedKey","mintedPub","setMintedPub","copied","setCopied","keyCountdown","setKeyCountdown","KIKU_KEY_REVEAL_SECONDS","minting","setMinting","copyValue","useCallback","val","type","useEffect","t","s","handleUseExistingKey","pub","handleCreateKey","secret","publicId","useCallback","useChatCommands","attachments","setAttachments","setInput","send","defaultCurrency","t","handleKikuCapture","product","name","display","q","toSend","handleKikuCaptureAll","products","targets","p","names","handleKikuViewHistory","handleKikuDelete","useState","useCallback","useAkropolysContext","useCallback","useEffect","useRef","useState","INPUT_RATE","WORKLET_SRC","toBase64","buf","bytes","s","i","fromBase64","b64","bin","len","dataView","numSamples","float32","useLiveVoice","opts","state","setState","hearing","setHearing","sources","setSources","secondsLeft","setSecondsLeft","wsRef","ctxRef","streamRef","nodeRef","analyserRef","playAtRef","sourcesRef","outAnalyserRef","outGainRef","outRateRef","optsRef","readyRef","armCaptureRef","turnHeardRef","turnSaidRef","flushExchange","heard","said","chirp","beginCapture","arm","micLevel","a","d","sum","v","outbound","micSpectrum","out","spectrumBins","flushPlayback","g","ctx","now","src","enqueue","chunk","rate","at","stopHold","startHold","teardown","finalState","t","stop","attachWsHandlers","ws","abandoned","ev","f","hotReconnect","newVoice","oldWs","o","base","url","currentVoiceRef","start","AC","stream","e","track","inAnalyser","outGain","outAnalyser","blobUrl","node","curWs","srcNode","toVoicePhase","s","useVoiceController","voiceLang","speechLang","shopperLanguage","ttsVoice","handleSendUtterance","appendSpokenExchange","client","useAkropolysContext","voiceMode","setVoiceMode","useState","dictateState","setDictateState","voiceError","setVoiceError","voiceMuted","setVoiceMuted","voiceSecondsLeft","setVoiceSecondsLeft","voiceBlocked","setVoiceBlocked","liveVoiceName","setLiveVoiceName","stored","VOICE_STORAGE_KEY","LIVE_VOICES","v","chooseVoice","useCallback","name","voice","useVoiceSession","text","code","stopSpeech","apiUrl","siteId","token","kikuId","live","useLiveVoice","exchange","err","canConverse","startVoice","mode","isSecureOrigin","stopVoice","voicePhase","voiceConnecting","React","useEffect","useRef","jsx","jsxs","BODY","MOOD","HOP","hopAt","f","i","t0","s0","l0","t1","s1","l1","u","e","SLOTS","KEYS","clamp","v","a","b","side","x","y0","y1","bow","n","ym","xb","bodyPath","bw","bh","tr","br","rt","rb","p","y","k","ft","fb","NEUTRALS","POPS","RARE_SHADES","pickShade","current","options","s","toRGB","hex","rgbCSS","c","mix","base","tint","amount","MARBLE_PAPER","MARBLE_TINT","MARBLE_FLOOD","ALERT_SHADE","KikuAvatar","state","size","alert","theme","feminine","accessories","onImpact","triggerRef","stateRef","alertRef","isFeminine","showFlower","showLashes","showBlush","bodyRef","maskRef","figRef","decorRef","flowerGRef","cheeksGRef","lashesGRef","lashLRef","lashRRef","warmRef","contactRef","stop1Ref","stop2Ref","stop3Ref","marbleRefs","slotRefs","slotGRef","uid","onImpactRef","reduced","at","vel","slotAt","slotVel","blinkAt","blinkPhase","wander","wanderAt","raf","gooOn","hopDue","hopPhase","lean","leanVel","leanWant","leanAt","peek","peekVel","peekWant","peekAt","shade","deep","pale","deepWant","paleWant","DOUBLE_MS","lastHopAt","pendingEncore","singlesSince","queuedHop","now","puff","puffVel","wasAlert","nagDue","startHop","t","layout","lid","gx","gy","phase","out","eye","cx","dy","h","cycle","fuse","R","frame","shape","mood","facing","puffWant","breath","want","key","stiff","damp","squash","lift","splat","to","currentShade","deepCSS","paleCSS","baseWash","contactOpacity","lastSplat","wobble","bwF","bhF","d","wantGoo","targets","T","A","V","breathe","planted","tilt","shift","dip","flowerX","flowerY","flowerTilt","cheekY","isEyeFacing","lashes","cy","deg","len","th","sx","sy","ex","ey","cxp","cyp","offset","el","_","jsx","jsxs","ChatTopbar","title","hasMessages","avatarState","unread","awayFromBottom","themeMenuOpen","themeMenuClosing","isNarrow","currentTheme","onJumpToLatest","onReset","onClose","onToggleThemeMenu","onSelectTheme","tr","useT","isImpacting","setIsImpacting","React","impactColor","setImpactColor","impactGlow","setImpactGlow","triggerRef","longPressTimerRef","isLongPressRef","touchStartTimeRef","startPress","endPress","cancelPress","handleClick","e","handleImpact","splat","color","glow","jsxs","jsx","ChevronLeftIcon","cn","KikuAvatar","CloseIcon","THEMES","id","label","Icon","React","React","Fragment","jsx","jsxs","HSK_WORD_STAGGER_MS","plainText","node","segmentText","text","chunks","out","chunk","seg","segments","s","cascade","count","baseMs","keyPrefix","ci","delay","child","i","el","CascadeText","children","hash","prefix","jsx","jsxs","InkBloomSkeleton","lines","className","jsx","HSK_STAGGER_MS","HSK_FIELD_BASE_MS","JOINING_SCRIPT","splitPlaceholder","text","I","seg","s","AnimatedPlaceholder","placeholder","visible","replay","replaySeed","staggerMs","content","seed","units","last","unit","i","Fragment","jsx","jsxs","countShimmerUnits","node","splitPlaceholder","n","c","React","shimmerTree","cursor","last","baseIdx","unit","i","child","k","ShimmerText","text","OnboardingView","inOnboarding","justCompleted","onboardingMood","awaitingLang","awaitingName","awaitingEntityLang","awaitingConsent","termsAgreed","shopperLanguage","shopperName","entityLangPref","chromeReady","activeChips","t","tNode","chooseLanguage","chooseEntityLang","agreeTerms","handleSend","currentStep","displayShopperLang","endonymFor","countdown","setCountdown","timer","prev","CascadeText","LANGUAGE_CHOICES","l","InkBloomSkeleton","mode","cn","chip","React","useEffect","useState","describeAge","getLiveValue","isFresh","isStale","formatLiveValue","subscribeLiveValues","LIVE_FLASH_MS","jsx","jsxs","useLiveValues","keys","bump","joined","k","n","id","LiveQuoteCard","record","now","stale","fields","rawTitle","shortTitle","hasYesPrice","hasNoPrice","quotePills","volVal","closeDate","formattedClose","p","flash","LiveTable","seen","ordered","records","_","i","shown","r","useState","useEffect","useRef","jsx","jsxs","parseThinking","text","openMatch","openIdx","openTagLength","start","contentBefore","textAfterOpen","closeMatch","closeIdx","closeTagLength","ThinkingBlock","isComplete","fixedSeconds","tr","useT","startRef","useRef","seconds","setSeconds","useState","isOpen","setIsOpen","useEffect","t","finalSeconds","label","expandable","cn","o","useState","useRef","useEffect","useCallback","useAkropolysContext","Fragment","jsx","jsxs","SourceImg","src","alt","onImageClick","failed","setFailed","useState","SparkleIcon","e","SourcesCarousel","sources","defaultCurrency","onSelectSource","referencedIds","compact","isProperty","useAkropolysContext","railRef","useRef","showPrev","setShowPrev","showNext","setShowNext","activeIndex","setActiveIndex","display","s","measure","useCallback","el","travelled","maxScroll","idx","useEffect","ro","railStep","dir","rtl","scrollNext","scrollPrev","cn","ChevronLeftIcon","si","isReferenced","ChevronRightIcon","_","i","jsx","jsxs","SmartContextPills","intent","sources","onSend","loading","defaultCurrency","tr","useT","pills","cheapest","min","s","m","firstName","firstTwo","priceCeiling","nums","n","max","mag","rounded","short","ceiling","pill","Fragment","jsx","jsxs","MarkdownBlock","React","content","streaming","renderMarkdown","a","b","MessageItem","msg","idx","isLast","isLastUser","isRunEnd","runMid","runCont","isNarrow","loading","stopped","interrupted","sources","referencedIds","discussedSources","lastIntent","lastAction","defaultCurrency","vizState","setVizState","setLightboxSrc","setMarkupSrc","handleSend","handleSourceClick","onRetry","onEdit","onLongPress","hasError","retrying","t","messageRef","isUser","displayContent","copied","setCopied","touchStartPos","longPressTimer","startLongPress","targetEl","r","handleTouchStart","e","touch","handleTouchMove","handleTouchEnd","handleContextMenu","handleCopy","text","parsed","parseThinking","thinking","CALC_DISCLAIMER_REGEX","hasCalcDisclaimer","cleanContent","cn","img","i","MicIcon","RetryIcon","EditIcon","CheckIcon","CopyIcon","isComplete","ThinkingBlock","p","ref","LiveTable","n","msgReferencedIds","msgSources","msgIntent","hiddenIntent","SourcesCarousel","ExternalIcon","SmartContextPills","jsx","jsxs","PromptKeyCard","keyInput","setKeyInput","minting","handleUseExistingKey","handleCreateKey","t","SparkleIcon","e","MintedKeyCard","mintedKey","mintedPub","copied","keyCountdown","onDismiss","copyValue","Fragment","jsx","jsxs","ChatMessages","displayMessages","messageRefs","isNarrow","loading","streaming","sources","referencedIds","discussedSources","lastIntent","lastAction","defaultCurrency","stopped","interrupted","halted","haltedEmpty","error","errorCode","keyPhase","keyInput","setKeyInput","mintedKey","setMintedKey","mintedPub","setMintedPub","minting","copied","keyCountdown","handleUseExistingKey","handleCreateKey","copyValue","queuedMessage","sendQueuedNow","setLightboxSrc","setMarkupSrc","handleSend","handleSourceClick","onRetry","onEdit","onLongPress","retrying","continueGenerating","t","bottomRef","vizState","setVizState","messages","lastUserIdx","i","msg","idx","isLast","isUser","isLastUser","isRunEnd","runMid","runCont","key","hasError","MessageItem","el","cn","ContinueIcon","getFriendlyError","PromptKeyCard","MintedKeyCard","React","useState","useRef","useEffect","Fragment","jsx","jsxs","ChatComposer","gooId","input","setInput","showKikuPicker","setShowKikuPicker","showAtPicker","setShowAtPicker","captureAllowed","discussedSources","defaultCurrency","handleSelectExtension","handleKikuCapture","handleKikuCaptureAll","handleKikuViewHistory","handleKikuDelete","attachments","removeAttachment","chromeLoading","imageInputRef","handleImageFiles","enableVision","enableVoice","canConverse","voiceMode","startVoice","stopVoice","voiceBlocked","textareaRef","classNames","handleInput","handleKeyDown","voice","voicePhase","activePlaceholder","loading","streaming","stop","handleSend","voiceError","setVoiceError","shopperLanguage","t","rail","placeholderReplay","setPlaceholderReplay","React","toolsOpen","setToolsOpen","timer","onKey","e","placeholderSweepMs","splitPlaceholder","HSK_STAGGER_MS","launching","setLaunching","useState","launchTimer","useRef","launch","useEffect","PaperclipIcon","WaveformIcon","prev","SparkleIcon","src","i","BookmarkIcon","HistoryIcon","TrashIcon","att","XIcon","cn","o","PlusIcon","AnimatedPlaceholder","MicIcon","MicOffIcon","StopIcon","ArrowUpIcon","useEffect","useRef","jsx","parseColor","css","fallback","m","mix","a","b","t","rgba","c","alpha","BANDS","SPECTRUM_FRACTION","VoiceCanvas","phase","level","spectrum","bins","className","canvasRef","phaseRef","levelRef","spectrumRef","binsRef","canvas","ctx","style","accent","ink","raf","w","h","resize","dpr","rect","ro","reduced","bands","strokes","glow","strokesFor","freqBuf","amp","sweep","start","follow","cur","target","attack","release","readSpectrum","read","n","per","from","to","sum","i","v","synthesizeBands","energy","shape","bandAt","x","f","draw","now","p","live","cy","layers","l","depth","hue","g","maxAmp","step","lag","scale","px","py","u","envelope","focus","band","tl","ripple","y","width","jsx","jsxs","VoiceOverlay","siteId","themeAttr","stopVoice","chooseVoice","liveVoiceName","voiceSecondsLeft","voiceConnecting","voicePhase","live","voiceMuted","setVoiceMuted","shownSources","onSelectSource","defaultCurrency","voiceError","t","KikuDoodles_default","CloseIcon","LIVE_VOICES","v","i","cn","VoiceCanvas","src","SparkleIcon","m","MicOffIcon","MicIcon","jsx","jsxs","LightboxModal","src","onClose","CloseIcon","e","useRef","useEffect","jsx","jsxs","ConversationTimeline","items","activeIdx","progress","onJump","side","tr","useT","containerRef","useRef","trackRef","itemRefs","cursorRef","anchor","i","useEffect","node","cursor","track","container","containerHeight","nodeCenter","targetY","cn","item","el","useState","useEffect","useRef","useCallback","jsx","jsxs","TapbackMenu","msg","rect","containerRect","isUser","canRetry","canEdit","onPin","onRetry","onEdit","onCopy","onClose","t","copied","setCopied","useState","menuRef","useRef","useEffect","handleKeyDown","e","handleCopyAction","useCallback","handlePinAction","handleRetryAction","handleEditAction","measuredWidth","setMeasuredWidth","w","cTop","cLeft","cWidth","bTop","bLeft","bWidth","bHeight","btnCount","capsuleWidth","capsuleHeight","placeAbove","capsuleTop","targetX","capsuleLeft","tailOffset","anchorColor","toolIdx","cn","PinIcon","RetryIcon","EditIcon","CheckIcon","CopyIcon","jsx","jsxs","ChatModal","title","placeholder","backdropColor","backdropBlur","onClose","onSelectSource","defaultCurrency","chips","DEFAULT_CHIPS","theme","classNames","enableVoice","voiceLang","enableVision","visionCategoryHint","enableAudioResponse","ttsVoice","autoSpeakResponses","origin","client","useAkropolysContext","messages","sources","loading","streaming","error","errorCode","lastAction","lastIntent","allowedActions","send","queuedMessage","sendQueuedNow","appendSpokenExchange","stop","stopped","interrupted","continueGenerating","reset","referencedIds","useKiku","activeScouts","useScouts","shopperName","setShopperNameState","useState","shopperLanguage","setShopperLanguageState","entityLangPref","setEntityLangPrefState","justCompleted","setJustCompleted","chromeReady","isRTL","speechLang","scriptFont","fontStack","isNonLatin","hostFontCovers","t","tNode","useScriptFont","discussedSources","React","byRef","s","answer","m","seen","hay","aliases","name","n","w","out","a","named","captureAllowed","input","setInput","showKikuPicker","setShowKikuPicker","showAtPicker","setShowAtPicker","attachments","setAttachments","imageInputRef","useRef","vizState","setVizState","lightboxSrc","setLightboxSrc","markupSrc","setMarkupSrc","termsAgreed","setTermsAgreed","onboarding","awaitingLang","awaitingName","awaitingEntityLang","awaitingConsent","inOnboarding","hasLiveData","useEffect","subscribeLiveStream","isNarrow","setIsNarrow","mq","apply","chooseLanguage","lang","v","chooseEntityLang","mode","agreeTerms","activeTitle","activePlaceholder","activeChips","onboardingMood","currentTheme","setCurrentTheme","isThemeId","saved","DEFAULT_LIGHT","DEFAULT_DARK","handleToggleTheme","next","alsoCloseMenu","setThemeMenuOpen","setThemeMenuClosing","customStyles","resolveTheme","hskThemeAttr","useHostFontFace","handleSendRef","textareaRef","handleSend","text","extraAttachments","forcedIntent","captureTargets","raw","toSend","extractName","queryToSend","retrying","setRetrying","handleRetryMessage","useCallback","msg","target","handleEditMessage","len","retryLastMessage","keyInput","setKeyInput","keyPhase","setKeyPhase","mintedKey","setMintedKey","mintedPub","setMintedPub","copied","keyCountdown","minting","copyValue","handleUseExistingKey","handleCreateKey","useKikuKey","getStoredKikuId","fromSession","fromLocal","match","displayKikuPub","tapbackTarget","setTapbackTarget","handleLongPressMessage","rect","isUser","handlePinMessage","display","handleKikuCapture","handleKikuCaptureAll","handleKikuViewHistory","handleKikuDelete","useChatCommands","voiceMode","voicePhase","voiceConnecting","voiceError","setVoiceError","voiceMuted","setVoiceMuted","voiceSecondsLeft","voiceBlocked","liveVoiceName","chooseVoice","canConverse","startVoice","stopVoice","voice","live","useVoiceController","panelRef","themeMenuOpen","scoutsOpen","setScoutsOpen","themeMenuClosing","themeMenuCloseTimer","themeMenuRef","mobileThemeRef","messageRefs","bottomRef","overlayRef","gooId","useId","closeThemeMenu","handleOutside","e","path","isInsideRail","isInsideMobile","targetEl","isInsideTopbarMark","isInsideOoze","el","msgsContainerRef","lastExternalScrollRef","showJumpToBottom","scrollProgress","activeMsgIdx","unreadBelow","jumpToMessage","jumpToBottom","useChatScroll","useDragToDismiss","scrollbarWidth","prevOverflow","prevPadding","computedPadding","vv","root","h","handleReset","handleSourceClick","src","lastAssistant","price","handleSelectExtension","ext","handleKeyDown","composerHeight","singleRowFieldWidth","measureCanvasRef","getTextWidth","font","ctx","autoGrow","box","val","cs","textWidth","threshold","hasNewline","shouldExpand","targetHeight","handleInput","trimmed","handleImageFiles","files","list","file","dataUrl","downscaleImage","prev","removeAttachment","idx","_","i","shownSources","hasTranslucentBackdrop","backdropFilterStyle","halted","displayMessages","inFlight","timelineItems","clean","haltedEmpty","mountTimeRef","jsx","UIStringsContext","cn","jsxs","LightboxModal","MarkupEditor","instruction","marks","preview","KikuDoodles_default","ChatTopbar","OnboardingView","ChatMessages","ChatComposer","ConversationTimeline","ScoutRail","scout","THEMES","id","label","Icon","themeDef","CheckIcon","CopyIcon","VoiceOverlay","TapbackMenu","Fragment","jsx","jsxs","KikuButton","label","children","icon","title","placeholder","backdropColor","backdropBlur","className","onSelectSource","defaultCurrency","chips","DEFAULT_CHIPS","theme","classNames","enableVoice","voiceLang","enableVision","visionCategoryHint","enableAudioResponse","ttsVoice","autoSpeakResponses","client","useAkropolysContext","open","setOpen","useState","mounted","setMounted","origin","setOrigin","warmShadow","useCallback","getShadowContainer","warmChrome","DEFAULT_UI_STRINGS","openFrom","el","b","style","br","x","y","w","h","r","useEffect","ric","warmId","lastPath","originalPush","originalReplace","args","handleNavigation","cic","hskThemeAttr","customStyles","resolveTheme","useHostFontFace","cn","e","createPortal","ChatModal","useState","useEffect","useRef","createPortal","useSearch","useKiku","useAkropolysContext","Fragment","jsx","jsxs","SparkleIcon","className","size","cn","CloseIcon","getFriendlyError","err","str","parsed","SparkleModal","productName","limit","backdropColor","backdropBlur","onClose","onNavigate","onResult","theme","classNames","initialProduct","client","useAkropolysContext","fetchedProduct","setFetchedProduct","useState","displayProduct","results","searchLoading","search","useSearch","messages","sources","chatLoading","chatError","send","useKiku","chatInput","setChatInput","isMobile","setIsMobile","showSpecs","setShowSpecs","collapseSimilar","setCollapseSimilar","chatBottomRef","useRef","chatTextareaRef","useEffect","res","handleResize","h","e","overlayRef","prevOverflow","prevPosition","prevWidth","handleScrollLock","chatBodyRef","blurVal","bg","handleNav","r","handleSend","text","q","contextQuery","handleKeyDown","handleInput","t","customStyles","displayMessages","msg","idx","isUser","renderMarkdown","similarProducts","isSameName","isSameSlug","price","currency","ArrowUpIcon","key","val","i","Sparkle","product","children","open","setOpen","mounted","setMounted","createPortal","getShadowContainer","useEffect","useState","useRef","createRoot","AkropolysProvider","getAkropolysClient","jsx","normalizeShopifyProduct","p","id","title","priceStr","image","first","url","category","brand","tags","t","rawDescription","cleanDescription","defaultVariant","variantId","shopifyAddToCart","items","cartItems","item","res","data","err","shopifyGetCart","DraggableDockWrapper","children","position","dockable","isInline","coords","setCoords","useState","isDragging","setIsDragging","dragStartRef","useRef","wrapperRef","useEffect","computeDefault","defX","defY","saved","parsed","clampedX","clampedY","onResize","prev","onPointerDown","e","rect","onPointerMove","dx","dy","width","height","newX","newY","onPointerUp","hadMoved","clickCapturer","ev","StandaloneKikuApp","config","client","getAkropolysClient","prod","normalized","defaultOnAddToCart","AkropolysProvider","KikuButton","setupGlobalTriggers","initKiku","customConfig","scriptConfig","scriptTag","ds","mergedConfig","container","createRoot","product","shouldAutoInit","autoRun"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/SearchBar.tsx","../src/components/KikuButton.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\r\nimport { useSearch, SearchResult, AkropolysTheme, useAkropolysContext, useCardFields } from '@akropolys/sdk';\r\nimport { detailsOf } from '../utils/cardDetails';\r\nimport { cn } from '../utils/cn';\r\n\r\nexport interface SearchBarProps {\r\n placeholder?: string;\r\n limit?: number;\r\n debounceMs?: number;\r\n onSelect?: (result: SearchResult) => void;\r\n className?: string;\r\n inputClassName?: string;\r\n dropdownClassName?: string;\r\n renderResult?: (result: SearchResult) => React.ReactNode;\r\n theme?: AkropolysTheme;\r\n classNames?: {\r\n root?: string;\r\n input?: string;\r\n dropdown?: string;\r\n row?: string;\r\n };\r\n}\r\n\r\nconst SearchIcon = () => (\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\r\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\"/>\r\n <line x1=\"13\" y1=\"13\" x2=\"18\" y2=\"18\"/>\r\n </svg>\r\n);\r\n\r\nexport function SearchBar({\r\n placeholder = 'Search products…',\r\n limit = 10,\r\n debounceMs = 150,\r\n onSelect,\r\n className,\r\n inputClassName,\r\n dropdownClassName,\r\n renderResult,\r\n theme,\r\n classNames = {},\r\n}: SearchBarProps) {\r\n const [query, setQuery] = useState('');\r\n const [open, setOpen] = useState(false);\r\n const { results, loading, search, clear } = useSearch({ debounceMs });\r\n const client = useAkropolysContext();\r\n const cardFields = useCardFields();\r\n const wrap = useRef<HTMLDivElement>(null);\r\n const ignoreNextQueryChange = useRef(false);\r\n\r\n useEffect(() => {\r\n if (ignoreNextQueryChange.current) {\r\n ignoreNextQueryChange.current = false;\r\n return;\r\n }\r\n if (!query.trim()) {\r\n clear();\r\n setOpen(false);\r\n return;\r\n }\r\n setOpen(true); // open immediately (stale results show while fetching)\r\n search(query, limit);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [query]);\r\n\r\n useEffect(() => {\r\n const h = (e: MouseEvent) => {\r\n if (wrap.current && !wrap.current.contains(e.target as Node)) setOpen(false);\r\n };\r\n document.addEventListener('mousedown', h);\r\n return () => document.removeEventListener('mousedown', h);\r\n }, []);\r\n\r\n const handleSelect = (r: SearchResult) => {\r\n if (query.trim()) {\r\n client.api.searchVector(query, 1, undefined, true).catch(() => {});\r\n }\r\n ignoreNextQueryChange.current = true;\r\n setOpen(false);\r\n setQuery(r.entity.title ?? r.entity.name ?? '');\r\n onSelect?.(r);\r\n };\r\n\r\n const handleCommitSearch = () => {\r\n if (!query.trim()) return;\r\n client.api.searchVector(query, 1, undefined, true).catch(() => {});\r\n if (results.length > 0) {\r\n handleSelect(results[0]);\r\n }\r\n };\r\n\r\n const showDrop = open && query.trim().length > 0;\r\n\r\n const customStyles = {\r\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\r\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\r\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\r\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\r\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\r\n } as React.CSSProperties;\r\n\r\n return (\r\n <div className={cn(\"hsk-sb-wrap\", classNames.root, className)} ref={wrap} style={customStyles}>\r\n <span className=\"hsk-sb-icon\"><SearchIcon /></span>\r\n <input\r\n className={cn(\"hsk-sb-input\", classNames.input, inputClassName)}\r\n type=\"text\"\r\n value={query}\r\n placeholder={placeholder}\r\n onChange={e => setQuery(e.target.value)}\r\n onFocus={() => results.length > 0 && query.trim() && setOpen(true)}\r\n onKeyDown={e => {\r\n if (e.key === 'Enter') {\r\n handleCommitSearch();\r\n }\r\n }}\r\n autoComplete=\"off\"\r\n spellCheck={false}\r\n />\r\n {showDrop && (\r\n <div className={cn(\"hsk-sb-drop\", classNames.dropdown, dropdownClassName)} style={{ position: 'absolute' }}>\r\n {loading && <div className=\"hsk-sb-loading-bar\" />}\r\n\r\n {loading && results.length === 0 ? (\r\n <>\r\n <div className=\"hsk-sb-skeleton-row\">\r\n <span className=\"hsk-sb-skeleton-icon\" />\r\n <div className=\"hsk-sb-row-body\">\r\n <div className=\"hsk-sb-skeleton-text1\" />\r\n <div className=\"hsk-sb-skeleton-text2\" />\r\n </div>\r\n </div>\r\n <div className=\"hsk-sb-skeleton-row\">\r\n <span className=\"hsk-sb-skeleton-icon\" />\r\n <div className=\"hsk-sb-row-body\">\r\n <div className=\"hsk-sb-skeleton-text1\" style={{ width: '45%' }} />\r\n <div className=\"hsk-sb-skeleton-text2\" style={{ width: '25%' }} />\r\n </div>\r\n </div>\r\n </>\r\n ) : (\r\n <>\r\n {results.length === 0 && !loading && (\r\n <div className=\"hsk-sb-empty\">No results for “{query}”</div>\r\n )}\r\n\r\n {results.map((r, i) => {\r\n if (renderResult) {\r\n return (\r\n <div\r\n key={r.id}\r\n onClick={() => handleSelect(r)}\r\n className=\"hsk-sb-fade\"\r\n style={{ animationDelay: `${i * 18}ms` }}\r\n >\r\n {renderResult(r)}\r\n </div>\r\n );\r\n }\r\n const thumb = r.entity.image ?? r.entity.thumbnail ?? r.entity.images?.[0];\r\n return (\r\n <div\r\n key={r.id}\r\n className={cn(\"hsk-sb-row hsk-sb-fade\", classNames.row)}\r\n style={{ animationDelay: `${i * 18}ms` }}\r\n onClick={() => handleSelect(r)}\r\n >\r\n <span className=\"hsk-sb-row-thumb\">\r\n {thumb ? (\r\n <img\r\n src={thumb}\r\n alt=\"\"\r\n loading=\"lazy\"\r\n onError={e => { e.currentTarget.style.display = 'none'; }}\r\n />\r\n ) : (\r\n <SearchIcon />\r\n )}\r\n </span>\r\n <div className=\"hsk-sb-row-body\">\r\n <div className=\"hsk-sb-row-title\">{r.entity.title ?? r.entity.name}</div>\r\n {detailsOf({ fields: r.entity.fields ?? r.entity }, cardFields)[0] && (\r\n <div className=\"hsk-sb-row-sub\">\r\n {detailsOf({ fields: r.entity.fields ?? r.entity }, cardFields)[0].value}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","'use client';\n\nimport React, { useState, useEffect, useCallback, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { primeChimes } from '../utils/chime';\nimport type { AkropolysTheme, ChatSource } from '@akropolys/sdk';\nimport { useAkropolysContext } from '@akropolys/sdk';\nimport { cn } from '../utils/cn';\nimport { resolveTheme } from '../utils/theme';\nimport { useHostFontFace } from '../utils/hostFont';\nimport type { ModalOrigin } from './ChatModal/types';\n\ntype Chat = typeof import('./ChatModal/lazy');\nlet chat: Promise<Chat> | null = null;\n\nfunction loadChat(): Promise<Chat> {\n chat ??= import('./ChatModal/lazy').catch(err => { chat = null; throw err; });\n return chat;\n}\n\nexport interface KikuButtonProps {\n label?: React.ReactNode;\n children?: React.ReactNode;\n icon?: React.ReactNode;\n title?: string;\n\n /** Wordmark shown in place of the name in the topbar. */\n logo?: string;\n placeholder?: string;\n backdropColor?: string;\n backdropBlur?: string | number;\n className?: string;\n onSelectSource?: (source: ChatSource) => void;\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\n enableVoice?: boolean;\n\n voiceLang?: string;\n\n enableVision?: boolean;\n\n ttsVoice?: string;\n}\n\nexport function KikuButton({\n label = 'Ask AI',\n children,\n icon,\n title,\n logo,\n placeholder,\n backdropColor,\n backdropBlur,\n className,\n onSelectSource,\n chips,\n theme,\n classNames = {},\n enableVoice = false,\n voiceLang,\n ttsVoice,\n enableVision = false,\n}: KikuButtonProps) {\n const client = useAkropolysContext();\n const [open, setOpen] = useState(false);\n const [origin, setOrigin] = useState<ModalOrigin | null>(null);\n const [Chat, setChat] = useState<Chat | null>(null);\n const live = useRef(true);\n // Replies from the team that arrived while the chat was closed.\n const [unread, setUnread] = useState(0);\n useEffect(() => {\n if (open) { setUnread(0); return; }\n let current = true;\n client?.api?.unreadFromTeam?.().then((n: number) => { if (current) setUnread(n); }).catch(() => {});\n return () => { current = false; };\n }, [open, client]);\n\n const warmShadow = useCallback(() => {\n loadChat().then(c => {\n c.getShadowContainer();\n if (live.current) setChat(c);\n c.warmChrome(client, client?.getShopperLanguage?.() ?? '', c.DEFAULT_UI_STRINGS);\n client?.api?.widgetSettings?.().then((settings: any) => {\n if (settings?.detectedLanguage && settings.detectedLanguage.toLowerCase() !== 'english') {\n c.warmLanguage(client, settings.detectedLanguage, c.DEFAULT_UI_STRINGS);\n }\n }).catch(() => {});\n }).catch(() => {});\n }, [client]);\n\n const btnRef = useRef<HTMLButtonElement>(null);\n\n const openFrom = useCallback(() => {\n const b = btnRef.current?.getBoundingClientRect();\n setOrigin(b ? { x: b.left + b.width / 2, y: b.top + b.height / 2 } : null);\n setOpen(true);\n warmShadow();\n try { primeChimes(); } catch {}\n }, [warmShadow]);\n\n useEffect(() => {\n live.current = true;\n const ric = (window as any).requestIdleCallback;\n const warmId = ric ? ric(warmShadow, { timeout: 2000 }) : setTimeout(warmShadow, 300);\n\n if (typeof window !== 'undefined' && !(window as any).__akropolys_nav_patched) {\n (window as any).__akropolys_nav_patched = true;\n let lastPath = window.location.pathname;\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 if (window.location.pathname !== lastPath) {\n lastPath = window.location.pathname;\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\n }\n };\n\n window.history.replaceState = function(...args) {\n originalReplace.apply(this, args);\n if (window.location.pathname !== lastPath) {\n lastPath = window.location.pathname;\n window.dispatchEvent(new CustomEvent('akropolys:navigation'));\n }\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 live.current = false;\n const cic = (window as any).cancelIdleCallback;\n if (ric && cic) cic(warmId); else clearTimeout(warmId as any);\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('akropolys:navigation', handleNavigation);\n };\n }, [warmShadow]);\n\n const { themeAttr: hskThemeAttr, vars: customStyles } = resolveTheme(theme);\n useHostFontFace(theme);\n\n return (\n <>\n <button\n ref={btnRef}\n className={cn(\"hsk-cb-btn\", classNames.button, className)}\n onClick={openFrom}\n onPointerEnter={warmShadow}\n onPointerDown={warmShadow}\n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n aria-label=\"Open AI chat\"\n >\n {children !== undefined ? (\n children\n ) : (\n <>\n {icon ? (\n <span className=\"hsk-cb-btn-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n {icon}\n </span>\n ) : null}\n {label}\n </>\n )}\n {unread > 0 && <span className=\"hsk-cb-btn-badge\" aria-label={`${unread} new replies`}>{unread}</span>}\n </button>\n {open && Chat && createPortal(\n <Chat.ChatModal\n title={title}\n logo={logo}\n placeholder={placeholder}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n origin={origin}\n onClose={() => setOpen(false)}\n onSelectSource={onSelectSource}\n chips={chips ?? Chat.DEFAULT_CHIPS}\n theme={theme}\n classNames={classNames}\n enableVoice={enableVoice}\n voiceLang={voiceLang}\n enableVision={enableVision}\n ttsVoice={ttsVoice}\n />,\n Chat.getShadowContainer() ?? document.body\n )}\n </>\n );\n}\n"],"mappings":"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","names":["useState","useEffect","useRef","useSearch","useAkropolysContext","useCardFields","Fragment","jsx","jsxs","SearchIcon","SearchBar","placeholder","limit","debounceMs","onSelect","className","inputClassName","dropdownClassName","renderResult","theme","classNames","query","setQuery","useState","open","setOpen","results","loading","search","clear","useSearch","client","useAkropolysContext","cardFields","useCardFields","wrap","useRef","ignoreNextQueryChange","useEffect","h","e","handleSelect","r","handleCommitSearch","showDrop","customStyles","cn","i","thumb","detailsOf","useState","useEffect","useCallback","useRef","createPortal","useAkropolysContext","Fragment","jsx","jsxs","chat","loadChat","err","KikuButton","label","children","icon","title","logo","placeholder","backdropColor","backdropBlur","className","onSelectSource","chips","theme","classNames","enableVoice","voiceLang","ttsVoice","enableVision","client","useAkropolysContext","open","setOpen","useState","origin","setOrigin","Chat","setChat","live","useRef","unread","setUnread","useEffect","current","n","warmShadow","useCallback","c","settings","btnRef","openFrom","b","primeChimes","ric","warmId","lastPath","originalPush","originalReplace","args","handleNavigation","cic","hskThemeAttr","customStyles","resolveTheme","useHostFontFace","cn","createPortal"]}
|