@akropolys/kiku 2.2.0 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/ChatModal/ChatModal.tsx","../src/components/ChatModal/icons.tsx","../src/components/ChatModal/themes.ts","../src/utils/sheetGesture.ts","../src/utils/downscaleImage.ts","../src/components/MarkupEditor.tsx","../src/utils/markRegions.ts","../src/components/KikuDoodles.tsx","../src/components/ChatModal/types.ts","../src/utils/chromeWarm.ts","../src/components/ChatModal/hooks/useScriptFont.tsx","../src/components/ChatModal/hooks/useChatScroll.ts","../src/components/ChatModal/hooks/usePacedText.ts","../src/components/ChatModal/hooks/useKikuKey.ts","../src/components/ChatModal/hooks/useChatCommands.ts","../src/components/ChatModal/hooks/useVoiceController.ts","../src/utils/tts.ts","../src/utils/voiceSession.ts","../src/utils/liveVoice.ts","../src/utils/adpcm.ts","../src/utils/wav.ts","../src/components/ChatModal/ChatTopbar.tsx","../src/components/KikuAvatar.tsx","../src/components/ChatModal/components/SoundToggle.tsx","../src/utils/island.ts","../src/components/ChatModal/OnboardingView.tsx","../src/components/ChatModal/ClayLoader.tsx","../src/components/ChatModal/components/ThinkingBlock.tsx","../src/components/ChatModal/hooks/useDelayedClose.ts","../src/components/ChatModal/components/MessageItem.tsx","../src/utils/markdown.tsx","../src/utils/textDirection.ts","../src/components/LiveTable.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/ChatModal/components/AnimatedPlaceholder.tsx","../src/components/ChatModal/VoiceOverlay.tsx","../src/components/VoiceCanvas.tsx","../src/components/ChatModal/components/LightboxModal.tsx","../src/components/ChatModal/components/ConversationTimeline.tsx","../src/components/ChatModal/components/TapbackMenu.tsx","../src/styles/cssText.ts","../src/utils/shadowRoot.ts"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef, useCallback, useId } from 'react';\nimport { flushSync } from 'react-dom';\nimport { THEMES, isThemeId, themeDef, DEFAULT_THEME, type ThemeId } from './themes';\nimport { useKiku, ChatSource, ChatAttachment, CaptureTarget, subscribeLiveStream, type ChatMessage } from '@akropolys/sdk';\nimport { useAkropolysContext, useCardFields } from '@akropolys/sdk';\nimport { detailsOf, detailsText } from '../../utils/cardDetails';\nimport { cn } from '../../utils/cn';\nimport { resolveTheme } from '../../utils/theme';\nimport { useHostFontFace, preloadScriptFont } from '../../utils/hostFont';\nimport { useDragToDismiss } from '../../utils/sheetGesture';\nimport { downscaleImage } from '../../utils/downscaleImage';\nimport { MarkupEditor } from '../MarkupEditor';\nimport type { KikuState } from '../KikuAvatar';\nimport KikuDoodles, { bloomDoodles } from '../KikuDoodles';\n\nimport {\n DEFAULT_CHIPS,\n DEFAULT_UI_STRINGS,\n ONBOARDING_UI_STRINGS,\n UIStringsContext,\n extractName,\n ChatModalProps,\n getLoadingMeta,\n type ComposerAttachment,\n} from './types';\nimport { warmLanguage } from '../../utils/chromeWarm';\nimport { useScriptFont } from './hooks/useScriptFont';\nimport { useChatScroll } from './hooks/useChatScroll';\nimport { usePacedText } from './hooks/usePacedText';\nimport { useKikuKey } from './hooks/useKikuKey';\nimport { useChatCommands } from './hooks/useChatCommands';\nimport { useVoiceController } from './hooks/useVoiceController';\nimport { ChatTopbar } from './ChatTopbar';\nimport { CloseIcon, MessageIcon } from './icons';\nimport { OnboardingView } from './OnboardingView';\n\nconst THEME_MENU_EXIT_MS = 240; // outlasts the 220ms exit, or the menu is removed mid-fade and pops\nconst TRAY_EXIT_CEILING_MS = 700;\nconst OVERLAY_EXIT_MS = 200;\nimport { chime, primeChimes } from '../../utils/chime';\nimport { SoundToggle } from './components/SoundToggle';\nimport { isTeamNote } from './components/ThinkingBlock';\nimport { useDelayedClose } from './hooks/useDelayedClose';\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 logo,\n placeholder = 'Ask me anything…',\n backdropColor,\n backdropBlur,\n onClose,\n onSelectSource,\n chips = DEFAULT_CHIPS,\n theme,\n classNames = {},\n enableVoice = false,\n voiceLang,\n enableVision = false,\n ttsVoice = 'Algenib',\n origin,\n}: ChatModalProps) {\n const client = useAkropolysContext();\n const cardFields = useCardFields();\n const { messages, sources, loading, streaming, error, errorCode, lastAction, lastIntent, allowedActions, send, queuedMessage, sendQueuedNow, appendSpokenExchange, stop, stopped, interrupted, continueGenerating, reset, referencedIds, humanPending, leaveHuman } = useKiku();\n const [leaveAsk, setLeaveAsk] = useState<'close' | 'reset' | null>(null);\n const leaveRef = useRef<HTMLDivElement>(null);\n // A side-to-side nudge when the visitor tries anything else while the warning waits for an answer.\n const nudgeLeave = useCallback(() => {\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return;\n leaveRef.current?.animate(\n [0, -7, 6, -4, 2, 0].map(x => ({ transform: `translateX(${x}px)` })),\n { duration: 380, easing: 'cubic-bezier(.36, .07, .19, .97)' },\n );\n }, []);\n useEffect(() => {\n if (!leaveAsk) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key.length === 1 || e.key === 'Enter' || e.key === 'Backspace') nudgeLeave();\n };\n // The conversation is frozen too, so retry, edit and suggestions cannot send behind the warning.\n const onPointer = (e: PointerEvent) => {\n const hit = (cls: string) => e.composedPath().some(n => (n as Element).classList?.contains(cls));\n if (!hit('hsk-cb-leave') && !hit('hsk-cb-topbar')) nudgeLeave();\n };\n const msgs = msgsContainerRef.current as HTMLElement | null;\n msgs?.setAttribute('inert', '');\n document.addEventListener('keydown', onKey);\n document.addEventListener('pointerdown', onPointer, true);\n return () => {\n msgs?.removeAttribute('inert');\n document.removeEventListener('keydown', onKey);\n document.removeEventListener('pointerdown', onPointer, true);\n };\n }, [leaveAsk, nudgeLeave]);\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 const [preloadedStrings, setPreloadedStrings] = useState<Record<string, string> | null>(null);\n const [pendingLanguage, setPendingLanguage] = useState<string>('');\n const [langSwitching, setLangSwitching] = useState(false);\n\n const {\n chromeReady,\n baseFontReady,\n isRTL,\n speechLang,\n scriptFont,\n fontStack,\n isNonLatin,\n hostFontCovers,\n langPending,\n t,\n tNode,\n } = useScriptFont({ shopperLanguage: shopperLanguage || pendingLanguage, theme, preloadedStrings });\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<ComposerAttachment[]>([]);\n const photoReady = useRef(new Map<string, Promise<string>>());\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 targetLang = pendingLanguage || shopperLanguage;\n const isEn = !targetLang || targetLang.toLowerCase() === 'english' || targetLang.toLowerCase() === 'en';\n const isLangPreparing = langSwitching || !!pendingLanguage || (!!shopperLanguage && !chromeReady && !isEn);\n const awaitingLang = onboarding && !shopperLanguage && !isLangPreparing;\n const awaitingName = onboarding && !!shopperLanguage && !shopperName && !isLangPreparing;\n const awaitingEntityLang = onboarding && !!shopperLanguage && !!shopperName && !entityLangPref;\n const awaitingConsent = onboarding && !!shopperLanguage && !!shopperName && !!entityLangPref && !termsAgreed;\n const inOnboarding = awaitingLang || awaitingName || awaitingEntityLang || awaitingConsent || isLangPreparing;\n const inputLocked = awaitingEntityLang || awaitingConsent || isLangPreparing;\n\n const [prevPreparingForComposer, setPrevPreparingForComposer] = useState(isLangPreparing);\n const [composerHidden, setComposerHidden] = useState(false);\n const [composerExiting, setComposerExiting] = useState(false);\n const [composerRevealing, setComposerRevealing] = useState(false);\n const composerWasHidden = useRef(false);\n const composerHideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const composerRevealTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n if (isLangPreparing !== prevPreparingForComposer) {\n setPrevPreparingForComposer(isLangPreparing);\n if (isLangPreparing) {\n if (composerRevealTimer.current) clearTimeout(composerRevealTimer.current);\n setComposerRevealing(false);\n setComposerExiting(true);\n composerHideTimer.current = setTimeout(() => {\n setComposerHidden(true);\n setComposerExiting(false);\n composerWasHidden.current = true;\n }, 280);\n } else {\n if (composerHideTimer.current) clearTimeout(composerHideTimer.current);\n setComposerExiting(false);\n setComposerHidden(false);\n if (composerWasHidden.current) {\n composerWasHidden.current = false;\n setComposerRevealing(true);\n composerRevealTimer.current = setTimeout(() => setComposerRevealing(false), 560);\n }\n }\n }\n\n useEffect(() => () => {\n if (composerHideTimer.current) clearTimeout(composerHideTimer.current);\n if (composerRevealTimer.current) clearTimeout(composerRevealTimer.current);\n }, []);\n\n\n useEffect(() => {\n if (!awaitingLang) return;\n const trimmed = input.trim();\n if (trimmed.length < 2) return;\n const timer = setTimeout(() => {\n warmLanguage(client, trimmed, DEFAULT_UI_STRINGS);\n }, 150);\n return () => clearTimeout(timer);\n }, [awaitingLang, input, client]);\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: 1199px)');\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 = async (lang: string) => {\n const v = lang.trim();\n if (!v) {\n try { client.setShopperLanguage?.(''); } catch { }\n setShopperLanguageState('');\n setPendingLanguage('');\n setPreloadedStrings(null);\n return;\n }\n setPendingLanguage(v);\n setLangSwitching(true);\n\n const isTargetEn = v.toLowerCase() === 'english' || v.toLowerCase() === 'en';\n if (isTargetEn) {\n setPreloadedStrings(DEFAULT_UI_STRINGS);\n try { client.setShopperLanguage?.(v); } catch { }\n setShopperLanguageState(v);\n setPendingLanguage('');\n setLangSwitching(false);\n setJustCompleted(false);\n return;\n }\n\n const animStart = Date.now();\n const MIN_ANIM_MS = 1200;\n\n try {\n const cached = client.getCachedUIStrings?.(v, ONBOARDING_UI_STRINGS) ?? client.getCachedUIStrings?.(v, DEFAULT_UI_STRINGS);\n if (cached?.strings && Object.keys(cached.strings).length > 0) {\n setPreloadedStrings(cached.strings);\n if (cached.font) {\n await preloadScriptFont(cached.font, 800);\n }\n } else {\n const fetchP = client.getUIStrings?.(v, ONBOARDING_UI_STRINGS);\n const res = await Promise.race([\n fetchP,\n new Promise<null>((resolve) => setTimeout(() => resolve(null), 8000)),\n ]);\n if (res?.font) {\n await preloadScriptFont(res.font, 1200);\n }\n if (res?.strings && Object.keys(res.strings).length > 0) {\n setPreloadedStrings(res.strings);\n }\n }\n } catch { }\n\n const elapsed = Date.now() - animStart;\n if (elapsed < MIN_ANIM_MS) {\n await new Promise((r) => setTimeout(r, MIN_ANIM_MS - elapsed));\n }\n\n try { client.setShopperLanguage?.(v); } catch { }\n setShopperLanguageState(v);\n setPendingLanguage('');\n setLangSwitching(false);\n setJustCompleted(false);\n\n try {\n client.getUIStrings?.(v, DEFAULT_UI_STRINGS)?.catch?.(() => {});\n } catch { }\n };\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 activePlaceholder =\n isLangPreparing ? getLoadingMeta(pendingLanguage || shopperLanguage).preparing\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 }\n return DEFAULT_THEME;\n });\n\n const [theming, setTheming] = useState(false);\n const themingTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n useEffect(() => () => { if (themingTimer.current) clearTimeout(themingTimer.current); }, []);\n\n // When the doodle bloom from the dock reaches the chat, its content nudges up and away, then settles.\n const nudgeRef = useRef<Animation | null>(null);\n const nudgeContent = () => {\n const msgs = msgsContainerRef.current as HTMLElement | null;\n if (!msgs?.animate || window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return;\n const away = isRTL ? -3 : 3;\n nudgeRef.current?.cancel(); // two nudges on one element fight each other and read as a shake\n nudgeRef.current = msgs.animate(\n [\n { transform: 'translate(0, 0)', easing: 'cubic-bezier(.3, 0, .2, 1)' },\n { offset: 0.26, transform: `translate(${away}px, -6px)`, easing: 'cubic-bezier(.45, 0, .35, 1)' },\n { offset: 0.52, transform: `translate(${-away * 0.3}px, 1.6px)`, easing: 'cubic-bezier(.45, 0, .35, 1)' },\n { offset: 0.74, transform: `translate(${away * 0.1}px, -0.6px)`, easing: 'cubic-bezier(.45, 0, .55, 1)' },\n { transform: 'translate(0, 0)' },\n ],\n { duration: 1100, delay: 380 },\n );\n };\n // The first bloom waits for the greeting or messages to appear, which can lag the panel on a first open.\n // Text that has only just arrived must not nudge: it reads as landing in the wrong place.\n const openBloomedRef = useRef(false);\n useEffect(() => {\n if (openBloomedRef.current) return;\n const box = msgsContainerRef.current as HTMLElement | null;\n if (!box) {\n bloomDoodles();\n return;\n }\n let done = false;\n const shown = () => box.querySelector('.hsk-cb-hello-wrap, .hsk-cb-msg-group');\n const fire = () => {\n if (done) return;\n done = true;\n openBloomedRef.current = true;\n observer.disconnect();\n clearTimeout(limit);\n bloomDoodles();\n };\n const observer = new MutationObserver(() => { if (shown()) fire(); });\n observer.observe(box, { childList: true, subtree: true });\n const limit = window.setTimeout(fire, 2000);\n if (shown()) fire();\n return () => {\n done = true;\n observer.disconnect();\n clearTimeout(limit);\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleToggleTheme = (next: ThemeId, alsoCloseMenu = false) => {\n setTheming(true);\n if (themingTimer.current) clearTimeout(themingTimer.current);\n themingTimer.current = setTimeout(() => setTheming(false), 420);\n setCurrentTheme(next);\n nudgeContent();\n if (alsoCloseMenu) closeThemeMenuNow();\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 picked = extraAttachments ?? attachments;\n if ((!raw && picked.length === 0) || !chromeReady || queuedMessage) return;\n\n chime('send');\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 || langSwitching) return;\n setInput('');\n void chooseLanguage(raw);\n return;\n }\n if (inputLocked) {\n setInput('');\n return;\n }\n\n setShowKikuPicker(false);\n setShowAtPicker(false);\n setInput('');\n setAttachments([]);\n // A photo sent before its copy is ready waits for it here, out of sight.\n const toSend: ChatAttachment[] = (await Promise.all(picked.map(async ({ thumb, ...a }: ComposerAttachment) => {\n const data = a.data || (thumb ? await photoReady.current.get(thumb)?.catch(() => '') : '') || '';\n if (thumb) URL.revokeObjectURL(thumb);\n return { ...a, data };\n }))).filter(a => a.data);\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 // The key rides in the address fragment, which never leaves the browser; MiMi takes it and clears it.\n const openMimi = useCallback(() => {\n const key = client?.getKikuKey?.();\n if (key) window.open(`https://mimi.akropolys.cloud/#k=${encodeURIComponent(key)}`, '_blank', 'noopener');\n }, [client]);\n\n const [tapbackTarget, setTapbackTarget] = useState<{\n msg: any;\n rect: { top: number; left: number; width: number; height: number };\n isUser: boolean;\n el?: HTMLElement;\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 el?: HTMLElement\n ) => {\n setTapbackTarget({ msg, rect, isUser, el });\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 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 earlier,\n newVoiceChat,\n attachPhoto,\n } = useVoiceController({\n voiceLang,\n speechLang,\n shopperLanguage,\n ttsVoice,\n messages,\n handleSendUtterance: (text) => handleSendRef.current(text),\n appendSpokenExchange,\n });\n\n const panelRef = useRef<HTMLDivElement>(null);\n const [themeMenuOpen, setThemeMenuOpen] = useState(false);\n // The grid marks the theme it opened on; a pick just closes it rather than moving the mark first.\n const [themeMenuMark, setThemeMenuMark] = useState<ThemeId | null>(null);\n const themeMenuRef = useRef<HTMLDivElement>(null);\n const mobileThemeRef = useRef<HTMLDivElement>(null);\n\n const messageRefs = useRef<(HTMLDivElement | null)[]>([]);\n const overlayRef = useRef<HTMLDivElement>(null);\n const gooId = `hsk-goo-${useId()}`;\n\n const {\n closing: themeMenuClosing,\n requestClose: closeThemeMenu,\n closeNow: closeThemeMenuNow,\n } = useDelayedClose(isNarrow ? TRAY_EXIT_CEILING_MS : THEME_MENU_EXIT_MS, () => setThemeMenuOpen(false));\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 spacerRef,\n lastExternalScrollRef,\n showJumpToBottom,\n scrollProgress,\n activeMsgIdx,\n unreadBelow,\n jumpToMessage,\n jumpToBottom,\n } = useChatScroll({ messages, loading, streaming, messageRefs });\n\n const { closing: overlayClosing, requestClose: exitOverlay } = useDelayedClose(OVERLAY_EXIT_MS, onClose);\n // end=true tells the team the visitor is done; otherwise the request is kept for when they come back.\n const closeNow = useCallback((end: boolean) => {\n if (end) leaveHuman();\n setThemeMenuOpen(false);\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) onClose();\n else exitOverlay();\n }, [exitOverlay, onClose, leaveHuman]);\n // While a person is on the request, the visitor chooses whether to keep it or end it.\n const requestClose = useCallback(() => {\n if (leaveAsk) nudgeLeave();\n else if (humanPending) setLeaveAsk('close');\n else closeNow(false);\n }, [humanPending, closeNow, leaveAsk, nudgeLeave]);\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 requestClose();\n };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, [lightboxSrc, requestClose]);\n\n const resetNow = useCallback((end: boolean) => {\n if (end) leaveHuman();\n reset();\n setKeyPhase('idle');\n }, [reset, setKeyPhase, leaveHuman]);\n const handleReset = useCallback(() => {\n if (leaveAsk) nudgeLeave();\n else if (humanPending) setLeaveAsk('reset');\n else resetNow(false);\n }, [humanPending, resetNow, leaveAsk, nudgeLeave]);\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 send(t('cardClickQuery', { name: src.name, details: detailsText(detailsOf(src, cardFields)) }));\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 const thumb = URL.createObjectURL(file);\n const ready = downscaleImage(file);\n photoReady.current.set(thumb, ready);\n setAttachments(prev => [...prev, { type: 'image', data: '', thumb }]);\n ready\n .then(data => setAttachments(prev => prev.map(a => (a.thumb === thumb ? { ...a, data } : a))))\n .catch(() => setAttachments(prev => prev.filter(a => a.thumb !== thumb)))\n .finally(() => photoReady.current.delete(thumb));\n }\n };\n\n const removeAttachment = (idx: number) => {\n setAttachments(prev => {\n const gone = prev[idx]?.thumb;\n if (gone) URL.revokeObjectURL(gone);\n return prev.filter((_, i) => i !== idx);\n });\n };\n\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 wasStreaming = useRef(false);\n useEffect(() => {\n if (wasStreaming.current && !streaming) {\n const last = messages[messages.length - 1];\n if (last && last.role !== 'user') chime('reply');\n }\n wasStreaming.current = streaming;\n }, [streaming, messages]);\n\n const halted = (stopped || interrupted) && !loading && !streaming;\n\n const tail = messages[messages.length - 1];\n const pacedContent = usePacedText(tail?.role === 'assistant' ? tail.content ?? '' : '');\n const draining = tail?.role === 'assistant' && pacedContent.length < (tail.content?.length ?? 0);\n const revealing = streaming || draining;\n\n const displayMessages = React.useMemo(() => {\n const inFlight = loading || streaming;\n const kept = 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 || isTeamNote(m.statusStage);\n return hasBody;\n });\n const last = kept.length - 1;\n if (last < 0 || kept[last].role !== 'assistant') return kept;\n if (kept[last] !== messages[messages.length - 1]) return kept;\n // stream end is not reveal end; dropping paced content here prints the rest in one frame\n const draining = pacedContent.length < (kept[last].content?.length ?? 0);\n if (!inFlight && !draining) return kept;\n return kept.map((m, i) => (i === last ? { ...m, content: pacedContent } : m));\n }, [messages, loading, streaming, pacedContent]);\n\n const timelineItems = React.useMemo(() => {\n const items: Array<{ idx: number; text: string }> = [];\n displayMessages.forEach((m, idx) => {\n if (m.role === 'user' && !!m.content.trim()) {\n const clean = m.content.replace(/^@kiku\\s*/i, '').replace(/\\s+/g, ' ').trim();\n items.push({\n idx,\n text: clean.length > 28 ? clean.slice(0, 27).trimEnd() + '…' : clean,\n });\n }\n });\n return items;\n }, [displayMessages]);\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\", overlayClosing && \"hsk-cb-overlay--closing\", classNames.overlay)}\n onPointerDown={e => {\n primeChimes();\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 requestClose();\n }\n if (overlayRef.current) (overlayRef.current as any)._ptrDown = false;\n }}\n data-hsk-theme={hskThemeAttr}\n data-hsk-theming={theming ? '' : undefined}\n style={{\n ...(backdropFilterStyle),\n ...(backdropColor ? { background: backdropColor } : {}),\n ...(origin ? {\n '--hsk-ox': `${origin.x}px`,\n '--hsk-oy': `${origin.y}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 lang={speechLang || undefined}\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,\n [{ type: 'image', data: dataUrl, annotated: true, marks, instructed: true, 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'} waitForContent />\n\n <ChatTopbar\n title={title}\n logo={logo}\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 onThemeMenuClosed={closeThemeMenuNow}\n isNarrow={isNarrow}\n currentTheme={currentTheme}\n onJumpToLatest={jumpToBottom}\n onReset={handleReset}\n onClose={requestClose}\n onToggleThemeMenu={() => (themeMenuOpen ? closeThemeMenu() : setThemeMenuOpen(true))}\n onSelectTheme={(t) => { handleToggleTheme(t, true); }}\n themeAttr={hskThemeAttr}\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 pendingLanguage={pendingLanguage}\n shopperName={shopperName}\n entityLangPref={entityLangPref}\n chromeReady={chromeReady && baseFontReady}\n activeChips={activeChips}\n speechLang={speechLang}\n t={t}\n tNode={tNode}\n chooseLanguage={chooseLanguage}\n langSwitching={langSwitching}\n isLangPreparing={isLangPreparing}\n onPrewarmLanguage={(lang) => warmLanguage(client, lang, DEFAULT_UI_STRINGS)}\n chooseEntityLang={chooseEntityLang}\n agreeTerms={agreeTerms}\n handleSend={handleSend}\n />\n ) : (\n <ChatMessages\n doodleTheme={hskThemeAttr}\n displayMessages={displayMessages}\n messageRefs={messageRefs}\n isNarrow={isNarrow}\n loading={loading}\n streaming={revealing}\n sources={sources}\n referencedIds={referencedIds}\n discussedSources={discussedSources}\n lastIntent={lastIntent}\n lastAction={lastAction}\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 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 spacerRef={spacerRef}\n vizState={vizState}\n setVizState={setVizState}\n messages={messages}\n />\n )}\n </div>\n\n {!composerHidden && (\n <div\n className={cn(\n composerExiting && 'hsk-composer-exit-up',\n composerRevealing && 'hsk-composer-reveal',\n )}\n >\n <ChatComposer\n notice={leaveAsk && (\n <div className=\"hsk-cb-leave\" role=\"alertdialog\" ref={leaveRef}>\n <span>{t('leaveHumanWarning')}</span>\n <button type=\"button\" className=\"hsk-cb-leave-btn\" onClick={() => setLeaveAsk(null)}>{t('leaveHumanStay')}</button>\n <button\n type=\"button\"\n className=\"hsk-cb-leave-btn\"\n onClick={() => { const kind = leaveAsk; setLeaveAsk(null); if (kind === 'reset') resetNow(true); else closeNow(true); }}\n >\n {t('leaveHumanConfirm')}\n </button>\n <button\n type=\"button\"\n className=\"hsk-cb-leave-btn hsk-cb-leave-btn--end\"\n onClick={() => { const kind = leaveAsk; setLeaveAsk(null); if (kind === 'reset') resetNow(false); else closeNow(false); }}\n >\n {t('leaveHumanKeep')}\n </button>\n </div>\n )}\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 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 && !inOnboarding}\n enableVoice={enableVoice && !inOnboarding}\n canConverse={canConverse}\n startVoice={startVoice}\n inputLocked={inputLocked}\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 langSwitching={langSwitching || isLangPreparing}\n langPending={langPending}\n t={t}\n onOpenMimi={client?.getKikuKey?.() ? openMimi : undefined}\n />\n </div>\n )}\n </div>\n\n {voiceMode !== 'converse' && (\n <ConversationTimeline\n items={timelineItems}\n activeIdx={activeMsgIdx}\n progress={scrollProgress}\n onJump={jumpToMessage}\n side={isRTL ? 'left' : 'right'}\n />\n )}\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 <div className=\"hsk-cb-dock-frost\" aria-hidden=\"true\" />\n <SoundToggle />\n\n {/* One pill that grows into the theme grid and shrinks back, like the voices pill. */}\n <div className={cn(\"hsk-cb-theme-squircle-wrap\", themeMenuOpen && !themeMenuClosing && \"is-open\")} ref={themeMenuRef}>\n <div\n className=\"hsk-cb-theme-2x2-grid\"\n role=\"dialog\"\n aria-label=\"Theme selector\"\n ref={(el) => { if (el) el.inert = !themeMenuOpen || themeMenuClosing; }}\n >\n {THEMES.map(({ id, label, Icon }) => (\n <button\n key={id}\n type=\"button\"\n className={cn(\"hsk-cb-theme-grid-item\", (themeMenuMark ?? 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 <button\n type=\"button\"\n className=\"hsk-cb-theme-squircle-trigger\"\n onClick={() => {\n if (themeMenuOpen) { closeThemeMenuNow(); return; }\n setThemeMenuMark(currentTheme);\n setThemeMenuOpen(true);\n }}\n aria-label=\"Themes\"\n aria-expanded={themeMenuOpen}\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 </div>\n\n {/* MiMi is where a visitor reads their conversations with a team; it opens already unlocked. */}\n {client?.getKikuKey?.() && (\n <button type=\"button\" className=\"hsk-cb-sound-pill\" onClick={openMimi}>\n <MessageIcon size={13} />\n <span>MiMi</span>\n </button>\n )}\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 earlier={earlier}\n newVoiceChat={newVoiceChat}\n voiceMuted={voiceMuted}\n setVoiceMuted={setVoiceMuted}\n voiceError={voiceError}\n attachPhoto={attachPhoto}\n onSelectSource={(src: ChatSource) => {\n onSelectSource?.(src);\n live.ask(t('cardClickQuery', { name: src.name, details: detailsText(detailsOf(src, cardFields)) }));\n }}\n t={t}\n />\n )}\n\n {tapbackTarget && (\n <TapbackMenu\n msg={tapbackTarget.msg}\n rect={tapbackTarget.rect}\n anchorEl={tapbackTarget.el}\n containerEl={panelRef.current}\n containerRect={panelRef.current?.getBoundingClientRect()}\n isUser={tapbackTarget.isUser}\n isRTL={isRTL}\n canRetry={!loading && !streaming}\n onPin={handlePinMessage}\n onRetry={handleRetryMessage}\n onCopy={async (text) => {\n if (!text) return false;\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch { }\n try {\n const ta = document.createElement('textarea');\n ta.value = text;\n ta.setAttribute('readonly', '');\n ta.style.cssText = 'position:fixed;top:0;left:0;opacity:0;pointer-events:none';\n document.body.appendChild(ta);\n ta.select();\n ta.setSelectionRange(0, text.length);\n const ok = document.execCommand('copy');\n document.body.removeChild(ta);\n return ok;\n } catch {\n return false;\n }\n }}\n onClose={() => setTapbackTarget(null)}\n t={t}\n />\n )}\n </div>\n </div>\n </UIStringsContext.Provider>\n );\n}\n","import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport const KikuIcon = ({ className, size = 18, tight = false }: { className?: string; size?: number; tight?: boolean }) => (\n <svg\n className={cn(\"hsk-brand-mark\", className)}\n width={size}\n height={size}\n viewBox={tight ? \"10.2 17.4 79.5 79.5\" : \"0 0 100 100\"}\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-label=\"kiku\"\n >\n <g transform=\"translate(22.7 19) scale(0.62)\" fill=\"currentColor\" fillRule=\"evenodd\">\n <path d=\"M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z\" />\n <circle cx=\"55\" cy=\"82\" r=\"3.4\" />\n </g>\n </svg>\n);\n\nexport const SparkleIcon = KikuIcon;\n\nexport const StopIcon = () => (\n <svg className=\"hsk-stop-icon\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle\n className=\"hsk-stop-ring\"\n cx=\"12\" cy=\"12\" r=\"9.5\"\n stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\"\n />\n <rect className=\"hsk-stop-core\" x=\"8.5\" y=\"8.5\" width=\"7\" height=\"7\" rx=\"1.8\" fill=\"currentColor\" />\n </svg>\n);\n\nexport const SpeakerIcon = ({ active }: { active?: boolean }) => (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" fill={active ? 'currentColor' : 'none'} />\n {active ? (\n <>\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n </>\n ) : (\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\n )}\n </svg>\n);\n\nexport const ExternalIcon = () => (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n);\n\nexport const ContinueIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n);\n\nexport const CloseIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n);\n\nexport const ChevronLeftIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m15 18-6-6 6-6\"/>\n </svg>\n);\n\nexport const ChevronRightIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\"/>\n </svg>\n);\n\nexport const HistoryIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/>\n <path d=\"M3 3v5h5\"/>\n <path d=\"M12 7v5l4 2\"/>\n </svg>\n);\n\nexport const BookmarkIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M19 21 12 16l-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z\"/>\n </svg>\n);\n\nexport const TrashIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 6h18\"/>\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);\n\nexport const SecureShieldIcon = ({ className, size = 18 }: { className?: string; size?: number }) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n <path d=\"M12 11a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z\" />\n <path d=\"M12 11v4\" />\n </svg>\n);\n\nexport const PlusIcon = () => (\n <svg width=\"19\" height=\"19\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <path d=\"M12 5v14M5 12h14\"/>\n </svg>\n);\n\n// The dots bounce like someone typing when the control is hovered.\nexport const MessageIcon = ({ size = 18 }: { 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=\"M21 11.5a8.4 8.4 0 0 1-12.3 7.4L3 21l2.1-5.7A8.4 8.4 0 1 1 21 11.5Z\"/>\n {[8.9, 12.6, 16.3].map((cx, i) => (\n <circle key={cx} className=\"hsk-mimi-dot\" style={{ '--hsk-dot': i } as React.CSSProperties} cx={cx} cy=\"11.6\" r=\"1.15\" fill=\"currentColor\" stroke=\"none\" />\n ))}\n </svg>\n);\n\nexport const PaperclipIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\"/>\n </svg>\n);\n\nexport const ImageIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"4\" />\n <circle className=\"hsk-img-sun\" cx=\"9\" cy=\"9\" r=\"1.8\" />\n <path className=\"hsk-img-ridge\" d=\"m21 15-4.5-4.5L6 21\" />\n </svg>\n);\n\nexport const RetryIcon = ({ className, size = 13 }: { className?: string; size?: number } = {}) => (\n <svg\n className={cn(\"hsk-retry-icon\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path className=\"hsk-retry-arrow\" d=\"M21.5 2v6h-6\" />\n <path className=\"hsk-retry-arc\" d=\"M21.34 15.57a10 10 0 1 1-.57-8.38l5.67-5.19\" />\n </svg>\n);\n\nexport const EditIcon = ({ className, size = 13 }: { className?: string; size?: number } = {}) => (\n <svg\n className={cn(\"hsk-edit-icon\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\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\" />\n <path className=\"hsk-edit-lead\" d=\"m15 5 4 4\" />\n </svg>\n);\n\nexport const CopyIcon = ({ className, size = 13 }: { className?: string; size?: number } = {}) => (\n <svg\n className={cn(\"hsk-copy-icon\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect className=\"hsk-copy-sheet\" x=\"8.5\" y=\"7\" width=\"12\" height=\"14\" rx=\"3.5\" />\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\" />\n </svg>\n);\n\nexport const CheckIcon = ({ className, size = 13 }: { className?: string; size?: number } = {}) => (\n <svg\n className={cn(\"hsk-check-icon\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline className=\"hsk-check-mark\" points=\"20 6 9 17 4 12\" />\n </svg>\n);\n\nexport const MicIcon = ({ className, size = 18 }: { className?: string; size?: number } = {}) => (\n <svg className={className} width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\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\"/>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\n </svg>\n);\n\nexport const MicOffIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line className=\"hsk-mic-slash\" x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\"/>\n <path d=\"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2\"/>\n <path d=\"M5 10v2a7 7 0 0 0 12 5\"/>\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\"/>\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\"/>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"/>\n </svg>\n);\n\nexport const WaveformIcon = ({ active }: { active?: boolean }) => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\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\" />\n <path className=\"hsk-wave-bar\" style={{ '--hsk-bar': 1, '--hsk-amp': 1.78, '--hsk-period': '0.94s' } as React.CSSProperties} d=\"M6 8v8\" />\n <path className=\"hsk-wave-bar\" style={{ '--hsk-bar': 2, '--hsk-amp': 1.26, '--hsk-period': '1.42s' } as React.CSSProperties} d=\"M10 4v16\" />\n <path className=\"hsk-wave-bar\" style={{ '--hsk-bar': 3, '--hsk-amp': 1.62, '--hsk-period': '1.08s' } as React.CSSProperties} d=\"M14 7v10\" />\n <path className=\"hsk-wave-bar\" style={{ '--hsk-bar': 4, '--hsk-amp': 2.05, '--hsk-period': '0.86s' } as React.CSSProperties} d=\"M18 9v6\" />\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\" />\n </svg>\n);\n\nexport const ArrowUpIcon = () => (\n <svg\n className=\"hsk-telegram-icon\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polygon className=\"hsk-kite-wing hsk-kite-wing--far\" points=\"22 2 11 13 2 9\" />\n <polygon className=\"hsk-kite-wing hsk-kite-wing--near\" points=\"22 2 15 22 11 13\" />\n <line className=\"hsk-kite-spine\" x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n </svg>\n);\n\nexport const SunIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle className=\"hsk-sun-core\" cx=\"12\" cy=\"12\" r=\"5\"/>\n <g className=\"hsk-sun-rays\">\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"/>\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"/>\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"/>\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"/>\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"/>\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"/>\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"/>\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"/>\n </g>\n </svg>\n);\n\nexport const MoonIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\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\"/>\n </svg>\n);\n\nexport const WoodIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path className=\"hsk-wood-layer\" style={{ '--hsk-layer': 0 } as React.CSSProperties} d=\"M12 2L2 7l10 5 10-5-10-5z\"/>\n <path className=\"hsk-wood-layer\" style={{ '--hsk-layer': 2 } as React.CSSProperties} d=\"M2 17l10 5 10-5\"/>\n <path className=\"hsk-wood-layer\" style={{ '--hsk-layer': 1 } as React.CSSProperties} d=\"M2 12l10 5 10-5\"/>\n </svg>\n);\n\nexport const HeartIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\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\"/>\n </svg>\n);\n\nexport const CoffeeIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M17 8h1a4 4 0 1 1 0 8h-1\"/>\n <path d=\"M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4z\"/>\n <line className=\"hsk-steam\" style={{ '--hsk-steam': 0 } as React.CSSProperties} x1=\"6\" y1=\"1\" x2=\"6\" y2=\"4\"/>\n <line className=\"hsk-steam\" style={{ '--hsk-steam': 1 } as React.CSSProperties} x1=\"10\" y1=\"1\" x2=\"10\" y2=\"4\"/>\n <line className=\"hsk-steam\" style={{ '--hsk-steam': 2 } as React.CSSProperties} x1=\"14\" y1=\"1\" x2=\"14\" y2=\"4\"/>\n </svg>\n);\n\nexport const StarIcon = () => (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 3a6.5 6.5 0 0 0 9 9 9 9 0 1 1-9-9z\"/>\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\"/>\n </svg>\n);\n\nexport const ShieldIcon = ({ size = 18 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\n <path d=\"m9 12 2 2 4-4\"/>\n </svg>\n);\n\nexport const KeyOutlineIcon = ({ size = 18 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m21 2-2 2m-1.5 1.5L14 9a5.5 5.5 0 1 0 2 2l3.5-3.5\"/>\n <circle cx=\"7.5\" cy=\"15.5\" r=\"2.5\"/>\n </svg>\n);\n\nexport const VaultIcon = ({ size = 18 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"3\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"m14.5 9.5-5 5\"/>\n </svg>\n);\n\nexport const GlobeIcon = ({ size = 18 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"2\" x2=\"22\" y1=\"12\" y2=\"12\"/>\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\"/>\n </svg>\n);\n\nexport const XIcon = ({ size = 11 }: { size?: number }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n);\n\nexport const PinIcon = ({ className, size = 16, filled = false }: { className?: string; size?: number; filled?: boolean } = {}) => (\n <svg\n className={cn(\"hsk-pin-icon\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={filled ? \"currentColor\" : \"none\"}\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"22\" />\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\" />\n </svg>\n);\n\nexport const ShareTrayIcon = ({ className, size = 16 }: { className?: string; size?: number } = {}) => (\n <svg\n className={cn(\"hsk-share-tray-icon\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8\" />\n <polyline points=\"16 6 12 2 8 6\" />\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"15\" />\n </svg>\n);\n\nexport const VisualSearchSparkleIcon = ({ className, size = 16 }: { className?: string; size?: number } = {}) => (\n <svg\n className={cn(\"hsk-visual-search-icon\", className)}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"10\" cy=\"10\" r=\"6.5\" />\n <line x1=\"21\" y1=\"21\" x2=\"14.65\" y2=\"14.65\" />\n <path\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\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n </svg>\n);\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_THEME: ThemeId = 'coffee';\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';\n\nexport function rubberBand(offset: number, dimension: number, coeff = 0.55): number {\n if (dimension <= 0) return 0;\n return (offset * dimension * coeff) / (dimension + coeff * Math.abs(offset));\n}\n\ntype SpringOpts = { stiffness?: number; damping?: number; onFrame: (v: number) => void; onRest?: () => void };\n\nexport function createSpring({ stiffness = 500, damping = 45, onFrame, onRest }: SpringOpts) {\n let value = 0, velocity = 0, target = 0;\n let raf: number | null = null;\n let last = 0;\n\n const tick = (now: number) => {\n const dt = Math.min(0.032, (now - last) / 1000) || 1 / 60;\n last = now;\n const steps = Math.max(1, Math.ceil(dt / 0.008));\n const h = dt / steps;\n for (let i = 0; i < steps; i++) {\n const a = -stiffness * (value - target) - damping * velocity;\n velocity += a * h;\n value += velocity * h;\n }\n if (Math.abs(value - target) < 0.5 && Math.abs(velocity) < 0.5) {\n value = target; velocity = 0; raf = null;\n onFrame(value); onRest?.();\n return;\n }\n onFrame(value);\n raf = requestAnimationFrame(tick);\n };\n\n const start = () => { if (raf === null) { last = performance.now(); raf = requestAnimationFrame(tick); } };\n\n return {\n\n track(v: number) {\n if (raf !== null) { cancelAnimationFrame(raf); raf = null; }\n value = v; velocity = 0; onFrame(value);\n },\n\n to(t: number, v0 = 0) { target = t; velocity = v0; start(); },\n get value() { return value; },\n stop() { if (raf !== null) { cancelAnimationFrame(raf); raf = null; } },\n };\n}\n\ntype Opts = {\n panel: () => HTMLElement | null;\n scroller: () => HTMLElement | null;\n onDismiss: () => void;\n\n quiescent?: () => boolean;\n enabled?: boolean;\n};\n\nexport function useDragToDismiss({ panel, scroller, onDismiss, quiescent, enabled = true }: Opts): void {\n const dismissRef = useRef(onDismiss);\n dismissRef.current = onDismiss;\n\n useEffect(() => {\n if (!enabled) return;\n const el = panel();\n if (!el) return;\n if (typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches) return;\n\n let dragging = false, startY = 0, startX = 0, offset = 0, pointerId = -1;\n let lastY = 0, lastT = 0, velocity = 0, decided = false, exiting = false;\n\n const apply = (v: number) => {\n el.style.transform = v === 0 ? '' : `translate3d(0, ${v}px, 0)`;\n const host = el.parentElement;\n if (host) host.style.opacity = v === 0 ? '' : String(Math.max(0.35, 1 - v / (el.offsetHeight || 1) * 1.1));\n };\n const spring = createSpring({\n onFrame: apply,\n onRest: () => {\n el.style.willChange = '';\n if (exiting) { exiting = false; dismissRef.current(); }\n },\n });\n\n const atTop = () => {\n const s = scroller();\n if (s && s.scrollTop > 0) return false;\n return quiescent ? quiescent() : true;\n };\n\n const onDown = (e: PointerEvent) => {\n if (e.pointerType === 'mouse' || !e.isPrimary) return;\n dragging = false; decided = false;\n pointerId = e.pointerId;\n startY = lastY = e.clientY; startX = e.clientX;\n lastT = e.timeStamp; velocity = 0;\n offset = spring.value;\n };\n\n const onMove = (e: PointerEvent) => {\n if (e.pointerId !== pointerId) return;\n const dy = e.clientY - startY;\n const dx = e.clientX - startX;\n\n if (!decided) {\n if (Math.abs(dy) < 6 && Math.abs(dx) < 6) return;\n decided = true;\n dragging = dy > 0 && Math.abs(dy) > Math.abs(dx) && atTop();\n if (dragging) {\n try { el.setPointerCapture(e.pointerId); } catch { }\n spring.stop();\n el.style.animation = 'none';\n el.style.willChange = 'transform';\n }\n }\n if (!dragging) return;\n\n const dt = e.timeStamp - lastT;\n if (dt > 0) velocity = ((e.clientY - lastY) / dt) * 1000;\n lastY = e.clientY; lastT = e.timeStamp;\n\n const raw = offset + dy;\n spring.track(raw < 0 ? -rubberBand(-raw, el.offsetHeight || 1) : raw);\n if (e.cancelable) e.preventDefault();\n };\n\n const onUp = (e: PointerEvent) => {\n if (e.pointerId !== pointerId) return;\n try { if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId); } catch { }\n pointerId = -1;\n if (!dragging) return;\n dragging = false;\n const h = el.offsetHeight || 1;\n const projected = spring.value + velocity * 0.12;\n if (projected > h * 0.3 || velocity > 900) {\n exiting = true;\n el.style.pointerEvents = 'none';\n spring.to(h, velocity);\n } else {\n spring.to(0, velocity);\n }\n };\n\n el.addEventListener('pointerdown', onDown, { passive: true });\n el.addEventListener('pointermove', onMove, { passive: false });\n el.addEventListener('pointerup', onUp, { passive: true });\n el.addEventListener('pointercancel', onUp, { passive: true });\n return () => {\n spring.stop();\n el.removeEventListener('pointerdown', onDown);\n el.removeEventListener('pointermove', onMove);\n el.removeEventListener('pointerup', onUp);\n el.removeEventListener('pointercancel', onUp);\n el.style.transform = ''; el.style.willChange = ''; el.style.animation = ''; el.style.pointerEvents = '';\n const host = el.parentElement;\n if (host) host.style.opacity = '';\n };\n }, [enabled, panel, scroller, quiescent]);\n}\n","const MAX_EDGE = 1536;\nconst QUALITY = 0.85;\n\nconst SKIP_UNDER_BYTES = 300 * 1024;\n\nfunction readAsDataURL(blob: Blob): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error ?? new Error('read failed'));\n reader.readAsDataURL(blob);\n });\n}\n\n// Small files, GIFs and SVGs go as they are; anything larger is decoded at its sending size and encoded off the main thread, so picking a photo never stalls the page.\nexport async function downscaleImage(file: File): Promise<string> {\n if (file.type === 'image/gif' || file.type === 'image/svg+xml' || file.size <= SKIP_UNDER_BYTES) {\n return readAsDataURL(file);\n }\n try {\n const probe = await createImageBitmap(file);\n const scale = Math.min(1, MAX_EDGE / Math.max(probe.width, probe.height));\n const w = Math.max(1, Math.round(probe.width * scale));\n const h = Math.max(1, Math.round(probe.height * scale));\n probe.close?.();\n\n const bitmap = await createImageBitmap(file, { resizeWidth: w, resizeHeight: h, resizeQuality: 'high' });\n try {\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n const cx = canvas.getContext('2d');\n if (!cx) return readAsDataURL(file);\n cx.drawImage(bitmap, 0, 0);\n const keepPNG = file.type === 'image/png';\n const blob = await new Promise<Blob | null>(resolve => canvas.toBlob(resolve, keepPNG ? 'image/png' : 'image/jpeg', QUALITY));\n if (!blob || blob.size >= file.size) return readAsDataURL(file);\n return readAsDataURL(blob);\n } finally {\n bitmap.close?.();\n }\n } catch {\n return readAsDataURL(file);\n }\n}\n","import React, { useEffect, useRef, useState } from 'react';\r\nimport { buildMarkRegions, type MarkRegion } from '../utils/markRegions';\r\n\r\ntype Tool = 'pen' | 'eraser' | 'select' | 'pin';\r\n\r\ninterface Point { x: number; y: number }\r\ninterface StrokeAction { kind: 'stroke'; tool: 'pen' | 'eraser'; size: number; points: Point[] }\r\ninterface PinAction { kind: 'pin'; x: number; y: number; id: string; label: string; size: number }\r\ntype Action = StrokeAction | PinAction;\r\ninterface Selection { points: Point[]; closed: boolean }\r\n\r\nconst MARK_COLOR = '#ff5a5a';\r\nconst MAX_EXPORT_DIM = 1280;\r\nconst MAX_PINS = 4;\r\nconst PIN_LABEL_MAX = 80;\r\n\r\nfunction wrapLabel(ctx: CanvasRenderingContext2D, text: string, maxWidth: number): string[] {\r\n const lines: string[] = [];\r\n let line = '';\r\n for (const word of text.split(/\\s+/)) {\r\n const next = line ? `${line} ${word}` : word;\r\n if (line && ctx.measureText(next).width > maxWidth) {\r\n lines.push(line);\r\n line = word;\r\n } else {\r\n line = next;\r\n }\r\n }\r\n if (line) lines.push(line);\r\n return lines.slice(0, 3);\r\n}\r\n\r\n// Anchored to the nearer edge near the sides, so a long label never runs off the photo.\r\nfunction labelPlacement(xPct: number, topPct: number): React.CSSProperties {\r\n const top = `${topPct}%`;\r\n if (xPct < 33) return { top, left: 8, transform: 'translateY(-100%)' };\r\n if (xPct > 67) return { top, right: 8, transform: 'translateY(-100%)' };\r\n return { top, left: `${xPct}%`, transform: 'translate(-50%, -100%)' };\r\n}\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>('pin');\r\n const nextPin = useRef(0);\r\n const [activePin, setActivePin] = useState<string | null>(null);\r\n const pinDrag = useRef<{ id: string; offset: Point } | null>(null);\r\n const [selectionHistory, setSelectionHistory] = useState<Selection[]>([{ points: [], closed: false }]);\r\n const selection = selectionHistory[selectionHistory.length - 1];\r\n const selectionId = useRef(`selection-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`);\r\n const vertexDrag = useRef<{ index: number; point: Point } | null>(null);\r\n const remember = (next: Selection) => setSelectionHistory(prev => [...prev.slice(-66), next]);\r\n const selecting = tool === 'select';\r\n const [actions, setActions] = useState<Action[]>([]);\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\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 return () => { el.onload = null; el.onerror = null; };\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') continue;\r\n lctx.save();\r\n lctx.globalCompositeOperation = a.tool === 'eraser' ? 'destination-out' : 'source-over';\r\n lctx.strokeStyle = MARK_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 }\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 const visiblePoints = selection.points.map((p, i) => vertexDrag.current?.index === i ? vertexDrag.current.point : p);\r\n if (visiblePoints.length) {\r\n ctx.save();\r\n ctx.beginPath();\r\n visiblePoints.forEach((p, i) => i ? ctx.lineTo(p.x, p.y) : ctx.moveTo(p.x, p.y));\r\n if (selection.closed) { ctx.closePath(); ctx.fillStyle = '#22c55e33'; ctx.fill(); }\r\n ctx.strokeStyle = '#22c55e';\r\n ctx.lineWidth = Math.max(2, dims.w / 400);\r\n ctx.stroke();\r\n ctx.restore();\r\n }\r\n for (const p of visiblePoints) {\r\n ctx.beginPath(); ctx.arc(p.x, p.y, Math.max(3, dims.w / 260), 0, Math.PI * 2);\r\n ctx.fillStyle = '#ffffff'; ctx.fill(); ctx.strokeStyle = '#15803d'; ctx.stroke();\r\n }\r\n for (const a of all) {\r\n if (a.kind !== 'pin') continue;\r\n const r = a.size;\r\n ctx.save();\r\n ctx.beginPath(); ctx.moveTo(a.x, a.y);\r\n ctx.bezierCurveTo(a.x - r * 2, a.y - r * 2, a.x - r, a.y - r * 3.5, a.x, a.y - r * 3.5);\r\n ctx.bezierCurveTo(a.x + r, a.y - r * 3.5, a.x + r * 2, a.y - r * 2, a.x, a.y);\r\n ctx.fillStyle = MARK_COLOR; ctx.fill(); ctx.lineWidth = Math.max(1, r / 7); ctx.strokeStyle = '#fff'; ctx.stroke();\r\n ctx.beginPath(); ctx.arc(a.x, a.y - r * 2.2, r * .5, 0, Math.PI * 2); ctx.fillStyle = '#fff'; ctx.fill();\r\n if (a.label) {\r\n ctx.font = `600 ${r * 1.2}px system-ui, sans-serif`; ctx.textAlign = 'center'; ctx.textBaseline = 'middle';\r\n const lines = wrapLabel(ctx, a.label, canvas.width * 0.32);\r\n const lineH = r * 1.5;\r\n const w = Math.min(canvas.width, Math.max(...lines.map(l => ctx.measureText(l).width)) + r);\r\n const h = lines.length * lineH + r * .4;\r\n const x = Math.max(w / 2, Math.min(canvas.width - w / 2, a.x));\r\n const bottom = Math.max(h, a.y - r * 3.7);\r\n ctx.fillStyle = 'rgba(0,0,0,.8)'; ctx.fillRect(x - w / 2, bottom - h, w, h);\r\n ctx.fillStyle = '#fff';\r\n lines.forEach((l, i) => ctx.fillText(l, x, bottom - h + r * .2 + lineH * (i + .5), w - r));\r\n }\r\n ctx.restore();\r\n }\r\n };\r\n\r\n useEffect(() => { paint(); }, [img, actions, selection, dims.w, dims.h]);\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: Math.max(0, Math.min(canvas.width, ((e.clientX - rect.left) / rect.width) * canvas.width)),\r\n y: Math.max(0, Math.min(canvas.height, ((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\r\n const removePin = (id: string) => {\r\n setActions(prev => prev.filter(a => a.kind !== 'pin' || a.id !== id));\r\n setActivePin(null);\r\n };\r\n\r\n // A tap away from an open label closes it; an unnamed pin goes with it.\r\n const closeActivePin = () => {\r\n const open = actions.find(a => a.kind === 'pin' && a.id === activePin);\r\n if (open?.kind === 'pin' && !open.label.trim()) removePin(open.id);\r\n else setActivePin(null);\r\n };\r\n\r\n const onPointerDown = (e: React.PointerEvent) => {\r\n if (!img) return;\r\n const p = toCanvasPoint(e);\r\n if (tool === 'pin') {\r\n const hit = actions.find(a => a.kind === 'pin' && Math.hypot(p.x - a.x, p.y - (a.y - a.size * 1.7)) < a.size * 2);\r\n if (hit?.kind === 'pin') {\r\n setActivePin(hit.id); e.currentTarget.setPointerCapture(e.pointerId);\r\n pinDrag.current = { id: hit.id, offset: { x: p.x - hit.x, y: p.y - hit.y } }; return;\r\n }\r\n if (activePin) { closeActivePin(); return; }\r\n if (actions.filter(a => a.kind === 'pin').length >= MAX_PINS) return;\r\n const id = `pin-${++nextPin.current}`;\r\n const size = Math.max(10, dims.w / canvasRef.current!.getBoundingClientRect().width * 9);\r\n setActions(prev => [...prev, { kind: 'pin', ...p, id, label: '', size }]);\r\n setActivePin(id); return;\r\n }\r\n if (tool === 'select') {\r\n const first = selection.points[0];\r\n const rect = canvasRef.current!.getBoundingClientRect();\r\n const hitRadius = 12 * dims.w / rect.width;\r\n if (!selection.closed && first && selection.points.length >= 3 && Math.hypot(p.x - first.x, p.y - first.y) < hitRadius) {\r\n remember({ ...selection, closed: true });\r\n } else {\r\n const index = selection.points.findIndex(v => Math.hypot(p.x - v.x, p.y - v.y) < hitRadius);\r\n if (index >= 0) { e.currentTarget.setPointerCapture(e.pointerId); vertexDrag.current = { index, point: p }; return; }\r\n if (selection.closed || selection.points.length >= 64) return;\r\n remember({ ...selection, points: [...selection.points, p] });\r\n }\r\n return;\r\n }\r\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\r\n drawingRef.current = { kind: 'stroke', tool, size: strokeSize(), points: [p] };\r\n paint(drawingRef.current);\r\n };\r\n const onPointerMove = (e: React.PointerEvent) => {\r\n if (pinDrag.current) {\r\n const { id, offset } = pinDrag.current; const p = toCanvasPoint(e);\r\n setActions(prev => prev.map(a => a.kind === 'pin' && a.id === id ? { ...a, x: Math.max(0, Math.min(dims.w, p.x - offset.x)), y: Math.max(0, Math.min(dims.h, p.y - offset.y)) } : a));\r\n return;\r\n }\r\n if (vertexDrag.current) { vertexDrag.current.point = toCanvasPoint(e); paint(); return; }\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 (pinDrag.current) { pinDrag.current = null; return; }\r\n if (vertexDrag.current) {\r\n const { index, point } = vertexDrag.current;\r\n vertexDrag.current = null;\r\n remember({ ...selection, points: selection.points.map((p, i) => i === index ? point : p) });\r\n return;\r\n }\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 pins = actions.filter((a): a is PinAction => a.kind === 'pin');\r\n const editingPin = pins.find(a => a.id === activePin);\r\n const canSend = !!img && !(selection.points.length > 0 && !selection.closed) &&\r\n pins.length > 0 && pins.every(p => p.label.trim());\r\n\r\n const handleSend = () => {\r\n if (!canSend || !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 const marks = buildMarkRegions(actions, dims.w, dims.h);\r\n if (selection.closed) {\r\n const normX = (x: number) => Math.round(x / dims.w * 1000);\r\n const normY = (y: number) => Math.round(y / dims.h * 1000);\r\n marks.unshift({\r\n gesture: 'selection', id: selectionId.current,\r\n box: [\r\n normY(Math.min(...selection.points.map(p => p.y))), normX(Math.min(...selection.points.map(p => p.x))),\r\n normY(Math.max(...selection.points.map(p => p.y))), normX(Math.max(...selection.points.map(p => p.x))),\r\n ],\r\n points: selection.points.map(p => [normX(p.x), normY(p.y)]),\r\n });\r\n }\r\n onSend(dataUrl, pins.map(p => p.label.trim()).join('; '), marks, drawn);\r\n } catch {\r\n setExportError(true);\r\n }\r\n };\r\n\r\n const hint = tool === 'pin' ? 'markupPinHint' : tool === 'select'\r\n ? (selection.closed ? 'markupSelectedHint' : 'markupOutlineHint') : 'markupSketchHint';\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\" role=\"status\">{t(hint)}</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 style={{ touchAction: 'none', cursor: selecting || tool === 'pin' ? 'crosshair' : undefined }}\r\n onPointerDown={onPointerDown}\r\n onPointerMove={onPointerMove}\r\n onPointerUp={onPointerUp}\r\n onPointerCancel={() => { pinDrag.current = null; vertexDrag.current = null; drawingRef.current = null; paint(); }}\r\n />\r\n {tool === 'pin' && editingPin && (\r\n <div\r\n className=\"hsk-markup-pinlabel\"\r\n style={labelPlacement(editingPin.x / dims.w * 100, Math.max(12, (editingPin.y - editingPin.size * 4) / dims.h * 100))}\r\n >\r\n <input\r\n autoFocus\r\n aria-label={t('markupPinLabel')}\r\n placeholder={t('markupPinLabelHint')}\r\n value={editingPin.label}\r\n maxLength={PIN_LABEL_MAX}\r\n style={{ width: `${Math.min(34, Math.max(16, editingPin.label.length + 2))}ch` }}\r\n onChange={e => setActions(prev => prev.map(a => a.kind === 'pin' && a.id === editingPin.id ? { ...a, label: e.target.value } : a))}\r\n onKeyDown={e => { if (e.key === 'Enter' || e.key === 'Escape') closeActivePin(); }}\r\n />\r\n <button aria-label={t('markupRemovePin')} title={t('markupRemovePin')} onClick={() => removePin(editingPin.id)}>×</button>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n <div className=\"hsk-markup-tools\">\r\n <button className={`hsk-markup-tool${tool === 'pin' ? ' hsk-markup-tool--on' : ''}`} onClick={() => setTool('pin')}>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" style={{ verticalAlign: 'middle', marginInlineEnd: 5 }} aria-hidden=\"true\"><path d=\"M20 10c0 6-8 12-8 12S4 16 4 10a8 8 0 1 1 16 0Z\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/></svg>\r\n {t('markupPin')}\r\n </button>\r\n <button className={`hsk-markup-tool${tool === 'select' ? ' hsk-markup-tool--on' : ''}`} onClick={() => { setActivePin(null); setTool('select'); }}>{t('markupSelect')}</button>\r\n <button className=\"hsk-markup-tool\" disabled={selection.closed || selection.points.length < 3} onClick={() => remember({ ...selection, closed: true })}>{t('markupCloseOutline')}</button>\r\n <button className={`hsk-markup-tool${tool === 'pen' ? ' hsk-markup-tool--on' : ''}`} onClick={() => { setActivePin(null); setTool('pen'); }}>{t('markupSketch')}</button>\r\n <button className={`hsk-markup-tool${tool === 'eraser' ? ' hsk-markup-tool--on' : ''}`} onClick={() => { setActivePin(null); setTool('eraser'); }}>{t('markupEraser')}</button>\r\n <button className=\"hsk-markup-tool\" onClick={() => selecting ? setSelectionHistory(prev => prev.length > 1 ? prev.slice(0, -1) : prev) : setActions(prev => prev.slice(0, -1))} disabled={selecting ? selectionHistory.length < 2 : actions.length === 0}>{t('markupUndo')}</button>\r\n <button className=\"hsk-markup-tool\" onClick={() => { setActions([]); setActivePin(null); setSelectionHistory([{ points: [], closed: false }]); setTool('pin'); }} disabled={actions.length === 0 && !selection.points.length}>{t('markupClear')}</button>\r\n <button className=\"hsk-markup-go\" onClick={handleSend} disabled={!canSend}>{t('markupSend')}</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' | 'selection' | 'pin';\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;\n id?: string;\n points?: [number, number][];\n targetBox?: [number, number, number, number];\n}\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; id?: string; label?: string }>,\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[] = [];\n const pins: MarkRegion[] = [];\n\r\n for (const a of actions) {\n if (a.kind === 'pin' && typeof a.x === 'number' && typeof a.y === 'number') {\n const p = { x: a.x, y: a.y };\n pins.push({ gesture: 'pin', id: a.id, text: a.label, box: norm(bbox([p, p]), width, height) });\n continue;\n }\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 [...pins, ...out, ...texts];\n}\r\n","import React, { useEffect, useRef, useState } from 'react';\n\ntype Rng = () => number;\n\nfunction hashSeed(s: string): number {\n let h = 2166136261 >>> 0;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return h >>> 0;\n}\n\nfunction mulberry32(seed: number): Rng {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\nconst smooth = (t: number) => t * t * (3 - 2 * t);\n\nfunction makeNoise(rng: Rng) {\n const size = 256;\n const lat = new Float32Array(size * size);\n for (let i = 0; i < lat.length; i++) lat[i] = rng();\n const at = (x: number, y: number) => lat[(y & 255) * size + (x & 255)];\n\n return (x: number, y: number) => {\n const xi = Math.floor(x);\n const yi = Math.floor(y);\n const xf = smooth(x - xi);\n const yf = smooth(y - yi);\n const a = at(xi, yi);\n const b = at(xi + 1, yi);\n const c = at(xi, yi + 1);\n const d = at(xi + 1, yi + 1);\n return (a + (b - a) * xf) * (1 - yf) + (c + (d - c) * xf) * yf;\n };\n}\n\nfunction poisson(w: number, h: number, r: number, rng: Rng): Array<[number, number]> {\n const cell = r / Math.SQRT2;\n const gw = Math.ceil(w / cell);\n const gh = Math.ceil(h / cell);\n const grid = new Int32Array(gw * gh).fill(-1);\n const pts: Array<[number, number]> = [];\n const active: number[] = [];\n\n const place = (x: number, y: number) => {\n const i = pts.length;\n pts.push([x, y]);\n grid[Math.floor(y / cell) * gw + Math.floor(x / cell)] = i;\n active.push(i);\n };\n\n const fits = (x: number, y: number) => {\n if (x < 0 || y < 0 || x >= w || y >= h) return false;\n const cx = Math.floor(x / cell);\n const cy = Math.floor(y / cell);\n for (let gy = Math.max(cy - 2, 0); gy <= Math.min(cy + 2, gh - 1); gy++) {\n for (let gx = Math.max(cx - 2, 0); gx <= Math.min(cx + 2, gw - 1); gx++) {\n const j = grid[gy * gw + gx];\n if (j < 0) continue;\n const dx = pts[j][0] - x;\n const dy = pts[j][1] - y;\n if (dx * dx + dy * dy < r * r) return false;\n }\n }\n return true;\n };\n\n place(rng() * w, rng() * h);\n while (active.length) {\n const ai = (rng() * active.length) | 0;\n const [px, py] = pts[active[ai]];\n let placed = false;\n for (let k = 0; k < 24; k++) {\n const ang = rng() * Math.PI * 2;\n const rad = r * (1 + rng());\n const x = px + Math.cos(ang) * rad;\n const y = py + Math.sin(ang) * rad;\n if (fits(x, y)) {\n place(x, y);\n placed = true;\n break;\n }\n }\n if (!placed) active.splice(ai, 1);\n }\n return pts;\n}\n\ntype Glyph = (ctx: CanvasRenderingContext2D, s: number, rng: Rng) => void;\n\nconst wob = (rng: Rng, k: number) => (rng() - 0.5) * k;\n\nconst motifs: Glyph[] = [\n (ctx, s, rng) => {\n const h = s * 0.5;\n const w = s * (0.14 + rng() * 0.04);\n const cap = s * 0.07;\n ctx.beginPath();\n ctx.moveTo(-w - cap * 0.6, -h);\n ctx.lineTo(w + cap * 0.6, -h);\n ctx.moveTo(-w, -h + cap);\n ctx.lineTo(w, -h + cap);\n ctx.moveTo(-w, -h + cap);\n ctx.lineTo(-w * 0.85, h - cap);\n ctx.moveTo(w, -h + cap);\n ctx.lineTo(w * 0.85, h - cap);\n ctx.moveTo(0, -h + cap * 1.7);\n ctx.lineTo(0, h - cap * 1.7);\n ctx.moveTo(-w, h - cap);\n ctx.lineTo(w, h - cap);\n ctx.moveTo(-w - cap * 0.6, h);\n ctx.lineTo(w + cap * 0.6, h);\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n const eave = -q * (0.18 + rng() * 0.1);\n ctx.beginPath();\n ctx.moveTo(-q, eave);\n ctx.lineTo(0, -q);\n ctx.lineTo(q, eave);\n ctx.closePath();\n ctx.moveTo(-q * 0.92, eave + q * 0.16);\n ctx.lineTo(q * 0.92, eave + q * 0.16);\n for (const x of [-0.62, -0.21, 0.21, 0.62]) {\n ctx.moveTo(q * x, eave + q * 0.16);\n ctx.lineTo(q * x, q * 0.8);\n }\n ctx.moveTo(-q, q * 0.8);\n ctx.lineTo(q, q * 0.8);\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n const belly = q * (0.48 + rng() * 0.12);\n ctx.beginPath();\n ctx.moveTo(-q * 0.2, -q * 0.86);\n ctx.lineTo(q * 0.2, -q * 0.86);\n ctx.moveTo(-q * 0.15, -q * 0.78);\n ctx.bezierCurveTo(-belly, -q * 0.3, -belly * 0.85, q * 0.6, 0, q * 0.86);\n ctx.bezierCurveTo(belly * 0.85, q * 0.6, belly, -q * 0.3, q * 0.15, -q * 0.78);\n ctx.moveTo(-q * 0.17, -q * 0.64);\n ctx.quadraticCurveTo(-belly * 1.16, -q * 0.48, -belly * 0.7, -q * 0.04);\n ctx.moveTo(q * 0.17, -q * 0.64);\n ctx.quadraticCurveTo(belly * 1.16, -q * 0.48, belly * 0.7, -q * 0.04);\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.moveTo(-q * 0.9, q * 0.52);\n ctx.quadraticCurveTo(0, -q * 0.18, q * 0.9, -q * 0.58);\n ctx.stroke();\n const n = 4 + ((rng() * 3) | 0);\n for (let i = 0; i < n; i++) {\n const t = 0.16 + (i / n) * 0.8;\n const px = -q * 0.9 + t * q * 1.8;\n const py = q * 0.52 - t * q * 1.16 + (1 - t) * t * q * 0.3;\n const dir = i % 2 ? 1 : -1;\n const l = q * (0.26 + rng() * 0.1);\n ctx.beginPath();\n ctx.moveTo(px, py);\n ctx.quadraticCurveTo(px + l * 0.5, py + dir * l * 0.66, px + l * 0.9, py + dir * l * 0.08);\n ctx.quadraticCurveTo(px + l * 0.42, py + dir * l * 0.04, px, py);\n ctx.stroke();\n }\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.moveTo(-q * 0.85, -q * 0.7);\n ctx.quadraticCurveTo(-q * 0.1, -q * 0.35, q * 0.2, q * 0.1);\n ctx.stroke();\n const drupes: Array<[number, number]> = [\n [-q * 0.45, -q * 0.12],\n [q * 0.05, q * 0.3],\n [q * 0.42, -q * 0.4],\n ];\n for (const [ox, oy] of drupes) {\n ctx.beginPath();\n ctx.moveTo(ox, oy - q * 0.28);\n ctx.lineTo(ox - q * 0.02, oy - q * 0.16);\n ctx.stroke();\n ctx.beginPath();\n ctx.ellipse(ox, oy, q * (0.15 + rng() * 0.04), q * 0.19, wob(rng, 0.5), 0, Math.PI * 2);\n ctx.stroke();\n }\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n for (const side of [-1, 1]) {\n ctx.beginPath();\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);\n ctx.stroke();\n for (let i = 0; i < 5; i++) {\n const a = -1.05 + (i / 4) * 2.1;\n const ax = Math.sin(a) * side * q * 0.72;\n const ay = Math.cos(a) * q * 0.72;\n const l = q * (0.2 + rng() * 0.08);\n ctx.beginPath();\n ctx.moveTo(ax, ay);\n ctx.quadraticCurveTo(ax + side * l * 0.9, ay - l * 0.5, ax + side * l * 0.6, ay - l * 1.05);\n ctx.stroke();\n }\n }\n },\n (ctx, s) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.moveTo(-q, q * 0.6);\n ctx.lineTo(q * 0.55, q * 0.6);\n ctx.lineTo(q * 0.55, -q * 0.6);\n ctx.lineTo(-q * 0.45, -q * 0.6);\n ctx.lineTo(-q * 0.45, q * 0.15);\n ctx.lineTo(q * 0.1, q * 0.15);\n ctx.lineTo(q * 0.1, -q * 0.18);\n ctx.stroke();\n },\n (ctx, s) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.moveTo(-q * 0.62, q * 0.8);\n ctx.lineTo(-q * 0.62, -q * 0.05);\n ctx.arc(0, -q * 0.05, q * 0.62, Math.PI, 0);\n ctx.lineTo(q * 0.62, q * 0.8);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(-q * 0.86, q * 0.8);\n ctx.lineTo(q * 0.86, q * 0.8);\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.arc(0, 0, q * 0.4, 0, Math.PI * 2);\n ctx.stroke();\n const off = rng() * 0.5;\n for (let i = 0; i < 8; i++) {\n const a = off + (i / 8) * Math.PI * 2;\n ctx.beginPath();\n ctx.moveTo(Math.cos(a) * q * 0.6, Math.sin(a) * q * 0.6);\n ctx.lineTo(Math.cos(a) * q * 0.94, Math.sin(a) * q * 0.94);\n ctx.stroke();\n }\n },\n (ctx, s) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.moveTo(-q * 0.44, q * 0.7);\n ctx.bezierCurveTo(-q, q * 0.2, -q * 0.8, -q * 0.7, -q * 0.3, -q * 0.6);\n ctx.moveTo(q * 0.44, q * 0.7);\n ctx.bezierCurveTo(q, q * 0.2, q * 0.8, -q * 0.7, q * 0.3, -q * 0.6);\n ctx.moveTo(-q * 0.32, -q * 0.64);\n ctx.lineTo(q * 0.32, -q * 0.64);\n ctx.moveTo(-q * 0.44, q * 0.7);\n ctx.lineTo(q * 0.44, q * 0.7);\n for (const x of [-0.16, 0.02, 0.2]) {\n ctx.moveTo(q * x, -q * 0.56);\n ctx.lineTo(q * x, q * 0.62);\n }\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n const lift = q * (0.4 + rng() * 0.18);\n ctx.beginPath();\n ctx.moveTo(-q, q * 0.16);\n ctx.quadraticCurveTo(-q * 0.5, -lift, 0, -q * 0.02);\n ctx.quadraticCurveTo(q * 0.5, -lift, q, q * 0.16);\n ctx.stroke();\n },\n];\n\nconst scribbles: Glyph[] = [\n (ctx, s, rng) => {\n const q = s * 0.5;\n let px = -q + wob(rng, q * 0.3);\n let py = wob(rng, q);\n ctx.beginPath();\n ctx.moveTo(px, py);\n const n = 4 + ((rng() * 4) | 0);\n for (let i = 0; i < n; i++) {\n const nx = px + (q * 2) / n + wob(rng, q * 0.5);\n const ny = wob(rng, q * 1.5);\n ctx.quadraticCurveTo(px + wob(rng, q * 0.9), py + wob(rng, q * 1.6), nx, ny);\n px = nx;\n py = ny;\n }\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n const turns = 2.2 + rng() * 1.6;\n const dir = rng() < 0.5 ? -1 : 1;\n ctx.beginPath();\n for (let i = 0; i <= 60; i++) {\n const t = i / 60;\n const a = dir * t * turns * Math.PI * 2;\n const rr = q * t * (0.9 + wob(rng, 0.06));\n const x = Math.cos(a) * rr;\n const y = Math.sin(a) * rr;\n if (i === 0) ctx.moveTo(x, y);\n else ctx.lineTo(x, y);\n }\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n const n = 4 + ((rng() * 4) | 0);\n const lean = wob(rng, 0.7);\n for (let i = 0; i < n; i++) {\n const x = -q + (i / (n - 1)) * q * 2 + wob(rng, q * 0.16);\n const len = q * (0.7 + rng() * 0.6);\n ctx.beginPath();\n ctx.moveTo(x - lean * len * 0.5, -len * 0.5);\n ctx.quadraticCurveTo(x + wob(rng, q * 0.2), 0, x + lean * len * 0.5, len * 0.5);\n ctx.stroke();\n }\n },\n (ctx, s, rng) => {\n const q = s * 0.5;\n const n = 2 + ((rng() * 3) | 0);\n const step = (q * 2) / n;\n ctx.beginPath();\n ctx.moveTo(-q, q * 0.4);\n for (let i = 0; i < n; i++) {\n const x = -q + i * step;\n const r = step * (0.42 + rng() * 0.18);\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));\n }\n ctx.stroke();\n },\n];\n\nconst specks: Glyph[] = [\n (ctx, s, rng) => {\n ctx.beginPath();\n ctx.arc(0, 0, s * 0.1 + rng() * s * 0.04, 0, Math.PI * 2);\n ctx.fill();\n },\n (ctx, s, rng) => {\n ctx.beginPath();\n ctx.arc(wob(rng, s * 0.04), wob(rng, s * 0.04), s * 0.32, 0, Math.PI * 2);\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const o = s * 0.4;\n const i = o * (0.2 + rng() * 0.12);\n ctx.beginPath();\n ctx.moveTo(0, -o);\n ctx.quadraticCurveTo(i, -i, o, 0);\n ctx.quadraticCurveTo(i, i, 0, o);\n ctx.quadraticCurveTo(-i, i, -o, 0);\n ctx.quadraticCurveTo(-i, -i, 0, -o);\n ctx.stroke();\n },\n (ctx, s, rng) => {\n const q = s * 0.4;\n ctx.beginPath();\n ctx.moveTo(-q, wob(rng, s * 0.08));\n ctx.quadraticCurveTo(0, wob(rng, s * 0.16), q, wob(rng, s * 0.08));\n ctx.stroke();\n },\n];\n\n// One per theme, drawn rarely and a touch brighter than the field around it.\nconst accents: Record<string, Glyph> = {\n light: (ctx, s) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.moveTo(0, -q);\n ctx.quadraticCurveTo(q * 0.16, -q * 0.16, q, 0);\n ctx.quadraticCurveTo(q * 0.16, q * 0.16, 0, q);\n ctx.quadraticCurveTo(-q * 0.16, q * 0.16, -q, 0);\n ctx.quadraticCurveTo(-q * 0.16, -q * 0.16, 0, -q);\n ctx.stroke();\n },\n dark: (ctx, s) => {\n const q = s * 0.44;\n ctx.beginPath();\n ctx.moveTo(-q * 0.6, -q * 0.5);\n ctx.lineTo(q * 0.6, -q * 0.5);\n ctx.lineTo(q, q * 0.05);\n ctx.lineTo(0, q);\n ctx.lineTo(-q, q * 0.05);\n ctx.closePath();\n ctx.moveTo(-q, q * 0.05);\n ctx.lineTo(q, q * 0.05);\n ctx.moveTo(-q * 0.6, -q * 0.5);\n ctx.lineTo(-q * 0.3, q * 0.05);\n ctx.lineTo(0, q);\n ctx.moveTo(q * 0.6, -q * 0.5);\n ctx.lineTo(q * 0.3, q * 0.05);\n ctx.lineTo(0, q);\n ctx.stroke();\n },\n mahogany: (ctx, s) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.moveTo(0, q);\n ctx.bezierCurveTo(-q * 0.9, q * 0.2, -q * 0.7, -q * 0.7, 0, -q);\n ctx.bezierCurveTo(q * 0.7, -q * 0.7, q * 0.9, q * 0.2, 0, q);\n ctx.moveTo(0, q * 0.86);\n ctx.lineTo(0, -q * 0.86);\n for (let i = 0; i < 3; i++) {\n const t = -0.34 + i * 0.36;\n ctx.moveTo(0, q * t);\n ctx.lineTo(q * 0.44, q * (t - 0.26));\n ctx.moveTo(0, q * t);\n ctx.lineTo(-q * 0.44, q * (t - 0.26));\n }\n ctx.stroke();\n },\n blush: (ctx, s) => {\n const q = s * 0.5;\n for (let i = 0; i < 5; i++) {\n const a = (i / 5) * Math.PI * 2 - Math.PI / 2;\n ctx.beginPath();\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);\n ctx.stroke();\n }\n ctx.beginPath();\n ctx.arc(0, 0, q * 0.19, 0, Math.PI * 2);\n ctx.stroke();\n },\n coffee: (ctx, s) => {\n const q = s * 0.5;\n ctx.beginPath();\n ctx.ellipse(0, 0, q * 0.6, q * 0.9, 0, 0, Math.PI * 2);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(0, -q * 0.84);\n ctx.bezierCurveTo(q * 0.34, -q * 0.3, -q * 0.34, q * 0.3, 0, q * 0.84);\n ctx.stroke();\n },\n midnight: (ctx, s) => {\n const q = s * 0.5;\n ctx.beginPath();\n for (let i = 0; i < 10; i++) {\n const r = i % 2 === 0 ? q : q * 0.4;\n const a = (i / 10) * Math.PI * 2 - Math.PI / 2;\n const x = Math.cos(a) * r;\n const y = Math.sin(a) * r;\n if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);\n }\n ctx.closePath();\n ctx.stroke();\n },\n};\n\nconst rgb = (s: string): [number, number, number] => {\n const p = s.split(',').map(n => parseFloat(n.trim()));\n return [p[0] || 0, p[1] || 0, p[2] || 0];\n};\n\nfunction mix(a: string, b: string, k: number): string {\n const A = rgb(a);\n const B = rgb(b);\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)})`;\n}\n\ninterface DoodleGlyph {\n x: number;\n y: number;\n roll: number;\n rotation: number;\n lineWidth: number;\n alpha: number;\n baseColor: string;\n shimmerColor: string;\n drawFn: (ctx: CanvasRenderingContext2D, size: number, rng: Rng) => void;\n size: number;\n seed: number;\n normDist: number;\n bloom: number; // when the opening bloom reaches this doodle, 0 at the dock corner\n glow: number; // how bright its glint is as it arrives; brighter on dark themes, where faint ink disappears\n ux: number; // direction away from the dock corner\n uy: number;\n dx?: number;\n dy?: number;\n dr?: number;\n hop?: number;\n}\n\nexport interface Thump { x: number; y: number; strength: number }\n\nconst thumpListeners = new Set<(t: Thump) => void>();\n\n// Something struck the table at a viewport point: the doodles lying on it jump and land a little moved.\nconst bloomListeners = new Set<() => void>();\n\n// Starts the opening bloom of a canvas that is waiting for the chat's content to appear.\nexport function bloomDoodles() {\n for (const start of bloomListeners) start();\n}\n\nexport function thumpDoodles(t: Thump) {\n thumpListeners.forEach(l => l(t));\n}\n\nconst JOLT_FRAME_MS = 83;\nconst JOLT_FRAMES = [\n { k: 0.45, hop: 1 },\n { k: 1.15, hop: 0.55 },\n { k: 0.95, hop: 0.12 },\n { k: 1, hop: 0 },\n];\nconst MAX_DRIFT = 7;\nconst MAX_TURN = 0.28;\n\nfunction getShimmerColor(seed: number, normDist: number, isDarkMode: boolean): string {\n // Exact rainbow spectrum as the animated placeholder text (0 -> 300 hue)\n const hue = Math.round((normDist * 300) % 360);\n const sat = isDarkMode ? 72 : 68;\n const light = isDarkMode ? 58 : 46;\n return `hsl(${hue}, ${sat}%, ${light}%)`;\n}\n\nfunction generateGlyphs(\n w: number,\n h: number,\n ink: string,\n tint: string,\n seed: number,\n isRTL: boolean,\n themeId?: string,\n originY = h, // the visible bottom edge, where the dock corner is\n): DoodleGlyph[] {\n const accent = themeId ? accents[themeId] : undefined;\n const rng = mulberry32(seed);\n const noise = makeNoise(mulberry32(seed ^ 0x9e3779b9));\n\n const area = w * h;\n const target = Math.max(40, Math.min(520, Math.round(area / 3100)));\n const raw = target / 0.48;\n const r = Math.max(26, Math.sqrt((0.7 * area) / raw));\n const pts = poisson(w, h, r, rng);\n\n const fa = 4.4 / Math.max(w, h);\n const fb = fa * 2.6;\n const reach = Math.hypot(w, h);\n const angle = rng() * Math.PI * 2;\n const ca = Math.cos(angle);\n const sa = Math.sin(angle);\n const poleX = w * (0.18 + rng() * 0.64);\n const poleY = h * (0.12 + rng() * 0.5);\n\n const glyphs: DoodleGlyph[] = [];\n const maxDist = Math.hypot(w, h) || 1;\n const jitter = mulberry32(seed ^ 0x5bd1e995);\n const ox = isRTL ? w : 0;\n const reachFromDock = Math.hypot(w, originY) || 1;\n // light ink means it is being drawn onto a dark surface\n const [ir, ig, ib] = ink.split(',').map(n => parseFloat(n) || 0);\n const isDarkMode = 0.2126 * ir + 0.7152 * ig + 0.0722 * ib > 128;\n\n for (const [x, y] of pts) {\n const d = noise(x * fa, y * fa) * 0.72 + noise(x * fb, y * fb) * 0.28;\n const t = Math.min(1, Math.max(0, (d - 0.26) / 0.44));\n if (rng() > t * t * (3 - 2 * t)) continue;\n const roll = rng();\n const bloom = Math.max(0, 1 - Math.hypot(x - poleX, y - poleY) / (reach * 0.72)) ** 1.6;\n const axis = ((x - w / 2) * ca + (y - h / 2) * sa) / reach + 0.5;\n const isLightMode = !isDarkMode;\n const alphaBase = isLightMode ? 0.055 : 0.028;\n const alpha = (alphaBase + rng() * (isLightMode ? 0.04 : 0.025)) * (0.75 + axis * 0.55) * (1 + bloom * 0.4);\n\n const baseColor = mix(ink, tint, bloom * 0.85);\n // The wave starts at the theme dock's bottom corner (left, or right in RTL) and sweeps to the opposite top corner.\n const normDist = ((isRTL ? w - x : x) + h - y) / (w + h || 1);\n\n const glyphSeed = (rng() * 0xffffff) | 0;\n const shimmerColor = getShimmerColor(glyphSeed, normDist, isDarkMode);\n\n let rotation = 0;\n let lineWidth = isLightMode ? 1.05 + rng() * 0.35 : 0.65 + rng() * 0.35;\n let size = 20;\n let drawFn = motifs[0];\n let alphaMul = 1;\n\n if (roll < 0.5) {\n rotation = wob(rng, 0.16);\n lineWidth = isLightMode ? 1.15 + rng() * 0.45 : 0.7 + rng() * 0.35;\n size = 20 + rng() * 16;\n drawFn = motifs[(rng() * motifs.length) | 0];\n } else if (roll < 0.82) {\n rotation = rng() * Math.PI * 2;\n lineWidth = isLightMode ? 0.95 + rng() * 0.4 : 0.6 + rng() * 0.4;\n size = 16 + rng() * 20;\n drawFn = scribbles[(rng() * scribbles.length) | 0];\n } else if (roll < 0.95 || !accent) {\n rotation = rng() * Math.PI * 2;\n lineWidth = isLightMode ? 0.85 + rng() * 0.35 : 0.55 + rng() * 0.35;\n size = 7 + rng() * 7;\n drawFn = specks[(rng() * specks.length) | 0];\n } else {\n rotation = wob(rng, 0.3);\n lineWidth = isLightMode ? 1.1 + rng() * 0.3 : 0.75 + rng() * 0.3;\n size = 15 + rng() * 9;\n drawFn = accent;\n alphaMul = 2.6;\n }\n\n glyphs.push({\n x,\n y,\n roll,\n rotation,\n lineWidth,\n alpha: alpha * alphaMul,\n baseColor,\n shimmerColor,\n drawFn,\n size,\n seed: glyphSeed,\n normDist,\n bloom: Math.min(1, Math.hypot(x - ox, y - originY) / reachFromDock) * 0.62 + jitter() * 0.08,\n glow: isDarkMode ? 0.2 : 0.06,\n ux: (x - ox) / (Math.hypot(x - ox, y - originY) || 1),\n uy: (y - originY) / (Math.hypot(x - ox, y - originY) || 1),\n });\n }\n\n return glyphs;\n}\n\nconst BLOOM_SPAN = 0.3;\n\nfunction easeOutBack(t: number) {\n const c = 1.2;\n return 1 + (c + 1) * (t - 1) ** 3 + c * (t - 1) ** 2;\n}\n\nfunction renderDoodles(\n ctx: CanvasRenderingContext2D,\n glyphs: DoodleGlyph[],\n w: number,\n h: number,\n shimmerProgress: number,\n alphaScale = 1,\n bloomT?: number, // the opening bloom's linear time, 0 to 1\n) {\n ctx.clearRect(0, 0, w, h);\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n\n const isShimmering = shimmerProgress >= 0 && shimmerProgress <= 1.4;\n const wavePos = isShimmering ? shimmerProgress * 1.4 - 0.2 : -999;\n const waveWidth = 0.30;\n\n for (const g of glyphs) {\n let alpha = g.alpha;\n let stroke = g.baseColor;\n let lw = g.lineWidth;\n let grow = 1;\n let driftX = 0;\n let driftY = 0;\n\n if (bloomT !== undefined) {\n // Each doodle eases in on its own clock, so the bloom spreads like a breath instead of a line.\n const lp = Math.min(1, Math.max(0, (bloomT - g.bloom) / BLOOM_SPAN));\n if (lp <= 0) continue;\n const settle = 1 - (1 - lp) ** 3;\n const glint = Math.sin(lp * Math.PI) ** 2;\n alpha = g.alpha * settle + glint * g.glow;\n stroke = mix(g.baseColor, g.shimmerColor, glint * (g.glow > 0.1 ? 0.85 : 0.55));\n lw = g.lineWidth * (1 + glint * 0.35);\n grow = 0.86 + 0.14 * easeOutBack(lp);\n driftX = -g.ux * (1 - settle) * 9;\n driftY = -g.uy * (1 - settle) * 9;\n } else if (isShimmering) {\n const diff = g.normDist - wavePos;\n\n if (diff > waveWidth) {\n alpha = g.alpha * 0.45;\n stroke = g.baseColor;\n lw = g.lineWidth;\n }\n else if (diff < -waveWidth) {\n alpha = g.alpha;\n stroke = g.baseColor;\n lw = g.lineWidth;\n }\n else {\n const surge = Math.cos((diff / waveWidth) * (Math.PI / 2)) ** 2;\n alpha = g.alpha + surge * 0.08;\n stroke = surge > 0.08 ? mix(g.baseColor, g.shimmerColor, surge * 0.65) : g.baseColor;\n lw = g.lineWidth * (1 + surge * 0.2);\n }\n }\n\n ctx.save();\n ctx.translate(g.x + (g.dx ?? 0) + driftX, g.y + (g.dy ?? 0) + driftY);\n ctx.rotate(g.rotation + (g.dr ?? 0));\n if (grow !== 1) ctx.scale(grow, grow);\n if (g.hop) {\n ctx.scale(1 + g.hop, 1 + g.hop);\n alpha *= 1 + g.hop * 2;\n }\n ctx.globalAlpha = Math.min(alpha * alphaScale, 1.0);\n ctx.strokeStyle = stroke;\n ctx.fillStyle = stroke;\n ctx.lineWidth = lw;\n\n const glyphRng = mulberry32(g.seed);\n g.drawFn(ctx, g.size, glyphRng);\n ctx.restore();\n }\n}\n\nconst KikuDoodles = React.memo(function KikuDoodles({\n seed = '',\n theme,\n dir,\n waitForContent = false,\n}: {\n seed?: string;\n theme?: string;\n dir?: string;\n waitForContent?: boolean; // hold the first bloom until bloomDoodles(), so it starts with what is on the chat\n}) {\n const ref = useRef<HTMLCanvasElement>(null);\n const isAnimatingRef = useRef(false);\n const animFrameRef = useRef(0);\n const cachedGlyphsRef = useRef<DoodleGlyph[] | null>(null);\n const lastWidthRef = useRef<number>(0);\n const coveredHeightRef = useRef<number>(0);\n const waitingRef = useRef(waitForContent);\n\n useEffect(() => {\n const cv = ref.current;\n if (!cv) return;\n\n const numeric = hashSeed(seed || 'kiku');\n let timer = 0;\n\n const tick = (startTime: number, duration: number, glyphs: DoodleGlyph[], isRTL: boolean) => (now: number) => {\n const elapsed = now - startTime;\n const rawProgress = Math.min(1, elapsed / duration);\n\n const w = cv.clientWidth;\n const h = cv.clientHeight;\n if (w && h) {\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\n const targetW = Math.round(w * dpr);\n const targetH = Math.round(h * dpr);\n if (cv.width !== targetW || cv.height !== targetH) {\n cv.width = targetW;\n cv.height = targetH;\n }\n const ctx = cv.getContext('2d');\n if (ctx) {\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n renderDoodles(ctx, glyphs, w, h, -1, 1, rawProgress);\n }\n }\n\n if (rawProgress < 1) {\n animFrameRef.current = requestAnimationFrame(tick(startTime, duration, glyphs, isRTL));\n } else {\n isAnimatingRef.current = false;\n const w = cv.clientWidth;\n const h = cv.clientHeight;\n const ctx = cv.getContext('2d');\n if (ctx && w && h) {\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n renderDoodles(ctx, glyphs, w, h, -1);\n }\n }\n };\n\n const updateCanvas = () => {\n const w = cv.clientWidth;\n const h = cv.clientHeight;\n if (!w || !h) return;\n\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\n const ctx = cv.getContext('2d');\n if (!ctx) return;\n\n const cs = getComputedStyle(cv);\n const ink = cs.getPropertyValue('--hsk-doodle-ink').trim() || '31,31,31';\n const tint = cs.getPropertyValue('--hsk-doodle-tint').trim() || ink;\n const isRTL = dir === 'rtl' || cs.direction === 'rtl' || cv.closest('[dir=\"rtl\"]') !== null;\n\n const fullScreenH = typeof window !== 'undefined' ? Math.max(h, window.innerHeight || 0) : h;\n\n const glyphs = generateGlyphs(w, fullScreenH, ink, tint, numeric, isRTL, theme, h);\n cachedGlyphsRef.current = glyphs;\n lastWidthRef.current = w;\n coveredHeightRef.current = fullScreenH;\n\n const targetW = Math.round(w * dpr);\n const targetH = Math.round(h * dpr);\n if (cv.width !== targetW || cv.height !== targetH) {\n cv.width = targetW;\n cv.height = targetH;\n }\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n\n if (waitingRef.current) {\n ctx.clearRect(0, 0, w, h);\n return;\n }\n\n const reducedMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;\n\n if (reducedMotion) {\n renderDoodles(ctx, glyphs, w, h, -1);\n return;\n }\n\n cancelAnimationFrame(animFrameRef.current);\n isAnimatingRef.current = true;\n const duration = 1500;\n const startTime = performance.now();\n animFrameRef.current = requestAnimationFrame(tick(startTime, duration, glyphs, isRTL));\n };\n\n // A height-only change (the keyboard) keeps the same doodles in place; only a new width lays them out again.\n const handleResize = () => {\n const glyphs = cachedGlyphsRef.current;\n const w = cv.clientWidth;\n const h = cv.clientHeight;\n if (glyphs && w === lastWidthRef.current && h <= coveredHeightRef.current) {\n if (isAnimatingRef.current || waitingRef.current || !h) return;\n const ctx = cv.getContext('2d');\n if (!ctx) return;\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\n cv.width = Math.round(w * dpr);\n cv.height = Math.round(h * dpr);\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n renderDoodles(ctx, glyphs, w, h, -1);\n return;\n }\n clearTimeout(timer);\n timer = window.setTimeout(updateCanvas, 20);\n };\n\n updateCanvas();\n\n const start = () => {\n if (!waitingRef.current) return;\n waitingRef.current = false;\n updateCanvas();\n };\n bloomListeners.add(start);\n const waitLimit = waitingRef.current ? window.setTimeout(start, 2000) : 0;\n\n const ro = new ResizeObserver(handleResize);\n ro.observe(cv);\n const scheme = window.matchMedia?.('(prefers-color-scheme: dark)');\n const handleSchemeChange = () => {\n updateCanvas();\n };\n scheme?.addEventListener?.('change', handleSchemeChange);\n\n let joltTimer = 0;\n const redraw = () => {\n const glyphs = cachedGlyphsRef.current;\n const ctx = cv.getContext('2d');\n const w = cv.clientWidth;\n const h = cv.clientHeight;\n if (!glyphs || !ctx || !w || !h) return;\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n renderDoodles(ctx, glyphs, w, h, -1);\n };\n const onThump = ({ x, y, strength }: Thump) => {\n const glyphs = cachedGlyphsRef.current;\n if (!glyphs || window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches) return;\n cancelAnimationFrame(animFrameRef.current);\n isAnimatingRef.current = false;\n clearTimeout(joltTimer);\n const r = cv.getBoundingClientRect();\n const ox = x - r.left;\n const oy = y - r.top;\n const rng = mulberry32((performance.now() * 997) | 0);\n const clamp = (v: number, m: number) => Math.max(-m, Math.min(m, v));\n const moves = glyphs.map(g => {\n const fx = g.dx ?? 0, fy = g.dy ?? 0, fr = g.dr ?? 0;\n const ax = g.x - ox, ay = g.y - oy;\n const d = Math.hypot(ax, ay) || 1;\n const s = strength * (0.18 + 0.82 * Math.exp(-d / 220));\n const push = s * (0.6 + rng() * 1.8);\n const tx = clamp(fx + (ax / d) * push + (rng() - 0.5) * s * 2, MAX_DRIFT);\n const ty = clamp(fy + (ay / d) * push + (rng() - 0.5) * s * 2, MAX_DRIFT);\n const tr = clamp(fr + (rng() - 0.5) * s * 0.12, MAX_TURN);\n return { g, fx, fy, fr, tx, ty, tr, lift: s * 0.09 };\n });\n let i = 0;\n const step = () => {\n const f = JOLT_FRAMES[i];\n for (const m of moves) {\n m.g.dx = m.fx + (m.tx - m.fx) * f.k;\n m.g.dy = m.fy + (m.ty - m.fy) * f.k;\n m.g.dr = m.fr + (m.tr - m.fr) * f.k;\n m.g.hop = m.lift * f.hop;\n }\n redraw();\n if (++i < JOLT_FRAMES.length) joltTimer = window.setTimeout(step, JOLT_FRAME_MS);\n };\n step();\n };\n thumpListeners.add(onThump);\n\n return () => {\n thumpListeners.delete(onThump);\n bloomListeners.delete(start);\n clearTimeout(waitLimit);\n clearTimeout(joltTimer);\n clearTimeout(timer);\n cancelAnimationFrame(animFrameRef.current);\n isAnimatingRef.current = false;\n ro.disconnect();\n scheme?.removeEventListener?.('change', handleSchemeChange);\n };\n }, [seed, theme, dir]);\n\n\n return <canvas className=\"hsk-cb-doodles\" ref={ref} aria-hidden=\"true\" />;\n});\n\nconst SHIMMER_SCALE = 3; // the field is laid out three times larger, then drawn at a third: a miniature, not a crowd\nconst SHIMMER_MS = 1800;\n\nexport function DoodleShimmer({ seed = '', theme, alphaScale = 1.8, weight = 0.6 }: { seed?: string; theme?: string; alphaScale?: number; weight?: number }) {\n const ref = useRef<HTMLCanvasElement>(null);\n\n useEffect(() => {\n const cv = ref.current;\n const ctx = cv?.getContext('2d');\n if (!cv || !ctx) return;\n let raf = 0;\n\n const start = () => {\n const w = cv.clientWidth;\n const h = cv.clientHeight;\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\n cv.width = Math.round(w * dpr);\n cv.height = Math.round(h * dpr);\n\n const cs = getComputedStyle(cv);\n const ink = cs.getPropertyValue('--hsk-doodle-ink').trim() || '31,31,31';\n const tint = cs.getPropertyValue('--hsk-doodle-tint').trim() || ink;\n const vw = w * SHIMMER_SCALE;\n const vh = h * SHIMMER_SCALE;\n const glyphs = generateGlyphs(vw, vh, ink, tint, hashSeed(seed || 'kiku'), false, theme);\n for (const g of glyphs) g.lineWidth *= SHIMMER_SCALE * weight; // weight is the share of the page's stroke, not a third\n ctx.setTransform(dpr / SHIMMER_SCALE, 0, 0, dpr / SHIMMER_SCALE, 0, 0);\n\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches) {\n renderDoodles(ctx, glyphs, vw, vh, -1, alphaScale);\n return;\n }\n\n const began = performance.now();\n const loop = (now: number) => {\n // Back and forth, so the wave never snaps the field dim at a restart.\n const k = ((now - began) % (SHIMMER_MS * 2)) / SHIMMER_MS;\n const tri = k < 1 ? k : 2 - k;\n renderDoodles(ctx, glyphs, vw, vh, ((1 - Math.cos(tri * Math.PI)) / 2) * 1.4, alphaScale);\n raf = requestAnimationFrame(loop);\n };\n raf = requestAnimationFrame(loop);\n };\n\n // Laid over a photo that may still be loading, so it waits for a real size.\n const ro = new ResizeObserver(() => {\n if (raf || !cv.clientWidth || !cv.clientHeight) return;\n ro.disconnect();\n start();\n });\n ro.observe(cv);\n return () => {\n ro.disconnect();\n cancelAnimationFrame(raf);\n };\n }, [seed, theme, alphaScale, weight]);\n\n return <canvas className=\"hsk-doodle-shimmer\" ref={ref} aria-hidden=\"true\" />;\n}\n\nconst VEIL_EXIT_MS = 300;\n\n// The shimmer laid over an image that is being sent or reworked: see-through doodles and a breathing halo, the picture left clear.\nexport function WorkingVeil({ active, seed, theme }: { active: boolean; seed?: string; theme?: string }) {\n const [shown, setShown] = useState(active);\n useEffect(() => {\n if (active) {\n setShown(true);\n return;\n }\n const t = setTimeout(() => setShown(false), VEIL_EXIT_MS);\n return () => clearTimeout(t);\n }, [active]);\n if (!shown) return null;\n return (\n <span className={`hsk-working-veil${active ? '' : ' is-leaving'}`} aria-hidden=\"true\">\n <DoodleShimmer seed={seed} theme={theme} alphaScale={18} weight={1.15} />\n </span>\n );\n}\n\nexport default KikuDoodles;\n","import React from 'react';\nimport type { AkropolysTheme, ChatSource, ChatAttachment } from '@akropolys/sdk';\nimport type { KikuButtonProps } from '../KikuButton';\n\nexport const DEFAULT_CHIPS: string[] = [];\n\nexport const LANGUAGE_CHOICES = [\n { value: 'English', native: 'English', tag: 'en', rtl: false },\n { value: 'Chinese', native: '中文', tag: 'zh', rtl: false },\n { value: 'Spanish', native: 'Español', tag: 'es', rtl: false },\n { value: 'Arabic', native: 'العربية', tag: 'ar', rtl: true },\n { value: 'Hindi', native: 'हिन्दी', tag: 'hi', rtl: false },\n { value: 'French', native: 'Français', tag: 'fr', rtl: false },\n { value: 'Swahili', native: 'Kiswahili', tag: 'sw', rtl: false },\n { value: 'Portuguese', native: 'Português', tag: 'pt', rtl: false },\n { value: 'Japanese', native: '日本語', tag: 'ja', rtl: false },\n { value: 'Urdu', native: 'اردو', tag: 'ur', rtl: true },\n];\n\nexport function endonymFor(lang: string | null | undefined, bcp47?: string | null): string | undefined {\n if (!lang) return undefined;\n const typed = lang.trim();\n if (!typed) return undefined;\n const l = typed.toLowerCase();\n const hit = LANGUAGE_CHOICES.find(\n x => x.value.toLowerCase() === l || x.native.toLowerCase() === l || x.tag === l\n );\n if (hit) return hit.native;\n if (LANGUAGE_METAS[l]?.endonym) return LANGUAGE_METAS[l].endonym;\n const byEndonym = Object.values(LANGUAGE_METAS).find(m => m.endonym?.toLowerCase() === l);\n if (byEndonym?.endonym) return byEndonym.endonym;\n\n const tag = bcp47 || (l.length <= 3 ? l : undefined);\n if (tag && typeof Intl !== 'undefined' && Intl.DisplayNames) {\n try {\n const dn = new Intl.DisplayNames([tag], { type: 'language' });\n const name = dn.of(tag);\n if (name && name.toLowerCase() !== tag.toLowerCase()) {\n return name;\n }\n } catch { }\n }\n\n return typed;\n}\n\nexport function isRTLText(s: string): boolean {\n for (const ch of s) {\n const code = ch.codePointAt(0) ?? 0;\n if (\n (code >= 0x0590 && code <= 0x08ff) || // Hebrew, Arabic, Syriac, Arabic Supplement, Thaana, NKo, Samaritan, Mandaic, Arabic Extended-A\n (code >= 0xfb1d && code <= 0xfdff) || // Hebrew/Arabic presentation forms A\n (code >= 0xfe70 && code <= 0xfeff) // Arabic presentation forms B\n ) {\n return true;\n }\n }\n return false;\n}\n\nexport const LANGUAGE_METAS: Record<string, { preparing: string; changeLang: string; rtl?: boolean; endonym?: string }> = {\n english: { preparing: 'Preparing in English…', changeLang: 'Change language', endonym: 'English' },\n swahili: { preparing: 'Inatayarisha kwa Kiswahili…', changeLang: 'Badilisha lugha', endonym: 'Kiswahili' },\n french: { preparing: 'Configuration en français…', changeLang: 'Changer de langue', endonym: 'Français' },\n spanish: { preparing: 'Configurando en español…', changeLang: 'Cambiar idioma', endonym: 'Español' },\n arabic: { preparing: 'جارٍ الإعداد باللغة العربية…', changeLang: 'تغيير اللغة', rtl: true, endonym: 'العربية' },\n portuguese: { preparing: 'Configurando em português…', changeLang: 'Alterar idioma', endonym: 'Português' },\n hindi: { preparing: 'हिन्दी में तैयार किया जा रहा है…', changeLang: 'भाषा बदलें', endonym: 'हिन्दी' },\n chinese: { preparing: '正在准备中文环境…', changeLang: '更改语言', endonym: '中文' },\n urdu: { preparing: 'اردو میں تیاری جاری ہے…', changeLang: 'زبان تبدیل کریں', rtl: true, endonym: 'اردو' },\n japanese: { preparing: '日本語を設定中…', changeLang: '言語を変更', endonym: '日本語' },\n german: { preparing: 'Wird auf Deutsch eingerichtet…', changeLang: 'Sprache ändern', endonym: 'Deutsch' },\n italian: { preparing: 'Configurazione in italiano…', changeLang: 'Cambia lingua', endonym: 'Italiano' },\n russian: { preparing: 'Настройка на русском…', changeLang: 'Изменить язык', endonym: 'Русский' },\n korean: { preparing: '한국어로 설정 중…', changeLang: '언어 변경', endonym: '한국어' },\n turkish: { preparing: 'Türkçe olarak hazırlanıyor…', changeLang: 'Dili değiştir', endonym: 'Türkçe' },\n vietnamese: { preparing: 'Đang thiết lập bằng Tiếng Việt…', changeLang: 'Đổi ngôn ngữ', endonym: 'Tiếng Việt' },\n indonesian: { preparing: 'Menyiapkan dalam Bahasa Indonesia…', changeLang: 'Ubah bahasa', endonym: 'Bahasa Indonesia' },\n malay: { preparing: 'Menyediakan dalam Bahasa Melayu…', changeLang: 'Tukar bahasa', endonym: 'Bahasa Melayu' },\n bahasa: { preparing: 'Menyediakan dalam Bahasa Melayu…', changeLang: 'Tukar bahasa', endonym: 'Bahasa Melayu' },\n polish: { preparing: 'Przygotowywanie w języku polskim…', changeLang: 'Zmień język', endonym: 'Polski' },\n dutch: { preparing: 'Instellen in het Nederlands…', changeLang: 'Taal wijzigen', endonym: 'Nederlands' },\n thai: { preparing: 'กำลังตั้งค่าเป็นภาษาไทย…', changeLang: 'เปลี่ยนภาษา', endonym: 'ไทย' },\n bengali: { preparing: 'বাংলায় প্রস্তুত করা হচ্ছে…', changeLang: 'ভাষা পরিবর্তন করুন', endonym: 'বাংলা' },\n tamil: { preparing: 'தமிழில் தயார் செய்யப்படுகிறது…', changeLang: 'மொழியை மாற்றவும்', endonym: 'தமிழ்' },\n telugu: { preparing: 'తెలుగులో సిద్ధం చేస్తోంది…', changeLang: 'భాషను మార్చండి', endonym: 'తెలుగు' },\n persian: { preparing: 'در حال آماده‌سازی به زبان فارسی…', changeLang: 'تغییر زبان', rtl: true, endonym: 'فارسی' },\n farsi: { preparing: 'در حال آماده‌سازی به زبان فارسی…', changeLang: 'تغییر زبان', rtl: true, endonym: 'فارسی' },\n greek: { preparing: 'Ρύθμιση στα ελληνικά…', changeLang: 'Αλλαγή γλώσσας', endonym: 'Ελληνικά' },\n hebrew: { preparing: 'מגדיר בעברית…', changeLang: 'שנה שפה', rtl: true, endonym: 'עברית' },\n burmese: { preparing: 'မြန်မာဘာသာဖြင့် ပြင်ဆင်နေသည်…', changeLang: 'ဘာသာစကားပြောင်းရန်', endonym: 'မြန်မာဘာသာ' },\n burma: { preparing: 'မြန်မာဘာသာဖြင့် ပြင်ဆင်နေသည်…', changeLang: 'ဘာသာစကားပြောင်းရန်', endonym: 'မြန်မာဘာသာ' },\n myanmar: { preparing: 'မြန်မာဘာသာဖြင့် ပြင်ဆင်နေသည်…', changeLang: 'ဘာသာစကားပြောင်းရန်', endonym: 'မြန်မာဘာသာ' },\n khmer: { preparing: 'កំពុងរៀបចំជាភាសាខ្មែរ…', changeLang: 'ប្តូរភាសា', endonym: 'ភាសាខ្មែរ' },\n cambodian: { preparing: 'កំពុងរៀបចំជាភាសាខ្មែរ…', changeLang: 'ប្តូរភាសា', endonym: 'ភាសាខ្មែរ' },\n swedish: { preparing: 'Ställer in på svenska…', changeLang: 'Byt språk', endonym: 'Svenska' },\n svenska: { preparing: 'Ställer in på svenska…', changeLang: 'Byt språk', endonym: 'Svenska' },\n sv: { preparing: 'Ställer in på svenska…', changeLang: 'Byt språk', endonym: 'Svenska' },\n kikuyu: { preparing: 'Gĩkũyũ gĩgĩthondekwo…', changeLang: 'Cenjia rũthiomi', endonym: 'Gĩkũyũ' },\n gikuyu: { preparing: 'Gĩkũyũ gĩgĩthondekwo…', changeLang: 'Cenjia rũthiomi', endonym: 'Gĩkũyũ' },\n akan: { preparing: 'Yɛresiesie wɔ Akan mu…', changeLang: 'Sesa kasa', endonym: 'Akan' },\n twi: { preparing: 'Yɛresiesie wɔ Twi mu…', changeLang: 'Sesa kasa', endonym: 'Twi' },\n yoruba: { preparing: 'Ngbaradi ni Èdè Yorùbá…', changeLang: 'Yi ede pada', endonym: 'Èdè Yorùbá' },\n amharic: { preparing: 'በአማርኛ በመዘጋጀት ላይ…', changeLang: 'ቋንቋ ቀይር', endonym: 'አማርኛ' },\n somali: { preparing: 'Diyaarinta af Soomaali…', changeLang: 'Beddel luqadda', endonym: 'Af-Soomaali' },\n soomaali: { preparing: 'Diyaarinta af Soomaali…', changeLang: 'Beddel luqadda', endonym: 'Af-Soomaali' },\n 'af-soomaali': { preparing: 'Diyaarinta af Soomaali…', changeLang: 'Beddel luqadda', endonym: 'Af-Soomaali' },\n so: { preparing: 'Diyaarinta af Soomaali…', changeLang: 'Beddel luqadda', endonym: 'Af-Soomaali' },\n hausa: { preparing: 'Shirya cikin Hausa…', changeLang: 'Canja harshe', endonym: 'Hausa' },\n zulu: { preparing: 'Ilungiselela ngesiZulu…', changeLang: 'Shintsha ulimi', endonym: 'isiZulu' },\n oromo: { preparing: 'Afaan Oromootiin qophaa\\'aa jira…', changeLang: 'Afaan jijjiiri', endonym: 'Afaan Oromoo' },\n luganda: { preparing: 'Tuteekateeka mu Oluganda…', changeLang: 'Kyusa olulimi', endonym: 'Oluganda' },\n igbo: { preparing: 'Na-akwadebe na Asụsụ Igbo…', changeLang: 'Gbanwee asụsụ', endonym: 'Asụsụ Igbo' },\n xhosa: { preparing: 'Ilungiselela ngesiXhosa…', changeLang: 'Tshintsha ulwimi', endonym: 'isiXhosa' },\n kinyarwanda: { preparing: 'Guteza imbere mu Kinyarwanda…', changeLang: 'Hindura ururimi', endonym: 'Ikinyarwanda' },\n lingala: { preparing: 'Kozala na Lingála…', changeLang: 'Bongola lokótá', endonym: 'Lingála' },\n shona: { preparing: 'Kugadzirira mu chiShona…', changeLang: 'Chinja mutauro', endonym: 'chiShona' },\n tigrinya: { preparing: 'ብትግርኛ ኣብ ምድላው ይርከብ…', changeLang: 'ቋንቋ ምቕያር', endonym: 'ትግርኛ' },\n wolof: { preparing: 'Waajal ci Wolof…', changeLang: 'Soppi làkk', endonym: 'Wolof' },\n afrikaans: { preparing: 'Berei voor in Afrikaans…', changeLang: 'Verander taal', endonym: 'Afrikaans' },\n};\n\nfunction formatLangName(str: string): string {\n const trimmed = str.trim();\n if (!trimmed) return '…';\n return trimmed.charAt(0).toUpperCase() + trimmed.slice(1);\n}\n\nexport function getLoadingMeta(lang: string | null | undefined) {\n if (!lang) {\n return {\n nativeName: '…',\n preparing: 'Preparing…',\n changeLang: '←',\n rtl: false,\n known: true,\n };\n }\n const l = lang.trim().toLowerCase();\n const hit = Object.entries(LANGUAGE_METAS).find(\n ([k, v]) => k === l || v.endonym?.toLowerCase() === l || endonymFor(k)?.toLowerCase() === l\n );\n if (hit) {\n return {\n nativeName: hit[1].endonym || endonymFor(lang) || formatLangName(lang),\n preparing: hit[1].preparing,\n changeLang: hit[1].changeLang,\n rtl: !!hit[1].rtl || isRTLText(hit[1].preparing),\n known: true,\n };\n }\n const rawName = endonymFor(lang) || lang;\n const nativeName = formatLangName(rawName);\n const rtl = isRTLText(nativeName);\n return {\n nativeName,\n preparing: `Preparing in ${nativeName}…`,\n changeLang: rtl ? 'تغيير' : 'Change',\n rtl,\n known: false,\n };\n}\n\n// Gemini's prebuilt voices; Live accepts every one. Genders from Google's Chirp 3 HD voice list.\nexport const LIVE_VOICES = [\n { name: 'Puck', trait: 'Upbeat', gender: 'male' },\n { name: 'Charon', trait: 'Informative', gender: 'male' },\n { name: 'Kore', trait: 'Firm', gender: 'female' },\n { name: 'Aoede', trait: 'Breezy', gender: 'female' },\n { name: 'Zephyr', trait: 'Bright', gender: 'female' },\n { name: 'Fenrir', trait: 'Excitable', gender: 'male' },\n { name: 'Leda', trait: 'Youthful', gender: 'female' },\n { name: 'Orus', trait: 'Firm', gender: 'male' },\n { name: 'Callirrhoe', trait: 'Easy-going', gender: 'female' },\n { name: 'Autonoe', trait: 'Bright', gender: 'female' },\n { name: 'Enceladus', trait: 'Breathy', gender: 'male' },\n { name: 'Iapetus', trait: 'Clear', gender: 'male' },\n { name: 'Umbriel', trait: 'Easy-going', gender: 'male' },\n { name: 'Algieba', trait: 'Smooth', gender: 'male' },\n { name: 'Despina', trait: 'Smooth', gender: 'female' },\n { name: 'Erinome', trait: 'Clear', gender: 'female' },\n { name: 'Algenib', trait: 'Gravelly', gender: 'male' },\n { name: 'Rasalgethi', trait: 'Informative', gender: 'male' },\n { name: 'Laomedeia', trait: 'Upbeat', gender: 'female' },\n { name: 'Achernar', trait: 'Soft', gender: 'female' },\n { name: 'Alnilam', trait: 'Firm', gender: 'male' },\n { name: 'Schedar', trait: 'Even', gender: 'male' },\n { name: 'Gacrux', trait: 'Mature', gender: 'female' },\n { name: 'Pulcherrima', trait: 'Forward', gender: 'female' },\n { name: 'Achird', trait: 'Friendly', gender: 'male' },\n { name: 'Zubenelgenubi', trait: 'Casual', gender: 'male' },\n { name: 'Vindemiatrix', trait: 'Gentle', gender: 'female' },\n { name: 'Sadachbia', trait: 'Lively', gender: 'male' },\n { name: 'Sadaltager', trait: 'Knowledgeable', gender: 'male' },\n { name: 'Sulafat', trait: 'Warm', gender: 'female' },\n] as const;\n\nexport type { VoicePhase } from '../../utils/voiceSession';\n\nexport const VOICE_STORAGE_KEY = 'hsk-live-voice';\n\nexport const ONBOARDING_UI_STRINGS: Record<string, string> = {\n langPlaceholder: \"Type your language…\",\n nameStepTitle: \"Good to meet you.\",\n nameStepAsk: \"What should I call you?\",\n namePlaceholder: \"Type your name…\",\n howShouldResultsLook: \"How do you want to see results?\",\n entityLangIntro: \"I will write to you in {lang}. Names stay as this website wrote them. For the other details, choose below.\",\n asWritten: \"Same as the website\",\n inLanguage: \"In {lang}\",\n namesAsWritten: \"Details stay exactly as the website wrote them.\",\n detailsTranslated: \"Details are translated. Numbers and links do not change.\",\n entityLangPlaceholder: \"Choose one, then press Continue…\",\n termsStepTitle: \"Privacy and terms\",\n termsStepSubtitle: \"Please read how kiku works on this website.\",\n termsPiiTitle: \"Your contact details\",\n termsPiiDesc: \"kiku never asks for your email, phone number or real name. Any name or nickname is fine.\",\n termsSessionTitle: \"A random code\",\n termsSessionDesc: \"Your browser keeps a random code so kiku can remember your conversation. The code is not linked to your name.\",\n termsMemoryTitle: \"What is kept\",\n termsMemoryDesc: \"Your questions (not kiku's answers) are kept so this website can improve. Things you save with @kiku are kept at mimi.akropolys.cloud, and only your secret key opens them.\",\n termsCookieTitle: \"This website's own rules\",\n termsCookieDesc: \"This website may use cookies or collect more information. kiku does not control this.\",\n termsAiTitle: \"From this website, explained by AI\",\n termsAiDesc: \"kiku answers from what this website really lists. The facts are the website's own; how kiku summarises, compares or translates them is AI and may read them differently. Check anything that matters on the website itself.\",\n termsAgreeButton: \"I agree\",\n termsAgreeCounting: \"I agree ({seconds}s)\",\n nameStepHint: \"Any name or nickname is fine.\",\n privacyMore: \"Read our full terms at\",\n continueButton: \"Continue\",\n termsPlaceholder: \"Please read the notes above…\",\n allSet: \"You are ready, {name}.\",\n replyingOriginal: \"I will write to you in {lang}. Results stay as this website wrote them. Ask me anything.\",\n replyingTranslated: \"I will write to you in {lang}. Results will be translated too. Ask me anything.\",\n greetReturning: \"Hello, {name}.\",\n greetReturningLead: \"What can I find for you today?\",\n defaultPlaceholder: \"Ask me anything…\",\n};\n\nexport const DEFAULT_UI_STRINGS = {\n back: 'Back',\n langPlaceholder: \"Type your language…\",\n nameStepTitle: \"Good to meet you.\",\n nameStepAsk: \"What should I call you?\",\n namePlaceholder: \"Type your name…\",\n attachImage: 'Attach a photo',\n vizUnavailable: 'The preview could not be loaded.',\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 calcDisclaimer: 'This is a calculation from live figures, not a guarantee — the market can move against it.',\n staleTitle: 'No longer available',\n staleRemoved: '{title} has been removed and is no longer on offer.',\n staleUnavailable: '{title} is currently unavailable.',\n keyPastePrompt: 'Paste your public id — or create one',\n keyPastePlaceholder: 'your public id…',\n keyUseMine: 'Use my id',\n keyCreating: 'Creating…',\n keyCreateNew: \"I'm new — create one\",\n keySecretTitle: 'Your secret key — shown once',\n keyDismiss: 'Dismiss',\n keyCopySecret: 'Copy',\n keyCopied: 'Copied',\n keySecretHint: 'Keep it private. It unlocks your memory.',\n keyPublicTitle: 'Your public id',\n keyCopyId: 'Copy id',\n greetReturning: \"Hello, {name}.\",\n greetReturningLead: \"What can I find for you today?\",\n howShouldResultsLook: \"How do you want to see results?\",\n entityLangIntro: \"I will write to you in {lang}. Names stay as this website wrote them. For the other details, choose below.\",\n asWritten: \"Same as the website\",\n inLanguage: \"In {lang}\",\n namesAsWritten: \"Details stay exactly as the website wrote them.\",\n detailsTranslated: \"Details are translated. Numbers and links do not change.\",\n entityLangPlaceholder: \"Choose one, then press Continue…\",\n termsStepTitle: \"Privacy and terms\",\n termsStepSubtitle: \"Please read how kiku works on this website.\",\n termsPiiTitle: \"Your contact details\",\n termsPiiDesc: \"kiku never asks for your email, phone number or real name. Any name or nickname is fine.\",\n termsSessionTitle: \"A random code\",\n termsSessionDesc: \"Your browser keeps a random code so kiku can remember your conversation. The code is not linked to your name.\",\n termsMemoryTitle: \"What is kept\",\n termsMemoryDesc: \"Your questions (not kiku's answers) are kept so this website can improve. Things you save with @kiku are kept at mimi.akropolys.cloud, and only your secret key opens them.\",\n termsCookieTitle: \"This website's own rules\",\n termsCookieDesc: \"This website may use cookies or collect more information. kiku does not control this.\",\n termsAiTitle: \"From this website, explained by AI\",\n termsAiDesc: \"kiku answers from what this website really lists. The facts are the website's own; how kiku summarises, compares or translates them is AI and may read them differently. Check anything that matters on the website itself.\",\n termsAgreeButton: \"I agree\",\n termsAgreeCounting: \"I agree ({seconds}s)\",\n nameStepHint: \"Any name or nickname is fine.\",\n privacyMore: \"Read our full terms at\",\n continueButton: \"Continue\",\n termsPlaceholder: \"Please read the notes above…\",\n allSet: \"You are ready, {name}.\",\n replyingTranslated: \"I will write to you in {lang}. Results will be translated too. Ask me anything.\",\n replyingOriginal: \"I will write to you in {lang}. Results stay as this website wrote them. Ask me anything.\",\n defaultPlaceholder: \"Ask me anything…\",\n voiceListening: 'Listening… tap the mic to stop',\n voiceSending: 'Got it — sending…',\n voiceModeStart: 'Hands-free conversation',\n voiceModeExit: 'Leave hands-free',\n voicePhaseListening: 'Listening',\n voicePhaseThinking: 'Thinking',\n micDenied: 'Microphone blocked. Allow mic access for this site, then try again.',\n micInsecure: 'Voice needs a secure (https) connection.',\n micMissing: 'No microphone found.',\n micLangUnsupported: 'This browser cannot transcribe that language yet. Type instead.',\n micNetwork: \"Couldn't reach voice. Try again in a moment.\",\n voiceUnavailable: 'Voice is unavailable right now. Try again in a moment.',\n voiceLimitReached: \"You've used up today's voice time. It resets in a day — chat still works.\",\n voiceSiteLimit: 'Voice is out of allowance on this site for now. Chat still works.',\n voiceIdleEnded: 'Voice closed after a quiet minute. Tap the mic to talk again.',\n voiceSessionEnded: 'Voice session ended. Tap the mic to talk again.',\n voicePhotoFailed: \"That photo couldn't be added. Try another one.\",\n voiceAttachPhoto: 'Attach a photo',\n voicePickerLabel: 'Choose a voice',\n voiceFemale: 'Female',\n voiceMale: 'Male',\n voiceNewChat: 'New voice chat',\n pillVoice: '{n} min voice',\n pillImages: '{n} images',\n pillVideos: '{n} videos',\n pillReplies: '{n} replies',\n micNoSpeech: \"Didn't catch anything. Try again, a little closer to the mic.\",\n micFailed: \"Couldn't hear that. Try again.\",\n clearChat: 'Clear chat',\n thinking: 'Thinking',\n thoughtForSeconds: 'Thought for {duration}',\n thoughtProcess: 'Thought process',\n reachingTeam: 'Getting a person',\n passedToTeam: 'Passed to a person',\n withTeam: 'Sent to the team · a person will reply here',\n repliedIn: 'Replied in {duration}',\n backWithKiku: 'Kiku is back with you',\n teamClosed: 'The team closed this conversation',\n teamJoined: 'Another team member joined the conversation',\n leaveHumanWarning: 'A person is replying here.',\n leaveHumanStay: 'Stay',\n leaveHumanKeep: 'Keep for later',\n leaveHumanConfirm: 'End request',\n requestsTitle: 'Your requests',\n requestWaiting: 'Waiting for a person',\n requestHuman: 'With a person',\n requestKiku: 'Answered',\n requestClosed: 'Closed',\n requestNewReply: 'New reply',\n captureAndRemember: 'kiku — capture & remember',\n captureCurrentPage: 'Capture current page',\n captureAll: 'Capture all ({count})',\n whatHaveYouSaved: 'What have you saved?',\n deleteThis: 'Delete this',\n errShopperReplyLimit: \"You've reached this site's reply limit.\",\n langStillLoading: 'Your language is still being prepared. Kiku will switch to it as soon as it is ready.',\n errAccessRevoked: 'Your access to the assistant has been revoked on this website.',\n errAccountRequired: 'Please create an account to continue using the chat assistant.',\n errStreamInterrupted: 'The reply was interrupted. Please try again.',\n errNetwork: \"The assistant couldn't respond just now — please try again in a moment.\",\n errGeneric: 'Something went wrong. Please try again.',\n vizWorking: 'Visualizing…',\n vizMarkEdit: 'Mark & edit',\n swatchTarget: 'Your colour',\n markupCancel: 'Cancel',\n markupSketch: 'Sketch',\n markupPin: 'Edit Pin',\n markupPinLabel: 'What should happen here?',\n markupPinLabelHint: 'e.g. move the sofa here',\n markupSketchHint: 'Sketch around an area, then drop a pin saying what to do with it.',\n markupRemovePin: 'Remove pin',\n markupPinHint: 'Drop a pin and say what should happen there. Drag to move it. Up to 4 pins.',\n markupSelect: 'Select outline',\n markupCloseOutline: 'Close outline',\n markupOutlineHint: 'Tap around the item, then close the outline. Undo removes the last point.',\n markupSelectedHint: 'Drag the outline points to refine, then drop a pin saying what to do with it.',\n markupEraser: 'Eraser',\n markupUndo: 'Undo',\n markupClear: 'Clear',\n markupSend: 'Send',\n markupDialogLabel: 'Mark up image',\n markupError: \"Couldn't process this image — try a newer visualization.\",\n markupLoadError: \"This image can't be edited here.\",\n markupLoading: 'Loading image…',\n openMemory: 'Open my memory on MiMi',\n errTooManyRequests: 'The assistant is currently receiving too many requests. Please try again in a few moments.',\n errTokenLimit: \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\",\n statusSent: 'Sent',\n statusStopped: 'Sent · reply stopped',\n queuedWaiting: 'Queued',\n queuedSendNow: 'Send now',\n jumpToLatest: 'Scroll to latest',\n timelineLabel: 'Questions in this conversation',\n voiceConnecting: 'Connecting — wait for the tone before speaking',\n stoppedByYou: 'You stopped this response.',\n stoppedInterrupted: 'This response was interrupted.',\n continueGenerating: 'Continue generating',\n generateResponse: 'Generate response',\n pillCompareTop2: 'Compare top 2',\n pillCompareTop2Query: 'Compare the {a} and {b}',\n pillMoreOn: 'More on {name}',\n pillMoreOnQuery: 'Tell me more about the {name}',\n pillSimilarOptions: 'Similar options',\n pillSimilarOptionsQuery: 'Show me more like the {name}',\n pillWhichBest: 'Which is best?',\n pillWhichBestQuery: 'Which one would you recommend and why?',\n pillFindAlternatives: 'Find alternatives',\n pillFindAlternativesQuery: 'What are good alternatives to the {name}?',\n pillShowPopular: 'Show popular items',\n pillShowPopularQuery: 'What are your most popular items?',\n pillRecommend: 'Recommend something',\n pillRecommendQuery: 'What do you recommend for me?',\n cardClickAnswer: 'The {name}',\n cardClickQuery: 'Tell me more about the {name}{details} — what are its key details, who is it best suited for, and what should I know?',\n displayCapture: 'capture {name}',\n displayCaptureAll: 'capture all ({count} items)',\n displayViewHistory: 'what have you saved?',\n displayDelete: 'delete this',\n retry: 'Retry',\n edit: 'Edit',\n copy: 'Copy',\n copied: 'Copied',\n msgFailed: 'Failed to send',\n} as const;\n\nexport type UIStringKey = keyof typeof DEFAULT_UI_STRINGS;\nexport type Translate = (key: UIStringKey, vars?: Record<string, string>) => string;\n\nexport const UIStringsContext = React.createContext<Translate>(\n (key, vars) => {\n let s: string = DEFAULT_UI_STRINGS[key];\n if (vars) for (const [k, v] of Object.entries(vars)) s = s.split(`{${k}}`).join(v);\n return s;\n }\n);\nexport const useT = () => React.useContext(UIStringsContext);\n\nexport function extractName(raw: string): string | null {\n let s = raw.trim();\n if (!s || s.length > 40 || s.includes('?')) return null;\n s = s.replace(/^(hi|hey|hello|yo)[,!.\\s]+/i, '');\n s = s.replace(/^(i['’]?m|im|my name is|call me|it['’]?s|this is|name['’]?s)\\s+/i, '');\n s = s.trim().replace(/[.!,]+$/, '');\n const words = s.split(/\\s+/);\n if (words.length === 0 || words.length > 3) return null;\n if (!/^[\\p{L}][\\p{L}\\-'’ ]{0,30}$/u.test(s)) return null;\n const q = s.toLowerCase();\n const queryish = ['phone', 'laptop', 'tv', 'cheap', 'best', 'under', 'buy', 'search', 'find', 'show', 'need', 'want', 'price', 'sofa', 'shoe', 'headphone', 'camera', 'gift', 'help'];\n if (queryish.some(w => q.includes(w))) return null;\n const name = words[0];\n return name.charAt(0).toUpperCase() + name.slice(1);\n}\n\nexport const SERVER_ERROR_STRINGS: Record<string, UIStringKey> = {\n shopper_reply_limit: 'errShopperReplyLimit',\n RATE_LIMIT_EXCEEDED: 'errShopperReplyLimit',\n access_revoked: 'errAccessRevoked',\n account_required: 'errAccountRequired',\n stream_interrupted: 'errStreamInterrupted',\n};\n\nexport const TERMINAL_ERROR_CODES = new Set(['account_required', 'access_revoked', 'shopper_reply_limit', 'RATE_LIMIT_EXCEEDED']);\n\nexport const isTerminalError = (code: string | null | undefined): boolean =>\n Boolean(code && TERMINAL_ERROR_CODES.has(code));\n\nexport const getFriendlyError = (err: any, tr: Translate) => {\n const code = err && typeof err === 'object' ? (err as { code?: string }).code : undefined;\n if (code && SERVER_ERROR_STRINGS[code]) return tr(SERVER_ERROR_STRINGS[code]);\n\n let str = '';\n if (typeof err === 'string') str = err;\n else if (err && typeof err === 'object' && err.message) str = err.message;\n else try { str = JSON.stringify(err); } catch { str = String(err); }\n\n const lower = str.toLowerCase();\n if (\n lower.includes('429') ||\n lower.includes('too many requests') ||\n lower.includes('requests per minute limit exceeded') ||\n lower.includes('too_many_requests_error') ||\n lower.includes('request_quota_exceeded') ||\n lower.includes('quota')\n ) {\n return tr('errTooManyRequests');\n }\n\n if (lower.includes('token limit')) {\n return tr('errTokenLimit');\n }\n\n if (lower.includes('failed to fetch') || lower.includes('networkerror') || lower.includes('request failed')) {\n return tr('errNetwork');\n }\n\n if (str) {\n try { console.warn('[kiku] untranslated error:', str); } catch { /* no console */ }\n }\n return tr('errGeneric');\n};\n\nexport const isSecureOrigin = () =>\n typeof window === 'undefined' || window.isSecureContext !== false;\n\nexport const KIKU_KEY_REVEAL_SECONDS = 15;\n\nexport interface ModalOrigin {\n x: number;\n y: number;\n}\n\nexport interface ChatModalProps extends Pick<KikuButtonProps, 'title' | 'logo' | 'placeholder' | 'backdropColor' | 'backdropBlur' | 'onSelectSource' | 'chips' | 'theme' | 'classNames' | 'enableVoice' | 'voiceLang' | 'enableVision' | 'ttsVoice'> {\n theme?: 'light' | 'dark' | AkropolysTheme;\n classNames?: any;\n origin?: ModalOrigin | null;\n onClose: () => void;\n}\n\n// A photo in the composer shows at once from its file; data fills in when the sending copy is ready.\nexport type ComposerAttachment = ChatAttachment & { thumb?: string };\n","import type { ScriptFont } from '@akropolys/sdk';\nimport { preloadScriptFont } from './hostFont';\n\nconst BASE_FONT = new WeakMap<object, Promise<ScriptFont | null>>();\nconst BASE_FONT_READY = new WeakMap<object, ScriptFont | null>();\n\n// Resolved base font for a client that already warmed, so a reopen mounts with it.\nexport function readyBaseFont(client: any): ScriptFont | null {\n return client ? BASE_FONT_READY.get(client) ?? null : null;\n}\n\nexport function cachedBaseFont(client: any): Promise<ScriptFont | null> {\n if (!client) return Promise.resolve(null);\n const hit = BASE_FONT.get(client);\n if (hit) return hit;\n const p = Promise.resolve()\n .then(() => client.baseFont?.() ?? null)\n .then((f: ScriptFont | null) => {\n if (f) {\n BASE_FONT_READY.set(client, f);\n preloadScriptFont(f, 0).catch(() => {});\n }\n return f;\n })\n .catch(() => null);\n BASE_FONT.set(client, p);\n return p;\n}\n\n// Pulled forward on hover/idle so the click doesn't pay for the round trips.\nexport function warmChrome(client: any, shopperLanguage: string, defaults: Record<string, string>): void {\n if (!client) return;\n cachedBaseFont(client);\n if (shopperLanguage) {\n warmLanguage(client, shopperLanguage, defaults);\n }\n}\n\nexport function warmLanguage(client: any, language: string, defaults: Record<string, string>): void {\n if (!client || !language) return;\n try {\n client.getUIStrings?.(language, defaults)?.then?.((res: any) => {\n if (res?.font) {\n preloadScriptFont(res.font, 1200).catch(() => {});\n }\n })?.catch?.(() => {});\n } catch { }\n}\n","import React, { useState, useEffect, useCallback } from 'react';\nimport type { ScriptFont, AkropolysTheme } from '@akropolys/sdk';\nimport { useAkropolysContext } from '@akropolys/sdk';\nimport { useScriptFontFace, preloadScriptFont, loadFontsFor, fontsLoadedFor } from '../../../utils/hostFont';\nimport { cachedBaseFont, readyBaseFont } from '../../../utils/chromeWarm';\nimport { DEFAULT_UI_STRINGS, ONBOARDING_UI_STRINGS, getLoadingMeta, type UIStringKey } from '../types';\n\nexport interface UseScriptFontOptions {\n shopperLanguage: string;\n theme?: 'light' | 'dark' | AkropolysTheme;\n preloadedStrings?: Record<string, string> | null;\n}\n\nconst LANGUAGE_CODES: Record<string, string> = {\n english: 'en', en: 'en',\n swahili: 'sw', kiswahili: 'sw', sw: 'sw',\n french: 'fr', français: 'fr', francais: 'fr', fr: 'fr',\n spanish: 'es', español: 'es', espanol: 'es', es: 'es',\n arabic: 'ar', 'العربية': 'ar', ar: 'ar',\n portuguese: 'pt', português: 'pt', pt: 'pt',\n hindi: 'hi', 'हिन्दी': 'hi', hi: 'hi',\n chinese: 'zh', '中文': 'zh', zh: 'zh',\n japanese: 'ja', '日本語': 'ja', ja: 'ja',\n urdu: 'ur', 'اردو': 'ur', ur: 'ur',\n burmese: 'my', burma: 'my', myanmar: 'my', 'မြန်မာ': 'my', 'မြန်မာဘာသာ': 'my', my: 'my',\n khmer: 'km', cambodian: 'km', 'ភាសាខ្មែរ': 'km', 'ខ្មែរ': 'km', km: 'km',\n persian: 'fa', farsi: 'fa', 'فارسی': 'fa', fa: 'fa', fas: 'fa',\n malay: 'ms', bahasa: 'ms', indonesian: 'id', 'bahasa melayu': 'ms', 'bahasa indonesia': 'id', ms: 'ms', id: 'id',\n amharic: 'am', 'አማርኛ': 'am', am: 'am',\n};\n\n// Direction and speech language only; the words come from /ui-strings (cached per language by the sdk).\nfunction knownLanguage(lang: string): { dir: 'ltr' | 'rtl'; bcp47: string } | null {\n const bcp47 = lang ? LANGUAGE_CODES[lang.trim().toLowerCase()] : undefined;\n if (!bcp47) return null;\n return { dir: bcp47 === 'ar' || bcp47 === 'ur' || bcp47 === 'fa' ? 'rtl' : 'ltr', bcp47 };\n}\n\nfunction resolveFirstFamily(varRef: string): string {\n const name = /var\\(\\s*(--[\\w-]+)/.exec(varRef)?.[1];\n if (!name || typeof document === 'undefined') return '';\n for (const el of [document.documentElement, document.body]) {\n const value = el ? getComputedStyle(el).getPropertyValue(name).trim() : '';\n if (value) return value.split(',')[0].trim();\n }\n return '';\n}\n\n// The clay page holds until the next page's letters are drawn in their own font, but never longer than this.\nconst FONT_WAIT_MS = 5000;\n\n// A language that is not ready by then, or failed to load, opens the chat in English and keeps trying behind it.\nconst LANG_WAIT_MS = 8000;\nconst LANG_RETRY_MS = [5000, 15000, 45000, 120000];\n\nexport function useScriptFont({ shopperLanguage, theme, preloadedStrings }: UseScriptFontOptions) {\n const client = useAkropolysContext();\n const cachedInitial = shopperLanguage ? (\n client?.getCachedUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS) ??\n client?.getCachedUIStrings?.(shopperLanguage, ONBOARDING_UI_STRINGS)\n ) : null;\n const initialStrings = (preloadedStrings && Object.keys(preloadedStrings).length > 0)\n ? preloadedStrings\n : (cachedInitial?.strings ?? {});\n const [chromeStrings, setChromeStrings] = useState<Record<string, string>>(() => initialStrings);\n const [chromeReady, setChromeReady] = useState<boolean>(() => !shopperLanguage || (preloadedStrings && Object.keys(preloadedStrings).length > 0) || !!cachedInitial?.complete);\n const [loadedLang, setLoadedLang] = useState<string>(() => {\n if (preloadedStrings && Object.keys(preloadedStrings).length > 0) return shopperLanguage;\n if (cachedInitial?.complete) return shopperLanguage;\n const isEn = !shopperLanguage || knownLanguage(shopperLanguage)?.bcp47 === 'en';\n return isEn ? (shopperLanguage || 'en') : '';\n });\n\n const isEn = !shopperLanguage || knownLanguage(shopperLanguage)?.bcp47 === 'en';\n let effectiveStrings = chromeStrings;\n if (preloadedStrings && Object.keys(preloadedStrings).length > 0) {\n effectiveStrings = { ...chromeStrings, ...preloadedStrings };\n }\n\n const dirKey = shopperLanguage ? `akropolys_ui_dir_${shopperLanguage.toLowerCase()}` : '';\n const [isRTL, setIsRTL] = useState<boolean>(() => {\n if (cachedInitial?.dir) return cachedInitial.dir === 'rtl';\n const known = knownLanguage(shopperLanguage);\n if (known) return known.dir === 'rtl';\n const meta = getLoadingMeta(shopperLanguage);\n if (meta?.rtl) return true;\n if (typeof window === 'undefined' || !dirKey) return false;\n try { return localStorage.getItem(dirKey) === 'rtl'; } catch { return false; }\n });\n const [speechLang, setSpeechLang] = useState(() => {\n return cachedInitial?.bcp47 || knownLanguage(shopperLanguage)?.bcp47 || '';\n });\n const [scriptFont, setScriptFont] = useState<ScriptFont | null>(() => cachedInitial?.font ?? null);\n const [baseFont, setBaseFont] = useState<ScriptFont | null>(() => readyBaseFont(client));\n const [baseFontReady, setBaseFontReady] = useState<boolean>(true);\n const [fontWait, setFontWait] = useState(false);\n const [langPending, setLangPending] = useState(false);\n const openedLangRef = React.useRef(shopperLanguage);\n\n // Sync synchronously during render if shopperLanguage changes, preventing any 1-frame flash of old strings\n const [prevShopperLanguage, setPrevShopperLanguage] = useState(shopperLanguage);\n if (shopperLanguage !== prevShopperLanguage) {\n setPrevShopperLanguage(shopperLanguage);\n const knownNow = knownLanguage(shopperLanguage);\n if (knownNow) {\n setIsRTL(knownNow.dir === 'rtl');\n setSpeechLang(knownNow.bcp47);\n }\n const cached = shopperLanguage ? (\n client?.getCachedUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS) ??\n client?.getCachedUIStrings?.(shopperLanguage, ONBOARDING_UI_STRINGS)\n ) : null;\n const sourceStrings = (preloadedStrings && Object.keys(preloadedStrings).length > 0)\n ? preloadedStrings\n : cached?.strings;\n if (sourceStrings && Object.keys(sourceStrings).length > 0) {\n setChromeStrings(sourceStrings);\n effectiveStrings = sourceStrings;\n if (cached) {\n if (cached.font) setScriptFont(cached.font);\n if (cached.dir) setIsRTL(cached.dir === 'rtl');\n if (cached.bcp47) setSpeechLang(cached.bcp47);\n }\n if (cached?.font) void preloadScriptFont(cached.font);\n setFontWait(!fontsLoadedFor([cached?.font?.family, baseFont?.family].filter((f): f is string => !!f), sourceStrings));\n setLoadedLang(shopperLanguage);\n setChromeReady(true);\n }\n }\n\n const effectiveChromeReady = isEn || (!fontWait && (\n (loadedLang.toLowerCase() === shopperLanguage.toLowerCase() && chromeReady) ||\n Object.keys(effectiveStrings).length > 0\n ));\n\n useEffect(() => {\n if (!shopperLanguage) {\n setSpeechLang('');\n setScriptFont(null);\n setChromeStrings({});\n setLoadedLang('');\n setChromeReady(true);\n setIsRTL(false);\n return;\n }\n const known = knownLanguage(shopperLanguage);\n const meta = getLoadingMeta(shopperLanguage);\n const isLangEn = known?.bcp47 === 'en';\n let cancelled = false;\n\n // Only a language picked during this visit holds the clay page; a returning visitor's page is never covered.\n const holdForFonts = (font: ScriptFont | null | undefined, strings: Record<string, string>) => {\n const families = [font?.family, baseFont?.family].filter((f): f is string => !!f);\n if (shopperLanguage === openedLangRef.current || fontsLoadedFor(families, strings)) {\n setFontWait(false);\n return;\n }\n setFontWait(true);\n loadFontsFor(families, strings, FONT_WAIT_MS).then(() => {\n if (!cancelled) setFontWait(false);\n });\n };\n\n const cachedFull = client?.getCachedUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS);\n if (cachedFull?.strings && Object.keys(cachedFull.strings).length > 0) {\n setChromeStrings(cachedFull.strings);\n setIsRTL(cachedFull.dir === 'rtl');\n setSpeechLang(cachedFull.bcp47 || known?.bcp47 || '');\n if (cachedFull.font) {\n void preloadScriptFont(cachedFull.font);\n setScriptFont(cachedFull.font);\n }\n holdForFonts(cachedFull.font, cachedFull.strings);\n setLoadedLang(shopperLanguage);\n setChromeReady(true);\n return () => {\n cancelled = true;\n };\n }\n\n const cachedOnboarding = client?.getCachedUIStrings?.(shopperLanguage, ONBOARDING_UI_STRINGS);\n if (cachedOnboarding?.strings && Object.keys(cachedOnboarding.strings).length > 0) {\n setChromeStrings(cachedOnboarding.strings);\n setIsRTL(cachedOnboarding.dir === 'rtl');\n setSpeechLang(cachedOnboarding.bcp47 || known?.bcp47 || '');\n if (cachedOnboarding.font) {\n void preloadScriptFont(cachedOnboarding.font);\n setScriptFont(cachedOnboarding.font);\n }\n holdForFonts(cachedOnboarding.font, cachedOnboarding.strings);\n setLoadedLang(shopperLanguage);\n setChromeReady(true);\n } else {\n setFontWait(false);\n setChromeStrings({});\n if (known) {\n setIsRTL(known.dir === 'rtl');\n setSpeechLang(known.bcp47);\n } else {\n if (meta?.rtl) setIsRTL(true);\n }\n if (!isLangEn) {\n setChromeReady(false);\n }\n }\n\n const openInEnglish = () => {\n if (cancelled) return;\n setLangPending(true);\n setLoadedLang(shopperLanguage);\n setChromeReady(true);\n setFontWait(false);\n };\n\n const tryLoad = async (): Promise<boolean> => {\n let got = Boolean(cachedOnboarding?.strings);\n try {\n if (!cachedOnboarding?.strings) {\n const resFast = await client.getUIStrings?.(shopperLanguage, ONBOARDING_UI_STRINGS);\n if (!cancelled && resFast?.complete) {\n got = true;\n setFontWait(true);\n setChromeStrings(prev => ({ ...prev, ...resFast.strings }));\n setIsRTL(resFast.dir === 'rtl');\n setSpeechLang(resFast.bcp47 || known?.bcp47 || '');\n try { localStorage.setItem(dirKey, resFast.dir); } catch { }\n if (resFast.font) void preloadScriptFont(resFast.font);\n const families = [resFast.font?.family, baseFont?.family].filter((f): f is string => !!f);\n await loadFontsFor(families, resFast.strings, FONT_WAIT_MS);\n if (!cancelled) {\n if (resFast.font) setScriptFont(resFast.font);\n setLoadedLang(shopperLanguage);\n setChromeReady(true);\n setFontWait(false);\n }\n }\n }\n\n const resFull = await client.getUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS);\n if (!cancelled && resFull?.complete) {\n got = true;\n setChromeStrings(prev => ({ ...prev, ...resFull.strings }));\n if (resFull.font) {\n await preloadScriptFont(resFull.font, 1200);\n if (!cancelled) setScriptFont(resFull.font);\n }\n }\n } catch {\n return false;\n }\n return got;\n };\n\n const slow = window.setTimeout(openInEnglish, LANG_WAIT_MS);\n (async () => {\n for (let attempt = 0; !cancelled; attempt++) {\n if (await tryLoad()) break;\n openInEnglish();\n if (attempt >= LANG_RETRY_MS.length) break;\n await new Promise(resolve => window.setTimeout(resolve, LANG_RETRY_MS[attempt]));\n }\n window.clearTimeout(slow);\n if (!cancelled) setLangPending(false);\n })();\n return () => {\n cancelled = true;\n window.clearTimeout(slow);\n setLangPending(false);\n };\n }, [shopperLanguage, client, dirKey]);\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n try {\n const f = await cachedBaseFont(client);\n if (!cancelled && f) setBaseFont(f);\n } catch {\n\n }\n if (!cancelled) setBaseFontReady(true);\n })();\n return () => { cancelled = true; };\n }, [client]);\n\n useScriptFontFace(scriptFont);\n useScriptFontFace(baseFont);\n\n const fontStack = React.useMemo(() => {\n const declared = typeof theme === 'object' && theme?.fontFamily ? theme.fontFamily : '';\n const first = declared.split(',')[0].trim();\n const isVarRef = /^var\\(/i.test(first);\n const hostName = first.replace(/^['\"]|['\"]$/g, '');\n const resolved = isVarRef ? resolveFirstFamily(first) : '';\n const host = isVarRef\n ? (resolved ? `${resolved}, ` : '')\n : (hostName ? `\"${hostName}\", ` : '');\n\n if (scriptFont) {\n return `\"${scriptFont.family}\", ${host}\"Geist\", system-ui, sans-serif`;\n }\n\n const l = shopperLanguage ? shopperLanguage.trim().toLowerCase() : '';\n if (l === 'japanese' || l === 'ja' || l === '日本語') {\n return `${host}\"Geist\", \"Hiragino Sans\", \"Hiragino Kaku Gothic ProN\", \"Yu Gothic\", \"Meiryo\", system-ui, sans-serif`;\n }\n if (l === 'chinese' || l === 'zh' || l === '中文') {\n return `${host}\"Geist\", \"PingFang SC\", \"Microsoft YaHei\", \"Hiragino Sans GB\", system-ui, sans-serif`;\n }\n if (l === 'urdu' || l === 'ur' || l === 'اردو') {\n return `\"Noto Nastaliq Urdu\", ${host}\"IBM Plex Sans Arabic\", \"Geist\", system-ui, sans-serif`;\n }\n if (l === 'arabic' || l === 'ar' || l === 'العربية') {\n return `\"IBM Plex Sans Arabic\", ${host}\"Geist\", system-ui, sans-serif`;\n }\n if (l === 'hindi' || l === 'hi' || l === 'हिन्दी') {\n return `\"Hind\", ${host}\"Geist\", system-ui, sans-serif`;\n }\n\n return undefined;\n }, [scriptFont, shopperLanguage, typeof theme === 'object' && theme ? theme.fontFamily : undefined]);\n\n const isNonLatin = React.useMemo(() => {\n let latin = 0;\n let other = 0;\n for (const v of Object.values(chromeStrings)) {\n for (const ch of v) {\n const c = ch.codePointAt(0) ?? 0;\n if (c < 0x00c0) continue;\n if (!/\\p{L}/u.test(ch)) continue;\n if (c <= 0x024f) latin++;\n else other++;\n }\n }\n return other > latin;\n }, [chromeStrings]);\n\n const [fontEpoch, setFontEpoch] = useState(0);\n useEffect(() => {\n if (typeof document === 'undefined' || !(document as any).fonts?.ready) return;\n let live = true;\n (document as any).fonts.ready.then(() => {\n if (live) setFontEpoch(e => e + 1);\n });\n return () => { live = false; };\n }, [scriptFont]);\n\n const hostFontCovers = React.useMemo(() => {\n if (!isNonLatin || typeof document === 'undefined') return true;\n const declared = typeof theme === 'object' && theme?.fontFamily ? theme.fontFamily : '';\n const first = declared.split(',')[0].trim();\n if (!first) return false;\n let sample = '';\n for (const v of Object.values(chromeStrings)) {\n if (v) { sample = v; break; }\n }\n if (!sample) return true;\n const text = sample.replace(/\\s+/g, '');\n if (!text) return true;\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) return true;\n const hostFamily = first.startsWith('var(')\n ? getComputedStyle(document.documentElement).getPropertyValue(first.slice(4, -1).trim()).trim() || first\n : first;\n ctx.font = `16px ${hostFamily}, __akropolys_nonexistent_font__`;\n const withHost = ctx.measureText(text).width;\n ctx.font = '16px __akropolys_nonexistent_font__';\n const withoutHost = ctx.measureText(text).width;\n return Math.abs(withHost - withoutHost) > 1;\n } catch {\n return true;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isNonLatin, chromeStrings, typeof theme === 'object' && theme ? theme.fontFamily : undefined, fontEpoch]);\n\n const t = useCallback((key: UIStringKey, vars?: Record<string, string>): string => {\n let s: string = effectiveStrings[key] || chromeStrings[key] || DEFAULT_UI_STRINGS[key] || key;\n if (vars) {\n for (const [k, v] of Object.entries(vars)) s = s.split(`{${k}}`).join(v);\n }\n return s;\n }, [effectiveStrings, chromeStrings]);\n\n const tNode = useCallback((key: UIStringKey, vars?: Record<string, string>) => {\n let s = effectiveStrings[key] || chromeStrings[key] || DEFAULT_UI_STRINGS[key] || key;\n return s.split(/(\\{[a-zA-Z]+\\})/g).map((part, i) => {\n const m = part.match(/^\\{([a-zA-Z]+)\\}$/);\n if (m && vars?.[m[1]] !== undefined) return <bdi key={i}>{vars[m[1]]}</bdi>;\n return <React.Fragment key={i}>{part}</React.Fragment>;\n });\n }, [effectiveStrings, chromeStrings]);\n\n return {\n chromeStrings,\n chromeReady: effectiveChromeReady,\n isRTL,\n speechLang,\n scriptFont,\n fontStack,\n isNonLatin,\n hostFontCovers,\n baseFontReady,\n langPending,\n t,\n tNode,\n };\n}\n","import { useState, useRef, useEffect, useLayoutEffect, 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 streaming: boolean;\r\n messageRefs: React.MutableRefObject<(HTMLDivElement | null)[]>;\r\n}\r\n\r\nexport function useChatScroll({ messages, loading, streaming, 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 // The answer outgrew the view: the reader stays with its start, and new lines below are not announced.\r\n const readingRef = useRef(false);\r\n const spacerRef = useRef<HTMLDivElement>(null);\r\n const anchorNodeRef = useRef<HTMLElement | null>(null);\r\n const prevLenRef = useRef(messages.length);\r\n const pendingAnchorRef = useRef(false);\r\n const layoutAnchorRef = useRef<(mode: 'glide' | 'sync') => void>(() => {});\r\n const followBottomRef = useRef<() => void>(() => {});\r\n const syncScrollRef = useRef<((to: number) => void) | null>(null);\r\n const releaseAnchorRef = useRef<() => void>(() => {});\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 spacerH = spacerRef.current?.offsetHeight ?? 0;\r\n const distance = el.scrollHeight - spacerH - el.scrollTop - el.clientHeight;\r\n const readerMoved = performance.now() - lastExternalScrollRef.current < 400;\r\n if (distance <= STICK_ON && (!readingRef.current || readerMoved)) {\r\n if (!stickToBottomRef.current) resetAlertArmingRef.current();\r\n stickToBottomRef.current = true;\r\n readingRef.current = false;\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 <= 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(() => { // rows resize after the commit (tables, images, fonts)\r\n if (anchorNodeRef.current) layoutAnchorRef.current('sync');\r\n else if (stickToBottomRef.current && !touchScrollingRef.current) followBottomRef.current();\r\n onScroll();\r\n });\r\n ro.observe(el);\r\n for (const node of messageRefs.current) if (node) ro.observe(node);\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 releaseAnchor = useCallback(() => {\r\n pendingAnchorRef.current = false;\r\n if (!anchorNodeRef.current) return;\r\n anchorNodeRef.current = null;\r\n if (spacerRef.current) spacerRef.current.style.height = '';\r\n }, []);\r\n releaseAnchorRef.current = releaseAnchor;\r\n\r\n followBottomRef.current = () => {\r\n const el = msgsContainerRef.current;\r\n if (!el) return;\r\n const bottom = el.scrollHeight - el.clientHeight;\r\n if (syncScrollRef.current) syncScrollRef.current(bottom);\r\n else el.scrollTop = bottom;\r\n };\r\n\r\n layoutAnchorRef.current = (mode) => {\r\n const el = msgsContainerRef.current;\r\n const spacer = spacerRef.current;\r\n const node = anchorNodeRef.current;\r\n const move = (to: number) => {\r\n const fn = mode === 'sync' ? syncScrollRef.current : glideScrollRef.current;\r\n if (fn) fn(to);\r\n else if (el) el.scrollTop = to;\r\n };\r\n const followBottom = followBottomRef.current;\r\n\r\n if (!el || !spacer || !node || !node.isConnected) {\r\n releaseAnchor();\r\n if (stickToBottomRef.current) followBottom();\r\n return;\r\n }\r\n\r\n const padTop = parseFloat(getComputedStyle(el).paddingTop) || 0;\r\n if (spacer.offsetHeight < el.clientHeight) spacer.style.height = `${el.clientHeight}px`; // defeat margin-top:auto before measuring\r\n const top = Math.max(0, node.offsetTop - padTop);\r\n const need = top + el.clientHeight - (el.scrollHeight - spacer.offsetHeight);\r\n\r\n if (need <= 0) {\r\n // Following the bottom from here dragged the reader away from the start of the answer on every new line.\r\n releaseAnchor();\r\n stickToBottomRef.current = false;\r\n readingRef.current = true;\r\n move(top);\r\n return;\r\n }\r\n\r\n if (need !== spacer.offsetHeight) spacer.style.height = `${need}px`; // exact: integer scrollHeight flickers +-1 per token\r\n move(top);\r\n };\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 - 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 readingRef.current = false;\r\n releaseAnchorRef.current();\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 useLayoutEffect(() => {\r\n const container = msgsContainerRef.current;\r\n if (!container) return;\r\n\r\n const added = messages.slice(prevLenRef.current);\r\n prevLenRef.current = messages.length;\r\n if (added.some(m => m.role === 'user')) {\r\n stickToBottomRef.current = true;\r\n readingRef.current = false;\r\n resetAlertArmingRef.current();\r\n anchorNodeRef.current = null;\r\n pendingAnchorRef.current = true;\r\n }\r\n\r\n if (pendingAnchorRef.current) {\r\n pendingAnchorRef.current = false;\r\n for (let i = messageRefs.current.length - 1; i >= 0; i--) {\r\n const node = messageRefs.current[i];\r\n if (node?.dataset.hskRole === 'user') { anchorNodeRef.current = node; break; }\r\n }\r\n if (anchorNodeRef.current) { layoutAnchorRef.current('glide'); return; }\r\n }\r\n if (anchorNodeRef.current) { layoutAnchorRef.current('glide'); return; }\r\n\r\n const before = container.scrollTop;\r\n if (!stickToBottomRef.current) {\r\n if (!readingRef.current) {\r\n markUnread();\r\n notifyNewBelow(messages.length);\r\n }\r\n } else if (!touchScrollingRef.current) {\r\n followBottomRef.current(); // exact, not eased: easing lags growth and bobs the last line\r\n return;\r\n }\r\n if (container.scrollTop !== before) resyncScrollRef.current();\r\n }, [messages, loading, streaming, 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 syncScrollRef.current = (to: number) => {\r\n const next = Math.round(Math.max(0, Math.min(el.scrollHeight - el.clientHeight, to)));\r\n if (rafId !== null) { cancelAnimationFrame(rafId); rafId = null; el.classList.remove('hsk-scrolling'); }\r\n el.scrollTop = next;\r\n target = current = written = el.scrollTop;\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 anchorNodeRef.current = null; // spacer keeps its height: collapsing it mid-scroll clamps and jumps\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 anchorNodeRef.current = null; // spacer keeps its height: collapsing it under a moving finger clamps and jumps\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 syncScrollRef.current = null;\r\n };\r\n }, []);\r\n\r\n return {\r\n msgsContainerRef,\r\n spacerRef,\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, useRef, useEffect } from 'react';\r\n\r\nconst WINDOW_MS = 450;\r\nconst MIN_CPS = 45;\r\nconst MAX_CPS = 900;\r\nconst RATE_EASE_MS = 180;\r\n\r\nexport function usePacedText(content: string) {\r\n const [shown, setShown] = useState(content);\r\n const shownRef = useRef(content);\r\n const targetRef = useRef(content);\r\n const rateRef = useRef(0);\r\n const carryRef = useRef(0);\r\n const lastRef = useRef(0);\r\n const rafRef = useRef<number | null>(null);\r\n\r\n useEffect(() => () => { if (rafRef.current !== null) cancelAnimationFrame(rafRef.current); }, []);\r\n\r\n useEffect(() => {\r\n targetRef.current = content;\r\n const reduced = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\r\n // a rewritten message (retry, edit, new turn) is no longer a prefix -- show it whole\r\n if (reduced || !content.startsWith(shownRef.current)) {\r\n if (rafRef.current !== null) { cancelAnimationFrame(rafRef.current); rafRef.current = null; }\r\n shownRef.current = content;\r\n rateRef.current = 0;\r\n carryRef.current = 0;\r\n setShown(content);\r\n return;\r\n }\r\n if (rafRef.current !== null || shownRef.current.length >= content.length) return;\r\n\r\n lastRef.current = performance.now();\r\n const step = (now: number) => {\r\n const dt = Math.min(now - lastRef.current, 50);\r\n lastRef.current = now;\r\n const target = targetRef.current;\r\n const backlog = target.length - shownRef.current.length;\r\n const want = Math.min(MAX_CPS, Math.max(MIN_CPS, (backlog * 1000) / WINDOW_MS));\r\n rateRef.current += (want - rateRef.current) * (1 - Math.exp(-dt / RATE_EASE_MS));\r\n carryRef.current += (rateRef.current * dt) / 1000;\r\n const whole = Math.floor(carryRef.current);\r\n if (whole > 0) {\r\n carryRef.current -= whole;\r\n shownRef.current = target.slice(0, Math.min(target.length, shownRef.current.length + whole));\r\n setShown(shownRef.current);\r\n }\r\n if (shownRef.current.length < targetRef.current.length) {\r\n rafRef.current = requestAnimationFrame(step);\r\n } else {\r\n rafRef.current = null;\r\n carryRef.current = 0;\r\n }\r\n };\r\n rafRef.current = requestAnimationFrame(step);\r\n }, [content]);\r\n\r\n return shown;\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 if (navigator.clipboard && window.isSecureContext) await navigator.clipboard.writeText(val);\r\n else copyWithSelection(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\r\n// The async clipboard API is absent on plain-http pages, such as a phone preview over the LAN.\r\nfunction copyWithSelection(val: string) {\r\n const area = document.createElement('textarea');\r\n area.value = val;\r\n area.setAttribute('readonly', '');\r\n area.style.cssText = 'position:fixed;top:0;left:0;opacity:0;';\r\n document.body.appendChild(area);\r\n area.select();\r\n area.setSelectionRange(0, val.length);\r\n const ok = document.execCommand('copy');\r\n area.remove();\r\n if (!ok) throw new Error('copy failed');\r\n}\r\n","import { useCallback } from 'react';\nimport type { ChatSource, ChatAttachment, CaptureTarget } from '@akropolys/sdk';\nimport type { UIStringKey, ComposerAttachment } from '../types';\n\nexport interface UseChatCommandsOptions {\n attachments: ComposerAttachment[];\n setAttachments: React.Dispatch<React.SetStateAction<ComposerAttachment[]>>;\n setInput: React.Dispatch<React.SetStateAction<string>>;\n send: (\n prompt: string,\n displayContent?: string,\n attachments?: ChatAttachment[],\n forcedIntent?: string,\n captureTargets?: CaptureTarget[]\n ) => Promise<any>;\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\n}\n\nexport function useChatCommands({\n attachments,\n setAttachments,\n setInput,\n send,\n t,\n}: UseChatCommandsOptions) {\n const handleKikuCapture = useCallback((product: ChatSource) => {\n const name = product.name || '';\n const display = `@kiku ${t('displayCapture', { name }).trim()}`;\n const q = name || 'capture current page';\n setInput('');\n const toSend = attachments;\n setAttachments([]);\n send(q, display, toSend.length > 0 ? toSend : undefined, 'capture');\n }, [attachments, send, setAttachments, setInput, t]);\n\n const handleKikuCaptureAll = useCallback((products: ChatSource[]) => {\n const targets: CaptureTarget[] = products\n .filter(p => p.id)\n .map(p => ({\n name: p.name || '',\n url: (p as any).url || '',\n image: p.image || '',\n }));\n const names = products.map(p => p.name).filter(Boolean).join(', ');\n const display = `@kiku ${t('displayCaptureAll', { count: String(products.length) })}`;\n setInput('');\n setAttachments([]);\n send(names || 'capture all', display, undefined, 'capture_all', targets);\n }, [send, setAttachments, setInput, t]);\n\n const handleKikuViewHistory = useCallback(() => {\n const display = `@kiku ${t('displayViewHistory')}`;\n setInput('');\n setAttachments([]);\n send('show my saved items', display, undefined, 'view_history');\n }, [send, setAttachments, setInput, t]);\n\n const handleKikuDelete = useCallback(() => {\n const display = `@kiku ${t('displayDelete')}`;\n setInput('');\n setAttachments([]);\n send('delete this', display, undefined, 'delete');\n }, [send, setAttachments, setInput, t]);\n\n return {\n handleKikuCapture,\n handleKikuCaptureAll,\n handleKikuViewHistory,\n handleKikuDelete,\n };\n}\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport { useAkropolysContext, type ChatMessage, type SpokenMedia } from '@akropolys/sdk';\nimport { stopSpeech } from '../../../utils/tts';\nimport { useVoiceSession } from '../../../utils/voiceSession';\nimport { useLiveVoice, type LiveImage, type LiveState, type LiveTurn } from '../../../utils/liveVoice';\nimport { LIVE_VOICES, VOICE_STORAGE_KEY, isSecureOrigin, type VoicePhase } from '../types';\n\nconst toVoicePhase = (s: LiveState): VoicePhase =>\n s === 'connecting' || s === 'ended' ? 'idle' : s;\n\nexport interface EarlierCalls {\n turns: LiveTurn[];\n images: LiveImage[];\n}\n\nconst NO_EARLIER: EarlierCalls = { turns: [], images: [] };\n\nconst newConversation = () => `v${Date.now().toString(36)}`;\n\nfunction earlierCalls(messages: ChatMessage[], conversation: string): EarlierCalls {\n const turns: LiveTurn[] = [];\n const images: LiveImage[] = [];\n for (const m of messages) {\n if (m.live !== conversation) continue;\n if (m.content) turns.push({ role: m.role === 'user' ? 'user' : 'assistant', text: m.content, done: true });\n for (const url of [...(m.images ?? []), ...(m.visualization ? [m.visualization] : [])]) {\n images.push({ id: -(images.length + 1), url, pending: false });\n }\n }\n return { turns, images };\n}\n\nexport interface UseVoiceControllerOptions {\n voiceLang?: string;\n speechLang: string;\n shopperLanguage: string;\n ttsVoice?: string;\n messages: ChatMessage[];\n handleSendUtterance: (text: string) => void;\n appendSpokenExchange: (heard: string, said: string, duration?: number, userAudioUrl?: string, assistantAudioUrl?: string, media?: SpokenMedia) => void;\n}\n\nexport function useVoiceController({\n voiceLang,\n speechLang,\n shopperLanguage,\n ttsVoice = 'Algenib',\n messages,\n handleSendUtterance,\n appendSpokenExchange,\n}: UseVoiceControllerOptions) {\n const client = useAkropolysContext();\n const [voiceMode, setVoiceMode] = useState<'off' | 'dictate' | 'converse'>('off');\n const [dictateState, setDictateState] = useState<'idle' | 'listening' | 'thinking'>('idle');\n const [voiceError, setVoiceError] = useState<string>('');\n const [voiceMuted, setVoiceMuted] = useState(false);\n const [voiceBlocked, setVoiceBlocked] = useState(false);\n\n const [liveVoiceName, setLiveVoiceName] = useState<string>(() => {\n try {\n const stored = localStorage.getItem(VOICE_STORAGE_KEY);\n if (stored && LIVE_VOICES.some(v => v.name === stored)) return stored;\n } catch { }\n return ttsVoice || 'Algenib';\n });\n\n // Which voice conversation new exchanges belong to; a new voice chat starts another.\n const conversationRef = useRef(newConversation());\n\n const chooseVoice = useCallback((name: string) => {\n setLiveVoiceName(name);\n try { localStorage.setItem(VOICE_STORAGE_KEY, name); } catch { }\n }, []);\n\n const voice = useVoiceSession({\n lang: voiceLang || speechLang,\n onUtterance: (text) => {\n setDictateState('thinking');\n handleSendUtterance(text);\n },\n onError: (code) => {\n setVoiceMode('off');\n setDictateState('idle');\n if (code === 'not-allowed') setVoiceError('micDenied');\n else if (code === 'language-not-supported') setVoiceError('micLangUnsupported');\n else if (code === 'audio-capture') setVoiceError('micMissing');\n else if (code === 'network') setVoiceError('micNetwork');\n else setVoiceError('micFailed');\n },\n onBargeIn: () => { stopSpeech(); },\n });\n\n const voiceUrl = (client as any)?.voiceUrl || (client as any)?.api?.voiceUrl;\n const apiUrl = voiceUrl || (client as any)?.api?.apiUrl || (client as any)?.apiUrl || '';\n const siteId = (client as any)?.api?.siteId || (client as any)?.siteId || '';\n const token = (client as any)?.api?.apiToken || (client as any)?.apiToken || '';\n const kikuId = client?.getShopperId?.() || client?.getKikuPub?.() || undefined;\n const shopperName = client?.getShopperName?.() || undefined;\n\n const live = useLiveVoice({\n apiUrl,\n siteId,\n token,\n kikuId,\n proof: client?.getUserProof?.() || undefined,\n sessionId: client?.getSessionId?.() || undefined,\n storeScene: (image: string) => client?.storeScene?.(image) ?? Promise.resolve(false),\n name: shopperName,\n language: shopperLanguage,\n voice: liveVoiceName,\n muted: voiceMuted,\n onExchange: (exchange) => {\n appendSpokenExchange(exchange.heard, exchange.said, exchange.duration, exchange.userAudioUrl, exchange.audioUrl, {\n images: exchange.images,\n visualization: exchange.visualization,\n live: conversationRef.current,\n });\n },\n onError: (err) => {\n if (err === 'shopper_reply_limit' || err === 'access_revoked' || err === 'account_required') {\n setVoiceBlocked(true);\n live.stop();\n setVoiceMode('off');\n return;\n }\n setVoiceMode('off');\n if (err === 'idle') setVoiceError('voiceIdleEnded');\n else if (err === 'not-allowed') setVoiceError('micDenied');\n else if (err === 'audio-capture') setVoiceError('micMissing');\n else if (err === 'limit') setVoiceError('voiceLimitReached');\n else if (err === 'siteLimit') setVoiceError('voiceSiteLimit');\n else if (err === 'connection' || err === 'network') setVoiceError('micNetwork');\n else setVoiceError('voiceUnavailable');\n },\n onRefused: (code) => {\n if (code === 'shopper_reply_limit' || code === 'access_revoked' || code === 'account_required') {\n setVoiceBlocked(true);\n }\n setVoiceMode('off');\n setVoiceError('voiceUnavailable');\n },\n });\n\n const canConverse = typeof window !== 'undefined' &&\n !!(window as any).WebSocket &&\n !!(window.AudioContext || (window as any).webkitAudioContext) &&\n !!navigator.mediaDevices?.getUserMedia;\n\n // Idle-time, so opening the chat never waits on audio setup; no mic is requested here.\n const { prewarm } = live;\n useEffect(() => {\n if (!canConverse) return;\n const w = window as any;\n if (w.requestIdleCallback) {\n const id = w.requestIdleCallback(prewarm, { timeout: 3000 });\n return () => w.cancelIdleCallback(id);\n }\n const id = window.setTimeout(prewarm, 1500);\n return () => window.clearTimeout(id);\n }, [canConverse, prewarm]);\n\n // The server ended the session; a dead overlay would keep saying \"Listening\".\n useEffect(() => {\n if (voiceMode === 'converse' && live.state === 'ended') {\n setVoiceMode('off');\n setVoiceError('voiceSessionEnded');\n }\n }, [voiceMode, live.state]);\n\n // Taken once per call: this call's own exchanges land in messages too and would repeat.\n const [earlier, setEarlier] = useState<EarlierCalls>(NO_EARLIER);\n\n const startVoice = useCallback(async (mode: 'dictate' | 'converse') => {\n if (!isSecureOrigin()) { setVoiceError('micInsecure'); return; }\n setVoiceError('');\n setVoiceMode(mode);\n if (mode === 'dictate') {\n setDictateState('listening');\n await voice.start();\n } else {\n const before = earlierCalls(messages, conversationRef.current);\n setEarlier(before);\n live.start(before.turns);\n }\n }, [live, voice, messages]);\n\n // A fresh voice conversation: the call restarts with no memory, and the chat keeps everything.\n const newVoiceChat = useCallback(() => {\n live.stop();\n conversationRef.current = newConversation();\n setEarlier(NO_EARLIER);\n live.start([]);\n }, [live]);\n\n const stopVoice = useCallback(() => {\n setVoiceMode('off');\n setDictateState('idle');\n voice.stop();\n live.stop();\n }, [live, voice]);\n\n const voicePhase: VoicePhase =\n voiceMode === 'converse' ? toVoicePhase(live.state)\n : voiceMode === 'dictate' ? (dictateState === 'listening' ? (voice.hearing ? 'speaking' : 'listening') : dictateState)\n : 'idle';\n\n const voiceConnecting =\n voiceMode === 'converse' &&\n live.state !== 'listening' &&\n live.state !== 'thinking' &&\n live.state !== 'speaking';\n\n const attachPhoto = async (file: File) => {\n if (!(await live.attachPhoto(file))) setVoiceError('voicePhotoFailed');\n };\n\n return {\n attachPhoto,\n voiceMode,\n voicePhase,\n voiceConnecting,\n voiceError,\n setVoiceError,\n voiceMuted,\n setVoiceMuted,\n voiceSecondsLeft: live.secondsLeft ?? null,\n voiceBlocked,\n liveVoiceName,\n chooseVoice,\n canConverse,\n startVoice,\n stopVoice,\n voice,\n live,\n earlier,\n newVoiceChat,\n };\n}\n","let ctx: AudioContext | null = null;\r\nlet analyser: AnalyserNode | null = null;\r\nlet duckGain: GainNode | null = null;\r\nlet timeData: Uint8Array | null = null;\r\nlet speaking = false;\r\nlet smoothed = 0;\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 (!analyser || !timeData) return smoothed;\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 stopSpeech() {\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","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 { useCallback, useEffect, useRef, useState } from 'react';\nimport { chime, primeChimes } from './chime';\nimport { AdpcmEncoder, decodeAdpcm } from './adpcm';\nimport { float32ToWav, int16ToWav } from './wav';\nimport { downscaleImage } from './downscaleImage';\n\nexport type LiveState = 'idle' | 'connecting' | 'listening' | 'thinking' | 'speaking' | 'ended';\n\nexport interface LiveSource {\n id?: string;\n url?: string;\n name: string;\n image?: string;\n fields?: Record<string, any>;\n}\n\nexport interface LiveVoiceExchange {\n heard: string;\n said: string;\n duration?: number;\n userAudioUrl?: string;\n audioUrl?: string;\n // Photos attached and the image rendered this turn, so chat keeps them after voice closes.\n images?: string[];\n visualization?: string;\n}\n\nexport interface LiveVoiceOptions {\n apiUrl: string;\n siteId: string;\n\n token: string;\n // The site server's signature over kikuId, for sites that require one.\n proof?: string;\n kikuId?: string;\n // The chat session: a photo parked here is the scene the voice model edits.\n sessionId?: string;\n name?: string;\n storeScene?: (image: string) => Promise<boolean>;\n\n language?: string;\n voice?: string;\n\n onExchange?: (exchange: LiveVoiceExchange) => void;\n onRefused?: (code: string) => void;\n onError?: (code: string) => void;\n\n muted?: boolean;\n}\n\nconst INPUT_RATE = 16000;\nconst OUTPUT_RATE = 24000;\nconst START_BUFFER_SEC = 0.08;\nconst REFILL_BUFFER_SEC = 0.12;\nconst SCHEDULE_LEAD = 0.03;\nconst FLUSH_FADE = 0.08;\nconst MAX_PENDING_CHUNKS = 250; // 10s of 40ms chunks held until the server is ready\nconst HEARING_LEVEL = 0.12;\nconst HEARING_HOLD_MS = 500;\nconst IDLE_CLOSE_MS = 60_000;\n\nconst WORKLET_SRC = `\nclass KikuCapture extends AudioWorkletProcessor {\n constructor() {\n super();\n this._ratio = sampleRate / ${INPUT_RATE};\n this._chunk = ${Math.round(INPUT_RATE * 0.04)};\n this._acc = new Int16Array(this._chunk);\n this._n = 0;\n this._pos = 0;\n }\n process(inputs) {\n const ch = inputs[0] && inputs[0][0];\n if (!ch) return true;\n while (this._pos < ch.length) {\n const i = this._pos | 0;\n const frac = this._pos - i;\n const a = ch[i];\n const b = i + 1 < ch.length ? ch[i + 1] : a;\n const s = a + (b - a) * frac;\n const c = s < -1 ? -1 : s > 1 ? 1 : s;\n this._acc[this._n++] = c < 0 ? c * 0x8000 : c * 0x7fff;\n if (this._n === this._chunk) {\n this.port.postMessage(this._acc.buffer, [this._acc.buffer]);\n this._acc = new Int16Array(this._chunk);\n this._n = 0;\n }\n this._pos += this._ratio;\n }\n this._pos -= ch.length;\n return true;\n }\n}\nregisterProcessor('kiku-capture', KikuCapture);\n`;\n\n// A browser cannot set headers on a socket, so the key and the proof ride as subprotocols and stay out of the address.\nfunction voiceProtocols(o: LiveVoiceOptions): string[] {\n return o.proof ? ['akropolys.token.' + o.token, 'akropolys.proof.' + o.proof] : ['akropolys.token.' + o.token];\n}\n\nfunction liveUrl(o: LiveVoiceOptions, voiceOverride?: string): string {\n const base = o.apiUrl.replace(/\\/+$/, '');\n const path = base.endsWith('/voice/live') ? base : base + '/voice/live';\n const url = new URL(path, window.location.href);\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n url.searchParams.set('siteId', o.siteId);\n if (o.kikuId) url.searchParams.set('kikuId', o.kikuId);\n if (o.sessionId) url.searchParams.set('sessionId', o.sessionId);\n if (o.name) url.searchParams.set('name', o.name);\n if (o.language) url.searchParams.set('language', o.language);\n url.searchParams.set('codec', 'adpcm');\n const v = voiceOverride || o.voice;\n if (v) url.searchParams.set('voice', v);\n return url.toString();\n}\n\nexport interface LiveTurn {\n role: 'user' | 'assistant';\n text: string;\n done: boolean;\n}\n\n// One square in the image row: an attached photo, or a render (pending while it is made).\nexport interface LiveImage {\n id: number;\n url: string;\n pending: boolean;\n // A photo the visitor attached, still uploading.\n sending?: boolean;\n}\n\nexport function useLiveVoice(opts: LiveVoiceOptions) {\n const [state, setState] = useState<LiveState>('idle');\n const [hearing, setHearing] = useState(false);\n const [sources, setSources] = useState<LiveSource[]>([]);\n const [secondsLeft, setSecondsLeft] = useState<number | null>(null);\n const [photos, setPhotos] = useState(false);\n\n const wsRef = useRef<WebSocket | null>(null);\n const startedRef = useRef(false);\n const openOnReadyRef = useRef(false);\n const micAttachRef = useRef<(() => void) | null>(null);\n const lastLoudRef = useRef(0);\n const botSpeakingRef = useRef(false);\n const spokeLoggedRef = useRef(false);\n const ctxRef = useRef<AudioContext | null>(null);\n const streamRef = useRef<MediaStream | null>(null);\n const nodeRef = useRef<AudioWorkletNode | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n\n const playAtRef = useRef(0);\n const replyingRef = useRef(false);\n const heldRef = useRef<Float32Array[]>([]);\n const heldSecRef = useRef(0);\n const sourcesRef = useRef<Set<AudioBufferSourceNode>>(new Set());\n const outAnalyserRef = useRef<AnalyserNode | null>(null);\n const outGainRef = useRef<GainNode | null>(null);\n const outRateRef = useRef(OUTPUT_RATE);\n\n const optsRef = useRef(opts);\n useEffect(() => {\n optsRef.current = opts;\n const stream = streamRef.current;\n if (stream) {\n for (const track of stream.getAudioTracks()) {\n track.enabled = !opts.muted;\n }\n }\n }, [opts]);\n\n const readyRef = useRef(false);\n const pendingRef = useRef<ArrayBuffer[]>([]);\n const encoderRef = useRef(new AdpcmEncoder());\n const workletCtxRef = useRef<Promise<AudioContext | null> | null>(null);\n\n const turnHeardRef = useRef('');\n const turnSaidRef = useRef('');\n const [turns, setTurns] = useState<LiveTurn[]>([]);\n const turnsRef = useRef<LiveTurn[]>([]);\n turnsRef.current = turns;\n // Earlier calls in this chat, handed to each new socket so the model remembers them.\n const historyRef = useRef<LiveTurn[]>([]);\n const [images, setImages] = useState<LiveImage[]>([]);\n const imageIdRef = useRef(0);\n // What this turn showed, handed to chat with the exchange.\n const turnImagesRef = useRef<string[]>([]);\n const turnVizRef = useRef<string | undefined>(undefined);\n const turnStartRef = useRef<number | null>(null);\n const turnBotAudioChunksRef = useRef<Float32Array[]>([]);\n const turnUserAudioChunksRef = useRef<Int16Array[]>([]);\n\n const flushExchange = useCallback(() => {\n const heard = turnHeardRef.current.trim();\n const said = turnSaidRef.current.trim();\n const duration = turnStartRef.current ? Math.max(0.1, (Date.now() - turnStartRef.current) / 1000) : undefined;\n\n let audioUrl: string | undefined;\n if (turnBotAudioChunksRef.current.length > 0) {\n try {\n const blob = float32ToWav(turnBotAudioChunksRef.current, outRateRef.current);\n audioUrl = URL.createObjectURL(blob);\n } catch (e) {\n console.error('[kiku] failed to encode bot audio wav:', e);\n }\n }\n\n let userAudioUrl: string | undefined;\n if (turnUserAudioChunksRef.current.length > 0) {\n try {\n const blob = int16ToWav(turnUserAudioChunksRef.current, INPUT_RATE);\n userAudioUrl = URL.createObjectURL(blob);\n } catch (e) {\n console.error('[kiku] failed to encode user audio wav:', e);\n }\n }\n\n const images = turnImagesRef.current.length ? turnImagesRef.current : undefined;\n const visualization = turnVizRef.current;\n\n turnHeardRef.current = '';\n turnSaidRef.current = '';\n turnStartRef.current = null;\n turnBotAudioChunksRef.current = [];\n turnUserAudioChunksRef.current = [];\n turnImagesRef.current = [];\n turnVizRef.current = undefined;\n\n if (!heard && !said && !images && !visualization) return;\n optsRef.current.onExchange?.({ heard, said, duration, userAudioUrl, audioUrl, images, visualization });\n }, []);\n\n const chirp = useCallback(() => {\n // Silent - no synthetic beeps during live voice\n }, []);\n\n const sendAudio = useCallback((buf: ArrayBuffer) => {\n if (optsRef.current.muted) return;\n const pcm = new Int16Array(buf);\n let peak = 0;\n for (let i = 0; i < pcm.length; i += 8) {\n const v = Math.abs(pcm[i]);\n if (v > peak) peak = v;\n }\n if (peak > 1200) lastLoudRef.current = Date.now();\n const ws = wsRef.current;\n if (!readyRef.current || !ws || ws.readyState !== WebSocket.OPEN) return;\n turnUserAudioChunksRef.current.push(new Int16Array(buf.slice(0)));\n ws.send(encoderRef.current.encode(new Int16Array(buf)));\n }, []);\n\n const flushPending = useCallback(() => {\n pendingRef.current = [];\n }, []);\n\n // Built once per context and reused, so tapping voice only waits for the mic.\n const audioContext = useCallback((): Promise<AudioContext | null> => {\n const held = ctxRef.current;\n if (workletCtxRef.current && held && held.state !== 'closed') return workletCtxRef.current;\n const AC: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\n if (!AC) return Promise.resolve(null);\n const ctx = new AC({ latencyHint: 'interactive', sampleRate: OUTPUT_RATE });\n ctxRef.current = ctx;\n const blobUrl = URL.createObjectURL(new Blob([WORKLET_SRC], { type: 'application/javascript' }));\n workletCtxRef.current = ctx.audioWorklet.addModule(blobUrl)\n .then(() => ctx)\n .catch(() => null)\n .finally(() => URL.revokeObjectURL(blobUrl));\n return workletCtxRef.current;\n }, []);\n\n const warmContext = useCallback(() => {\n if (typeof window === 'undefined') return;\n void audioContext();\n }, [audioContext]);\n\n const micLevel = useCallback(() => {\n const a = analyserRef.current;\n if (!a) return 0;\n const d = new Uint8Array(a.fftSize);\n a.getByteTimeDomainData(d);\n let sum = 0;\n for (let i = 0; i < d.length; i++) { const v = (d[i] - 128) / 128; sum += v * v; }\n return Math.min(1, Math.sqrt(sum / d.length) * 4);\n }, []);\n\n const outbound = state === 'speaking' || state === 'thinking';\n\n const micSpectrum = useCallback((out: Uint8Array) => {\n const a = outbound ? outAnalyserRef.current : analyserRef.current;\n if (!a || out.length !== a.frequencyBinCount) return false;\n a.getByteFrequencyData(out as Uint8Array<ArrayBuffer>);\n return true;\n }, [outbound]);\n\n const spectrumBins = useCallback(\n () => (outbound ? outAnalyserRef.current : analyserRef.current)?.frequencyBinCount ?? 0,\n [outbound]\n );\n\n const flushPlayback = useCallback(() => {\n const g = outGainRef.current;\n const ctx = ctxRef.current;\n if (!g || !ctx || ctx.state === 'closed') {\n playAtRef.current = 0;\n for (const src of sourcesRef.current) {\n try { src.onended = null; src.stop(); } catch { }\n }\n sourcesRef.current.clear();\n return;\n }\n const now = ctx.currentTime;\n const fadeEnd = now + FLUSH_FADE;\n g.gain.cancelScheduledValues(now);\n g.gain.setValueAtTime(g.gain.value, now);\n g.gain.linearRampToValueAtTime(0, fadeEnd);\n g.gain.setValueAtTime(1, fadeEnd);\n for (const src of sourcesRef.current) {\n try { src.onended = null; src.stop(fadeEnd); } catch { }\n }\n sourcesRef.current.clear();\n playAtRef.current = fadeEnd; // next turn must not open inside the fade\n }, []);\n\n const schedule = useCallback((chunk: Float32Array) => {\n const ctx = ctxRef.current;\n const out = outAnalyserRef.current;\n if (!ctx || !out || chunk.length === 0) return;\n if (ctx.state === 'suspended') {\n ctx.resume().catch(() => {});\n }\n\n const buf = ctx.createBuffer(1, chunk.length, outRateRef.current);\n buf.getChannelData(0).set(chunk);\n\n const src = ctx.createBufferSource();\n src.buffer = buf;\n src.connect(out);\n\n const now = ctx.currentTime;\n const at = playAtRef.current > now ? playAtRef.current : now + SCHEDULE_LEAD;\n src.start(at);\n playAtRef.current = at + buf.duration;\n\n sourcesRef.current.add(src);\n src.onended = () => {\n sourcesRef.current.delete(src);\n if (sourcesRef.current.size === 0) {\n playAtRef.current = 0;\n replyingRef.current = false;\n setState(s => (s === 'speaking' ? 'listening' : s));\n }\n };\n setState(s => (s === 'speaking' || s === 'idle' || s === 'ended' ? s : 'speaking'));\n }, []);\n\n const releaseHeld = useCallback(() => {\n const held = heldRef.current;\n heldRef.current = [];\n heldSecRef.current = 0;\n for (const chunk of held) schedule(chunk);\n }, [schedule]);\n\n const dropHeld = useCallback(() => {\n heldRef.current = [];\n heldSecRef.current = 0;\n }, []);\n\n const enqueue = useCallback((chunk: Float32Array) => {\n const ctx = ctxRef.current;\n if (!ctx || chunk.length === 0) return;\n const playing = playAtRef.current > ctx.currentTime;\n if (playing && heldRef.current.length === 0) {\n schedule(chunk);\n return;\n }\n const target = replyingRef.current ? REFILL_BUFFER_SEC : START_BUFFER_SEC;\n heldRef.current.push(chunk);\n heldSecRef.current += chunk.length / outRateRef.current;\n if (heldSecRef.current >= target) {\n replyingRef.current = true;\n releaseHeld();\n }\n }, [schedule, releaseHeld]);\n\n const holdTimerRef = useRef<any>(null);\n const holdGainRef = useRef<GainNode | null>(null);\n\n const stopHold = useCallback(() => {\n if (holdTimerRef.current) {\n clearInterval(holdTimerRef.current);\n holdTimerRef.current = null;\n }\n const g = holdGainRef.current;\n const ctx = ctxRef.current;\n if (g && ctx && ctx.state !== 'closed') {\n const now = ctx.currentTime;\n try {\n g.gain.cancelScheduledValues(now);\n g.gain.setValueAtTime(g.gain.value, now);\n g.gain.linearRampToValueAtTime(0.0001, now + 0.04);\n } catch {}\n setTimeout(() => {\n try { g.disconnect(); } catch {}\n if (holdGainRef.current === g) holdGainRef.current = null;\n }, 50);\n }\n }, []);\n\n const startHold = useCallback(() => {}, []);\n\n const teardown = useCallback((finalState: LiveState) => {\n flushExchange();\n wsRef.current = null;\n readyRef.current = false;\n pendingRef.current = [];\n workletCtxRef.current = null;\n replyingRef.current = false;\n heldRef.current = [];\n heldSecRef.current = 0;\n stopHold();\n flushPlayback();\n nodeRef.current?.disconnect();\n nodeRef.current = null;\n streamRef.current?.getTracks().forEach(t => t.stop());\n streamRef.current = null;\n analyserRef.current = null;\n outAnalyserRef.current = null;\n outGainRef.current = null;\n ctxRef.current?.close().catch(() => { });\n ctxRef.current = null;\n setState(finalState);\n setHearing(false);\n setSources([]);\n startedRef.current = false;\n openOnReadyRef.current = false;\n }, [flushExchange, flushPlayback, stopHold]);\n\n const stop = useCallback(() => {\n try { wsRef.current?.send(JSON.stringify({ type: 'close' })); } catch { }\n try { wsRef.current?.close(); } catch { }\n teardown('idle');\n }, [teardown]);\n\n const sendOpen = useCallback((ws: WebSocket) => {\n const history = [...historyRef.current, ...turnsRef.current.filter(x => x.done)]\n .filter(x => x.text)\n .map(x => ({ role: x.role, text: x.text }));\n try { ws.send(JSON.stringify({ type: 'open', history })); } catch { }\n }, []);\n\n const attachWsHandlers = useCallback((ws: WebSocket) => {\n let abandoned = false;\n ws.binaryType = 'arraybuffer';\n encoderRef.current = new AdpcmEncoder();\n ws.onopen = () => {\n if (wsRef.current !== ws || !openOnReadyRef.current) return;\n openOnReadyRef.current = false;\n sendOpen(ws);\n };\n ws.onmessage = ev => {\n if (ev.data instanceof ArrayBuffer) {\n if (!botSpeakingRef.current) {\n botSpeakingRef.current = true;\n const said = turnSaidRef.current.trim();\n if (said) {\n setTurns(prev => {\n const next = prev.slice();\n for (let i = next.length - 1; i >= 0; i--) {\n if (next[i].role === 'user' && !next[i].done) next[i] = { ...next[i], done: true };\n }\n next.push({ role: 'assistant', text: said, done: false });\n return next;\n });\n }\n }\n if (!spokeLoggedRef.current && lastLoudRef.current) {\n spokeLoggedRef.current = true;\n console.log('[kiku] wait from last speech to first audio: ' + (Date.now() - lastLoudRef.current) + 'ms');\n }\n stopHold();\n const pcm = decodeAdpcm(ev.data);\n turnBotAudioChunksRef.current.push(pcm.slice());\n enqueue(pcm);\n return;\n }\n let f: any;\n try { f = JSON.parse(ev.data); } catch { return; }\n switch (f.type) {\n case 'ready':\n if (f.sampleRate) {\n outRateRef.current = f.sampleRate;\n if (f.sampleRate !== OUTPUT_RATE) {\n console.warn(`[kiku] live audio rate ${f.sampleRate} != context ${OUTPUT_RATE}; per-buffer resampling will click at every chunk seam`);\n }\n }\n if (typeof f.secondsLeft === 'number') setSecondsLeft(f.secondsLeft);\n setPhotos(f.photos === true);\n readyRef.current = true;\n setState('listening');\n flushPending();\n micAttachRef.current?.();\n micAttachRef.current = null;\n // A designed tone, not the model clearing its throat.\n chime('connect', true);\n break;\n case 'hearing':\n if (!turnStartRef.current) turnStartRef.current = Date.now();\n setHearing(true);\n break;\n case 'thinking':\n if (!turnStartRef.current) turnStartRef.current = Date.now();\n setHearing(false);\n setState('thinking');\n startHold();\n if (f.tool === 'visualize') {\n setImages(prev => (prev.some(i => i.pending) ? prev : [...prev, { id: ++imageIdRef.current, url: '', pending: true }]));\n }\n break;\n case 'viz':\n // A url fills the waiting square; none means the render failed and the square goes.\n if (typeof f.url === 'string' && f.url) {\n turnVizRef.current = f.url;\n setImages(prev => prev.map(i => (i.pending ? { ...i, url: f.url, pending: false } : i)));\n } else {\n setImages(prev => prev.filter(i => !i.pending));\n }\n break;\n case 'heard':\n if (sourcesRef.current.size === 0) playAtRef.current = 0;\n if (!turnStartRef.current) {\n turnStartRef.current = Date.now();\n chime('heard');\n }\n turnHeardRef.current += f.text;\n setTurns(prev => {\n const next = prev.slice();\n const last = next[next.length - 1];\n if (last && last.role === 'user' && !last.done) {\n next[next.length - 1] = { ...last, text: turnHeardRef.current.trim() };\n } else {\n next.push({ role: 'user', text: turnHeardRef.current.trim(), done: false });\n }\n return next;\n });\n setHearing(false);\n setState('thinking');\n startHold();\n break;\n case 'said':\n turnSaidRef.current += f.text;\n if (!botSpeakingRef.current) break;\n setTurns(prev => {\n const next = prev.slice();\n for (let i = next.length - 1; i >= 0; i--) {\n if (next[i].role === 'user' && !next[i].done) next[i] = { ...next[i], done: true };\n }\n const last = next[next.length - 1];\n const text = turnSaidRef.current.trim();\n if (last && last.role === 'assistant' && !last.done) {\n next[next.length - 1] = { ...last, text };\n } else {\n next.push({ role: 'assistant', text, done: false });\n }\n return next;\n });\n break;\n case 'interrupted':\n replyingRef.current = false;\n dropHeld();\n stopHold();\n flushPlayback();\n chime('interrupt');\n setHearing(false);\n setState('listening');\n break;\n case 'turn_complete':\n spokeLoggedRef.current = false;\n botSpeakingRef.current = false;\n lastLoudRef.current = 0;\n setTurns(prev => prev.map(x => (x.done ? x : { ...x, done: true })));\n releaseHeld();\n replyingRef.current = false;\n stopHold();\n setHearing(false);\n flushExchange();\n break;\n case 'sources':\n if (Array.isArray(f.sources) && f.sources.length) setSources(f.sources);\n break;\n case 'seconds':\n if (typeof f.secondsLeft === 'number') setSecondsLeft(f.secondsLeft);\n break;\n case 'refused':\n optsRef.current.onRefused?.(f.code || 'guest');\n stop();\n break;\n case 'error':\n optsRef.current.onError?.(f.code || 'unavailable');\n stop();\n break;\n }\n };\n\n ws.onclose = ev => {\n if (wsRef.current !== ws) return;\n if (ev.code === 4402) {\n abandoned = true;\n optsRef.current.onError?.(ev.reason === 'site' ? 'siteLimit' : 'limit');\n }\n teardown('ended');\n };\n ws.onerror = () => { if (!abandoned && wsRef.current === ws) optsRef.current.onError?.('connection'); };\n }, [dropHeld, enqueue, flushExchange, flushPending, flushPlayback, releaseHeld, sendOpen, startHold, stopHold, stop, teardown]);\n\n const hotReconnect = useCallback((newVoice?: string) => {\n const oldWs = wsRef.current;\n readyRef.current = false;\n setState('connecting');\n flushPlayback();\n stopHold();\n if (oldWs) {\n try { oldWs.send(JSON.stringify({ type: 'close' })); } catch { }\n try { oldWs.close(); } catch { }\n }\n const o = optsRef.current;\n // A new socket arms and waits; the shopper already tapped, so claim it on open.\n openOnReadyRef.current = true;\n const ws = new WebSocket(liveUrl(o, newVoice), voiceProtocols(o));\n wsRef.current = ws;\n attachWsHandlers(ws);\n }, [attachWsHandlers, flushPlayback, stopHold]);\n\n const currentVoiceRef = useRef(opts.voice);\n useEffect(() => {\n if (currentVoiceRef.current !== opts.voice) {\n currentVoiceRef.current = opts.voice;\n if (wsRef.current && (state === 'listening' || state === 'thinking' || state === 'speaking')) {\n hotReconnect(opts.voice);\n }\n }\n }, [opts.voice, state, hotReconnect]);\n\n const start = useCallback(async (history: LiveTurn[] = []) => {\n if (startedRef.current && wsRef.current) return;\n startedRef.current = true;\n setState('connecting');\n const o = optsRef.current;\n pendingRef.current = [];\n // This call's own turns; earlier calls arrive as history and are shown by the overlay.\n historyRef.current = history;\n turnsRef.current = [];\n setTurns([]);\n setImages([]);\n turnHeardRef.current = '';\n turnSaidRef.current = '';\n\n // Resumed inside the tap, the one moment a browser allows it.\n const ctxReady = audioContext();\n ctxRef.current?.resume().catch(() => {});\n primeChimes();\n\n let ws = wsRef.current;\n if (ws && ws.readyState === WebSocket.OPEN) {\n sendOpen(ws);\n } else if (ws && ws.readyState === WebSocket.CONNECTING) {\n openOnReadyRef.current = true;\n } else {\n ws = new WebSocket(liveUrl(o), voiceProtocols(o));\n wsRef.current = ws;\n openOnReadyRef.current = true;\n attachWsHandlers(ws);\n }\n\n let stream: MediaStream;\n try {\n if (!navigator.mediaDevices?.getUserMedia) throw { name: 'NotAllowedError' };\n stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n });\n } catch (e: any) {\n try { ws.close(); } catch { }\n wsRef.current = null;\n setState('idle');\n o.onError?.(e?.name === 'NotAllowedError' ? 'not-allowed' : 'audio-capture');\n return;\n }\n if (wsRef.current !== ws) {\n stream.getTracks().forEach(t => t.stop());\n return;\n }\n streamRef.current = stream;\n for (const track of stream.getAudioTracks()) {\n track.enabled = !optsRef.current.muted;\n }\n\n const ctx = await ctxReady;\n if (wsRef.current !== ws) {\n stream.getTracks().forEach(t => t.stop());\n return;\n }\n if (!ctx) {\n optsRef.current.onError?.('audio-worklet');\n stop();\n return;\n }\n if (ctx.state === 'suspended') {\n ctx.resume().catch(() => {});\n }\n\n const inAnalyser = ctx.createAnalyser();\n inAnalyser.fftSize = 1024;\n inAnalyser.smoothingTimeConstant = 0.25;\n analyserRef.current = inAnalyser;\n\n const outGain = ctx.createGain();\n outGain.gain.value = 1;\n outGain.connect(ctx.destination);\n outGainRef.current = outGain;\n\n const outAnalyser = ctx.createAnalyser();\n outAnalyser.fftSize = 1024;\n outAnalyser.smoothingTimeConstant = 0.25;\n outAnalyser.connect(outGain);\n outAnalyserRef.current = outAnalyser;\n\n try {\n const node = new AudioWorkletNode(ctx, 'kiku-capture');\n nodeRef.current = node;\n node.port.onmessage = e => sendAudio(e.data);\n const srcNode = ctx.createMediaStreamSource(stream);\n const attach = () => {\n if (wsRef.current !== ws || !nodeRef.current) return;\n try { srcNode.connect(inAnalyser); } catch { }\n try { srcNode.connect(node); } catch { }\n };\n if (readyRef.current) {\n attach();\n } else {\n micAttachRef.current = attach;\n }\n } catch {\n optsRef.current.onError?.('audio-worklet');\n stop();\n }\n }, [attachWsHandlers, audioContext, sendAudio, sendOpen, stop]);\n\n // The model sends no partial transcripts, so \"hearing\" comes from the mic itself.\n useEffect(() => {\n if (state !== 'listening') {\n setHearing(false);\n return;\n }\n let lastLoud = 0;\n let on = false;\n // Replies re-enter listening, so this clock only runs while nobody is talking.\n const quietSince = Date.now();\n const id = window.setInterval(() => {\n const now = Date.now();\n if (!optsRef.current.muted && micLevel() > HEARING_LEVEL) lastLoud = now;\n if (now - Math.max(lastLoud, quietSince) > IDLE_CLOSE_MS) {\n window.clearInterval(id);\n optsRef.current.onError?.('idle');\n stop();\n return;\n }\n const next = now - lastLoud < HEARING_HOLD_MS;\n if (next !== on) {\n on = next;\n setHearing(next);\n }\n }, 100);\n return () => window.clearInterval(id);\n }, [state, micLevel, stop]);\n\n const prewarm = useCallback(() => {\n warmContext();\n }, [warmContext]);\n\n useEffect(() => () => { stop(); }, [stop]);\n\n useEffect(() => {\n const stream = streamRef.current;\n if (!stream) return;\n for (const track of stream.getAudioTracks()) track.enabled = !opts.muted;\n }, [opts.muted, state]);\n\n const attachPhoto = useCallback(async (file: File): Promise<boolean> => {\n const store = optsRef.current.storeScene;\n if (!store || !file.type.startsWith('image/')) return false;\n let image: string;\n try {\n image = await downscaleImage(file);\n } catch {\n return false;\n }\n const id = ++imageIdRef.current;\n setImages(prev => [...prev, { id, url: image, pending: false, sending: true }]);\n if (!(await store(image))) {\n setImages(prev => prev.filter(i => i.id !== id));\n return false;\n }\n setImages(prev => prev.map(i => (i.id === id ? { ...i, sending: false } : i)));\n turnImagesRef.current.push(image);\n const ws = wsRef.current;\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({\n type: 'text',\n text: '(The visitor just attached a photo. You cannot see it. In one short sentence, ask what they would like changed in it.)',\n }));\n }\n return true;\n }, []);\n\n // A typed question into the live call — how a tapped card asks about itself.\n const ask = useCallback((text: string) => {\n const ws = wsRef.current;\n if (ws && ws.readyState === WebSocket.OPEN && text.trim()) ws.send(JSON.stringify({ type: 'text', text }));\n }, []);\n\n return { state, phase: state, hearing, sources, secondsLeft, photos, turns, images, micLevel, micSpectrum, spectrumBins, start, stop, prewarm, attachPhoto, ask };\n}\n","// 4-bit IMA ADPCM blocks, byte-identical to the server's: int16 predictor, uint8 index, uint8 odd-flag, nibbles low-first.\r\nconst HEADER = 4;\r\n\r\nconst INDEX_TABLE = [-1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8];\r\n\r\nconst STEP_TABLE = [\r\n 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,\r\n 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,\r\n 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,\r\n 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,\r\n 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,\r\n 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,\r\n 32767,\r\n];\r\n\r\nconst clampIndex = (i: number) => (i < 0 ? 0 : i > 88 ? 88 : i);\r\nconst clampSample = (v: number) => (v < -32768 ? -32768 : v > 32767 ? 32767 : v);\r\n\r\nexport class AdpcmEncoder {\r\n private index = 0;\r\n\r\n encode(pcm: Int16Array): ArrayBuffer {\r\n const n = pcm.length;\r\n const out = new Uint8Array(HEADER + ((n + 1) >> 1));\r\n if (n === 0) return out.buffer;\r\n let pred = pcm[0];\r\n const view = new DataView(out.buffer);\r\n view.setInt16(0, pred, true);\r\n out[2] = this.index;\r\n out[3] = n & 1;\r\n let idx = this.index;\r\n for (let i = 0; i < n; i++) {\r\n let step = STEP_TABLE[idx];\r\n let diff = pcm[i] - pred;\r\n let nib = 0;\r\n if (diff < 0) { nib = 8; diff = -diff; }\r\n let vpdiff = step >> 3;\r\n if (diff >= step) { nib |= 4; diff -= step; vpdiff += step; }\r\n step >>= 1;\r\n if (diff >= step) { nib |= 2; diff -= step; vpdiff += step; }\r\n step >>= 1;\r\n if (diff >= step) { nib |= 1; vpdiff += step; }\r\n pred = clampSample(nib & 8 ? pred - vpdiff : pred + vpdiff);\r\n idx = clampIndex(idx + INDEX_TABLE[nib]);\r\n out[HEADER + (i >> 1)] |= nib << (4 * (i & 1));\r\n }\r\n this.index = idx;\r\n return out.buffer;\r\n }\r\n}\r\n\r\nexport function decodeAdpcm(block: ArrayBuffer): Float32Array {\r\n const bytes = new Uint8Array(block);\r\n if (bytes.length < HEADER) return new Float32Array(0);\r\n let pred = new DataView(block).getInt16(0, true);\r\n let idx = clampIndex(bytes[2]);\r\n let n = (bytes.length - HEADER) * 2;\r\n if (bytes[3] & 1 && n > 0) n--;\r\n const out = new Float32Array(n);\r\n for (let i = 0; i < n; i++) {\r\n const nib = (bytes[HEADER + (i >> 1)] >> (4 * (i & 1))) & 0xf;\r\n const step = STEP_TABLE[idx];\r\n let vpdiff = step >> 3;\r\n if (nib & 4) vpdiff += step;\r\n if (nib & 2) vpdiff += step >> 1;\r\n if (nib & 1) vpdiff += step >> 2;\r\n pred = clampSample(nib & 8 ? pred - vpdiff : pred + vpdiff);\r\n idx = clampIndex(idx + INDEX_TABLE[nib]);\r\n out[i] = pred / 32768;\r\n }\r\n return out;\r\n}\r\n","\r\nfunction writeAscii(view: DataView, offset: number, string: string): void {\r\n for (let i = 0; i < string.length; i++) {\r\n view.setUint8(offset + i, string.charCodeAt(i));\r\n }\r\n}\r\n\r\nexport function float32ToWav(chunks: Float32Array[], sampleRate = 24000): Blob {\r\n let totalLen = 0;\r\n for (const c of chunks) totalLen += c.length;\r\n const merged = new Float32Array(totalLen);\r\n let offset = 0;\r\n for (const c of chunks) {\r\n merged.set(c, offset);\r\n offset += c.length;\r\n }\r\n\r\n const buffer = new ArrayBuffer(44 + totalLen * 2);\r\n const view = new DataView(buffer);\r\n\r\n // RIFF chunk descriptor\r\n writeAscii(view, 0, 'RIFF');\r\n view.setUint32(4, 36 + totalLen * 2, true);\r\n writeAscii(view, 8, 'WAVE');\r\n\r\n // fmt sub-chunk\r\n writeAscii(view, 12, 'fmt ');\r\n view.setUint32(16, 16, true); // Subchunk1Size (16 for PCM)\r\n view.setUint16(20, 1, true); // AudioFormat (1 = PCM)\r\n view.setUint16(22, 1, true); // NumChannels (1 = mono)\r\n view.setUint32(24, sampleRate, true); // SampleRate\r\n view.setUint32(28, sampleRate * 2, true); // ByteRate (SampleRate * 1 * 16 / 8)\r\n view.setUint16(32, 2, true); // BlockAlign (1 * 16 / 8)\r\n view.setUint16(34, 16, true); // BitsPerSample (16 bits)\r\n\r\n // data sub-chunk\r\n writeAscii(view, 36, 'data');\r\n view.setUint32(40, totalLen * 2, true);\r\n\r\n // Write 16-bit PCM samples\r\n let dataOffset = 44;\r\n for (let i = 0; i < totalLen; i++) {\r\n const s = Math.max(-1, Math.min(1, merged[i]));\r\n view.setInt16(dataOffset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\r\n dataOffset += 2;\r\n }\r\n\r\n return new Blob([buffer], { type: 'audio/wav' });\r\n}\r\n\r\nexport function int16ToWav(chunks: Int16Array[], sampleRate = 16000): Blob {\r\n let totalLen = 0;\r\n for (const c of chunks) totalLen += c.length;\r\n const merged = new Int16Array(totalLen);\r\n let offset = 0;\r\n for (const c of chunks) {\r\n merged.set(c, offset);\r\n offset += c.length;\r\n }\r\n\r\n const buffer = new ArrayBuffer(44 + totalLen * 2);\r\n const view = new DataView(buffer);\r\n\r\n writeAscii(view, 0, 'RIFF');\r\n view.setUint32(4, 36 + totalLen * 2, true);\r\n writeAscii(view, 8, 'WAVE');\r\n\r\n writeAscii(view, 12, 'fmt ');\r\n view.setUint32(16, 16, true);\r\n view.setUint16(20, 1, true);\r\n view.setUint16(22, 1, true);\r\n view.setUint32(24, sampleRate, true);\r\n view.setUint32(28, sampleRate * 2, true);\r\n view.setUint16(32, 2, true);\r\n view.setUint16(34, 16, true);\r\n\r\n writeAscii(view, 36, 'data');\r\n view.setUint32(40, totalLen * 2, true);\r\n\r\n let dataOffset = 44;\r\n for (let i = 0; i < totalLen; i++) {\r\n view.setInt16(dataOffset, merged[i], true);\r\n dataOffset += 2;\r\n }\r\n\r\n return new Blob([buffer], { type: 'audio/wav' });\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 { SoundToggle } from './components/SoundToggle';\nimport { cn } from '../../utils/cn';\nimport { useIslandMorph } from '../../utils/island';\n\nexport interface ChatTopbarProps {\n title: string;\n logo?: string;\n hasMessages: boolean;\n avatarState?: KikuState;\n unread?: boolean;\n awayFromBottom?: boolean;\n themeMenuOpen?: boolean;\n themeMenuClosing?: boolean;\n onThemeMenuClosed?: () => void;\n isNarrow?: boolean;\n currentTheme?: ThemeId;\n onJumpToLatest?: () => void;\n onReset: () => void;\n onClose: () => void;\n onToggleThemeMenu?: () => void;\n onSelectTheme?: (theme: ThemeId) => void;\n themeAttr?: string;\n below?: React.ReactNode; // shown under the open phone dock\n}\n\nlet droppedIn = false;\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 logo,\n hasMessages,\n avatarState = 'idle',\n unread = false,\n awayFromBottom = false,\n themeMenuOpen = false,\n themeMenuClosing = false,\n onThemeMenuClosed,\n isNarrow = false,\n currentTheme = 'dark',\n onJumpToLatest,\n onReset,\n onClose,\n onToggleThemeMenu,\n onSelectTheme,\n themeAttr,\n below,\n}: ChatTopbarProps) {\n const tr = useT();\n const barRef = React.useRef<HTMLDivElement>(null);\n const trayRef = React.useRef<HTMLDivElement>(null);\n const shadowRef = React.useRef<HTMLDivElement>(null);\n const nameRef = React.useRef<HTMLElement | null>(null);\n const [dropIn] = React.useState(() => { const first = !droppedIn; droppedIn = true; return first; });\n // The dock's top border runs through the middle of the name pill, like the thinking tab on a reply.\n React.useLayoutEffect(() => {\n const bar = barRef.current, name = nameRef.current, dock = trayRef.current;\n if (!bar || !name || !dock) return;\n // Layout offsets, not the on-screen rect: the pill squashes with every hop, and a mid-hop measure moved the edge.\n const mark = name.offsetParent as HTMLElement | null;\n if (!mark) return;\n const pillMiddle = mark.offsetTop + name.offsetTop + name.offsetHeight / 2;\n bar.style.setProperty('--hsk-tray-top', `${pillMiddle}px`);\n bar.style.setProperty('--hsk-tray-head', `${name.offsetHeight / 2 + 8}px`);\n bar.style.setProperty('--hsk-tray-h', `${dock.offsetHeight}px`);\n bar.style.setProperty('--hsk-tray-w', `${dock.offsetWidth}px`);\n }, [themeMenuOpen, isNarrow]);\n const [trayMotion] = React.useState(() =>\n typeof window !== 'undefined' && !window.matchMedia?.('(prefers-reduced-motion: reduce)').matches\n );\n // The dock's first mount blocked the page for a visible beat, so it mounts parked once the chat is idle.\n const [trayReady, setTrayReady] = React.useState(false);\n React.useEffect(() => {\n if (!isNarrow || trayReady) return;\n const ric = (window as any).requestIdleCallback;\n const id = ric ? ric(() => setTrayReady(true), { timeout: 1200 }) : setTimeout(() => setTrayReady(true), 600);\n return () => {\n const cic = (window as any).cancelIdleCallback;\n if (ric && cic) cic(id); else clearTimeout(id);\n };\n }, [isNarrow, trayReady]);\n const trayMounted = isNarrow && (themeMenuOpen || trayReady);\n\n const tray = useIslandMorph({\n target: React.useCallback(() => trayRef.current, []),\n trigger: React.useCallback(() => nameRef.current, []),\n shadow: React.useCallback(() => shadowRef.current, []),\n radius: 18,\n enabled: isNarrow && themeMenuOpen && trayMotion,\n onClosed: () => onThemeMenuClosed?.(),\n });\n React.useEffect(() => {\n if (isNarrow && themeMenuClosing) tray.close();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [themeMenuClosing, isNarrow]);\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 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 ref={barRef} className={cn(\"hsk-cb-topbar\", isNarrow && themeMenuOpen && \"is-docked\")}>\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 <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') : `${title} (tap for themes)`}\n >\n <KikuAvatar\n state={avatarState}\n size={34}\n theme={currentTheme}\n alert={unread}\n onImpact={handleImpact}\n triggerRef={triggerRef}\n dropIn={dropIn}\n />\n {logo ? (\n <img ref={nameRef as React.Ref<HTMLImageElement>} className=\"hsk-cb-topbar-logo\" src={logo} alt={title} />\n ) : (\n <span ref={nameRef as React.Ref<HTMLSpanElement>} className=\"hsk-cb-topbar-name\">{title}</span>\n )}\n </div>\n\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 {!isNarrow && (\n <button\n type=\"button\"\n className=\"hsk-cb-squircle-btn hsk-cb-exit-btn\"\n onClick={onClose}\n aria-label=\"Close Chat\"\n >\n <CloseIcon />\n </button>\n )}\n </div>\n\n {isNarrow && themeMenuOpen && (\n <div\n className={cn(\"hsk-cb-topbar-scrim\", themeMenuClosing && \"is-closing\")}\n onClick={onToggleThemeMenu}\n aria-hidden=\"true\"\n />\n )}\n\n {trayMounted && (\n <div className={cn(\"hsk-cb-tray-shadow\", !themeMenuOpen && \"is-parked\")} aria-hidden=\"true\"><div ref={shadowRef} /></div>\n )}\n {trayMounted && (\n <div\n ref={trayRef}\n className={cn(\"hsk-cb-topbar-ooze-menu\", themeMenuClosing && \"is-closing\", trayMotion && \"is-island\", !themeMenuOpen && \"is-parked\")}\n role=\"dialog\"\n aria-label=\"Theme selector\"\n style={{\n position: 'absolute',\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-block\">\n <div className=\"hsk-cb-tray-aside\">\n <SoundToggle compact />\n <span className=\"hsk-cb-tray-rule\" aria-hidden=\"true\" />\n <span className=\"hsk-cb-theme-vlabel\" aria-hidden=\"true\">Themes</span>\n </div>\n <div className=\"hsk-cb-theme-2x2-grid\">\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 </div>\n )}\n {isNarrow && themeMenuOpen && below && (\n <div className={cn(\"hsk-cb-tray-below\", themeMenuClosing && \"is-closing\")}>{below}</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\nconst HOP_APEX = 0.42;\r\nconst DROP_DELAY_MS = 170; // waits for the chat shape to open past the mark\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 // Starts at the top of a hop and lands, for an entrance onto whatever it sits on.\r\n dropIn?: boolean;\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 dropIn = false,\r\n}: KikuAvatarProps) {\r\n const dropInRef = useRef(dropIn);\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, dropAt = 0;\r\n if (dropInRef.current && !reduced) { hopPhase = HOP_APEX; dropAt = performance.now() + DROP_DELAY_MS; }\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 if (t >= dropAt) 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 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, { useState } from 'react';\r\nimport { cn } from '../../../utils/cn';\r\nimport { chime, chimeState, soundsEnabled, setSoundsEnabled } from '../../../utils/chime';\r\n\r\nexport function SoundToggle({ className = '', compact = false }: { className?: string; compact?: boolean }) {\r\n const [on, setOn] = useState(() => soundsEnabled());\r\n const [state, setState] = useState('');\r\n\r\n const toggle = () => {\r\n const next = !on;\r\n setSoundsEnabled(next);\r\n setOn(next);\r\n // Both directions answer, or the control gives no sign it did anything.\r\n chime(next ? 'reply' : 'interrupt', true);\r\n setState(chimeState());\r\n };\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className={cn('hsk-cb-sound-pill', compact && 'is-compact', on && 'is-on', state && state !== 'running' && state !== 'off' && 'is-blocked', className)}\r\n onClick={toggle}\r\n role=\"switch\"\r\n aria-checked={on}\r\n aria-label={on ? 'Mute notification sounds' : 'Unmute notification sounds'}\r\n >\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=\"M11 5 6 9H3v6h3l5 4V5Z\" />\r\n {on ? (\r\n <>\r\n <path className=\"hsk-snd-wave\" style={{ '--hsk-wave': 0 } as React.CSSProperties} d=\"M15.5 8.5a5 5 0 0 1 0 7\" />\r\n <path className=\"hsk-snd-wave\" style={{ '--hsk-wave': 1 } as React.CSSProperties} d=\"M18.5 5.5a9 9 0 0 1 0 13\" />\r\n </>\r\n ) : (\r\n <>\r\n <line className=\"hsk-snd-x\" x1=\"16\" y1=\"9\" x2=\"21\" y2=\"15\" />\r\n <line className=\"hsk-snd-x\" x1=\"21\" y1=\"9\" x2=\"16\" y2=\"15\" />\r\n </>\r\n )}\r\n </svg>\r\n {!compact && <span>{on ? 'Sounds' : 'Muted'}</span>}\r\n </button>\r\n );\r\n}\r\n","import { useCallback, useLayoutEffect, useRef } from 'react';\r\n\r\ntype Opts = {\r\n // The element that morphs; its own box is the expanded shape.\r\n target: () => HTMLElement | null;\r\n // What it grows out of and lands back into; it stays on screen above the shape.\r\n trigger: () => HTMLElement | null;\r\n // Carries the box-shadow that clip-path would cut off, resized to the shape every frame so it never paints inside it.\r\n shadow?: () => HTMLElement | null;\r\n radius?: number;\r\n enabled: boolean;\r\n onClosed: () => void;\r\n};\r\n\r\ntype Shell = { top: number; left: number; width: number; height: number; radius: number };\r\n\r\n// A clipped box cannot show overshoot, so no spring: a timed ease that never passes its target.\r\nconst OPEN_MS = 300;\r\nconst CLOSE_MS = 220;\r\nconst MIN_MS = 120;\r\nconst CONTENT_FROM = 0.45;\r\nconst CONTENT_SPAN = 0.4;\r\nconst SHAPE_FADE = 0.25; // the landed glass and its shadow fade under the pill instead of vanishing in one frame\r\n\r\nconst clamp01 = (v: number) => Math.min(1, Math.max(0, v));\r\n\r\nfunction cubicBezier(x1: number, y1: number, x2: number, y2: number) {\r\n const cx = 3 * x1, bx = 3 * (x2 - x1) - cx, ax = 1 - cx - bx;\r\n const cy = 3 * y1, by = 3 * (y2 - y1) - cy, ay = 1 - cy - by;\r\n const sx = (t: number) => ((ax * t + bx) * t + cx) * t;\r\n const sy = (t: number) => ((ay * t + by) * t + cy) * t;\r\n const dx = (t: number) => (3 * ax * t + 2 * bx) * t + cx;\r\n return (x: number) => {\r\n let t = x;\r\n for (let i = 0; i < 8; i++) {\r\n const err = sx(t) - x;\r\n const d = dx(t);\r\n if (Math.abs(err) < 1e-5 || Math.abs(d) < 1e-6) break;\r\n t -= err / d;\r\n }\r\n return sy(clamp01(t));\r\n };\r\n}\r\n\r\nconst EASE = cubicBezier(0.32, 0.72, 0, 1); // iOS drawer curve\r\n\r\nfunction readShell(el: HTMLElement): Shell {\r\n const b = el.getBoundingClientRect();\r\n return {\r\n top: b.top, left: b.left, width: b.width, height: b.height,\r\n radius: Math.min(parseFloat(getComputedStyle(el).borderTopLeftRadius) || 0, b.height / 2),\r\n };\r\n}\r\n\r\nexport function useIslandMorph({ target, trigger, shadow, radius = 0, enabled, onClosed }: Opts) {\r\n const shellRef = useRef<Shell | null>(null);\r\n const boxRef = useRef<DOMRect | null>(null);\r\n const closingRef = useRef(false);\r\n const progressRef = useRef(0);\r\n const rafRef = useRef<number | null>(null);\r\n const onClosedRef = useRef(onClosed);\r\n onClosedRef.current = onClosed;\r\n\r\n const paint = useCallback((p: number) => {\r\n progressRef.current = p;\r\n const el = target();\r\n const r = shellRef.current;\r\n const b = boxRef.current;\r\n if (!el || !r || !b) return;\r\n const q = 1 - p;\r\n // A trigger outside the box (a menu under its button) is reached by moving the box.\r\n const inTop = Math.min(Math.max(r.top, b.top), b.bottom - r.height);\r\n const inLeft = Math.min(Math.max(r.left, b.left), b.right - r.width);\r\n const shiftY = (r.top - inTop) * q;\r\n const shiftX = (r.left - inLeft) * q;\r\n const top = Math.max(0, (inTop - b.top) * q);\r\n const left = Math.max(0, (inLeft - b.left) * q);\r\n const right = Math.max(0, (b.right - inLeft - r.width) * q);\r\n const bottom = Math.max(0, (b.bottom - inTop - r.height) * q);\r\n const round = r.radius * q + radius * p;\r\n el.style.clipPath = `inset(${top}px ${right}px ${bottom}px ${left}px round ${round}px)`;\r\n el.style.translate = shiftX || shiftY ? `${shiftX}px ${shiftY}px` : '';\r\n const sh = shadow?.();\r\n if (sh) {\r\n Object.assign(sh.style, {\r\n left: `${left}px`, top: `${top}px`,\r\n width: `${Math.max(0, b.width - left - right)}px`, height: `${Math.max(0, b.height - top - bottom)}px`,\r\n borderRadius: `${round}px`, translate: el.style.translate,\r\n });\r\n }\r\n el.style.setProperty('--hsk-island-content', String(clamp01((p - CONTENT_FROM) / CONTENT_SPAN)));\r\n const fade = String(clamp01(p / SHAPE_FADE));\r\n el.style.opacity = fade;\r\n if (sh) sh.style.opacity = fade;\r\n }, [target, shadow, radius]);\r\n\r\n const release = () => {\r\n const el = target();\r\n if (el) for (const prop of ['clip-path', 'translate', '--hsk-island-content', 'opacity']) el.style.removeProperty(prop);\r\n const sh = shadow?.();\r\n if (sh) for (const prop of ['left', 'top', 'width', 'height', 'border-radius', 'translate', 'opacity']) sh.style.removeProperty(prop);\r\n };\r\n\r\n const stop = () => {\r\n if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);\r\n rafRef.current = null;\r\n };\r\n\r\n // An interrupted run starts from where the shape is, with the time scaled to the distance left.\r\n const run = (to: number, fullMs: number, onDone: () => void) => {\r\n stop();\r\n const from = progressRef.current;\r\n const ms = Math.max(MIN_MS, fullMs * Math.abs(to - from));\r\n const start = performance.now();\r\n const frame = (now: number) => {\r\n const k = clamp01((now - start) / ms);\r\n paint(from + (to - from) * EASE(k));\r\n if (k < 1) rafRef.current = requestAnimationFrame(frame);\r\n else { rafRef.current = null; onDone(); }\r\n };\r\n paint(from);\r\n rafRef.current = requestAnimationFrame(frame);\r\n };\r\n\r\n const begin = (el: HTMLElement, tr: HTMLElement) => {\r\n shellRef.current = readShell(tr);\r\n el.style.clipPath = '';\r\n el.style.translate = '';\r\n boxRef.current = el.getBoundingClientRect();\r\n };\r\n\r\n useLayoutEffect(() => {\r\n if (!enabled) return;\r\n const el = target();\r\n const tr = trigger();\r\n if (!el || !tr) return;\r\n closingRef.current = false;\r\n el.style.removeProperty('pointer-events');\r\n begin(el, tr);\r\n progressRef.current = 0;\r\n run(1, OPEN_MS, release);\r\n return () => { stop(); release(); };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [enabled]);\r\n\r\n const close = useCallback(() => {\r\n const el = target();\r\n const tr = enabled ? trigger() : null;\r\n const rect = tr?.getBoundingClientRect();\r\n const inView = rect && rect.bottom > 0 && rect.top < window.innerHeight;\r\n if (!el || !tr || !inView) { onClosedRef.current(); return; }\r\n const at = rafRef.current !== null ? progressRef.current : 1;\r\n begin(el, tr);\r\n closingRef.current = true;\r\n el.style.pointerEvents = 'none'; // the landing tail must not swallow taps meant for the page\r\n progressRef.current = at;\r\n // Leave the landed shape in place until it unmounts: clearing it first paints one unclipped frame.\r\n run(0, CLOSE_MS, () => onClosedRef.current());\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [enabled, target, trigger]);\r\n\r\n return { close };\r\n}\r\n","import React from 'react';\nimport { cn } from '../../utils/cn';\nimport type { KikuState } from '../KikuAvatar';\nimport { LANGUAGE_CHOICES, endonymFor, getLoadingMeta, type UIStringKey } from './types';\nimport { ClayLoader } from './ClayLoader';\n\nfunction CheckMark() {\n return (\n <span className=\"hsk-cb-check\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 16 16\">\n <path d=\"M3.5 8.4 6.6 11.4 12.6 4.8\" />\n </svg>\n </span>\n );\n}\n\ntype SpinnerPhase = 'idle' | 'step1-exit' | 'spinner-enter' | 'spinner-steady' | 'spinner-exit';\n\nexport interface OnboardingViewProps {\n inOnboarding: boolean;\n justCompleted: boolean;\n onboardingMood?: KikuState;\n awaitingLang: boolean;\n awaitingName: boolean;\n awaitingEntityLang: boolean;\n awaitingConsent: boolean;\n termsAgreed: boolean;\n shopperLanguage: string;\n pendingLanguage?: string;\n shopperName: string;\n entityLangPref: string;\n chromeReady: boolean;\n activeChips: string[];\n speechLang?: string;\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\n tNode: (key: UIStringKey, vars?: Record<string, string>) => React.ReactNode;\n chooseLanguage: (lang: string) => void;\n langSwitching?: boolean;\n isLangPreparing?: boolean;\n onPrewarmLanguage?: (lang: string) => void;\n chooseEntityLang: (mode: 'translated' | 'original') => void;\n agreeTerms: () => void;\n handleSend: (text: string) => void;\n}\n\nexport function OnboardingView({\n inOnboarding,\n justCompleted,\n onboardingMood,\n awaitingLang,\n awaitingName,\n awaitingEntityLang,\n awaitingConsent,\n termsAgreed,\n shopperLanguage,\n pendingLanguage,\n shopperName,\n entityLangPref,\n chromeReady,\n activeChips,\n speechLang,\n t,\n tNode,\n chooseLanguage,\n langSwitching = false,\n isLangPreparing: isLangPreparingProp,\n onPrewarmLanguage,\n chooseEntityLang,\n agreeTerms,\n handleSend,\n}: OnboardingViewProps) {\n const targetLang = pendingLanguage || shopperLanguage;\n const isEn = !targetLang || targetLang.toLowerCase() === 'english' || targetLang.toLowerCase() === 'en';\n // Use prop from ChatModal if provided, otherwise compute locally (backward-compat)\n const isLangPreparing = isLangPreparingProp ??\n (langSwitching || !!pendingLanguage || (!!shopperLanguage && !chromeReady && !isEn));\n const loadingMeta = getLoadingMeta(targetLang);\n\n const [prevPreparing, setPrevPreparing] = React.useState(isLangPreparing);\n const [spinnerPhase, setSpinnerPhase] = React.useState<SpinnerPhase>(() =>\n isLangPreparing ? 'spinner-steady' : 'idle',\n );\n const phaseTimers = React.useRef<ReturnType<typeof setTimeout>[]>([]);\n const clearPhaseTimers = () => {\n phaseTimers.current.forEach(clearTimeout);\n phaseTimers.current = [];\n };\n\n // Adjust state synchronously during render so there is NEVER a 1-frame flash\n if (isLangPreparing !== prevPreparing) {\n setPrevPreparing(isLangPreparing);\n clearPhaseTimers();\n if (isLangPreparing) {\n setSpinnerPhase('step1-exit');\n phaseTimers.current.push(setTimeout(() => setSpinnerPhase('spinner-enter'), 280));\n phaseTimers.current.push(setTimeout(() => setSpinnerPhase('spinner-steady'), 280 + 680));\n } else {\n setSpinnerPhase('spinner-exit');\n phaseTimers.current.push(setTimeout(() => setSpinnerPhase('idle'), 460));\n }\n }\n\n React.useEffect(() => () => clearPhaseTimers(), []);\n\n const showSpinner = (\n spinnerPhase === 'spinner-enter' ||\n spinnerPhase === 'spinner-steady' ||\n spinnerPhase === 'spinner-exit'\n );\n const showStep1Exiting = spinnerPhase === 'step1-exit';\n\n const currentStep =\n showSpinner || showStep1Exiting ? '1'\n : (!shopperLanguage || awaitingLang) ? '1'\n : (!shopperName || awaitingName) ? '2'\n : (!entityLangPref || awaitingEntityLang) ? '3'\n : (!termsAgreed || awaitingConsent) ? '4'\n : null;\n\n const [picked, setPicked] = React.useState<'translated' | 'original' | null>(null);\n const [countdown, setCountdown] = React.useState(3);\n\n React.useEffect(() => {\n if (!awaitingConsent) return;\n setCountdown(3);\n const timer = setInterval(() => {\n setCountdown(prev => {\n if (prev <= 1) { clearInterval(timer); return 0; }\n return prev - 1;\n });\n }, 1000);\n return () => clearInterval(timer);\n }, [awaitingConsent]);\n const displayShopperLang = shopperLanguage\n ? (endonymFor(shopperLanguage, speechLang) ||\n (shopperLanguage.charAt(0).toUpperCase() + shopperLanguage.slice(1)))\n : '';\n\n React.useEffect(() => {\n if (awaitingLang && onPrewarmLanguage) {\n const ric = typeof window !== 'undefined' ? (window as any).requestIdleCallback : undefined;\n const id = ric\n ? ric(() => onPrewarmLanguage('Urdu'), { timeout: 2000 })\n : setTimeout(() => onPrewarmLanguage('Urdu'), 500);\n return () => {\n if (ric && typeof window !== 'undefined') (window as any).cancelIdleCallback?.(id);\n else clearTimeout(id);\n };\n }\n }, [awaitingLang, onPrewarmLanguage]);\n\n return (\n <div className=\"hsk-cb-empty\">\n <div className=\"hsk-cb-onboarding-card\">\n {currentStep && (\n <div className=\"hsk-cb-onboarding-head\">\n <span className=\"hsk-cb-step-badge\" dir=\"ltr\">\n {currentStep} / 4\n </span>\n </div>\n )}\n\n {showSpinner ? (\n <div\n className={cn(\n 'hsk-lang-loader',\n spinnerPhase === 'spinner-enter' && 'hsk-lang-loader--enter',\n spinnerPhase === 'spinner-exit' && 'hsk-lang-loader--exit',\n )}\n key=\"spinner-loading\"\n >\n <ClayLoader\n phase={spinnerPhase === 'spinner-exit' ? 'exit' : spinnerPhase === 'spinner-enter' ? 'enter' : 'steady'}\n label={loadingMeta.preparing}\n />\n </div>\n\n ) : (showStep1Exiting || awaitingLang || !shopperLanguage) ? (\n <div\n className={cn('hsk-cb-hello-wrap', showStep1Exiting && 'hsk-step1-exit')}\n key=\"step-lang\"\n >\n <h2 className=\"hsk-cb-hello\">Which language do you want to use?</h2>\n <div className=\"hsk-cb-lang-chips\">\n {LANGUAGE_CHOICES.map((l, i) => (\n <button\n key={l.value}\n type=\"button\"\n className=\"hsk-cb-lang-chip\"\n style={{ '--hsk-pill-idx': i } as React.CSSProperties}\n lang={l.tag}\n dir={l.rtl ? 'rtl' : 'ltr'}\n disabled={langSwitching}\n onPointerEnter={() => !langSwitching && onPrewarmLanguage?.(l.value)}\n onPointerDown={() => !langSwitching && onPrewarmLanguage?.(l.value)}\n onClick={() => !langSwitching && chooseLanguage(l.value)}\n >\n {l.native}\n </button>\n ))}\n <span\n className=\"hsk-cb-lang-chips-hint\"\n style={{ '--hsk-pill-idx': LANGUAGE_CHOICES.length } as React.CSSProperties}\n >\n or type another one\n </span>\n </div>\n </div>\n\n ) : (awaitingName || !shopperName) ? (\n <div className=\"hsk-cb-hello-wrap hsk-cb-name-step hsk-step-enter\" key=\"step-name\">\n <h2 className=\"hsk-cb-hello\">{t('nameStepTitle')}</h2>\n <p className=\"hsk-cb-hello-ask\">{t('nameStepAsk')}</p>\n <p className=\"hsk-cb-hello-hint\">{t('nameStepHint')}</p>\n </div>\n\n ) : awaitingEntityLang ? (\n <div className=\"hsk-cb-hello-wrap\" key=\"step-entity-lang\">\n <h2 className=\"hsk-cb-hello\">{t('howShouldResultsLook')}</h2>\n <p className=\"hsk-cb-hello-lead\">{tNode('entityLangIntro', { lang: displayShopperLang })}</p>\n <div className=\"hsk-cb-entlang-opts\" role=\"radiogroup\" aria-label={t('howShouldResultsLook')}>\n {(['translated', 'original'] as const).map((mode, i) => (\n <button\n key={mode}\n type=\"button\"\n role=\"radio\"\n aria-checked={(picked ?? entityLangPref) === mode}\n className={cn('hsk-cb-entlang-opt', (picked ?? entityLangPref) === mode && 'is-selected')}\n style={{ '--hsk-opt-idx': i } as React.CSSProperties}\n onClick={() => setPicked(mode)}\n >\n <CheckMark />\n <span className=\"hsk-cb-entlang-opt-text\">\n <span className=\"hsk-cb-entlang-opt-title\">\n {mode === 'translated' ? tNode('inLanguage', { lang: displayShopperLang }) : t('asWritten')}\n </span>\n <span className=\"hsk-cb-entlang-opt-note\">\n {mode === 'translated' ? t('detailsTranslated') : t('namesAsWritten')}\n </span>\n </span>\n </button>\n ))}\n </div>\n <div className=\"hsk-cb-terms-action-wrap\">\n <button\n type=\"button\"\n className={cn('hsk-cb-terms-agree-btn', picked && 'is-active')}\n disabled={!picked}\n onClick={() => picked && chooseEntityLang(picked)}\n >\n {t('continueButton')}\n </button>\n </div>\n </div>\n\n ) : awaitingConsent ? (\n <div className=\"hsk-cb-hello-wrap\" key=\"step-terms\">\n <h2 className=\"hsk-cb-hello\">{t('termsStepTitle')}</h2>\n <p className=\"hsk-cb-hello-lead\">{t('termsStepSubtitle')}</p>\n <div className=\"hsk-cb-terms-sanctuary\">\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 0 } as React.CSSProperties}>\n <div className=\"hsk-cb-terms-head\">\n <span className=\"hsk-cb-terms-numeral\">I</span>\n <h3 className=\"hsk-cb-terms-title\">{t('termsPiiTitle')}</h3>\n </div>\n <p className=\"hsk-cb-terms-desc\">{t('termsPiiDesc')}</p>\n </div>\n <div className=\"hsk-cb-terms-divider\" />\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 1 } as React.CSSProperties}>\n <div className=\"hsk-cb-terms-head\">\n <span className=\"hsk-cb-terms-numeral\">II</span>\n <h3 className=\"hsk-cb-terms-title\">{t('termsSessionTitle')}</h3>\n </div>\n <p className=\"hsk-cb-terms-desc\">{t('termsSessionDesc')}</p>\n </div>\n <div className=\"hsk-cb-terms-divider\" />\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 2 } as React.CSSProperties}>\n <div className=\"hsk-cb-terms-head\">\n <span className=\"hsk-cb-terms-numeral\">III</span>\n <h3 className=\"hsk-cb-terms-title\">{t('termsMemoryTitle')}</h3>\n </div>\n <p className=\"hsk-cb-terms-desc\">{t('termsMemoryDesc')}</p>\n </div>\n <div className=\"hsk-cb-terms-divider\" />\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 3 } as React.CSSProperties}>\n <div className=\"hsk-cb-terms-head\">\n <span className=\"hsk-cb-terms-numeral\">IV</span>\n <h3 className=\"hsk-cb-terms-title\">{t('termsCookieTitle')}</h3>\n </div>\n <p className=\"hsk-cb-terms-desc\">{t('termsCookieDesc')}</p>\n </div>\n <div className=\"hsk-cb-terms-divider\" />\n <div className=\"hsk-cb-terms-item\" style={{ '--hsk-row-idx': 4 } as React.CSSProperties}>\n <div className=\"hsk-cb-terms-head\">\n <span className=\"hsk-cb-terms-numeral\">V</span>\n <h3 className=\"hsk-cb-terms-title\">{t('termsAiTitle')}</h3>\n </div>\n <p className=\"hsk-cb-terms-desc\">{t('termsAiDesc')}</p>\n </div>\n </div>\n <p className=\"hsk-cb-terms-more\">\n {t('privacyMore')}{' '}\n <a href=\"https://akropolys.cloud/privacy\" target=\"_blank\" rel=\"noopener noreferrer\" dir=\"ltr\">\n akropolys.cloud/privacy\n </a>\n </p>\n <div className=\"hsk-cb-terms-action-wrap\">\n <button\n type=\"button\"\n className={cn('hsk-cb-terms-agree-btn', countdown === 0 && 'is-active')}\n disabled={countdown > 0}\n onClick={agreeTerms}\n >\n {countdown > 0\n ? t('termsAgreeCounting', { seconds: String(countdown) })\n : t('termsAgreeButton')}\n </button>\n </div>\n </div>\n\n ) : justCompleted ? (\n <div className=\"hsk-cb-hello-wrap\" key=\"step-completed\">\n <h2 className=\"hsk-cb-hello\">{tNode('allSet', { name: shopperName })}</h2>\n <p className=\"hsk-cb-hello-lead\">\n {entityLangPref === 'translated'\n ? tNode('replyingTranslated', { lang: displayShopperLang })\n : tNode('replyingOriginal', { lang: displayShopperLang })}\n </p>\n </div>\n\n ) : shopperName ? (\n <div className=\"hsk-cb-hello-wrap\" key=\"step-returning\">\n <h2 className=\"hsk-cb-hello\">{tNode('greetReturning', { name: shopperName })}</h2>\n <p className=\"hsk-cb-hello-lead\">{t('greetReturningLead')}</p>\n </div>\n\n ) : (\n <div className=\"hsk-cb-hello-wrap\" key=\"step-initial\">\n <h2 className=\"hsk-cb-hello\">Hello, I am <b>kiku</b>.</h2>\n <p className=\"hsk-cb-hello-lead\">\n Ask me to find, show or save anything. I look through this whole website for you.\n </p>\n </div>\n )}\n\n {!inOnboarding && (activeChips?.length ?? 0) > 0 && (\n <div className=\"hsk-cb-chips\">\n {activeChips.map((chip, i) => (\n <button\n key={chip}\n className=\"hsk-cb-chip\"\n style={{ '--hsk-pill-idx': i } as React.CSSProperties}\n onClick={() => handleSend(chip)}\n >\n {chip}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { thumpDoodles } from '../KikuDoodles';\n\nexport type ClayPhase = 'enter' | 'steady' | 'exit';\n\nconst FRAME_MS = 83;\nconst HOLD = 2;\nconst W = 240;\nconst H = 160;\nconst CX = W / 2;\nconst CY = H / 2;\nconst LUMP = 24;\nconst DISC_RX = 50;\nconst DISC_RY = 56;\nconst LOG = 124;\nconst LOG_H = 22;\nconst PIECES = 6;\nconst SUSHI_R = 13;\nconst SUSHI_GAP = 30;\n\ninterface Paint {\n ctx: CanvasRenderingContext2D;\n dpr: number;\n n: number;\n clay: string;\n light: string;\n dark: string;\n ink: string;\n}\n\ninterface Frame {\n draw: (p: Paint) => void;\n thump?: number;\n hold?: number;\n}\n\nconst lerp = (a: number, b: number, k: number) => a + (b - a) * k;\nconst boil = (n: number, i: number) => Math.sin(n * 12.9898 + i * 78.233) * 0.5;\n\nfunction blob(p: Paint, x: number, y: number, rx: number, ry: number, turn = 0) {\n const pts: [number, number][] = [];\n for (let i = 0; i < 16; i++) {\n const a = (i / 16) * Math.PI * 2;\n const r = 1 + Math.sin(i * 2.3 + 1.7) * 0.06 + Math.sin(i * 5.1) * 0.03 + boil(p.n, i) * 0.02;\n pts.push([x + Math.cos(a + turn) * rx * r, y + Math.sin(a + turn) * ry * r]);\n }\n const mid = (a: [number, number], b: [number, number]) => [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2] as const;\n const { ctx } = p;\n ctx.beginPath();\n ctx.moveTo(...mid(pts[15], pts[0]));\n for (let i = 0; i < 16; i++) ctx.quadraticCurveTo(pts[i][0], pts[i][1], ...mid(pts[i], pts[(i + 1) % 16]));\n ctx.closePath();\n}\n\nfunction shade(p: Paint, lift: number) {\n const { ctx, dpr } = p;\n ctx.shadowColor = `rgba(0,0,0,${0.5 - lift * 0.22})`;\n ctx.shadowBlur = (4 + lift * 14) * dpr;\n ctx.shadowOffsetX = (1.5 + lift * 13) * dpr;\n ctx.shadowOffsetY = (2.5 + lift * 17) * dpr;\n}\n\nfunction round(p: Paint, x: number, y: number, r: number) {\n const g = p.ctx.createRadialGradient(x - r * 0.35, y - r * 0.4, 0, x, y, r * 1.15);\n g.addColorStop(0, p.light);\n g.addColorStop(0.35, p.clay);\n g.addColorStop(1, p.dark);\n return g;\n}\n\nfunction tube(p: Paint, y: number, h: number) {\n const g = p.ctx.createLinearGradient(0, y - h / 2, 0, y + h / 2);\n g.addColorStop(0, p.clay);\n g.addColorStop(0.25, p.light);\n g.addColorStop(0.5, p.clay);\n g.addColorStop(1, p.dark);\n return g;\n}\n\nfunction lump(p: Paint, r: number, lift = 0) {\n const { ctx } = p;\n const s = r * (1 + lift * 0.3);\n ctx.save();\n shade(p, lift);\n ctx.fillStyle = round(p, CX, CY, s);\n blob(p, CX, CY, s, s, p.n * 0.03);\n ctx.fill();\n ctx.restore();\n}\n\nfunction disc(p: Paint, rx: number, ry: number, clipBelow?: number) {\n const { ctx } = p;\n ctx.save();\n if (clipBelow !== undefined) {\n ctx.beginPath();\n ctx.rect(0, 0, W, clipBelow);\n ctx.clip();\n }\n shade(p, 0);\n ctx.fillStyle = round(p, CX, CY, Math.max(rx, ry));\n blob(p, CX, CY, rx, ry);\n ctx.fill();\n ctx.restore();\n}\n\nfunction log(p: Paint, x0: number, x1: number, y: number, h: number, left = h / 2, right = h / 2) {\n const { ctx } = p;\n ctx.save();\n shade(p, 0);\n ctx.fillStyle = tube(p, y, h);\n ctx.beginPath();\n ctx.roundRect(x0 + boil(p.n, x0) * 0.6, y - h / 2 + boil(p.n, y) * 0.6, x1 - x0, h, [left, right, right, left]);\n ctx.fill();\n ctx.restore();\n}\n\nfunction sushi(p: Paint, x: number, y: number, r: number, lift = 0) {\n const { ctx } = p;\n const s = r * (1 + lift * 0.2);\n ctx.save();\n shade(p, lift);\n ctx.fillStyle = round(p, x, y, s);\n ctx.beginPath();\n ctx.arc(x, y, s, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n ctx.save();\n ctx.strokeStyle = p.dark;\n ctx.lineWidth = 1.4;\n ctx.lineCap = 'round';\n ctx.beginPath();\n for (let t = 0; t <= 1.001; t += 0.04) {\n const a = t * Math.PI * 5 + x * 0.3;\n const rr = (1.5 + t * (r - 4)) * (1 + lift * 0.2);\n const px = x + Math.cos(a) * rr;\n const py = y + Math.sin(a) * rr;\n if (t === 0) ctx.moveTo(px, py);\n else ctx.lineTo(px, py);\n }\n ctx.stroke();\n ctx.restore();\n}\n\nfunction marks(p: Paint, strength: number) {\n const { ctx } = p;\n ctx.save();\n ctx.strokeStyle = `rgba(${p.ink},${0.55 * strength})`;\n ctx.lineWidth = 2;\n ctx.lineCap = 'round';\n for (let i = 0; i < 7; i++) {\n const a = (i / 7) * Math.PI * 2 + 0.14;\n const r0 = 38 + (1 - strength) * 8;\n const len = i % 2 ? 5 : 8;\n ctx.beginPath();\n ctx.moveTo(CX + Math.cos(a) * r0, CY + Math.sin(a) * r0);\n ctx.lineTo(CX + Math.cos(a) * (r0 + len), CY + Math.sin(a) * (r0 + len));\n ctx.stroke();\n }\n ctx.restore();\n}\n\nconst cutX = (i: number) => CX - LOG / 2 + (LOG * i) / PIECES;\n\nfunction score(p: Paint, x: number) {\n const { ctx } = p;\n ctx.save();\n ctx.strokeStyle = p.dark;\n ctx.lineWidth = 1.5;\n ctx.lineCap = 'round';\n ctx.beginPath();\n ctx.moveTo(x, CY - LOG_H / 2 + 2);\n ctx.lineTo(x + boil(p.n, x) * 1.5, CY + LOG_H / 2 - 2);\n ctx.stroke();\n ctx.restore();\n}\nconst sushiX = (i: number) => CX + (i - (PIECES - 1) / 2) * SUSHI_GAP;\n\nfunction pieces(p: Paint, opened: number, standing = -1, tipping = -1) {\n for (let i = 0; i < PIECES; i++) {\n let shift = 0;\n for (let c = 0; c < opened; c++) shift += i <= c ? -2 : 2;\n const x0 = cutX(i) + shift;\n const x1 = cutX(i + 1) + shift;\n if (i === tipping) sushi(p, lerp((x0 + x1) / 2, sushiX(i), 0.5), CY - 4, SUSHI_R, 0.5);\n else if (i <= standing) sushi(p, sushiX(i), CY, SUSHI_R);\n else log(p, x0, x1, CY, LOG_H, i === 0 ? LOG_H / 2 : 2, i === PIECES - 1 ? LOG_H / 2 : 2);\n }\n}\n\nfunction buildLoop(): Frame[] {\n const f: Frame[] = [];\n for (let i = 0; i < 5; i++) f.push({ draw: p => lump(p, LUMP) });\n\n const passes = [[LUMP, LUMP, 34, 38], [34, 38, 44, 48], [44, 48, DISC_RX, DISC_RY]];\n for (const [rx0, ry0, rx1, ry1] of passes) {\n for (let i = 0; i < 3; i++) {\n const k = (i + 1) / 3;\n const press = i === 0 ? 1.05 : 1;\n f.push({\n hold: 1,\n thump: i === 0 ? 0.25 : undefined,\n draw: p => disc(p, lerp(rx0, rx1, k), lerp(ry0, ry1, k) * press),\n });\n }\n f.push({ hold: 1, draw: p => disc(p, rx1, ry1) });\n }\n\n let widest = 0;\n for (let i = 0; i < 12; i++) {\n const k = (i + 1) / 12;\n const edge = lerp(CY + DISC_RY, CY - DISC_RY, k);\n const h = lerp(8, 24, k);\n const off = (edge - CY) / DISC_RY;\n widest = Math.max(widest, 2 * DISC_RX * Math.sqrt(Math.max(0, 1 - off * off)), 30);\n const w = widest;\n f.push({\n draw: p => {\n if (k < 1) disc(p, DISC_RX, DISC_RY, edge - h * 0.3);\n log(p, CX - w / 2, CX + w / 2, edge, h);\n },\n });\n }\n for (const k of [0.5, 1]) {\n f.push({ draw: p => log(p, CX - DISC_RX, CX + DISC_RX, lerp(CY - DISC_RY, CY, k), 24) });\n }\n for (let i = 0; i < 6; i++) {\n const k = (i + 1) / 6;\n const w = lerp(2 * DISC_RX, LOG, k);\n const h = lerp(24, LOG_H, k);\n const sway = i % 2 ? 2 : -2;\n f.push({ draw: p => log(p, CX - w / 2 + sway, CX + w / 2 + sway, CY, h) });\n }\n\n for (let c = 1; c < PIECES; c++) {\n f.push({ draw: p => { pieces(p, c - 1); score(p, cutX(c)); } });\n f.push({ thump: 0.35, draw: p => pieces(p, c) });\n }\n f.push({ draw: p => pieces(p, PIECES - 1) });\n\n for (let i = 0; i < PIECES; i++) {\n f.push({ thump: 0.12, draw: p => pieces(p, PIECES - 1, i - 1, i) });\n }\n for (let i = 0; i < 4; i++) f.push({ draw: p => pieces(p, PIECES - 1, PIECES - 1) });\n\n for (const k of [0.35, 0.7, 1]) {\n f.push({\n draw: p => {\n for (let i = 0; i < PIECES; i++) sushi(p, lerp(sushiX(i), CX, k), CY, lerp(SUSHI_R, 10, k), 0.4);\n },\n });\n }\n f.push({ thump: 1, draw: p => { lump(p, LUMP * 1.3); marks(p, 1); } });\n f.push({ draw: p => { lump(p, LUMP * 1.12); marks(p, 0.4); } });\n f.push({ draw: p => lump(p, LUMP * 1.04) });\n return f;\n}\n\nconst LOOP = buildLoop();\n\nconst ENTER: Frame[] = [\n ...[1.6, 1.25, 0.9, 0.5, 0.18].map(lift => ({ draw: (p: Paint) => lump(p, LUMP, lift) })),\n { thump: 0.7, draw: (p: Paint) => { lump(p, LUMP * 1.24); marks(p, 1); } },\n { draw: (p: Paint) => { lump(p, LUMP * 1.08); marks(p, 0.4); } },\n];\n\nconst EXIT_FADE = [1, 0.7, 0.35, 0];\n\nfunction resolveColor(host: HTMLElement, css: string) {\n const el = document.createElement('span');\n el.style.display = 'none';\n el.style.color = css;\n host.parentElement?.appendChild(el);\n const c = getComputedStyle(el).color;\n el.remove();\n return c;\n}\n\n// Clay on the table, seen from above: rolled flat, rolled back into a log, sliced and stood up, squashed together again.\nexport function ClayLoader({ phase, label }: { phase: ClayPhase; label: React.ReactNode }) {\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\n const labelRef = React.useRef<HTMLParagraphElement>(null);\n const run = React.useRef({ n: 0, at: 0, held: 0, entered: false, last: LOOP[0] });\n\n React.useEffect(() => {\n const cv = canvasRef.current;\n const text = labelRef.current;\n const ctx = cv?.getContext('2d');\n if (!cv || !ctx || !text) return;\n\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\n cv.width = W * dpr;\n cv.height = H * dpr;\n const primary = 'var(--hsk-primary, #ff6a33)';\n const p: Paint = {\n ctx,\n dpr,\n n: 0,\n clay: resolveColor(cv, primary),\n light: resolveColor(cv, `color-mix(in srgb, ${primary} 55%, white)`),\n dark: resolveColor(cv, `color-mix(in srgb, ${primary} 70%, black)`),\n ink: getComputedStyle(cv).getPropertyValue('--hsk-doodle-ink').trim() || '31, 31, 31',\n };\n const st = run.current;\n\n const paint = (frame: Frame, alpha = 1) => {\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, W, H);\n ctx.globalAlpha = alpha;\n p.n = st.n++;\n frame.draw(p);\n ctx.globalAlpha = 1;\n };\n const thump = (strength: number) => {\n const r = cv.getBoundingClientRect();\n thumpDoodles({ x: r.left + r.width / 2, y: r.top + r.height / 2, strength });\n text.style.translate = '0 1px';\n text.style.rotate = `${boil(st.n, 4) * 0.8}deg`;\n };\n\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches) {\n paint(LOOP[0]);\n return;\n }\n\n let seq: Frame[] | null = phase === 'exit' ? null : phase === 'enter' && !st.entered ? ENTER : LOOP;\n if (seq) st.at = 0;\n let fade = 0;\n let id = 0;\n\n const tick = () => {\n text.style.translate = '';\n text.style.rotate = '';\n if (!seq) {\n if (fade === 0) thump(0.6);\n paint(st.last, EXIT_FADE[fade]);\n if (++fade >= EXIT_FADE.length) clearInterval(id);\n return;\n }\n const frame = seq[st.at];\n paint(frame);\n st.last = frame;\n if (frame.thump && st.held === 0) thump(frame.thump);\n if (seq === LOOP && ++st.held < (frame.hold ?? HOLD)) return;\n st.held = 0;\n if (++st.at < seq.length) return;\n if (seq === ENTER) st.entered = true;\n seq = LOOP;\n st.at = 0;\n };\n\n tick();\n id = window.setInterval(tick, FRAME_MS);\n return () => clearInterval(id);\n }, [phase === 'exit']);\n\n return (\n <div className=\"hsk-clay\">\n <canvas className=\"hsk-clay-table\" ref={canvasRef} aria-hidden=\"true\" />\n <p className=\"hsk-lang-preparing\" ref={labelRef}>{label}</p>\n </div>\n );\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { useT } from '../types';\n\nexport function parseThinking(text: string): { thinking: string; content: string; isComplete: boolean } {\n const openMatch = text.match(/<\\s*thinking\\s*>/i);\n if (!openMatch) {\n return { thinking: '', content: text, isComplete: true };\n }\n\n const openIdx = openMatch.index ?? 0;\n const openTagLength = openMatch[0].length;\n const start = openIdx + openTagLength;\n\n const contentBefore = text.slice(0, openIdx);\n const textAfterOpen = text.slice(start);\n\n const closeMatch = textAfterOpen.match(/<\\/\\s*thinking\\s*>/i);\n if (!closeMatch) {\n return {\n thinking: textAfterOpen,\n content: contentBefore,\n isComplete: false\n };\n }\n\n const closeIdx = closeMatch.index ?? 0;\n const closeTagLength = closeMatch[0].length;\n\n return {\n thinking: textAfterOpen.slice(0, closeIdx),\n content: contentBefore + textAfterOpen.slice(closeIdx + closeTagLength),\n isComplete: true\n };\n}\n\n// Stages that stand on their own line with no reply text beneath them.\nexport const isTeamNote = (stage?: string) => stage === 'with_team' || stage === 'back_with_kiku' || stage === 'team_closed' || stage === 'team_joined';\n\n// A person can take minutes or hours to answer, so the wait reads in the largest whole unit.\nexport function replyWait(seconds: number): string {\n if (seconds < 60) return `${Math.max(1, Math.round(seconds))}s`;\n if (seconds < 3600) return `${Math.round(seconds / 60)} min`;\n return `${Math.round(seconds / 3600)} h`;\n}\n\nexport function ThinkingBlock({ text, isComplete, seconds: fixedSeconds, stage, repliedSeconds }: {\n text: string;\n isComplete: boolean;\n seconds?: number;\n stage?: string;\n repliedSeconds?: number;\n}) {\n const tr = useT();\n const startRef = useRef(Date.now());\n const [seconds, setSeconds] = useState<number | null>(() => (isComplete ? null : 0));\n const [isOpen, setIsOpen] = useState(!isComplete);\n\n useEffect(() => {\n if (isComplete) {\n if (seconds !== null) {\n setSeconds(Math.max(1, Math.round((Date.now() - startRef.current) / 1000)));\n setIsOpen(false);\n }\n return;\n }\n setIsOpen(true);\n const t = setInterval(() => {\n setSeconds(Math.round((Date.now() - startRef.current) / 1000));\n }, 1000);\n return () => clearInterval(t);\n }, [isComplete]);\n\n const finalSeconds = fixedSeconds ?? seconds;\n const label = repliedSeconds != null\n ? tr('repliedIn', { duration: replyWait(repliedSeconds) })\n : stage === 'with_team'\n ? tr('withTeam')\n : stage === 'back_with_kiku'\n ? tr('backWithKiku')\n : stage === 'team_closed'\n ? tr('teamClosed')\n : stage === 'team_joined'\n ? tr('teamJoined')\n : stage === 'reaching_team'\n ? (isComplete ? tr('passedToTeam') : `${tr('reachingTeam')}…`)\n : isComplete\n ? (finalSeconds !== null && finalSeconds !== undefined\n ? tr('thoughtForSeconds', { duration: `${finalSeconds}s` })\n : tr('thoughtProcess'))\n : `${tr('thinking')}${seconds ? ` · ${seconds}s` : '…'}`;\n const expandable = !!text;\n\n return (\n <div className={cn('hsk-cb-think', !isComplete && 'hsk-cb-think--live', repliedSeconds == null && isTeamNote(stage) && 'hsk-cb-think--note')}>\n <button\n type=\"button\"\n className={cn('hsk-cb-think-head', !expandable && 'hsk-cb-think-head--static')}\n onClick={expandable ? () => setIsOpen(o => !o) : undefined}\n aria-expanded={expandable ? isOpen : undefined}\n >\n <span>{label}</span>\n {expandable && <span className={cn('hsk-cb-think-chevron', isOpen && 'hsk-cb-think-chevron--open')}>▶</span>}\n </button>\n {expandable && isOpen && <div className=\"hsk-cb-think-body\">{text}</div>}\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport function useDelayedClose(ms: number, onClosed: () => void) {\n const [closing, setClosing] = useState(false);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const closedRef = useRef(onClosed);\n closedRef.current = onClosed;\n\n useEffect(() => () => {\n if (timer.current) clearTimeout(timer.current);\n }, []);\n\n const requestClose = useCallback(() => {\n if (timer.current) return;\n setClosing(true);\n timer.current = setTimeout(() => {\n timer.current = null;\n setClosing(false);\n closedRef.current();\n }, ms);\n }, [ms]);\n\n /** Skips the exit entirely - for a handover, where the delay is the bug. */\n const closeNow = useCallback(() => {\n if (timer.current) {\n clearTimeout(timer.current);\n timer.current = null;\n }\n setClosing(false);\n closedRef.current();\n }, []);\n\n return { closing, requestClose, closeNow };\n}\n","import React from 'react';\r\nimport { useAkropolysContext, type ChatMessage, type ChatSource, type ChatAction } from '@akropolys/sdk';\r\nimport { cn } from '../../../utils/cn';\r\nimport { renderMarkdown, safeHref } from '../../../utils/markdown';\r\nimport { lineDirection } from '../../../utils/textDirection';\r\nimport { LiveTable } from '../../LiveTable';\r\nimport { WorkingVeil } from '../../KikuDoodles';\r\nimport { ThinkingBlock, parseThinking, isTeamNote } 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, hosts }: { content: string; streaming: boolean; hosts: string }) =>\r\n <>{renderMarkdown(content, streaming, new Set(hosts.split(',')))}</>,\r\n (a, b) => a.content === b.content && a.streaming === b.streaming && a.hosts === b.hosts\r\n);\r\nMarkdownBlock.displayName = 'MarkdownBlock';\r\n\r\nfunction hostsOf(urls: Array<string | undefined>): string {\r\n const hosts = new Set<string>();\r\n for (const u of urls) {\r\n if (!u) continue;\r\n try { hosts.add(new URL(u, location.href).host); } catch { }\r\n }\r\n return [...hosts].sort().join(',');\r\n}\r\n\r\n// A wrapped bubble is as wide as its longest line, not as wide as it was allowed to grow.\r\nfunction useSnugWidth(ref: React.RefObject<HTMLElement | null>, text: string) {\r\n React.useLayoutEffect(() => {\r\n const el = ref.current;\r\n if (!el) return;\r\n const fit = () => {\r\n el.style.width = '';\r\n const range = document.createRange();\r\n range.selectNodeContents(el);\r\n const lines = Array.from(range.getClientRects());\r\n const box = el.getBoundingClientRect();\r\n if (!lines.length || !el.offsetWidth || !box.width) return;\r\n const scale = box.width / el.offsetWidth; // the send animation scales the bubble while it is measured\r\n const style = getComputedStyle(el);\r\n const pad = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight) + parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);\r\n const longest = Math.max(...lines.map(r => r.right)) - Math.min(...lines.map(r => r.left));\r\n const content = Math.ceil(longest / scale) + 1;\r\n if (content + pad < el.offsetWidth) el.style.width = `${style.boxSizing === 'border-box' ? content + pad : content}px`;\r\n };\r\n fit();\r\n document.fonts?.ready.then(fit).catch(() => {});\r\n const row = el.closest('.hsk-cb-msg-group');\r\n if (!row || typeof ResizeObserver === 'undefined') return;\r\n const observer = new ResizeObserver(fit);\r\n observer.observe(row);\r\n return () => observer.disconnect();\r\n }, [ref, text]);\r\n}\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 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, el: HTMLElement) => 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 photosSending: boolean;\r\n workingOn?: string;\r\n doodleTheme?: string;\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 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 photosSending,\r\n workingOn,\r\n doodleTheme,\r\n}: MessageItemProps) {\r\n const api = useAkropolysContext()?.api;\r\n const doodleSeed = api?.siteId ?? '';\r\n const imageHosts = hostsOf([api?.apiUrl, ...(isLast ? sources : (msg.sources ?? [])).flatMap(s => [s.image, s.url])]);\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 bubbleRef = React.useRef<HTMLDivElement | null>(null);\r\n useSnugWidth(bubbleRef, msg.content);\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 const pressFired = React.useRef(false);\r\n\r\n const anchorFor = React.useCallback((el: HTMLElement): HTMLElement => {\r\n const sel = isUser ? '.hsk-cb-user-bubble' : '.hsk-cb-ai-text';\r\n if (el.matches?.(sel)) return el;\r\n return (el.querySelector(sel) as HTMLElement) || el;\r\n }, [isUser]);\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 anchor = anchorFor(targetEl);\r\n const r = anchor.getBoundingClientRect();\r\n onLongPress(msg, { top: r.top, left: r.left, width: r.width, height: r.height }, isUser, anchor);\r\n pressFired.current = true;\r\n }\r\n longPressTimer.current = null;\r\n }, 420);\r\n }, [msg, isUser, onLongPress, anchorFor]);\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 pressFired.current = false;\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((e: React.TouchEvent<HTMLElement>) => {\r\n if (longPressTimer.current) {\r\n clearTimeout(longPressTimer.current);\r\n longPressTimer.current = null;\r\n }\r\n touchStartPos.current = null;\r\n if (pressFired.current && e.cancelable) e.preventDefault(); // the lift's synthetic click would land on the new overlay and close it\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 if (pressFired.current) return;\r\n const el = anchorFor(e.currentTarget);\r\n const r = el.getBoundingClientRect();\r\n onLongPress(msg, { top: r.top, left: r.left, width: r.width, height: r.height }, isUser, el);\r\n }, [msg, isUser, onLongPress, anchorFor]);\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 data-hsk-role={isUser ? 'user' : 'assistant'}\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 <WorkingVeil active={photosSending} seed={doodleSeed} theme={doodleTheme} />\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 ref={bubbleRef}\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 dir={lineDirection(msg.content.replace(/^@kiku\\s*/i, ''))}\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 {isRunEnd && (\r\n <div className=\"hsk-cb-user-footer\">\r\n <div className=\"hsk-cb-msg-actions\">\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 )}\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 || msg.repliedSeconds != null || isTeamNote(msg.statusStage) || (isLast && (streaming || loading))) && (\r\n <ThinkingBlock text={thinking} isComplete={isComplete} seconds={msg.thoughtForSeconds} stage={msg.statusStage} repliedSeconds={msg.repliedSeconds} />\r\n )}\r\n {msg.spoken && typeof msg.thoughtForSeconds === 'number' && msg.thoughtForSeconds > 0 && (\r\n <div className=\"hsk-cb-think\">\r\n <span className=\"hsk-cb-think-head hsk-cb-think-head--static\">\r\n <MicIcon size={11} />\r\n <span>spoken · {msg.thoughtForSeconds.toFixed(1)}s</span>\r\n </span>\r\n </div>\r\n )}\r\n {cleanContent && (\r\n <div className=\"hsk-cb-ai-content\">\r\n <MarkdownBlock content={cleanContent} streaming={isLast && streaming} hosts={imageHosts} />\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\">\r\n <div className={cn('hsk-cb-viz--working', !workingOn && 'is-blank', msg.visualizationType === 'video' && 'is-video')} role=\"status\" aria-label={msg.visualizingText || t('vizWorking')}>\r\n {workingOn && <img src={workingOn} alt=\"\" />}\r\n <WorkingVeil active seed={doodleSeed} theme={doodleTheme} />\r\n </div>\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 onSelectSource={handleSourceClick}\r\n onImageClick={setLightboxSrc}\r\n referencedIds={msgReferencedIds}\r\n compact={!!msg.visualization}\r\n targetLabel={t('swatchTarget')}\r\n />\r\n );\r\n })()}\r\n\r\n {isLast && !loading && !streaming && lastAction?.type === 'open_memory' && safeHref(lastAction.url) && (\r\n <a\r\n className=\"hsk-cb-memory-pill\"\r\n href={safeHref(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 && safeHref(lastAction?.url) && lastAction?.type !== 'open_memory' && (\r\n <div className=\"hsk-action-pills\">\r\n <a className=\"hsk-action-pill\" href={safeHref(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 />\r\n )}\r\n\r\n {!isUser && isRunEnd && !streaming && cleanContent && (\r\n <div className=\"hsk-cb-ai-footer\">\r\n <div className=\"hsk-cb-msg-actions\">\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 from 'react';\r\nimport { lineDirection } from './textDirection';\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 LOCAL_IMG_REGEX = /^(data:image|blob):/i;\r\nconst SAFE_LINK_REGEX = /^(https?|mailto|tel):/i;\r\n\r\n// Only web, mail and phone links, or paths on this site: a javascript: address would run in the host page.\r\nexport function safeHref(url: unknown): string | undefined {\r\n const u = String(url ?? '').trim();\r\n return SAFE_LINK_REGEX.test(u) || (u.startsWith('/') && !u.startsWith('//')) ? u : undefined;\r\n}\r\nlet imageHosts: ReadonlySet<string> | null = null;\r\n\r\n// A reply's image loads only from this site or a host the caller names: any other address could carry the chat out.\r\nfunction safeImage(url: string): boolean {\r\n if (LOCAL_IMG_REGEX.test(url)) return true;\r\n if (typeof location === 'undefined') return false;\r\n try {\r\n const u = new URL(url, location.href);\r\n return /^https?:$/.test(u.protocol) && (u.host === location.host || !!imageHosts?.has(u.host));\r\n } catch {\r\n return false;\r\n }\r\n}\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 if (safeImage(url)) {\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\nconst TABLE_SEPARATOR_REGEX = /^\\s*\\|?[\\s:|-]*-[\\s:|-]*\\|?\\s*$/;\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, hosts?: ReadonlySet<string>): React.ReactNode {\r\n imageHosts = hosts ?? null;\r\n try {\r\n return buildMarkdown(content, streaming);\r\n } finally {\r\n imageHosts = null;\r\n }\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 if (!content.endsWith('\\n') && lines[lines.length - 1].trim().startsWith('|')) {\r\n lines.pop();\r\n }\r\n let start = lines.length - 1;\r\n while (start >= 0 && lines[start].trim().startsWith('|')) start--;\r\n start++;\r\n if (start < lines.length && !lines.slice(start).some(l => TABLE_SEPARATOR_REGEX.test(l))) {\r\n lines.length = start;\r\n }\r\n }\r\n\r\n // The line still being typed keeps the chat's direction until it has enough letters to call.\r\n const dirOf = (text: string, at: number) => lineDirection(text, streaming && at === lines.length - 1 ? 15 : 1);\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 if (safeImage(url)) {\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}`} dir={dirOf(headerMatch[2], i)}>{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 let listText = '';\r\n while (i < lines.length && lines[i].match(/^[\\s]*[-*+•]\\s+/)) {\r\n const itemText = lines[i].replace(/^[\\s]*[-*+•]\\s+/, '');\r\n listText += itemText + ' ';\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\" dir={dirOf(listText, i - 1)}>{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 let listText = '';\r\n while (i < lines.length && lines[i].match(/^[\\s]*\\d+[\\.\\)]\\s+/)) {\r\n const itemText = lines[i].replace(/^[\\s]*\\d+[\\.\\)]\\s+/, '');\r\n listText += itemText + ' ';\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\" dir={dirOf(listText, i - 1)}>{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 className={cell.trim().startsWith('✓') ? 'hsk-md-ok' : cell.trim().startsWith('✗') ? 'hsk-md-bad' : undefined}\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\" dir={dirOf(line, i)}>\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","const LETTER = /\\p{L}/u;\r\n// Link targets and bare URLs are Latin whatever language the sentence is in.\r\nconst URL_LIKE = /\\]\\([^)]*\\)|https?:\\/\\/\\S+|www\\.\\S+/g;\r\n\r\n// Same right-to-left ranges as isRTLText in ChatModal/types.\r\nfunction isRTLCode(code: number): boolean {\r\n return (code >= 0x0590 && code <= 0x08ff) || (code >= 0xfb1d && code <= 0xfdff) || (code >= 0xfe70 && code <= 0xfeff);\r\n}\r\n\r\n// A line reads in the script most of its letters are in; too few letters, or a tie, follows the chat.\r\nexport function lineDirection(text: string, minLetters = 1): 'rtl' | 'ltr' | undefined {\r\n let rtl = 0;\r\n let ltr = 0;\r\n for (const ch of text.replace(URL_LIKE, ' ')) {\r\n if (!LETTER.test(ch)) continue;\r\n if (isRTLCode(ch.codePointAt(0) ?? 0)) rtl++;\r\n else ltr++;\r\n }\r\n if (rtl + ltr < minLetters || rtl === ltr) return undefined;\r\n return rtl > ltr ? 'rtl' : 'ltr';\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\nconst TITLE_KEYS = ['title', 'name', 'label', 'headline', 'subject'];\r\nconst MAX_PILLS = 8;\r\nconst MAX_PILL_CHARS = 40;\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 titleKey = TITLE_KEYS.find(k => fields[k]);\r\n const rawTitle = titleKey ? fields[titleKey] : record.key;\r\n const shortTitle = rawTitle.length > 38 ? rawTitle.slice(0, 36) + '…' : rawTitle;\r\n\r\n // Every field the site publishes, under its own name; ids and long prose do not fit a pill.\r\n const quotePills = Object.entries(fields)\r\n .filter(([k, v]) => k !== titleKey && v !== '' && v.length <= MAX_PILL_CHARS && !/^[0-9a-fA-F-]{26,}$/.test(v))\r\n .slice(0, MAX_PILLS)\r\n .map(([k, v]) => ({ label: labelFor(k), value: formatLiveValue(v), rawKey: k }));\r\n\r\n return (\r\n <div className={`hsk-live-card${stale ? ' is-stale' : ''}`} role=\"region\" aria-label=\"Live values\">\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 </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 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, useRef, useEffect, useCallback } from 'react';\r\nimport type { ChatSource } from '@akropolys/sdk';\r\nimport { useAkropolysContext, useCardFields } from '@akropolys/sdk';\r\nimport { detailsOf } from '../../../utils/cardDetails';\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 onSelectSource?: (src: ChatSource) => void;\r\n onImageClick?: (src: string) => void;\r\n referencedIds?: string[];\r\n compact?: boolean;\r\n targetLabel?: string;\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, onSelectSource, onImageClick, referencedIds = [], compact = false, targetLabel = 'Your colour' }: SourcesCarouselProps) {\r\n const client = useAkropolysContext();\r\n const cardFields = useCardFields();\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 referenced = sources.filter(s => s.id && referencedIds.includes(s.id));\r\n const swatches = referenced.filter(s => s.swatch);\r\n const display = referenced.filter(s => !s.swatch);\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 && swatches.length === 0) return null;\r\n\r\n const swatchGrid = swatches.length > 0 && (\r\n <div className=\"hsk-cb-swatch-grid\">\r\n {swatches.map((src, si) => (\r\n <button\r\n key={src.id ?? si}\r\n type=\"button\"\r\n className={cn(\"hsk-cb-swatch\", src.target && \"hsk-cb-swatch--target\")}\r\n style={{ animationDelay: `${si * 40}ms` }}\r\n onClick={src.target ? undefined : () => onSelectSource?.(src)}\r\n >\r\n <span className=\"hsk-cb-swatch-chip\" style={{ background: src.swatch }} />\r\n <span className=\"hsk-cb-swatch-name\">{src.target ? targetLabel : src.name}</span>\r\n <span className=\"hsk-cb-swatch-code\">{src.swatch}</span>\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n if (display.length === 0) return swatchGrid || null;\r\n\r\n return (\r\n <>\r\n {swatchGrid}\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 </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 {detailsOf(src, cardFields).slice(0, 2).map(d => (\r\n <div key={d.label} className=\"hsk-cb-src-detail\">{d.value}</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}\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}\r\n\r\nexport function SmartContextPills({\r\n intent,\r\n sources,\r\n onSend,\r\n loading,\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 firstName = sources[0]?.name ?? '';\r\n const firstTwo = sources.slice(0, 2).map(s => s.name);\r\n\r\n if (intent === 'search' && sources.length > 0) {\r\n if (firstTwo.length >= 2) {\r\n pills.push({\r\n emoji: '⚖️',\r\n label: tr('pillCompareTop2'),\r\n query: tr('pillCompareTop2Query', { a: firstTwo[0], b: firstTwo[1] }),\r\n });\r\n }\r\n if (firstName) {\r\n const short = firstName.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: firstName }),\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, CopyIcon, CheckIcon } 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 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 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-secret-card\">\r\n <div className=\"hsk-cb-secret-head\">\r\n <span className=\"hsk-cb-secret-title\">{t('keySecretTitle')}</span>\r\n <span className=\"hsk-cb-secret-timer\">{keyCountdown}s</span>\r\n <button type=\"button\" className=\"hsk-cb-secret-dismiss\" onClick={onDismiss} aria-label={t('keyDismiss')}>×</button>\r\n </div>\r\n <button type=\"button\" className=\"hsk-cb-secret-key\" onClick={() => copyValue(mintedKey, 'secret')}>\r\n <code>{mintedKey}</code>\r\n <span className=\"hsk-cb-secret-copy\">{copied === 'secret' ? <CheckIcon /> : <CopyIcon />}{copied === 'secret' ? t('keyCopied') : t('keyCopySecret')}</span>\r\n </button>\r\n <span className=\"hsk-cb-secret-hint\">{t('keySecretHint')}</span>\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 { parseThinking } from './components/ThinkingBlock';\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 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 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, el: HTMLElement) => void;\r\n retrying?: boolean;\r\n continueGenerating: () => void;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n spacerRef: 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 doodleTheme?: string;\r\n}\r\n\r\nfunction latestPicture(messages: ChatMessage[], before: number): string | undefined {\r\n for (let i = before - 1; i >= 0; i--) {\r\n const m = messages[i];\r\n if (m.visualization && m.visualizationType !== 'video') return m.visualization;\r\n if (m.images?.length) return m.images[m.images.length - 1];\r\n }\r\n return undefined;\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 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 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 spacerRef,\r\n vizState,\r\n setVizState,\r\n messages,\r\n doodleTheme,\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 // A voice turn often lands as filler then answer; both roles stack as one run.\r\n const isRunEnd = displayMessages[idx + 1]?.role !== msg.role;\r\n const runMid = !isRunEnd;\r\n const runCont = displayMessages[idx - 1]?.role === msg.role;\r\n const key = (msg as any).id || `${msg.role}-${idx}`;\r\n // The photo just sent is in flight until the reply starts; a render reworks the latest picture before it.\r\n const reply = displayMessages[idx + 1]?.content ?? '';\r\n const photosSending = isLastUser && (loading || streaming) && !parseThinking(reply).content.trim();\r\n const workingOn = msg.visualizing ? latestPicture(displayMessages, idx) : undefined;\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 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 photosSending={photosSending}\r\n workingOn={workingOn}\r\n doodleTheme={doodleTheme}\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 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={spacerRef as any} className=\"hsk-cb-msgs-spacer\" />\r\n </>\r\n );\r\n}\r\n","import React, { useState, useRef, useEffect } from 'react';\nimport { useAkropolysContext, useCardFields, type ChatSource, type ChatAttachment } from '@akropolys/sdk';\nimport { cn } from '../../utils/cn';\nimport { detailsOf } from '../../utils/cardDetails';\nimport {\n SparkleIcon,\n BookmarkIcon,\n HistoryIcon,\n TrashIcon,\n PaperclipIcon,\n MessageIcon,\n WaveformIcon,\n StopIcon,\n ArrowUpIcon,\n PlusIcon,\n XIcon,\n} from './icons';\nimport { ListeningWave } from './components/ListeningWave';\nimport { AnimatedPlaceholder, HSK_STAGGER_MS, splitPlaceholder } from './components/AnimatedPlaceholder';\nimport type { UIStringKey, VoicePhase, ComposerAttachment } from './types';\n\nexport interface ChatComposerProps {\n gooId: string;\n input: string;\n setInput: React.Dispatch<React.SetStateAction<string>>;\n showKikuPicker: boolean;\n setShowKikuPicker: (show: boolean) => void;\n showAtPicker: boolean;\n setShowAtPicker: (show: boolean) => void;\n captureAllowed: boolean;\n discussedSources: ChatSource[];\n handleSelectExtension: (ext: string) => void;\n handleKikuCapture: (product: ChatSource) => void;\n handleKikuCaptureAll: (products: ChatSource[]) => void;\n handleKikuViewHistory: () => void;\n handleKikuDelete: () => void;\n attachments: ComposerAttachment[];\n removeAttachment: (idx: number) => void;\n chromeLoading: boolean;\n inputLocked: boolean;\n imageInputRef: React.RefObject<HTMLInputElement | null>;\n handleImageFiles: (files: FileList | null) => void;\n enableVision: boolean;\n enableVoice: boolean;\n canConverse: boolean;\n startVoice: (mode: 'dictate' | 'converse') => void;\n voiceBlocked: boolean;\n textareaRef: React.RefObject<HTMLTextAreaElement | null>;\n classNames?: { input?: string; sendButton?: string };\n handleInput: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\n voice: {\n active: boolean;\n supported: boolean;\n spectrumBins: () => number;\n micSpectrum: (out: Uint8Array) => boolean;\n };\n voicePhase: VoicePhase;\n activePlaceholder: string;\n loading: boolean;\n streaming: boolean;\n stop: () => void;\n handleSend: (text?: string) => Promise<void>;\n voiceError: string;\n setVoiceError?: (err: string) => void;\n langSwitching?: boolean;\n langPending?: boolean;\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\n rail?: React.ReactNode;\n notice?: React.ReactNode; // sits on the input's top edge, like a status pill on a reply\n onOpenMimi?: () => void;\n}\n\nexport function ChatComposer({\n gooId,\n input,\n setInput,\n showKikuPicker,\n setShowKikuPicker,\n showAtPicker,\n setShowAtPicker,\n captureAllowed,\n discussedSources,\n handleSelectExtension,\n handleKikuCapture,\n handleKikuCaptureAll,\n handleKikuViewHistory,\n handleKikuDelete,\n attachments,\n removeAttachment,\n chromeLoading,\n inputLocked,\n langSwitching = false,\n langPending = false,\n imageInputRef,\n handleImageFiles,\n enableVision,\n enableVoice,\n canConverse,\n startVoice,\n voiceBlocked,\n textareaRef,\n classNames = {},\n handleInput,\n handleKeyDown,\n voice,\n voicePhase,\n activePlaceholder,\n loading,\n streaming,\n stop,\n handleSend,\n voiceError,\n setVoiceError,\n t,\n rail,\n notice,\n onOpenMimi,\n}: ChatComposerProps) {\n const client = useAkropolysContext();\n const cardFields = useCardFields();\n const [placeholderReplay, setPlaceholderReplay] = React.useState(0);\n const [toolsOpen, setToolsOpen] = React.useState(false);\n\n React.useEffect(() => {\n if (!voiceError) return;\n const timer = setTimeout(() => {\n setVoiceError?.('');\n }, 6000);\n return () => clearTimeout(timer);\n }, [voiceError, setVoiceError]);\n\n React.useEffect(() => {\n if (!toolsOpen) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setToolsOpen(false);\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [toolsOpen]);\n\n const placeholderText = activePlaceholder || 'Ask me anything…';\n\n const fieldRef = useRef<HTMLDivElement>(null);\n const [phWraps, setPhWraps] = useState(() => placeholderText.length > 26); // a first guess the measurement corrects\n useEffect(() => {\n const field = fieldRef.current;\n if (!field || input) return;\n const measure = () => {\n const units = field.querySelectorAll<HTMLElement>('.hsk-animated-placeholder__char');\n if (units.length < 2) return setPhWraps(false);\n const first = units[0].offsetTop;\n const last = units[units.length - 1].offsetTop;\n setPhWraps(last - first > units[0].offsetHeight / 2);\n };\n measure();\n const ro = new ResizeObserver(measure);\n ro.observe(field);\n return () => ro.disconnect();\n }, [placeholderText, input]);\n const placeholderSweepMs =\n Math.max(splitPlaceholder(placeholderText).length - 1, 0) * HSK_STAGGER_MS;\n\n // the kite tears through the seam, the seam heals, a fresh kite glides in\n const [launching, setLaunching] = useState(false);\n const launchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const launch = () => {\n if (launchTimer.current) clearTimeout(launchTimer.current);\n setLaunching(true);\n launchTimer.current = setTimeout(() => {\n setLaunching(false);\n launchTimer.current = null;\n }, 550);\n };\n useEffect(() => () => { if (launchTimer.current) clearTimeout(launchTimer.current); }, []);\n\n // While a notice asks for a decision, the input takes no typing or clicks.\n const cardRef = useRef<HTMLDivElement>(null);\n const blocked = !!notice;\n useEffect(() => { cardRef.current?.toggleAttribute('inert', blocked); }, [blocked]);\n\n return (\n <div className=\"hsk-cb-input-wrap\">\n {toolsOpen && (\n <>\n <div className=\"hsk-cb-toolsheet-scrim\" onClick={() => setToolsOpen(false)} />\n <div className=\"hsk-cb-toolsheet-wrap\">\n <div className=\"hsk-cb-toolsheet\" role=\"menu\">\n {enableVision && (\n <button\n className=\"hsk-cb-toolsheet-item\"\n role=\"menuitem\"\n onClick={() => { setToolsOpen(false); imageInputRef.current?.click(); }}\n disabled={loading}\n >\n <PaperclipIcon />\n <span>{t('attachImage')}</span>\n </button>\n )}\n {enableVoice && canConverse && (\n <button\n className=\"hsk-cb-toolsheet-item\"\n role=\"menuitem\"\n onClick={() => {\n setToolsOpen(false);\n if (voiceBlocked) setVoiceError?.(t('errAccountRequired'));\n else startVoice('converse');\n }}\n disabled={loading || chromeLoading}\n >\n <WaveformIcon />\n <span>{t('voiceModeStart')}</span>\n </button>\n )}\n {onOpenMimi && (\n <button className=\"hsk-cb-toolsheet-item\" role=\"menuitem\" onClick={onOpenMimi}>\n <MessageIcon />\n <span>MiMi</span>\n </button>\n )}\n </div>\n </div>\n </>\n )}\n {notice}\n <div className=\"hsk-cb-input-card\" ref={cardRef}>\n {(/^@kiku\\b/i.test(input) || showKikuPicker || showAtPicker) && (\n <div className=\"hsk-cb-docked-header\">\n <span className=\"hsk-cb-docked-sub\">{t('captureAndRemember')}</span>\n <button\n type=\"button\"\n className=\"hsk-cb-docked-close\"\n onClick={() => {\n setInput(prev => prev.replace(/^@kiku\\s*/i, ''));\n setShowKikuPicker(false);\n setShowAtPicker(false);\n }}\n aria-label=\"Close mode\"\n >\n ×\n </button>\n </div>\n )}\n\n {(showKikuPicker || showAtPicker) && (\n <div className=\"hsk-cb-docked-options\" onMouseDown={e => e.preventDefault()}>\n {showAtPicker && captureAllowed && (\n <button\n type=\"button\"\n className=\"hsk-cb-docked-option\"\n onClick={() => handleSelectExtension('@kiku')}\n >\n <span className=\"hsk-cb-docked-option-icon\"><SparkleIcon /></span>\n <span className=\"hsk-cb-docked-option-title\">kiku</span>\n <span className=\"hsk-cb-docked-option-desc\">capture &amp; remember</span>\n </button>\n )}\n\n {showKikuPicker && captureAllowed && (\n <>\n {discussedSources.map((src, i) => (\n <button\n key={src.id ?? i}\n type=\"button\"\n className=\"hsk-cb-docked-option\"\n onClick={() => { handleKikuCapture(src); setShowKikuPicker(false); }}\n >\n <span className=\"hsk-cb-docked-option-icon\">\n {src.image ? <img src={src.image} alt=\"\" /> : <BookmarkIcon />}\n </span>\n <span className=\"hsk-cb-docked-option-title\">{src.name}</span>\n {detailsOf(src, cardFields)[0] && (\n <span className=\"hsk-cb-docked-option-detail\">{detailsOf(src, cardFields)[0].value}</span>\n )}\n </button>\n ))}\n {discussedSources.length > 1 && (\n <button\n type=\"button\"\n className=\"hsk-cb-docked-option\"\n onClick={() => { handleKikuCaptureAll(discussedSources); setShowKikuPicker(false); }}\n >\n <span className=\"hsk-cb-docked-option-icon\"><BookmarkIcon /></span>\n <span className=\"hsk-cb-docked-option-title\">{t('captureAll', { count: String(discussedSources.length) })}</span>\n </button>\n )}\n {discussedSources.length === 0 && (\n <button\n type=\"button\"\n className=\"hsk-cb-docked-option\"\n onClick={() => { handleKikuCapture({ name: 'current page', id: undefined }); setShowKikuPicker(false); }}\n >\n <span className=\"hsk-cb-docked-option-icon\"><BookmarkIcon /></span>\n <span className=\"hsk-cb-docked-option-title\">{t('captureCurrentPage')}</span>\n </button>\n )}\n <button\n type=\"button\"\n className=\"hsk-cb-docked-option\"\n onClick={() => { handleKikuViewHistory(); setShowKikuPicker(false); }}\n >\n <span className=\"hsk-cb-docked-option-icon\"><HistoryIcon /></span>\n <span className=\"hsk-cb-docked-option-title\">{t('whatHaveYouSaved')}</span>\n </button>\n <button\n type=\"button\"\n className=\"hsk-cb-docked-option\"\n onClick={() => { handleKikuDelete(); setShowKikuPicker(false); }}\n >\n <span className=\"hsk-cb-docked-option-icon\"><TrashIcon /></span>\n <span className=\"hsk-cb-docked-option-title\">{t('deleteThis')}</span>\n </button>\n </>\n )}\n </div>\n )}\n\n {attachments.length > 0 && (\n <div className=\"hsk-cb-img-strip\">\n {attachments.map((att, i) => (\n <div key={i} className=\"hsk-cb-img-thumb-wrap\">\n <img src={att.thumb || att.data} alt={`attachment ${i + 1}`} className=\"hsk-cb-img-thumb\" />\n <button\n type=\"button\"\n className=\"hsk-cb-img-thumb-remove\"\n onClick={() => removeAttachment(i)}\n aria-label=\"Remove image\"\n >\n <XIcon size={10} />\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div\n className={cn(\"hsk-cb-input-box\", chromeLoading && \"hsk-cb-input-box--waiting\")}\n data-cascade={placeholderReplay % 2 ? 'b' : 'a'}\n data-tools={toolsOpen ? 'open' : 'closed'}\n style={{ '--hsk-text-sweep': `${placeholderSweepMs}ms` } as React.CSSProperties}\n >\n <input\n ref={imageInputRef as any}\n type=\"file\"\n accept=\"image/*\"\n className=\"hsk-sr-only\"\n onChange={e => {\n handleImageFiles(e.target.files);\n e.target.value = '';\n }}\n />\n {(enableVision || (enableVoice && canConverse)) && (\n <button\n className={cn('hsk-cb-tools-toggle', toolsOpen && 'hsk-cb-tools-toggle--open')}\n onClick={() => setToolsOpen(o => !o)}\n disabled={loading || chromeLoading}\n aria-label={toolsOpen ? 'Close options' : 'More options'}\n aria-expanded={toolsOpen}\n >\n <PlusIcon />\n </button>\n )}\n <>\n {enableVision && (\n <button\n className=\"hsk-cb-attach-btn\"\n onClick={() => imageInputRef.current?.click()}\n disabled={loading}\n aria-label=\"Attach image\"\n >\n <PaperclipIcon />\n </button>\n )}\n </>\n <div className=\"hsk-cb-field\" ref={fieldRef} data-ph-lines={!input && phWraps ? '2' : undefined}>\n <textarea\n ref={textareaRef as any}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n rows={1}\n placeholder=\"\"\n className={cn(\"hsk-cb-textarea\", classNames.input)}\n aria-label={activePlaceholder}\n disabled={inputLocked || (loading && !streaming) || langSwitching}\n />\n <AnimatedPlaceholder\n placeholder={activePlaceholder}\n visible={!input}\n staggerMs={HSK_STAGGER_MS}\n replaySeed={placeholderReplay}\n />\n </div>\n {enableVoice && canConverse && (\n <button\n className={cn(\"hsk-cb-voice-mode-btn\", voiceBlocked && \"hsk-cb-voice-mode-btn--blocked\")}\n onClick={() => voiceBlocked ? setVoiceError?.(t('errAccountRequired')) : startVoice('converse')}\n disabled={loading || chromeLoading}\n aria-label=\"Voice conversation\"\n >\n <WaveformIcon />\n </button>\n )}\n {(loading || streaming) && !launching ? (\n <button\n className={cn(\"hsk-cb-send\", \"hsk-cb-send--stop\", classNames.sendButton)}\n onClick={stop}\n aria-label=\"Stop generating\"\n >\n <StopIcon />\n </button>\n ) : (\n <button\n className={cn(\n \"hsk-cb-send\",\n launching && \"is-launching\",\n classNames.sendButton\n )}\n onClick={() => {\n launch();\n handleSend();\n }}\n disabled={langSwitching || inputLocked || chromeLoading || (!input.trim() && attachments.length === 0)}\n aria-label=\"Send message\"\n >\n <svg width=\"0\" height=\"0\" aria-hidden=\"true\" focusable=\"false\" style={{ position: 'absolute' }}>\n <defs>\n <filter id={gooId}>\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"1.6\" result=\"blur\" />\n <feColorMatrix in=\"blur\" type=\"matrix\"\n values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 16 -7\" result=\"goo\" />\n <feBlend in=\"SourceGraphic\" in2=\"goo\" />\n </filter>\n </defs>\n </svg>\n <span className=\"hsk-cb-send-sheath\" aria-hidden=\"true\" />\n <span className=\"hsk-cb-send-stage\" style={{ filter: `url(#${gooId})` }}>\n <span className=\"hsk-cb-send-seam\" aria-hidden=\"true\" />\n <span className=\"hsk-cb-send-kite\">\n <ArrowUpIcon />\n </span>\n </span>\n </button>\n )}\n </div>\n </div>\n {voiceBlocked ? (\n <div className=\"hsk-cb-voice-error\" role=\"status\" onClick={() => setVoiceError?.('')}>\n <span>{t('errAccountRequired')}</span>\n <button\n type=\"button\"\n className=\"hsk-cb-voice-error-dismiss\"\n onClick={(e) => { e.stopPropagation(); setVoiceError?.(''); }}\n aria-label=\"Dismiss error\"\n >\n ×\n </button>\n </div>\n ) : voiceError && (\n <div className=\"hsk-cb-voice-error\" role=\"status\" onClick={() => setVoiceError?.('')}>\n <span>{t(voiceError as UIStringKey)}</span>\n <button\n type=\"button\"\n className=\"hsk-cb-voice-error-dismiss\"\n onClick={(e) => { e.stopPropagation(); setVoiceError?.(''); }}\n aria-label=\"Dismiss error\"\n >\n ×\n </button>\n </div>\n )}\n {langPending && !voiceBlocked && !voiceError && (\n <div className=\"hsk-cb-voice-error hsk-cb-lang-pending\" role=\"status\">\n <span>{t('langStillLoading')}</span>\n </div>\n )}\n </div>\n );\n}\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 long = content.length > 26;\r\n const units = long ? (content.match(/\\S+\\s*/g) ?? [content]) : splitPlaceholder(content);\r\n const last = Math.max(units.length - 1, 1);\r\n const fit = content.length > 44 ? '3' : long ? '2' : '1';\r\n\r\n return (\r\n <div className=\"hsk-animated-placeholder\" data-fit={fit} 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, { useEffect, useRef, useState } from 'react';\nimport { cn } from '../../utils/cn';\nimport { ChevronRightIcon, CloseIcon, EditIcon, ImageIcon, MicIcon, MicOffIcon } from './icons';\nimport { LIVE_VOICES, type UIStringKey, type VoicePhase } from './types';\nimport type { EarlierCalls } from './hooks/useVoiceController';\nimport { VoiceCanvas } from '../VoiceCanvas';\nimport KikuDoodles, { WorkingVeil } from '../KikuDoodles';\nimport { LightboxModal } from './components/LightboxModal';\nimport { SourcesCarousel } from './components/SourcesCarousel';\nimport type { ChatSource } from '@akropolys/sdk';\nimport type { LiveImage, LiveSource, LiveTurn } from '../../utils/liveVoice';\n\n// Every image of the call in a row above the wave: the photo, then each edit, newest last.\nfunction ImageRow({ images, siteId, themeAttr }: {\n images: LiveImage[];\n siteId: string;\n themeAttr?: string;\n}) {\n const rowRef = useRef<HTMLDivElement | null>(null);\n const [open, setOpen] = useState<string | null>(null);\n\n useEffect(() => {\n const row = rowRef.current;\n if (row) row.scrollTo({ left: row.scrollWidth, behavior: 'smooth' });\n }, [images.length]);\n\n if (!images.length) return null;\n // While a render is on its way, the picture it reworks is the latest one before it.\n const pendingAt = images.findIndex(i => i.pending);\n const reworked = pendingAt > 0 ? images.slice(0, pendingAt).reverse().find(i => i.url)?.id : undefined;\n return (\n <div className=\"hsk-voice-images\" ref={rowRef}>\n {images.map(img => (\n <button\n key={img.id}\n type=\"button\"\n className=\"hsk-voice-image\"\n data-pending={img.pending ? '' : undefined}\n disabled={img.pending}\n onClick={() => setOpen(img.url)}\n >\n {img.pending && <WorkingVeil active seed={siteId} theme={themeAttr} />}\n {img.url && <img key={img.url} src={img.url} alt=\"\" draggable={false} />}\n {img.url && <WorkingVeil active={!!img.sending || img.id === reworked} seed={siteId} theme={themeAttr} />}\n </button>\n ))}\n {open && <LightboxModal src={open} onClose={() => setOpen(null)} />}\n </div>\n );\n}\n\n// One pill naming the voice; the full list, by gender, only while choosing.\nfunction VoicePicker({ current, choose, label, groups }: {\n current: string;\n choose: (name: string) => void;\n label: string;\n groups: { female: string; male: string };\n}) {\n const chosen = LIVE_VOICES.find(v => v.name === current);\n const [open, setOpen] = useState(false);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n // Mounted while closed so it can fold away; inert keeps it out of tab order and clicks.\n if (listRef.current) listRef.current.inert = !open;\n if (!open) return;\n const list = listRef.current;\n const on = list?.querySelector<HTMLElement>('[aria-checked=\"true\"]');\n if (list && on) list.scrollTop = on.offsetTop - (list.clientHeight - on.offsetHeight) / 2;\n // The widget sits in a shadow root, so the event's composed path is what says \"inside\".\n const away = (e: PointerEvent) => {\n if (rootRef.current && !e.composedPath().includes(rootRef.current)) setOpen(false);\n };\n const esc = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); };\n document.addEventListener('pointerdown', away);\n document.addEventListener('keydown', esc);\n return () => {\n document.removeEventListener('pointerdown', away);\n document.removeEventListener('keydown', esc);\n };\n }, [open]);\n\n return (\n <div className=\"hsk-voice-picker\" ref={rootRef} data-open={open ? '' : undefined} dir=\"ltr\">\n <button\n type=\"button\"\n className=\"hsk-voice-pill hsk-voice-pill--current\"\n aria-haspopup=\"true\"\n aria-expanded={open}\n aria-label={`${label}: ${chosen?.trait ?? current} (${current})`}\n onClick={() => setOpen(o => !o)}\n >\n <span>{chosen?.trait ?? current}</span>\n <span className=\"hsk-voice-pill-caret\"><ChevronRightIcon /></span>\n </button>\n <div className=\"hsk-voice-menu-list\" role=\"radiogroup\" aria-label={label} ref={listRef}>\n {(['male', 'female'] as const).map(g => (\n <React.Fragment key={g}>\n <div className=\"hsk-voice-group\" aria-hidden=\"true\">{groups[g]}</div>\n {LIVE_VOICES.filter(v => v.gender === g).map(v => (\n <button\n key={v.name}\n type=\"button\"\n role=\"radio\"\n aria-checked={current === v.name}\n aria-label={`${v.trait}, ${groups[g]} (${v.name})`}\n className={cn('hsk-voice-option', current === v.name && 'hsk-voice-option--on')}\n onClick={() => {\n choose(v.name);\n setOpen(false);\n }}\n >\n <span className=\"hsk-voice-option-name\">{v.trait}</span>\n <span className=\"hsk-voice-option-trait\">{v.name}</span>\n </button>\n ))}\n </React.Fragment>\n ))}\n </div>\n </div>\n );\n}\n\nexport interface VoiceOverlayProps {\n siteId: string;\n themeAttr?: 'light' | 'dark' | string;\n stopVoice: () => void;\n chooseVoice: (name: string) => void;\n liveVoiceName: string;\n voiceSecondsLeft: number | null;\n voiceConnecting: boolean;\n voicePhase: VoicePhase;\n live: {\n micLevel: () => number;\n micSpectrum: (out: Uint8Array) => boolean;\n spectrumBins: () => number;\n turns?: LiveTurn[];\n images?: LiveImage[];\n sources?: LiveSource[];\n photos?: boolean;\n };\n // Earlier calls in this chat, shown above this one until the chat is cleared.\n earlier: EarlierCalls;\n // Clears the voice conversation and restarts the call with no memory; the chat keeps everything.\n newVoiceChat: () => void;\n // A tapped card asks Kiku about itself, the way a tapped card in chat does.\n onSelectSource: (src: ChatSource) => void;\n voiceMuted: boolean;\n setVoiceMuted: React.Dispatch<React.SetStateAction<boolean>>;\n voiceError: string;\n attachPhoto: (file: File) => Promise<void>;\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\n}\n\nexport function VoiceOverlay({\n siteId,\n themeAttr,\n stopVoice,\n chooseVoice,\n liveVoiceName,\n voiceSecondsLeft,\n voiceConnecting,\n voicePhase,\n live,\n earlier,\n newVoiceChat,\n voiceMuted,\n setVoiceMuted,\n voiceError,\n attachPhoto,\n onSelectSource,\n t,\n}: VoiceOverlayProps) {\n const threadRef = useRef<HTMLDivElement | null>(null);\n const endRef = useRef<HTMLDivElement | null>(null);\n const fileRef = useRef<HTMLInputElement | null>(null);\n const turns = [...earlier.turns, ...(live.turns ?? [])];\n const images = [...earlier.images, ...(live.images ?? [])];\n const sources = live.sources ?? [];\n const [lightbox, setLightbox] = useState<string | null>(null);\n const rendering = images.some(i => i.pending);\n const turnCount = turns.length;\n const lastText = turns[turnCount - 1]?.text ?? '';\n\n // Follows the conversation as it is spoken, the way a chat does; opens already at the end.\n const scrolledRef = useRef(false);\n useEffect(() => {\n endRef.current?.scrollIntoView({ block: 'end', behavior: scrolledRef.current ? 'smooth' : 'auto' });\n scrolledRef.current = true;\n }, [turnCount, lastText]);\n\n return (\n <div className=\"hsk-voice-overlay\" role=\"dialog\" aria-label={t('voiceModeStart')}>\n <KikuDoodles seed={siteId} theme={themeAttr} />\n\n {turns.some(x => x.text) && (\n <button\n type=\"button\"\n className=\"hsk-voice-new\"\n onClick={newVoiceChat}\n disabled={voiceConnecting}\n aria-label={t('voiceNewChat')}\n title={t('voiceNewChat')}\n >\n <EditIcon size={15} />\n </button>\n )}\n\n <button\n className=\"hsk-voice-exit\"\n onClick={stopVoice}\n aria-label={t('voiceModeExit')}\n >\n <CloseIcon />\n </button>\n\n <VoicePicker\n current={liveVoiceName}\n choose={chooseVoice}\n label={t('voicePickerLabel')}\n groups={{ female: t('voiceFemale'), male: t('voiceMale') }}\n />\n\n <div className=\"hsk-voice-thread\" ref={threadRef}>\n {turns.filter(x => x.text).map((turn, i) =>\n turn.role === 'user' ? (\n <div key={i} className=\"hsk-cb-user-msg\">\n <div\n className={cn(\n 'hsk-cb-user-bubble',\n 'hsk-cb-user-bubble--spoken',\n !turn.done && 'hsk-voice-turn--live',\n )}\n >\n {turn.text}\n </div>\n </div>\n ) : (\n <div key={i} className=\"hsk-cb-ai-msg\">\n <div className={cn('hsk-cb-ai-body', !turn.done && 'hsk-voice-turn--live')}>\n {turn.text}\n </div>\n </div>\n ),\n )}\n <div ref={endRef} />\n </div>\n\n {/* One shelf between the words and the wave: the shopper's images, then the entries the last search found. */}\n {(images.length > 0 || sources.length > 0) && (\n <div className=\"hsk-voice-shelf\">\n <ImageRow images={images} siteId={siteId} themeAttr={themeAttr} />\n {sources.length > 0 && (\n <div className=\"hsk-voice-sources\">\n <SourcesCarousel\n sources={sources}\n onSelectSource={onSelectSource}\n onImageClick={setLightbox}\n referencedIds={sources.map(s => s.id).filter((id): id is string => !!id)}\n compact\n />\n </div>\n )}\n </div>\n )}\n {lightbox && <LightboxModal src={lightbox} onClose={() => setLightbox(null)} />}\n\n {/* The wave and the mic already show listening, speaking and muted; only connecting needs words. */}\n {voiceConnecting && (\n <div className=\"hsk-voice-connecting\" role=\"status\">\n <span className=\"hsk-voice-connecting-dot\" />\n <span>{t('voiceConnecting')}</span>\n </div>\n )}\n\n {voiceError && <div className=\"hsk-voice-error\">{t(voiceError as UIStringKey)}</div>}\n\n <div className=\"hsk-voice-controls\" dir=\"ltr\">\n {live.photos && (\n <>\n <input\n ref={fileRef}\n type=\"file\"\n accept=\"image/*\"\n className=\"hsk-sr-only\"\n onChange={e => {\n const file = e.target.files?.[0];\n e.target.value = '';\n if (file) void attachPhoto(file);\n }}\n />\n <button\n type=\"button\"\n className=\"hsk-voice-control hsk-voice-control--attach\"\n data-control=\"attach\"\n disabled={voiceConnecting || rendering}\n onClick={() => fileRef.current?.click()}\n aria-label={t('voiceAttachPhoto')}\n >\n <span className=\"hsk-voice-control-icon\"><ImageIcon /></span>\n </button>\n </>\n )}\n <div className={cn('hsk-voice-stage', voiceConnecting && 'hsk-voice-stage--connecting')}>\n <VoiceCanvas\n className=\"hsk-voice-canvas\"\n phase={voicePhase}\n level={live.micLevel}\n spectrum={live.micSpectrum}\n bins={live.spectrumBins}\n />\n </div>\n <button\n className={cn(\n 'hsk-voice-control',\n voiceMuted && 'hsk-voice-control--muted',\n voiceConnecting && 'hsk-voice-control--waiting',\n )}\n data-control=\"mic\"\n disabled={voiceConnecting}\n onClick={() => setVoiceMuted(m => !m)}\n aria-label={voiceMuted ? t('voicePhaseListening') : t('voiceModeExit')}\n >\n <span key={voiceMuted ? 'off' : 'on'} className=\"hsk-voice-control-icon\">\n {voiceMuted ? <MicOffIcon /> : <MicIcon />}\n </span>\n </button>\n </div>\n </div>\n );\n}\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 { 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, useState } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { useT } from '../types';\n\nexport interface TimelineExchangeItem {\n idx: number;\n text: string;\n}\n\nexport interface ConversationTimelineProps {\n items: TimelineExchangeItem[];\n activeIdx: number;\n progress: number;\n onJump: (idx: number) => void;\n side?: 'left' | 'right';\n}\n\nconst WAVE_X = 14;\nconst WAVE_SWAY = 6;\n\n// Sinusoidal curve connecting each exchange along the vertical axis\nfunction buildWave(items: (HTMLButtonElement | null)[], anchor: number) {\n const nodes = items.filter(Boolean) as HTMLButtonElement[];\n if (nodes.length < 2) return null;\n const centre = (n: HTMLButtonElement) => n.offsetTop + n.offsetHeight / 2;\n const height = centre(nodes[nodes.length - 1]) + 10;\n const sway = (i: number) => (i === anchor ? WAVE_SWAY * 1.3 : WAVE_SWAY * 0.6) * (i % 2 ? 1 : -1);\n\n let d = `M ${WAVE_X} 0`;\n let prevY = 0;\n nodes.forEach((n, i) => {\n const y = centre(n);\n const mid = prevY + (y - prevY) / 2;\n d += ` C ${WAVE_X + sway(i)} ${mid}, ${WAVE_X + sway(i)} ${mid}, ${WAVE_X} ${y}`;\n prevY = y;\n });\n return { d: d + ` L ${WAVE_X} ${height}`, height };\n}\n\nexport function ConversationTimeline({\n items,\n activeIdx,\n progress,\n onJump,\n side = 'right',\n}: ConversationTimelineProps) {\n const tr = useT();\n const containerRef = useRef<HTMLElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const itemRefs = useRef<(HTMLButtonElement | null)[]>([]);\n const cursorRef = useRef<HTMLSpanElement>(null);\n const [wave, setWave] = useState<{ d: string; height: number } | null>(null);\n\n let anchor = 0;\n for (let i = 0; i < items.length; i++) {\n if (items[i].idx <= activeIdx) anchor = i;\n }\n\n useEffect(() => {\n const node = itemRefs.current[anchor];\n const cursor = cursorRef.current;\n const track = trackRef.current;\n const container = containerRef.current;\n if (!node) return;\n\n if (cursor) {\n cursor.style.transform = `translateY(${node.offsetTop + node.offsetHeight / 2}px)`;\n }\n\n setWave(buildWave(itemRefs.current, anchor));\n\n if (track && container) {\n const containerHeight = container.clientHeight;\n const trackHeight = track.scrollHeight;\n if (trackHeight > containerHeight && containerHeight > 0) {\n const nodeCenter = node.offsetTop + node.offsetHeight / 2;\n const targetY = containerHeight / 2 - nodeCenter;\n track.style.transform = `translateY(${targetY}px)`;\n } else {\n track.style.transform = 'none';\n }\n }\n }, [anchor, items.length]);\n\n if (items.length < 2) return null;\n\n return (\n <nav\n ref={containerRef}\n className={cn(\"hsk-cb-timeline\", side === 'left' ? \"hsk-cb-timeline--left\" : \"hsk-cb-timeline--right\")}\n aria-label={tr('timelineLabel')}\n >\n <div\n ref={trackRef}\n className=\"hsk-cb-timeline-track\"\n style={{ '--hsk-tl-progress': progress } as React.CSSProperties}\n >\n {wave && (\n <svg\n className=\"hsk-cb-tl-wave\"\n width=\"28\"\n height={wave.height}\n viewBox={`0 0 28 ${wave.height}`}\n aria-hidden=\"true\"\n >\n <path d={wave.d} />\n </svg>\n )}\n <span className=\"hsk-cb-tl-cursor\" ref={cursorRef} aria-hidden=\"true\" />\n {items.map((item, i) => (\n <button\n key={item.idx}\n ref={(el) => { itemRefs.current[i] = el; }}\n type=\"button\"\n className={cn('hsk-cb-tl-item', i === anchor && 'hsk-cb-tl-item--on')}\n style={{ '--hsk-tl-d': Math.min(Math.abs(i - anchor), 4) } as React.CSSProperties}\n onClick={() => onJump(item.idx)}\n title={item.text}\n >\n <span className=\"hsk-cb-tl-dot\" />\n <span className=\"hsk-cb-tl-label\">{item.text}</span>\n </button>\n ))}\n </div>\n </nav>\n );\n}\n","import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport type { ChatMessage } from '@akropolys/sdk';\nimport { cn } from '../../../utils/cn';\nimport { chime } from '../../../utils/chime';\nimport { useDelayedClose } from '../hooks/useDelayedClose';\nimport {\n PinIcon,\n RetryIcon,\n CopyIcon,\n CheckIcon,\n} from '../icons';\nimport type { UIStringKey } from '../types';\n\nconst TAPBACK_EXIT_MS = 190;\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 anchorEl?: HTMLElement | null;\n containerEl?: HTMLElement | null;\n isUser: boolean;\n isRTL?: boolean;\n canRetry?: boolean;\n onPin: (msg: ChatMessage) => void;\n onRetry?: (msg: ChatMessage) => void;\n onCopy: (text: string) => boolean | Promise<boolean>;\n onClose: () => void;\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\n}\n\nexport function TapbackMenu({\n msg,\n rect,\n containerRect,\n anchorEl,\n containerEl,\n isUser,\n isRTL = false,\n canRetry,\n onPin,\n onRetry,\n onCopy,\n onClose,\n t,\n}: TapbackMenuProps) {\n const [copied, setCopied] = useState(false);\n const menuRef = useRef<HTMLDivElement>(null);\n\n const { closing, requestClose } = useDelayedClose(TAPBACK_EXIT_MS, onClose);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') requestClose();\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [requestClose]);\n\n const handleCopyAction = useCallback(async () => {\n const ok = await onCopy(msg.content || '');\n if (!ok) return;\n setCopied(true);\n setTimeout(requestClose, 450);\n }, [msg.content, onCopy, requestClose]);\n\n const handlePinAction = useCallback(() => {\n chime('pin');\n onPin(msg);\n requestClose();\n }, [msg, onPin, requestClose]);\n\n const handleRetryAction = useCallback(() => {\n if (onRetry) onRetry(msg);\n requestClose();\n }, [msg, onRetry, requestClose]);\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 [live, setLive] = useState(rect);\n const [liveContainer, setLiveContainer] = useState(containerRect);\n\n useEffect(() => {\n if (!anchorEl) return;\n let raf = 0;\n const near = (a: number, b: number) => Math.abs(a - b) < 0.5;\n const tick = () => {\n const r = anchorEl.getBoundingClientRect();\n setLive((p) =>\n near(p.top, r.top) && near(p.left, r.left) && near(p.width, r.width) && near(p.height, r.height)\n ? p\n : { top: r.top, left: r.left, width: r.width, height: r.height },\n );\n if (containerEl) {\n const c = containerEl.getBoundingClientRect();\n setLiveContainer((p) =>\n p && near(p.top, c.top) && near(p.left, c.left) && near(p.width, c.width)\n ? p\n : { top: c.top, left: c.left, width: c.width, height: c.height },\n );\n }\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, [anchorEl, containerEl]);\n\n const [bubbleColor, setBubbleColor] = useState('');\n useEffect(() => {\n if (!anchorEl) return;\n const bg = getComputedStyle(anchorEl).backgroundColor;\n if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') setBubbleColor(bg);\n }, [anchorEl]);\n\n const box = live;\n const container = liveContainer ?? containerRect;\n\n const cTop = container?.top ?? 0;\n const cLeft = container?.left ?? 0;\n const cWidth = container?.width ?? (typeof window !== 'undefined' ? window.innerWidth : 390);\n\n const bTop = box.top - cTop;\n const bLeft = box.left - cLeft;\n const bWidth = box.width;\n const bHeight = box.height;\n\n let btnCount = 2; // Pin + Copy\n if (canRetry && onRetry) btnCount++;\n const estimatedWidth = btnCount === 2 ? 122 : 170;\n const capsuleWidth = measuredWidth || estimatedWidth;\n const capsuleHeight = 36;\n\n const thinkAbove = !!anchorEl?.closest('.hsk-cb-think')\n || !!anchorEl?.parentElement?.querySelector('.hsk-cb-think-head');\n const placeAbove = bTop >= 58 && !thinkAbove;\n const capsuleTop = placeAbove\n ? Math.max(8, bTop - capsuleHeight - 9)\n : Math.min(bTop + bHeight + 9, (container?.height ?? 800) - capsuleHeight - 8);\n\n const anchorRight = isUser ? isRTL : !isRTL;\n const targetX = anchorRight\n ? Math.min(cWidth - 18, bLeft + bWidth - 7)\n : Math.max(18, bLeft + 7);\n\n let capsuleLeft = anchorRight\n ? targetX - capsuleWidth + 18\n : targetX - 18;\n\n capsuleLeft = Math.max(10, Math.min(capsuleLeft, cWidth - capsuleWidth - 10));\n\n const tailOffset = Math.max(18, Math.min(targetX - capsuleLeft, capsuleWidth - 18));\n\n const anchorColor = bubbleColor\n || (isUser\n ? 'var(--hsk-user-bubble-bg, var(--hsk-primary, #007aff))'\n : 'var(--hsk-bubble-bg, #eeeef0)');\n\n let toolIdx = 0;\n\n return (\n <div className=\"hsk-tapback-overlay\" onClick={requestClose}>\n <div\n ref={menuRef}\n className={cn(\n \"hsk-tapback-group\",\n closing && \"is-closing\",\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 '--tail-dir': anchorRight ? 1 : -1,\n '--tail-step': isUser ? '9px' : '8px',\n '--hsk-anchor-color': anchorColor,\n '--hsk-skin': 'var(--hsk-bubble-bg, var(--hsk-chat-ai-bg, #eeeef0))',\n } as React.CSSProperties}\n onClick={e => e.stopPropagation()}\n >\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 <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 <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--mid\" />\n <span className=\"hsk-tapback-dot hsk-tapback-dot--anchor\" />\n </div>\n </div>\n </div>\n );\n}\n","export const KIKU_CSS = \"@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;}@property --hsk-pill-bg{syntax: \\\"<color>\\\"; inherits: true; initial-value: rgba(255,255,255,.06);}@property --hsk-glass-bg{syntax: \\\"<color>\\\"; inherits: true; initial-value: rgba(255,255,255,.07);}@property --hsk-glass-edge{syntax: \\\"<color>\\\"; inherits: true; initial-value: transparent;}@property --hsk-glass-edge-top{syntax: \\\"<color>\\\"; inherits: true; initial-value: transparent;}@property --hsk-glass-drop{syntax: \\\"<color>\\\"; inherits: true; initial-value: transparent;}@property --hsk-glass-sheen{syntax: \\\"<color>\\\"; inherits: true; initial-value: transparent;}[data-hsk-theme]{transition:--hsk-chat-bg .36s cubic-bezier(.4,0,.2,1),--hsk-chat-text .36s cubic-bezier(.4,0,.2,1),--hsk-chat-muted .36s cubic-bezier(.4,0,.2,1),--hsk-chat-divide .36s cubic-bezier(.4,0,.2,1),--hsk-chat-input-bg .36s cubic-bezier(.4,0,.2,1),--hsk-chat-source-bg .36s cubic-bezier(.4,0,.2,1),--hsk-fade-bg .36s cubic-bezier(.4,0,.2,1),--hsk-surface-1 .36s cubic-bezier(.4,0,.2,1),--hsk-surface-2 .36s cubic-bezier(.4,0,.2,1),--hsk-bubble-bg .36s cubic-bezier(.4,0,.2,1),--hsk-think-text .36s cubic-bezier(.4,0,.2,1),--hsk-placeholder .36s cubic-bezier(.4,0,.2,1),--hsk-grid-bg .36s cubic-bezier(.4,0,.2,1),--hsk-active-bg .36s cubic-bezier(.4,0,.2,1),--hsk-on-active .36s cubic-bezier(.4,0,.2,1),--hsk-src-title .36s cubic-bezier(.4,0,.2,1),--hsk-src-desc .36s cubic-bezier(.4,0,.2,1),--hsk-price-bg .36s cubic-bezier(.4,0,.2,1),--hsk-price-text .36s cubic-bezier(.4,0,.2,1),--hsk-sheet-bg .36s cubic-bezier(.4,0,.2,1),--hsk-primary .36s cubic-bezier(.4,0,.2,1),--hsk-pill-bg .36s cubic-bezier(.4,0,.2,1),--hsk-glass-bg .36s cubic-bezier(.4,0,.2,1),--hsk-glass-edge .36s cubic-bezier(.4,0,.2,1),--hsk-glass-edge-top .36s cubic-bezier(.4,0,.2,1),--hsk-glass-drop .36s cubic-bezier(.4,0,.2,1),--hsk-glass-sheen .36s cubic-bezier(.4,0,.2,1)}[data-hsk-theming] *,[data-hsk-theming] *:before,[data-hsk-theming] *:after{transition-property:transform,opacity!important}[data-hsk-theming] .hsk-cb-theme-squircle-wrap{transition-property:width,height,border-radius!important}[data-hsk-theming] .hsk-cb-theme-squircle-wrap>.hsk-cb-theme-squircle-trigger{transition-property:height,opacity!important}@media(prefers-reduced-motion:reduce){[data-hsk-theme]{transition:none}}:host,:root{--hsk-border-radius: 0px;--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),--hsk-pill-bg .45s cubic-bezier(.16,1,.3,1),--hsk-glass-bg .45s cubic-bezier(.16,1,.3,1),--hsk-glass-edge .45s cubic-bezier(.16,1,.3,1),--hsk-glass-edge-top .45s cubic-bezier(.16,1,.3,1),--hsk-glass-drop .45s cubic-bezier(.16,1,.3,1),--hsk-glass-sheen .45s cubic-bezier(.16,1,.3,1),--hsk-fade-bg .45s cubic-bezier(.16,1,.3,1),--hsk-chat-source-bg .45s cubic-bezier(.16,1,.3,1),--hsk-think-text .45s cubic-bezier(.16,1,.3,1),--hsk-placeholder .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-cb-overlay{--hsk-glass-border: 1px solid var(--hsk-glass-edge);--hsk-glass-border-top: 1px solid var(--hsk-glass-edge-top);--hsk-glass-shadow: 0 12px 32px -4px var(--hsk-glass-drop), 0 1px 0 0 var(--hsk-glass-sheen) inset}.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}}@keyframes hsk-pulse{0%,to{transform:scale(.8);opacity:.5}50%{transform:scale(1.2);opacity:1}}.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, 0px);border:1px solid rgba(255,106,51,.4);background:#ff6a331a;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:#ff6a332e;border-color:#ff6a33b3;box-shadow:0 4px 16px #ff6a3333}.hsk-cb-btn:active{transform:scale(.97)}.hsk-cb-topbar-mark:active .hsk-cb-topbar-name{transform:scale(.95)}.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{0%{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)}to{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)}to{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) * 12ms)}.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) * 12ms)}@keyframes hsk-pill-wave{0%{opacity:0;transform:translateY(6px) scale(.96)}to{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)}to{opacity:1;transform:translateY(0)}}.hsk-cb-overlay.hsk-cb-overlay--closing{animation:hsk-overlay-out .2s cubic-bezier(.4,0,1,1) both!important;pointer-events:none}.hsk-cb-overlay.hsk-cb-overlay--closing .hsk-cb-panel{animation:hsk-panel-sink .2s cubic-bezier(.4,0,1,1) both!important}@keyframes hsk-overlay-out{0%{opacity:1}to{opacity:0}}@keyframes hsk-panel-sink{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(8px) scale(.985)}}@media(prefers-reduced-motion:reduce){.hsk-cb-overlay.hsk-cb-overlay--closing,.hsk-cb-overlay.hsk-cb-overlay--closing .hsk-cb-panel{animation:none!important}.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{animation:none!important}}.hsk-cb-panel:lang(ja){font-feature-settings:\\\"palt\\\";word-break:auto-phrase;line-break:strict}.hsk-cb-panel:lang(ja) p,.hsk-cb-panel:lang(ja) li{font-weight:500}.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)}@keyframes hsk-panel-in{0%{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)}@media(hover:hover)and (pointer:fine){.hsk-cb-topbar-mark:hover>*{translate:0 -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%,to{transform:scale(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 #0000001f;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:var(--hsk-tray-top, calc(100% + 12px) )!important;left:50%;transform:translate(-50%);width:min(300px,calc(100vw - 28px))!important;padding:var(--hsk-tray-head, 6px) 6px 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;z-index:1000;transform-origin:50% 0;animation:hsk-topbar-ooze .25s cubic-bezier(.16,1,.3,1) both}.hsk-cb-topbar.is-docked{z-index:20!important}.hsk-cb-topbar-scrim{position:fixed;inset:0;z-index:999;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 30%,transparent);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);mask-image:linear-gradient(to bottom,#000 40vh,rgba(0,0,0,.97) 43.5vh,rgba(0,0,0,.84) 48.75vh,rgba(0,0,0,.5) 57.5vh,rgba(0,0,0,.16) 66.25vh,rgba(0,0,0,.03) 71.5vh,transparent 75vh);-webkit-mask-image:linear-gradient(to bottom,#000 40vh,rgba(0,0,0,.97) 43.5vh,rgba(0,0,0,.84) 48.75vh,rgba(0,0,0,.5) 57.5vh,rgba(0,0,0,.16) 66.25vh,rgba(0,0,0,.03) 71.5vh,transparent 75vh);animation:hsk-scrim-in .25s cubic-bezier(.16,1,.3,1) both}.hsk-cb-topbar-scrim.is-closing{animation:hsk-scrim-out .18s cubic-bezier(.4,0,1,1) both}.hsk-cb-topbar-mark.is-oozing{position:relative;z-index:1001}@keyframes hsk-scrim-in{0%{opacity:0}to{opacity:1}}@keyframes hsk-scrim-out{0%{opacity:1}to{opacity:0}}.hsk-cb-topbar-ooze-menu.is-closing{animation:hsk-topbar-ooze-out .18s cubic-bezier(.4,0,1,1) both;pointer-events:none}@keyframes hsk-topbar-ooze-out{0%{opacity:1;transform:translate(-50%) scale(1)}to{opacity:0;transform:translate(-50%) scale(.96)}}@media(prefers-reduced-motion:reduce){.hsk-cb-topbar-scrim,.hsk-cb-topbar-scrim.is-closing,.hsk-cb-topbar-ooze-menu.is-closing{animation:none}}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-grid-item{width:max-content;max-width:100%}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-block{display:flex;align-items:stretch;gap:8px;padding:6px 7px 0}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-vlabel{flex:0 0 auto;align-self:center;writing-mode:vertical-rl;transform:rotate(180deg);font-size:8px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--hsk-chat-muted);opacity:.38;user-select:none}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-2x2-grid{display:flex!important;flex-wrap:wrap!important;justify-content:flex-start!important;gap:6px!important;width:100%!important;max-width:100%!important;min-width:0!important;padding:0!important;box-sizing:border-box!important;margin-top:0!important;background:none!important;border:none!important;border-radius:0!important;box-shadow:none!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-grid-item{width:max-content;max-width:100%;height:34px;display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:0 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--hsk-chat-border, rgba(255, 255, 255, .4)) 22%,transparent)!important;background:color-mix(in srgb,var(--hsk-chat-bg, #ffffff) 34%,transparent)!important;color:var(--hsk-chat-muted, #71717a);font-size:11.5px;font-weight:600;box-sizing:border-box;white-space:nowrap;cursor:pointer;transition:background-color .16s cubic-bezier(.16,1,.3,1),color .16s cubic-bezier(.16,1,.3,1),border-color .16s cubic-bezier(.16,1,.3,1),box-shadow .16s cubic-bezier(.16,1,.3,1),transform .16s cubic-bezier(.16,1,.3,1)}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-grid-item svg{flex-shrink:0;width:12px;height:12px}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-grid-item:hover{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:#fff!important;border-color:var(--hsk-primary, #ff6a33)!important;box-shadow:0 3px 12px color-mix(in srgb,var(--hsk-primary, #ff6a33) 35%,transparent)!important}@keyframes hsk-topbar-ooze{0%{opacity:0;transform:translate(-50%) translateY(-6px) scale(.94)}to{opacity:1;transform:translate(-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-kiku-id-rail{display:none}@media(min-width:1200px){.hsk-cb-kiku-id-rail.hsk-cb-kiku-id-rail--left{display:flex;position:absolute;inset:auto 100% 48px auto!important;margin-right:28px!important;transform:none!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;inset:auto auto 48px 100%!important;margin-left:28px!important;transform:none!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-dock-frost{position:absolute;inset:-100vmax;z-index:-1;pointer-events:none;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 30%,transparent);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);mask-image:radial-gradient(circle at 50% 50%,#000 330px,rgba(0,0,0,.97) 369px,rgba(0,0,0,.84) 427px,rgba(0,0,0,.5) 525px,rgba(0,0,0,.16) 622px,rgba(0,0,0,.03) 681px,transparent 720px);-webkit-mask-image:radial-gradient(circle at 50% 50%,#000 330px,rgba(0,0,0,.97) 369px,rgba(0,0,0,.84) 427px,rgba(0,0,0,.5) 525px,rgba(0,0,0,.16) 622px,rgba(0,0,0,.03) 681px,transparent 720px);opacity:0;transition:opacity .2s cubic-bezier(.4,0,.9,.4)}.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 color-mix(in srgb,var(--hsk-chat-bg, #fff) 60%,transparent)!important;border-bottom:1px solid color-mix(in srgb,#000 6%,transparent)!important;box-shadow:0 4px 14px -2px color-mix(in srgb,#000 12%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 40%,transparent) inset;color:var(--hsk-chat-muted, #71717a);cursor:pointer;font-family:inherit;transition:all .2s 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:color-mix(in srgb,var(--hsk-chat-bg, #fff) 75%,transparent)!important;transform:translateY(-1px);box-shadow:0 6px 18px -2px color-mix(in srgb,#000 15%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 55%,transparent) 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 color-mix(in srgb,var(--hsk-chat-bg, #fff) 60%,transparent)!important;border-bottom:1px solid color-mix(in srgb,#000 6%,transparent)!important;box-shadow:0 4px 16px -2px color-mix(in srgb,#000 12%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 40%,transparent) 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:color-mix(in srgb,var(--hsk-chat-bg, #fff) 80%,transparent)!important;transform:translateY(-1px);box-shadow:0 6px 20px -2px color-mix(in srgb,#000 16%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 55%,transparent) 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:-.01em}.hsk-cb-theme-2x2-grid{display:flex;flex-wrap:wrap;justify-content:center;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 color-mix(in srgb,var(--hsk-chat-bg, #fff) 65%,transparent);border-bottom:1px solid color-mix(in srgb,#000 6%,transparent);box-shadow:0 16px 38px -6px color-mix(in srgb,#000 16%,transparent),0 0 0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 20%,transparent) inset,0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 50%,transparent) inset;transform-origin:bottom left;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 .22s cubic-bezier(.4,0,.2,1) both}.hsk-cb-theme-squircle-trigger{animation:hsk-theme-pill-in .24s cubic-bezier(.16,1,.3,1) both}.hsk-cb-theme-squircle-wrap{justify-content:flex-end;box-sizing:border-box;width:auto;height:32px;overflow:hidden;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 color-mix(in srgb,var(--hsk-chat-bg, #fff) 60%,transparent)!important;border-bottom:1px solid color-mix(in srgb,#000 6%,transparent)!important;box-shadow:0 4px 16px -2px color-mix(in srgb,#000 12%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 40%,transparent) inset!important;interpolate-size:allow-keywords;transition:width .38s cubic-bezier(.16,1,.3,1),height .38s cubic-bezier(.16,1,.3,1),border-radius .38s cubic-bezier(.16,1,.3,1)}.hsk-cb-theme-squircle-wrap.is-open{width:222px;height:auto;border-radius:18px}.hsk-cb-kiku-id-rail .hsk-cb-theme-squircle-wrap>.hsk-cb-theme-squircle-trigger,.hsk-cb-kiku-id-rail .hsk-cb-theme-squircle-wrap>.hsk-cb-theme-squircle-trigger:hover{flex:none;height:30px;background:none!important;border:0!important;box-shadow:none!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important;transform:none;animation:none;transition:height .38s cubic-bezier(.16,1,.3,1),opacity .2s ease,color .2s ease}.hsk-cb-kiku-id-rail .hsk-cb-theme-squircle-wrap.is-open>.hsk-cb-theme-squircle-trigger{height:0;opacity:0;pointer-events:none}.hsk-cb-kiku-id-rail .hsk-cb-theme-squircle-wrap>.hsk-cb-theme-2x2-grid{flex:none;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));width:220px;min-width:220px;max-width:220px;margin-inline-end:-220px;background:none!important;border:0!important;box-shadow:none!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important;border-radius:0;animation:none;opacity:0;transition:opacity .1s ease}.hsk-cb-kiku-id-rail .hsk-cb-theme-squircle-wrap>.hsk-cb-theme-2x2-grid>.hsk-cb-theme-grid-item{width:100%;justify-content:flex-start;padding:0 10px}.hsk-cb-kiku-id-rail .hsk-cb-theme-squircle-wrap.is-open>.hsk-cb-theme-2x2-grid{opacity:1;transition:opacity .24s ease .1s}.hsk-cb-theme-grid-item{display:inline-flex;flex-direction:row;align-items:center;justify-content:center;gap:6px;height:30px;padding:0 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--hsk-chat-border, rgba(255, 255, 255, .3)) 25%,transparent)!important;border-top:1px solid color-mix(in srgb,var(--hsk-chat-bg, #fff) 45%,transparent)!important;outline:none!important;background:color-mix(in srgb,var(--hsk-chat-bg, #ffffff) 65%,transparent);color:var(--hsk-chat-text, currentColor);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 #0000000a,0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 30%,transparent) 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:color-mix(in srgb,var(--hsk-chat-bg, #fff) 70%,transparent)!important;transform:translateY(-1px);box-shadow:0 3px 8px #00000014,0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 45%,transparent) inset!important}.hsk-cb-theme-grid-item.is-active{background:var(--hsk-primary, #ff6a33)!important;border-color:var(--hsk-primary, #ff6a33)!important;color:#fff!important;box-shadow:0 2px 10px color-mix(in srgb,var(--hsk-primary, #ff6a33) 38%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 40%,transparent) inset!important}}.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-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 color-mix(in srgb,var(--hsk-chat-bg, #fff) 35%,transparent);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 color-mix(in srgb,var(--hsk-chat-bg, #fff) 25%,transparent) inset;color:var(--hsk-chat-muted, currentColor);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;transition:all .2s 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:color-mix(in srgb,var(--hsk-chat-bg, #fff) 55%,transparent);box-shadow:0 3px 10px color-mix(in srgb,var(--hsk-chat-text, #000) 8%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 35%,transparent) 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 color-mix(in srgb,var(--hsk-chat-bg, #fff) 30%,transparent) inset}.hsk-cb-exit-btn:hover{background:radial-gradient(120% 90% at 30% 0%,rgba(255,255,255,.4),transparent 65%),color-mix(in srgb,var(--hsk-surface-1, currentColor) 35%,transparent);color:#ef4444}.hsk-cb-msgs{position:relative;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 0px,#000000 8px,#000000 100%);-webkit-mask-image:linear-gradient(to bottom,transparent 0px,#000000 8px,#000000 100%)}.hsk-cb-msgs-spacer{flex:none;height:1px;pointer-events:none}.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 0 auto;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;flex-shrink:0;overflow:hidden;padding-bottom:26px;margin-bottom:-26px}.hsk-cb-onboarding-head{display:flex;align-items:center;justify-content:flex-start;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{margin:0;font-size:clamp(24px,4.5vw,34px);font-weight:500;line-height:1.2;letter-spacing:-.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;font-size:16px;font-weight:500;color:var(--hsk-chat-text, #111);text-align:start}.hsk-cb-hello-hint{margin:0;font-size:13px;line-height:1.5;color:var(--hsk-chat-muted, #5f6368);text-align:start}.hsk-cb-name-step .hsk-cb-hello{color:var(--hsk-chat-text, #111)}.hsk-cb-name-step .hsk-cb-hello-ask{margin-top:6px;font-size:19px;font-weight:600;color:color-mix(in srgb,var(--hsk-chat-text, #111) 62%,var(--hsk-chat-muted, #8b8b8f))}.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-lang-chips{display:flex;flex-wrap:wrap;gap:8px 10px;margin:16px 0 8px;margin-inline-start:-4px;align-items:center}.hsk-cb-lang-chip{display:inline-flex;align-items:center;justify-content:center;min-height:34px;padding:6px 15px;font-family:var(--hsk-font);font-size:13.5px;font-weight:400;line-height:1.2;letter-spacing:-.01em;color:var(--hsk-chat-text, #27272a);background:color-mix(in srgb,var(--hsk-chat-card-bg, var(--hsk-chat-bg, #ffffff)) 72%,transparent);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);border:none;border-radius:999px;box-shadow:0 2px 8px -1px #0000000f,0 1px 2px #00000005;cursor:pointer;transition:all .18s cubic-bezier(.16,1,.3,1);user-select:none;-webkit-font-smoothing:antialiased}.hsk-cb-lang-chip:hover{background:color-mix(in srgb,var(--hsk-primary, #ff6a33) 12%,var(--hsk-chat-card-bg, #ffffff));color:var(--hsk-primary, #ff6a33);transform:translateY(-1px);box-shadow:0 4px 12px -2px #00000014}.hsk-cb-lang-chip:active{transform:translateY(0) scale(.97)}.hsk-cb-lang-chip:focus-visible{outline:2px solid var(--hsk-primary, #ff6a33);outline-offset:2px}[data-hsk-theme=dark] .hsk-cb-lang-chip,[data-hsk-theme=midnight] .hsk-cb-lang-chip{color:#e4e4e7;background:#ffffff12;border:none;box-shadow:0 2px 8px -1px #0000004d}[data-hsk-theme=dark] .hsk-cb-lang-chip:hover,[data-hsk-theme=midnight] .hsk-cb-lang-chip:hover{background:rgba(var(--hsk-primary-rgb, 255, 106, 51),.2);color:#fff}.hsk-cb-lang-chips-hint{display:inline-flex;align-items:center;font-size:13px;font-weight:400;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-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:translate(-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}to{background-position:-300% 0}}@keyframes hsk-chrome-sheen{0%{transform:translate(-100%)}to{transform:translate(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:#ff6a3326;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-progress{background:var(--hsk-chat-source-bg, rgba(0, 0, 0, .06))}.hsk-cb-chrome-back-btn{color:#52525b;background:#0000000a;border-color:#00000014}.hsk-cb-chrome-back-btn:hover{background:#00000014;color:#09090b;border-color:#00000024}}.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;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)}to{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-check{display:inline-grid;place-items:center;width:20px;height:20px;flex-shrink:0;border-radius:6px;border:1.5px solid color-mix(in srgb,var(--hsk-chat-text, #111) 28%,transparent);background:transparent;box-sizing:border-box;transition:background-color .22s ease,border-color .22s ease}.hsk-cb-check svg{width:14px;height:14px;fill:none;stroke:#fff;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}.hsk-cb-check path{stroke-dasharray:16;stroke-dashoffset:16;transition:stroke-dashoffset .3s cubic-bezier(.65,0,.35,1) .06s}.is-selected>.hsk-cb-check{background:var(--hsk-primary, #ff6a33);border-color:var(--hsk-primary, #ff6a33);animation:hsk-cb-check-press .42s cubic-bezier(.34,1.56,.64,1)}.is-selected>.hsk-cb-check path{stroke-dashoffset:0}.hsk-cb-entlang-opt:hover>.hsk-cb-check{border-color:var(--hsk-primary, #ff6a33)}@keyframes hsk-cb-check-press{0%{transform:scale(1)}35%{transform:scale(.78)}to{transform:scale(1)}}.hsk-cb-entlang-opt>.hsk-cb-check{margin-inline-end:14px}.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:-.01em}.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:translate(-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:translate(-100%)}to{transform:translate(200%)}}@keyframes hsk-ink-bloom-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes hsk-hello-rise{0%{opacity:0}to{opacity:1}}.hsk-cb-hello,.hsk-cb-hello-lead,.hsk-cb-hello-ask,.hsk-cb-hello-hint,.hsk-cb-hello-skip{opacity:0;animation:hsk-hello-rise .45s cubic-bezier(.22,1,.36,1) both}.hsk-cb-hello{animation-delay:.04s}.hsk-cb-hello-lead{animation-delay:.12s}.hsk-cb-hello-ask{animation-delay:.2s}.hsk-cb-hello-hint{animation-delay:.28s}.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{0%{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-hint,.hsk-cb-hello-skip,.hsk-cascade__w,.hsk-cb-check{animation:none;opacity:1;transform:none;filter:none}.hsk-cb-check path{transition: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, 0px);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:#ff6a330f}.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:3px;gap:0}.hsk-cb-msg-group--run-cont{padding-top:0}.hsk-cb-msg-group--run-mid .hsk-cb-ai-msg{margin-bottom:3px}.hsk-cb-msg-group--run-cont .hsk-cb-ai-text{margin-top:0}.hsk-cb-msg-group--run-mid .hsk-cb-ai-msg .hsk-cb-ai-text:before,.hsk-cb-msg-group--run-mid .hsk-cb-ai-msg .hsk-cb-ai-text:after{display:none}.hsk-cb-msg-group--run-mid .hsk-cb-user-bubble{border-bottom-right-radius:20px!important}[dir=rtl] .hsk-cb-msg-group--run-mid .hsk-cb-user-bubble,.hsk-cb-panel[dir=rtl] .hsk-cb-msg-group--run-mid .hsk-cb-user-bubble,.hsk-cb-msg-group--run-mid .hsk-cb-user-bubble[dir=rtl]{border-bottom-right-radius:20px!important;border-bottom-left-radius:20px!important}.hsk-cb-msg-group--run-cont .hsk-cb-user-bubble{border-top-right-radius:20px!important}[dir=rtl] .hsk-cb-msg-group--run-cont .hsk-cb-user-bubble,.hsk-cb-panel[dir=rtl] .hsk-cb-msg-group--run-cont .hsk-cb-user-bubble,.hsk-cb-msg-group--run-cont .hsk-cb-user-bubble[dir=rtl]{border-top-right-radius:20px!important;border-top-left-radius:20px!important}.hsk-cb-msg-group:last-child{border-bottom:none}@keyframes hsk-msg-in{0%{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 .3s cubic-bezier(.22,1,.36,1) 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(12px) scale(.94)}60%{opacity:1}to{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:#fff;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;width:fit-content;word-break:break-word;overflow-wrap:anywhere;letter-spacing:-.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-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%,460px);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-bubble--tail{border-bottom-right-radius:25px}.hsk-cb-panel[dir=rtl] .hsk-cb-user-bubble--tail{border-bottom-right-radius:20px;border-bottom-left-radius:25px}.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:translate(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:translate(0)}.hsk-cb-msg-action{display:inline-flex;align-items:center;justify-content: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;box-sizing:border-box;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));border:none;transform:translateY(-.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:transparent;border:none;box-shadow:none}.hsk-cb-msg-action--retry:hover:not(:disabled){color:var(--hsk-on-active, #ffffff)!important;background:var(--hsk-primary, #ff6a33)!important;border:none!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 #ef444499;animation:hsk-failed-pulse 1.8s ease-in-out infinite}@keyframes hsk-failed-pulse{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.25);opacity:.7}}.hsk-cb-msg-action--copied{color:#10b981!important;background:#10b98126!important;font-weight:600}@media(max-width:640px){.hsk-cb-msg-actions{display:none!important}}@keyframes hsk-sent-in{0%{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%,to{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:1200px){.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{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}.hsk-cb-timeline-track{--hsk-tl-x: 14px;position:relative;padding-left:28px!important;padding-right:6px!important;transition:transform .28s cubic-bezier(.22,1,.36,1)}.hsk-cb-timeline-track:before,.hsk-cb-timeline-track:after{display:none!important}.hsk-cb-tl-wave{position:absolute;left:0;top:0;overflow:visible;pointer-events:none;fill:none;stroke:var(--hsk-chat-divide, rgba(0, 0, 0, .12));stroke-width:2;stroke-linecap:round;transition:d .35s cubic-bezier(.22,1,.36,1)}@media(prefers-color-scheme:dark){.hsk-cb-tl-wave{stroke:var(--hsk-chat-divide, rgba(255, 255, 255, .14))}}.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, 14px) - 3px)!important;right:auto!important;top:50%;width:6px;height:6px;margin-top:-3px;border-radius:999px;background:var(--hsk-chat-muted, #8a8f98);opacity:max(.1,calc(.28 - var(--hsk-tl-d) * .07));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:translate(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:translate(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;box-shadow:0 0 0 5px color-mix(in srgb,var(--hsk-primary, #ff6a33) 14%,transparent);left:calc(var(--hsk-tl-x, 14px) - 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}.hsk-cb-tl-item--on .hsk-cb-tl-dot{opacity:0}.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 #00000024;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:#fff!important;border-color:var(--hsk-primary, #ff6a33)!important;transform:translateY(-50%) scale(1.1);box-shadow:0 6px 18px #ff6a3359}.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:#96969659;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, 0px);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{0%{opacity:0;transform:translate(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, 0px);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-detail{font-size:11px;padding:1px 6px}.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-detail{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-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{position:relative;z-index:95;border-radius:20px;background:var(--hsk-chat-input-bg, #ffffff);border:none!important;outline:none!important;box-shadow:0 3px 14px -1px #0000000d,0 1px 4px #00000008!important;overflow:hidden;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 #00000012,0 2px 6px #0000000a!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-sub{font-size:12px;font-weight:500;letter-spacing:-.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:#00000014;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-detail{font-size:12px;font-weight:600;color:var(--hsk-chat-muted, #6b7280)}.hsk-cb-input-box{position:relative;display:grid;grid-template-columns:auto 1fr auto auto;grid-template-rows:auto 0px;align-items:center;justify-items:start;column-gap:10px;row-gap:0px;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)}to{opacity:1;transform:translateY(0) scale(1)}}.hsk-cb-toolsheet-scrim{position:fixed;inset:0;z-index:90;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 30%,transparent);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);mask-image:linear-gradient(to top,#000 30vh,rgba(0,0,0,.84) 38vh,rgba(0,0,0,.4) 48vh,rgba(0,0,0,.1) 56vh,transparent 62vh);-webkit-mask-image:linear-gradient(to top,#000 30vh,rgba(0,0,0,.84) 38vh,rgba(0,0,0,.4) 48vh,rgba(0,0,0,.1) 56vh,transparent 62vh);animation:hsk-scrim-in .25s cubic-bezier(.16,1,.3,1) both;cursor:default}.hsk-cb-toolsheet-pub-text{display:flex;flex-direction:column;min-width:0;gap:2px}.hsk-cb-toolsheet-pub-text code{max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px;color:var(--hsk-chat-muted, #6b7280)}.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-input-box>.hsk-cb-attach-btn{grid-column:1;grid-row:1}.hsk-cb-input-box>.hsk-cb-field{grid-column:2;grid-row:1}.hsk-cb-input-box>.hsk-cb-voice-mode-btn{grid-column:3;grid-row:1}.hsk-cb-input-box>.hsk-cb-send,.hsk-cb-input-box>.hsk-chat-send{grid-column:4;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-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:var(--hsk-ph-font-size, var(--hsk-input-font-size, 16px))}.hsk-cb-attach-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,#0056b3);color:#fff;border-radius:12px!important;box-shadow:0 4px 14px #007aff61,inset 0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 35%,transparent);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 #007aff7a,inset 0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 45%,transparent)}.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 #007aff4d}.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-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;flex-wrap:wrap;align-items:center;align-content:center;row-gap:1px;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: .11s}.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: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)}to{transform:translateY(0) scale(1)}}@keyframes hsk-leaf-settle-b{0%{transform:translateY(0) scale(1)}42%{transform:translateY(-3px) scale(1.05)}to{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[data-fit=\\\"2\\\"]{--hsk-ph-font-size: 15px}.hsk-animated-placeholder[data-fit=\\\"3\\\"]{--hsk-ph-font-size: 14px}.hsk-cb-field{transition:min-block-size .26s cubic-bezier(.16,1,.3,1)}.hsk-cb-field[data-ph-lines=\\\"2\\\"]{min-block-size:48px}.hsk-animated-placeholder__char{display:inline-block;font-size:var(--hsk-ph-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%))}to{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.45;width:fit-content;max-width:min(92%,520px);margin-inline:auto;margin:8px auto 0;text-align:center;text-wrap:balance;color:#ff6b6b;padding:3px 8px;border-radius:0;background:transparent;border:none;border-bottom:1px solid rgba(229,72,77,.35);cursor:pointer;animation:hsk-msg-in .2s ease-out both}.hsk-cb-voice-error span{text-align:center}.hsk-cb-voice-error-dismiss{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;border:none;background:#ffffff1f;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:#ffffff40;transform:scale(1.1)}.hsk-cb-img-strip{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:10px 18px 2px;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 #00000014,0 0 0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 12%,transparent);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 #0000001f,0 0 0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 20%,transparent)}.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:#141418bf;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:#fff;border:1px solid rgba(255,255,255,.25);box-shadow:0 2px 6px #00000040;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:#ef4444eb;border-color:#fff6;transform:scale(1.15)}.hsk-cb-attach-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-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-voice-mode-btn:active:not(:disabled){transform:translateY(0) scale(.94);transition-duration:.1s}.hsk-cb-attach-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-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))}to{transform:scaleY(1)}}@keyframes hsk-wave-live{0%,to{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}to{transform:scaleX(1);opacity:.8}}@keyframes hsk-wave-live-tip{0%,to{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,.hsk-cb-toolsheet-pub:is(:hover,:active) .hsk-copy-sheet,.hsk-cb-secret-key:is(:hover,:active) .hsk-copy-sheet{transform:translate(.9px,.9px)}.hsk-cb-kiku-id-pill:hover .hsk-copy-back,.hsk-cb-toolsheet-pub:is(:hover,:active) .hsk-copy-back,.hsk-cb-secret-key:is(:hover,:active) .hsk-copy-back{transform:translate(-.9px,-.9px)}@media(prefers-reduced-motion:reduce){.hsk-cb-attach-btn:hover:not(:disabled) svg,.hsk-cb-kiku-id-pill:hover .hsk-copy-sheet,.hsk-cb-kiku-id-pill:hover .hsk-copy-back,.hsk-cb-toolsheet-pub:is(:hover,:active) :is(.hsk-copy-sheet,.hsk-copy-back),.hsk-cb-secret-key:is(:hover,:active) :is(.hsk-copy-sheet,.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-voice-mode-btn:disabled{opacity:.3;cursor:not-allowed;transform:none}.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;overflow:hidden;box-shadow:0 4px 16px #00000029}.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:#00000073;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-leave{position:relative;z-index:96;display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;width:fit-content;max-width:calc(100% - 24px);margin:0 12px -12px;padding:6px 6px 6px 14px;border-radius:18px;background:var(--hsk-chat-ai-bg, #eeeef0);color:var(--hsk-chat-text, #111827);box-shadow:0 0 0 3px var(--hsk-chat-bg, #fff),0 6px 20px #0000001f;font:500 13px/1.4 var(--hsk-font);animation:hsk-leave-in .18s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-leave-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}.hsk-cb-leave+.hsk-cb-input-card>*{opacity:.45;transition:opacity .15s}.hsk-cb-leave-btn{height:28px;padding:0 13px;border:none;border-radius:999px;background:#80808029;color:inherit;font:600 12.5px var(--hsk-font);cursor:pointer}.hsk-cb-leave-btn--end{background:var(--hsk-chat-text, #111827);color:var(--hsk-chat-bg, #fff)}.hsk-cb-error{display:block;width:fit-content;max-width:min(560px,100%);margin:10px auto 8px;padding:10px 14px;border-radius:10px;background:#ef444414;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:#ffffff38;border:1px solid rgba(255,255,255,.35);color:#fff;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;padding:12px 22px;font-size:15px;font-weight:600;text-decoration:none;color:#fff;background:linear-gradient(135deg,#007aff,#0056b3);border:none;border-radius:18px 18px 18px 4px!important;box-shadow:0 4px 16px -2px #007aff61,inset 0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 28%,transparent);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 #007aff7a}.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--note{margin-bottom:0}.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 #00000021;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-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:color-mix(in srgb,var(--hsk-chat-text, #111) 7%,transparent);border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 12%,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)}.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, 0px);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 #ff6a331f}.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, 0px);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-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, 0px);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}to{background-position:-200% 0}}.hsk-sb-fade{animation:hsk-fin .1s ease-out both}@keyframes hsk-fin{0%{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, 0px);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%,to{opacity:.6}50%{opacity:1}}@media(pointer:coarse){.hsk-cb-user-bubble,.hsk-cb-ai-body{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}}.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-closing{animation:hsk-tapback-flow-down .19s cubic-bezier(.55,0,.85,.35) forwards}.hsk-tapback-group.is-above{transform-origin:var(--tail-x, 80%) calc(100% + 16px)}.hsk-tapback-group.is-below{transform-origin:var(--tail-x, 80%) -16px}.hsk-tapback-capsule{display:inline-flex;align-items:center;gap:1px;padding:3px 5px;height:36px;min-height:36px;border-radius:999px;border:none;background:var(--hsk-skin, var(--hsk-bubble-bg, #eeeef0));box-shadow:0 0 0 3px var(--hsk-chat-bg, #ffffff),0 6px 18px #00000029;max-width:calc(100vw - 20px);position:relative;z-index:2;box-sizing:border-box}.hsk-tapback-tail{position:absolute;top:calc(100% - 2px);transform:translate(-50%);display:flex;flex-direction:column;align-items:center;gap:3px;pointer-events:none;z-index:1}.hsk-tapback-tail.is-below{top:auto;bottom:calc(100% - 2px);flex-direction:column-reverse}.hsk-tapback-dot--mid{margin-left:calc(var(--tail-dir, 0) * var(--tail-step, 5px))}.hsk-tapback-dot--anchor{margin-left:calc(var(--tail-dir, 0) * var(--tail-step, 5px) * 2.2)}.hsk-tapback-dot{display:block;border-radius:50%;flex-shrink:0;border:none}.hsk-tapback-dot--mid{width:12px;height:12px;background:var(--hsk-skin, var(--hsk-bubble-bg, #eeeef0));box-shadow:0 0 0 3px var(--hsk-chat-bg, #ffffff),0 2px 5px #0000001f;animation:hsk-tapback-bead .2s cubic-bezier(.16,1,.3,1) .06s backwards}.hsk-tapback-dot--anchor{width:9px;height:9px;background:var(--hsk-anchor-color, var(--hsk-primary, #007aff));animation:hsk-tapback-bead .2s cubic-bezier(.16,1,.3,1) .02s backwards}.hsk-tapback-tool-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;height:30px;border-radius:999px;font-size:12px;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(.12,.04)}18%{opacity:1}46%{transform:scale(1.06,1.13)}74%{transform:scale(.985,.95)}to{opacity:1;transform:scale(1)}}@keyframes hsk-tapback-flow-down{0%{opacity:1;transform:scale(1)}65%{opacity:1;transform:scale(.5,.34)}to{opacity:0;transform:scale(.12,.04)}}@keyframes hsk-tapback-bead{0%{opacity:0;transform:scale(.2)}to{opacity:1;transform:scale(1)}}@keyframes hsk-tapback-tool-pop{0%{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}.hsk-cb-topbar-logo{display:block;max-height:18px;max-width:104px;object-fit:contain}.hsk-cb-sound-pill{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 12px;border-radius:16px;font-family:var(--hsk-font);font-size:11px;font-weight:550;color:var(--hsk-chat-muted, #71717a);background:color-mix(in srgb,var(--hsk-chat-bg, #ffffff) 65%,transparent);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);cursor:pointer;transition:color .2s ease,border-color .2s ease,transform .2s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-sound-pill.is-on{color:var(--hsk-chat-text, #111)}.hsk-cb-req{position:relative;width:100%}.hsk-cb-req-dot{width:7px;height:7px;border-radius:50%;background:var(--hsk-primary, #ff6a33)}.hsk-cb-req-list{position:absolute;bottom:calc(100% + 10px);inset-inline-start:0;z-index:60;display:flex;flex-direction:column;width:100%;max-height:300px;overflow-y:auto;scrollbar-width:none;font-family:var(--hsk-font);animation:hsk-leave-in .18s cubic-bezier(.16,1,.3,1) both}.hsk-cb-req-open{display:flex;align-items:flex-start;gap:9px;width:100%;padding:6px 0 6px 12px;padding-inline:12px 0;border:none;background:none;color:var(--hsk-chat-muted, #8a8f98);font:inherit;text-align:start;cursor:pointer;opacity:.6;transition:opacity .2s ease,color .2s ease}.hsk-cb-req-open:hover,.hsk-cb-req-card.is-open .hsk-cb-req-open,.hsk-cb-req-card.is-active .hsk-cb-req-open{opacity:1}.hsk-cb-req-card.is-active .hsk-cb-req-summary{color:var(--hsk-chat-text, #1f1f1f);font-weight:500}.hsk-cb-req-mark{flex:none;width:6px;height:6px;margin-top:5px;border-radius:50%;background:currentColor;opacity:.45}.hsk-cb-req-card.is-open .hsk-cb-req-mark{background:var(--hsk-primary, #ff6a33);box-shadow:0 0 0 4px color-mix(in srgb,var(--hsk-primary, #ff6a33) 14%,transparent);opacity:1}.hsk-cb-req-text{display:flex;flex-direction:column;gap:1px;min-width:0}.hsk-cb-req-summary,.hsk-cb-req-status{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.hsk-cb-req-summary{font-size:12px;line-height:1.4}.hsk-cb-req-status{font-size:10.5px;opacity:.75}.hsk-cb-tray-below{position:absolute;top:calc(var(--hsk-tray-top, 100%) + var(--hsk-tray-h, 0px) + 14px);left:50%;transform:translate(-50%);width:min(300px,calc(100vw - 28px));z-index:1000;animation:hsk-scrim-in .25s cubic-bezier(.16,1,.3,1) .08s both}.hsk-cb-tray-below.is-closing{animation:hsk-scrim-out .18s cubic-bezier(.4,0,1,1) both;pointer-events:none}.hsk-cb-tray-below .hsk-cb-req-list{position:static;max-height:32vh;animation:none}.hsk-cb-tray-below-title{display:block;padding:0 12px 4px;font:600 10.5px var(--hsk-font);letter-spacing:.04em;text-transform:uppercase;color:var(--hsk-chat-muted, #8a8f98);opacity:.7}.hsk-cb-btn-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:#ef4444;color:#fff;font-size:11px;font-weight:700;line-height:1}.hsk-cb-sound-pill:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--hsk-primary, #ff6a33) 25%,transparent);color:var(--hsk-primary, #ff6a33)}.hsk-cb-topbar-ooze-menu .hsk-cb-tray-aside{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px}.hsk-cb-topbar-ooze-menu .hsk-cb-tray-rule{width:13px;height:1px;background:var(--hsk-chat-muted, #71717a);opacity:.25}.hsk-cb-sound-pill.is-compact{width:26px;height:26px;padding:0;gap:0;justify-content:center;border-radius:9px}.hsk-cb-topbar-ooze-menu .hsk-cb-tray-aside{width:14px;flex:0 0 14px}.hsk-cb-topbar-ooze-menu .hsk-cb-tray-aside .hsk-cb-sound-pill{width:14px;height:14px;border:none;background:none;backdrop-filter:none;-webkit-backdrop-filter:none;border-radius:0;opacity:.45}.hsk-cb-topbar-ooze-menu .hsk-cb-tray-aside .hsk-cb-sound-pill.is-on{opacity:.75}.hsk-cb-topbar-ooze-menu .hsk-cb-tray-aside .hsk-cb-sound-pill:hover{transform:none}.hsk-cb-topbar-ooze-menu .hsk-cb-tray-aside .hsk-cb-sound-pill svg{width:12px;height:12px}.hsk-cb-topbar-ooze-menu .hsk-cb-theme-2x2-grid{flex:1 1 auto!important}.hsk-cb-sound-pill.is-blocked{color:#ef4444!important;opacity:1!important}.hsk-cb-panel[dir=rtl] .hsk-cb-topbar-ooze-menu .hsk-cb-theme-vlabel{transform:none}.hsk-markdown-table td.hsk-md-ok,[data-hsk-theme] .hsk-markdown-table td.hsk-md-ok{color:color-mix(in srgb,#10b981 72%,var(--hsk-chat-text, #111))!important;font-weight:600}.hsk-markdown-table td.hsk-md-bad,[data-hsk-theme] .hsk-markdown-table td.hsk-md-bad{color:color-mix(in srgb,#ef4444 72%,var(--hsk-chat-text, #111))!important;font-weight:600}@media(max-width:1199px){.hsk-cb-topbar-ooze-menu.is-island,.hsk-cb-topbar-ooze-menu.is-island.is-closing{animation:none;will-change:clip-path}.hsk-cb-topbar-ooze-menu.is-island>*{opacity:var(--hsk-island-content, 1)}}.hsk-cb-topbar-ooze-menu.is-parked,.hsk-cb-tray-shadow.is-parked{visibility:hidden;pointer-events:none;opacity:0!important}[data-hsk-theme] .hsk-cb-topbar-ooze-menu.is-parked,.hsk-cb-topbar-ooze-menu.is-parked{backdrop-filter:none!important;-webkit-backdrop-filter:none!important;box-shadow:none!important}.hsk-cb-tray-shadow.is-parked>div{box-shadow:none!important}.hsk-cb-tray-shadow{position:absolute;top:var(--hsk-tray-top, 0px);left:50%;transform:translate(-50%);width:var(--hsk-tray-w, 0px);height:var(--hsk-tray-h, 0px);z-index:1000;pointer-events:none}.hsk-cb-tray-shadow>div{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:18px;box-shadow:0 16px 38px -6px color-mix(in srgb,#000 16%,transparent)}.hsk-cb-allowance{display:flex;flex-wrap:wrap;gap:6px;margin-block-start:8px;pointer-events:none}@media(min-width:1200px){.hsk-cb-allowance{flex-direction:column;flex-wrap:nowrap;align-items:flex-start;gap:12px;position:absolute;bottom:48px;width:auto;max-width:200px;margin-block-start:0;z-index:10;direction:ltr}.hsk-cb-allowance--right{left:100%!important;right:auto!important;margin-left:28px!important;margin-right:0!important;align-items:flex-start}.hsk-cb-allowance--left{left:auto!important;right:100%!important;margin-right:28px!important;margin-left:0!important;align-items:flex-end}}.hsk-cb-allowance-pill{display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 13px;border-radius:999px;font-family:inherit;font-size:11.5px;font-weight:550;letter-spacing:-.01em;line-height:1;white-space:nowrap;color:var(--hsk-chat-text)!important;background:color-mix(in srgb,var(--hsk-chat-bg, #ffffff) 68%,transparent)!important;backdrop-filter:blur(28px) saturate(var(--hsk-glass-saturate, 180%));-webkit-backdrop-filter:blur(28px) saturate(var(--hsk-glass-saturate, 180%));border:1px solid color-mix(in srgb,var(--hsk-chat-border, rgba(255, 255, 255, .35)) 35%,transparent)!important;border-top:1px solid color-mix(in srgb,var(--hsk-chat-bg, #fff) 70%,transparent)!important;border-bottom:1px solid color-mix(in srgb,#000 8%,transparent)!important;box-shadow:0 4px 18px -2px color-mix(in srgb,#000 14%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 45%,transparent) inset!important;animation:hsk-allowance-in .34s cubic-bezier(.22,1,.36,1) both;transition:all .2s cubic-bezier(.16,1,.3,1);cursor:default}.hsk-cb-allowance-pill:hover{background:color-mix(in srgb,var(--hsk-chat-bg, #ffffff) 82%,transparent)!important;border-top-color:color-mix(in srgb,var(--hsk-chat-bg, #fff) 85%,transparent)!important;transform:translateY(-1px);box-shadow:0 6px 20px -2px color-mix(in srgb,#000 18%,transparent),0 1px color-mix(in srgb,var(--hsk-chat-bg, #fff) 60%,transparent) inset!important}.hsk-cb-allowance-pill-icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--hsk-primary, #6366f1);opacity:.95}.hsk-cb-allowance-pill-icon svg{width:12.5px;height:12.5px}.hsk-cb-allowance-pill-label{font-family:inherit;letter-spacing:-.01em}.hsk-cb-allowance-pill.is-spent{opacity:.5;filter:grayscale(.6)}@keyframes hsk-allowance-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@media(prefers-reduced-motion:reduce){.hsk-cb-allowance-pill{animation:none}}.hsk-cb-onboarding-card .hsk-cb-entlang-opt{padding-inline:2px 0}.hsk-cb-secret-card{display:flex;flex-direction:column;gap:8px;max-width:340px}.hsk-cb-secret-head{display:flex;align-items:center;gap:8px}.hsk-cb-secret-title{flex:1;font-size:13px;font-weight:600;color:var(--hsk-chat-text, #111)}.hsk-cb-secret-timer{font-size:11px;font-variant-numeric:tabular-nums;color:var(--hsk-chat-muted, #6b7280)}.hsk-cb-secret-dismiss{display:grid;place-items:center;width:24px;height:24px;padding:0;font-size:15px;line-height:1;color:var(--hsk-chat-text, #111);background:color-mix(in srgb,var(--hsk-chat-text, #111) 8%,transparent);border:0;border-radius:50%;cursor:pointer}.hsk-cb-secret-key{display:flex;align-items:center;gap:10px;width:100%;padding:8px 8px 8px 14px;border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 10%,transparent);border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 70%,transparent);cursor:pointer}.hsk-cb-secret-key code{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;text-align:start;color:var(--hsk-chat-text, #111)}.hsk-cb-secret-copy{display:inline-flex;align-items:center;gap:5px;flex-shrink:0;padding:5px 12px;font-size:12px;font-weight:600;color:#fff;background:var(--hsk-primary, #ff6a33);border-radius:999px}.hsk-cb-secret-hint{font-size:11px;color:var(--hsk-chat-muted, #6b7280)}.hsk-cb-swatch-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));gap:10px;max-width:460px;margin-top:10px}.hsk-cb-swatch{display:flex;flex-direction:column;gap:2px;padding:0 0 8px;text-align:start;background:var(--hsk-chat-source-bg, rgba(0, 0, 0, .03));border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 8%,transparent);border-radius:14px;overflow:hidden;cursor:pointer;animation:hsk-msg-in .25s ease-out both;transition:transform .2s cubic-bezier(.34,1.56,.64,1),box-shadow .2s ease}.hsk-cb-swatch--target{cursor:default;background:transparent;border-style:dashed;border-color:color-mix(in srgb,var(--hsk-chat-text, #111) 28%,transparent)}.hsk-cb-swatch--target .hsk-cb-swatch-name{color:var(--hsk-chat-muted, #6b7280)}.hsk-cb-swatch:not(.hsk-cb-swatch--target):hover{transform:translateY(-2px);box-shadow:0 10px 24px -12px color-mix(in srgb,#000 35%,transparent)}.hsk-cb-swatch-chip{display:block;aspect-ratio:1 / .8;margin-bottom:6px;box-shadow:inset 0 -1px color-mix(in srgb,#000 8%,transparent)}.hsk-cb-swatch-name{padding:0 10px;font-size:12px;font-weight:600;line-height:1.3;color:var(--hsk-chat-text, #111);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hsk-cb-swatch-code{padding:0 10px;font-size:11px;font-variant-numeric:tabular-nums;letter-spacing:.02em;color:var(--hsk-chat-muted, #6b7280)}@media(prefers-reduced-motion:reduce){.hsk-cb-swatch,.hsk-cb-swatch:hover{animation:none;transform:none}}@keyframes hsk-card-in{0%{opacity:0;transform:scale(.96) translateY(-12px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes hsk-bar{0%{background-position:200% 0}to{background-position:-200% 0}}@media(max-width:768px){.hsk-cb-overlay{--hsk-font-size: var(--hsk-mobile-font-size, 14px) !important;position:fixed!important;inset: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 0 auto!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{display:none}.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-voice-mode-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-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:-.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-start!important;margin-bottom:12px!important}.hsk-cb-onboarding-card .hsk-cb-hello-wrap{align-items:flex-start!important;text-align:start!important}.hsk-cb-onboarding-card .hsk-cb-hello,.hsk-cb-onboarding-card .hsk-cb-hello-lead,.hsk-cb-onboarding-card .hsk-cb-hello-ask,.hsk-cb-onboarding-card .hsk-cb-hello-hint{text-align:start!important}.hsk-cb-onboarding-card .hsk-cb-lang-chips,.hsk-cb-onboarding-card .hsk-cb-lang-chips-hint{justify-content:flex-start!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-send,.hsk-chat-send{width:32px!important;height:32px!important;border-radius:8px!important}.hsk-cb-attach-btn svg,.hsk-cb-send svg,.hsk-chat-send svg{width:15px!important;height:15px!important}.hsk-cb-input-box{padding:10px 10px 10px 14px}.hsk-cb-user-bubble{max-width:85%}}.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:-.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;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;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:#80808026;padding:.2em .4em;border-radius:var(--hsk-border-radius, 0px);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 #0000002e;object-fit:cover;background:#80808014}.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:#0000000f;border-radius:99px;transition:background .2s ease}.hsk-chat-widget ::-webkit-scrollbar-thumb:hover,.hsk-cb-msgs ::-webkit-scrollbar-thumb:hover{background:#00000026}@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:#ffffff14}.hsk-chat-widget ::-webkit-scrollbar-thumb:hover,.hsk-cb-msgs ::-webkit-scrollbar-thumb:hover{background:#fff3}}.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, 0px);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, 0px);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{0%{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 #00000014}.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:#ffffff1a;color:var(--hsk-chat-text, #e8eaed)}}[data-hsk-theme=dark] .hsk-action-pill{--hsk-pill-bg: rgba(40,40,42,.85);border-color:#ffffff1a;color:var(--hsk-chat-text, #e8eaed)}.kiku-voice-btn:hover{background:var(--hsk-hover-bg, rgba(0,0,0,.06));color:var(--hsk-primary, #6c47ff)}@keyframes kiku-voice-pulse{0%{transform:scale(1);opacity:1}to{transform:scale(1.6);opacity:0}}.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-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:#ef44441a}.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}to{transform:scale(1.7);opacity:0}}.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:#ff6a331a;color:var(--hsk-primary, #ff6a33);font-size:11px;font-weight:500;white-space:nowrap}.hsk-kiku-badge{display:inline-flex;align-items:center;gap:3px;font-size:13px;font-weight:700;letter-spacing:-.01em;color:#fff;background:#ffffff47;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 #0000001f}.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:color-mix(in srgb,var(--hsk-chat-bg, #fff) 84%,transparent);backdrop-filter:blur(28px) saturate(180%);-webkit-backdrop-filter:blur(28px) saturate(180%);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{0%{opacity:0}to{opacity:1}}.hsk-lightbox-img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;border-radius:4px;box-shadow:0 18px 50px -12px color-mix(in srgb,#000 30%,transparent);cursor:default}.hsk-lightbox-close{position:absolute;top:16px;right:16px;width:36px;height:36px;border-radius:50%;border:none;background:color-mix(in srgb,var(--hsk-chat-text, #111) 8%,transparent);color:var(--hsk-chat-text, #111);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s}.hsk-lightbox-close:hover{background:color-mix(in srgb,var(--hsk-chat-text, #111) 16%,transparent)}.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:#0009;background:#00000008;border-color:#00000014}.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:#dc26260f}.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:#0000009e;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:color-mix(in srgb,var(--hsk-chat-bg, #fff) 84%,transparent);backdrop-filter:blur(28px) saturate(180%);-webkit-backdrop-filter:blur(28px) saturate(180%);display:flex;align-items:center;justify-content:center;padding:12px;animation:hsk-lightbox-in .15s ease-out both}.hsk-markup{height:100%;box-sizing:border-box;padding-top:max(32px,env(safe-area-inset-top));padding-bottom:max(24px,env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:12px;width:100%;max-height:100%;overflow-y:auto}.hsk-markup-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.hsk-markup-title{font-size:12px;font-weight:500;line-height:1.4;color:color-mix(in srgb,var(--hsk-chat-text, #111) 55%,transparent)}.hsk-markup-cancel{flex-shrink:0;padding:6px 12px;font-size:12px;font-weight:600;color:var(--hsk-chat-text, #111);border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 70%,transparent);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 10%,transparent);box-shadow:0 6px 18px -8px color-mix(in srgb,#000 22%,transparent);cursor:pointer}.hsk-markup-cancel:hover{background:color-mix(in srgb,var(--hsk-chat-text, #111) 16%,transparent)}.hsk-markup-stage{display:flex;flex:1;min-height:0;align-items:center;justify-content:center}.hsk-markup-canvas-wrap{position:relative;max-width:100%}.hsk-markup-canvas{display:block;max-width:100%;max-height:calc(100vh - 130px);box-shadow:0 18px 50px -12px color-mix(in srgb,#000 30%,transparent);border-radius:var(--hsk-border-radius, 0px);touch-action:none}.hsk-markup-canvas--pen,.hsk-markup-canvas--eraser{cursor:crosshair}.hsk-markup-pinlabel{position:absolute;display:flex;align-items:center;gap:4px;max-width:calc(100% - 16px);padding:4px 4px 4px 12px;border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 78%,transparent);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 10%,transparent);box-shadow:0 10px 28px -10px color-mix(in srgb,#000 40%,transparent)}.hsk-markup-pinlabel input{min-width:0;max-width:100%;padding:6px 0;font-size:13px;color:var(--hsk-chat-text, #111);background:transparent;border:0;outline:none}.hsk-markup-pinlabel input::placeholder{color:color-mix(in srgb,var(--hsk-chat-text, #111) 45%,transparent)}.hsk-markup-pinlabel button{flex-shrink:0;display:grid;place-items:center;width:26px;height:26px;padding:0;font-size:15px;line-height:1;color:var(--hsk-chat-text, #111);background:color-mix(in srgb,var(--hsk-chat-text, #111) 8%,transparent);border:0;border-radius:50%;cursor:pointer}.hsk-markup-loading,.hsk-markup-error{padding:40px 16px;font-size:13px;color:color-mix(in srgb,var(--hsk-chat-text, #111) 70%,transparent);text-align:center}.hsk-markup-tools{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;margin-top:auto}.hsk-markup-tool{flex-shrink:0;white-space:nowrap;padding:8px 14px;font-size:12px;font-weight:600;color:var(--hsk-chat-text, #111);border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 70%,transparent);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 10%,transparent);box-shadow:0 6px 18px -8px color-mix(in srgb,#000 22%,transparent);cursor:pointer}.hsk-markup-tool:hover:not(:disabled){background:color-mix(in srgb,var(--hsk-chat-text, #111) 16%,transparent)}.hsk-markup-tool--on{color:#fff;background:var(--hsk-primary, #ff6a33);border-color:transparent}.hsk-markup-tool--on:hover:not(:disabled){background:var(--hsk-primary, #ff6a33)}.hsk-markup-tool:disabled{opacity:.4;cursor:default}.hsk-markup-go{flex-shrink:0;padding:8px 22px;font-size:13px;font-weight:600;color:#fff;background:var(--hsk-primary, #ff6a33);border:none;border-radius:999px;box-shadow:0 6px 18px -8px color-mix(in srgb,var(--hsk-primary, #ff6a33) 60%,transparent);cursor:pointer}.hsk-markup-go:hover:not(:disabled){opacity:.9}.hsk-markup-go:disabled{opacity:.45;cursor:default}@media(max-width:640px){.hsk-markup-head{flex-direction:column-reverse;align-items:flex-start}.hsk-markup-cancel{align-self:flex-end}}.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-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-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-voice-error{font-size:12px;line-height:1.7;max-width:min(92%,520px);margin-left:auto;margin-right:auto}.hsk-cb-panel[data-script=nonlatin] .hsk-cb-msg-action{height:16px;padding:1px 6.5px;font-size:9.5px;line-height:1}.hsk-cb-panel[data-script=nonlatin] .hsk-cb-msg-action .hsk-cb-msg-action-label{font-size:9.5px;line-height:1}.hsk-cb-panel[data-script=nonlatin] .hsk-cb-user-footer,.hsk-cb-panel[data-script=nonlatin] .hsk-cb-ai-footer{min-height:16px}.hsk-cb-panel[data-script=nonlatin] .hsk-cb-sent-status,.hsk-cb-panel[data-script=nonlatin] .hsk-cb-failed-notice{font-size:10px;line-height:1}.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-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-nastaliq=true] .hsk-cb-voice-error{font-size:13px;line-height:2;max-width:min(92%,540px);margin-left:auto;margin-right:auto}.hsk-cb-panel[data-nastaliq=true] .hsk-cb-msg-action{height:16px;padding:1px 6.5px;font-size:9px;line-height:1}.hsk-cb-panel[data-nastaliq=true] .hsk-cb-msg-action .hsk-cb-msg-action-label{font-size:9px;line-height:1}.hsk-cb-panel[data-nastaliq=true] .hsk-cb-user-footer,.hsk-cb-panel[data-nastaliq=true] .hsk-cb-ai-footer{min-height:16px}.hsk-cb-panel[data-nastaliq=true] .hsk-cb-sent-status,.hsk-cb-panel[data-nastaliq=true] .hsk-cb-failed-notice{font-size:9.5px;line-height:1}.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-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){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-panel[data-script=nonlatin] .hsk-animated-placeholder[data-fit=\\\"2\\\"]{--hsk-ph-font-size: 13.5px}.hsk-cb-panel[data-script=nonlatin] .hsk-animated-placeholder[data-fit=\\\"3\\\"]{--hsk-ph-font-size: 12px}.hsk-cb-panel[data-nastaliq=true] .hsk-animated-placeholder[data-fit=\\\"1\\\"]{--hsk-ph-font-size: 15px}.hsk-cb-panel[data-nastaliq=true] .hsk-animated-placeholder[data-fit=\\\"2\\\"]{--hsk-ph-font-size: 13px}.hsk-cb-panel[data-nastaliq=true] .hsk-animated-placeholder[data-fit=\\\"3\\\"]{--hsk-ph-font-size: 11.5px}.hsk-cb-panel[data-script=nonlatin] .hsk-animated-placeholder__char{line-height:1.35}.hsk-cb-panel[data-script] .hsk-cb-chrome-loading,.hsk-cb-panel[data-script] .hsk-cb-chrome-loading *{font-family:system-ui,-apple-system,Segoe UI,Roboto,Noto Sans,sans-serif}.hsk-voice-overlay{position:absolute;inset:0;z-index:30;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:clamp(8px,1.4vh,16px);padding:clamp(14px,2.5vh,24px);overflow:hidden;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(46% 20% at 50% 92%,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{0%{opacity:0}to{opacity:1}}.hsk-voice-exit{position:absolute;z-index:2;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-new{position:absolute;z-index:2;top:14px;right:58px;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,transform .12s ease}.hsk-voice-new:hover:not(:disabled){color:var(--hsk-chat-text, #1f1f1f);border-color:color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 32%,transparent)}.hsk-voice-new:active:not(:disabled){transform:scale(.92)}.hsk-voice-new:disabled{opacity:.4;cursor:default}.hsk-voice-stage{grid-column:2;width:100%;height:clamp(64px,13vh,140px);min-width:0;animation:hsk-composer-to-wave .42s cubic-bezier(.2,.8,.2,1) both}@keyframes hsk-composer-to-wave{0%{opacity:0;translate:0 18px}to{opacity:1;translate:0 0}}@media(prefers-reduced-motion:reduce){.hsk-voice-stage{animation:none}}.hsk-voice-thread{position:relative;z-index:1;flex:1 1 auto;width:min(720px,100%);min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;scrollbar-width:none;-ms-overflow-style:none;display:flex;flex-direction:column;gap:12px;padding:clamp(46px,8vh,72px) 4px 6px;-webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 34px,#000 calc(100% - 30px),transparent 100%);mask-image:linear-gradient(to bottom,transparent 0,#000 34px,#000 calc(100% - 30px),transparent 100%)}.hsk-voice-turn--live{opacity:.72}.hsk-voice-canvas{display:block;width:100%;height:100%}.hsk-voice-controls{display:grid;grid-template-columns:52px minmax(0,1fr) 52px;align-items:center;gap:12px;flex:none;width:min(640px,100%)}.hsk-voice-controls [data-control=attach]{grid-column:1}.hsk-voice-controls [data-control=mic]{grid-column:3}.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 #00000014,0 1px 3px #0000000a;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 #0000001f}.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 #0000000a}.hsk-voice-control-icon{display:inline-flex;align-items:center;justify-content:center;z-index:2;transition:transform .2s ease}@media(prefers-reduced-motion:reduce){.hsk-voice-control-icon,.hsk-voice-control--muted{animation:none}}.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-error{font-family:var(--hsk-font);font-size:.85rem;color:#e5484d;text-align:center}@media(prefers-reduced-motion:reduce){.hsk-voice-overlay{animation:none}}.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;z-index:3;top:14px;left:14px;display:flex;flex-direction:column;width:auto;height:36px;overflow:hidden;border-radius:18px;border:1px solid color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 10%,transparent);background:linear-gradient(180deg,#ffffff1f,#fff0 60%),color-mix(in srgb,var(--hsk-chat-bg, #ffffff) 58%,transparent);backdrop-filter:blur(20px) saturate(160%);-webkit-backdrop-filter:blur(20px) saturate(160%);box-shadow:inset 0 1px #ffffff40,0 1px 2px #0000000d;interpolate-size:allow-keywords;transition:width .42s cubic-bezier(.16,1,.3,1),height .42s cubic-bezier(.16,1,.3,1),border-radius .42s cubic-bezier(.16,1,.3,1),box-shadow .3s ease;animation:hsk-voice-pill-in .42s cubic-bezier(.16,1,.3,1) both}.hsk-voice-picker[data-open]{width:224px;height:auto;border-radius:20px;background:linear-gradient(180deg,#ffffff1a,#fff0 50%),color-mix(in srgb,var(--hsk-chat-bg, #ffffff) 78%,transparent);box-shadow:inset 0 1px #ffffff40,0 8px 22px -8px #0003,0 1px 2px #0000000d}@keyframes hsk-voice-pill-in{0%{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}.hsk-voice-pill{display:flex;align-items:center;justify-content:space-between;gap:6px;flex:none;height:34px;padding:0 10px 0 14px;border:0;background:transparent;font:inherit;font-size:12px;font-weight:600;white-space:nowrap;color:var(--hsk-chat-text, #1f1f1f);cursor:pointer}.hsk-voice-pill-caret{display:inline-flex;color:var(--hsk-chat-muted, #71717a);transform:rotate(90deg) scale(.8);transition:transform .32s cubic-bezier(.16,1,.3,1)}.hsk-voice-picker[data-open] .hsk-voice-pill-caret{transform:rotate(-90deg) scale(.8)}.hsk-voice-menu-list{position:relative;contain:inline-size;display:flex;flex-direction:column;gap:1px;max-height:min(320px,50vh);padding:4px 5px 6px;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none;opacity:0;transition:opacity .18s ease;-webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 10px,#000 calc(100% - 16px),transparent 100%);mask-image:linear-gradient(to bottom,transparent 0,#000 10px,#000 calc(100% - 16px),transparent 100%)}.hsk-voice-menu-list::-webkit-scrollbar{display:none}.hsk-voice-picker[data-open] .hsk-voice-menu-list{opacity:1;transition:opacity .26s ease .12s}.hsk-voice-group{display:flex;align-items:center;gap:8px;flex:none;padding:10px 9px 4px;font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--hsk-chat-muted, #71717a)}.hsk-voice-group:after{content:\\\"\\\";flex:1;height:1px;background:color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 12%,transparent)}.hsk-voice-group:first-child{padding-top:4px}.hsk-voice-option{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex:none;padding:7px 9px;border:0;border-radius:13px;background:transparent;font:inherit;text-align:start;color:var(--hsk-chat-text, #1f1f1f);cursor:pointer;transition:background .14s ease}.hsk-voice-option:hover{background:color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 6%,transparent)}.hsk-voice-option-name{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600}.hsk-voice-option-trait{font-size:11px;color:var(--hsk-chat-muted, #71717a)}.hsk-voice-option--on,.hsk-voice-option--on:hover{background:color-mix(in srgb,var(--hsk-primary, #ff6a33) 12%,transparent)}.hsk-voice-option--on .hsk-voice-option-name{color:var(--hsk-primary, #ff6a33)}.hsk-voice-option--on .hsk-voice-option-name:before{content:\\\"\\\";width:5px;height:5px;border-radius:999px;background:currentColor}@media(prefers-reduced-motion:reduce){.hsk-voice-picker{animation:none;transition:none}}@media(max-width:520px){.hsk-cb-input-box{gap:6px;padding:10px 10px 10px 12px}.hsk-cb-attach-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}to{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-detail,.hsk-cb-entlang-price,.hsk-cb-src-detail,.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:-.01em}.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 #00000008}.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:#10b98140;border-color:#10b981}to{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-detail{font-size:11px;padding:1px 7px;margin-top:4px}}@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-card{flex:0 0 auto;width:fit-content;max-width:100%}}.hsk-voice-thread::-webkit-scrollbar{width:0;height:0}.hsk-voice-thread{font-family:var(--hsk-font);gap:0;padding-inline:20px}.hsk-voice-thread .hsk-cb-user-msg,.hsk-voice-thread .hsk-cb-ai-msg{align-self:stretch;max-width:100%;margin:0}.hsk-voice-thread .hsk-cb-user-bubble{max-width:100%;padding:0;background:none!important;border:none;border-radius:0;text-align:inherit;font-family:inherit;font-style:italic;font-size:16.5px;line-height:1.62;letter-spacing:.005em;color:color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 62%,transparent)}.hsk-voice-thread .hsk-cb-user-bubble:after{display:none!important}.hsk-voice-thread .hsk-cb-user-msg{align-items:flex-start}.hsk-voice-thread .hsk-cb-user-bubble{position:relative;text-align:start}.hsk-voice-thread .hsk-cb-user-bubble:before{content:\\\"\\\\201c\\\";display:block!important;position:absolute;inset-inline-start:-.62em;top:-.12em;width:auto;height:auto;background:none;font-size:1.55em;font-style:normal;line-height:1;color:color-mix(in srgb,var(--hsk-primary, #ff6a33) 72%,transparent);pointer-events:none}.hsk-voice-thread .hsk-cb-ai-msg{font-size:17px;line-height:1.68;color:var(--hsk-chat-text, #1f1f1f)}.hsk-voice-thread .hsk-cb-user-msg{margin-top:22px}.hsk-voice-thread>.hsk-cb-user-msg:first-child{margin-top:0}.hsk-voice-thread .hsk-cb-ai-msg{margin-top:6px}.hsk-voice-thread .hsk-cb-ai-body.hsk-voice-turn--live:after{content:\\\"\\\";display:inline-block;width:.36em;height:.36em;margin-inline-start:.34em;vertical-align:.08em;background:currentColor;border-radius:0 50% 50%;transform:rotate(45deg);animation:hsk-voice-nib 1.6s ease-in-out infinite}@keyframes hsk-voice-nib{0%,to{opacity:.25}50%{opacity:.85}}.hsk-voice-images{display:flex;gap:10px;flex:none;width:min(720px,100%);padding:4px 20px;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}.hsk-voice-images::-webkit-scrollbar{display:none}.hsk-voice-image{position:relative;flex:none;width:76px;height:76px;padding:0;border-radius:14px;overflow:hidden;border:1px solid color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 12%,transparent);background:color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 4%,transparent);cursor:zoom-in;animation:hsk-voice-image-in .45s cubic-bezier(.16,1,.3,1) both}@media(min-width:720px){.hsk-voice-image{width:92px;height:92px}}.hsk-voice-image img{display:block;width:100%;height:100%;object-fit:cover;animation:hsk-voice-develop 1.1s cubic-bezier(.16,1,.3,1) both}@keyframes hsk-voice-image-in{0%{opacity:0;transform:translate(10px) scale(.92)}to{opacity:1;transform:none}}@keyframes hsk-voice-develop{0%{opacity:0;filter:blur(8px) saturate(.2) brightness(1.2);transform:scale(1.06)}to{opacity:1;filter:none;transform:scale(1)}}.hsk-voice-image[data-pending]{cursor:progress;border-color:transparent;background:color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 5%,var(--hsk-chat-bg, #ffffff))}.hsk-doodle-shimmer{position:absolute;inset:0;width:100%;height:100%}.hsk-working-veil{--hsk-feather-12: linear-gradient(to right, transparent, #000 12px, #000 calc(100% - 12px) , transparent), linear-gradient(to bottom, transparent, #000 12px, #000 calc(100% - 12px) , transparent);--hsk-doodle-ink: 255, 122, 64;--hsk-doodle-tint: 255, 200, 165;position:absolute;inset:0;overflow:hidden;border-radius:inherit;pointer-events:none;background:radial-gradient(ellipse at center,transparent 45%,rgba(0,0,0,.22) 100%);-webkit-mask-image:var(--hsk-feather-12);-webkit-mask-composite:source-in;mask-image:var(--hsk-feather-12);mask-composite:intersect;animation:hsk-veil-in .3s cubic-bezier(.16,1,.3,1) both}.hsk-working-veil.is-leaving{animation:hsk-veil-out .3s ease-out both}.hsk-working-veil .hsk-doodle-shimmer{filter:drop-shadow(0 0 .6px rgba(0,0,0,.75));-webkit-mask-image:radial-gradient(ellipse at center,transparent 14%,rgba(0,0,0,.5) 36%,rgba(0,0,0,.9) 58%,#000 75%);mask-image:radial-gradient(ellipse at center,transparent 14%,rgba(0,0,0,.5) 36%,rgba(0,0,0,.9) 58%,#000 75%)}.hsk-working-veil:after{content:\\\"\\\";position:absolute;inset:0;box-shadow:inset 0 0 20px 8px color-mix(in srgb,var(--hsk-primary, #ff6a33) 90%,transparent),inset 0 0 48px 12px color-mix(in srgb,var(--hsk-primary, #ff6a33) 30%,transparent);animation:hsk-halo-breathe 2.4s ease-in-out infinite}.hsk-cb-user-img-cell:has(>.hsk-working-veil)>img,.hsk-cb-viz--working>img,.hsk-voice-image:has(>.hsk-working-veil)>img,.hsk-voice-image[data-pending],.hsk-cb-viz--working.is-blank{-webkit-mask-image:linear-gradient(to right,transparent,#000 26px,#000 calc(100% - 26px),transparent),linear-gradient(to bottom,transparent,#000 26px,#000 calc(100% - 26px),transparent);-webkit-mask-composite:source-in;mask-image:linear-gradient(to right,transparent,#000 26px,#000 calc(100% - 26px),transparent),linear-gradient(to bottom,transparent,#000 26px,#000 calc(100% - 26px),transparent);mask-composite:intersect}.hsk-voice-image:has(>.hsk-working-veil){border-color:transparent}@keyframes hsk-veil-in{0%{opacity:0}to{opacity:1}}@keyframes hsk-veil-out{0%{opacity:1}to{opacity:0}}@keyframes hsk-halo-breathe{0%,to{opacity:.7}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.hsk-working-veil:after{animation:none;opacity:.8}}.hsk-cb-viz--working{position:relative;display:inline-block;max-width:420px;border-radius:8px;overflow:hidden;line-height:0}.hsk-cb-viz--working.is-blank{display:block;width:min(100%,320px);aspect-ratio:1;background:color-mix(in srgb,var(--hsk-chat-text, #1f1f1f) 5%,var(--hsk-chat-bg, #ffffff))}.hsk-cb-viz--working.is-video{display:block;width:min(100%,420px);aspect-ratio:16 / 9}.hsk-cb-viz--working img{opacity:.85}.hsk-cb-viz--working.is-video img{width:100%;height:100%;object-fit:cover}.hsk-voice-control--attach{justify-self:center;width:44px;height:44px;color:var(--hsk-chat-muted, #888888);box-shadow:none}.hsk-voice-control--attach:hover:not(:disabled){transform:none;color:var(--hsk-chat-text, #1f1f1f);box-shadow:none}.hsk-voice-control--attach:active:not(:disabled){transform:scale(.9);transition-duration:.08s}@media(prefers-reduced-motion:reduce){.hsk-voice-thread .hsk-cb-ai-body.hsk-voice-turn--live:after,.hsk-voice-image,.hsk-voice-image img{animation:none}}.hsk-voice-shelf{display:flex;align-items:flex-start;gap:10px;flex:none;width:min(720px,100%);padding:0 20px;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}.hsk-voice-shelf::-webkit-scrollbar{display:none}.hsk-voice-shelf>.hsk-voice-images{width:auto;padding:4px 0;overflow:visible}.hsk-voice-shelf>.hsk-voice-sources{flex:0 1 auto;width:auto;min-width:0;padding:0}.hsk-voice-sources{flex:none;width:min(720px,100%);padding:0 20px;animation:hsk-voice-image-in .45s cubic-bezier(.16,1,.3,1) both}@media(prefers-reduced-motion:reduce){.hsk-voice-sources{animation:none}}.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-leave{background:var(--hsk-surface-2)!important;color: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-leave-btn{background:var(--hsk-surface-1)!important;color:var(--hsk-chat-text)!important}[data-hsk-theme] .hsk-cb-leave-btn--end{background:var(--hsk-primary)!important;color:var(--hsk-chat-bg)!important}[data-hsk-theme] .hsk-cb-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-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-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:hover{color:var(--hsk-primary)!important}[data-hsk-theme] .hsk-cb-theme-2x2-grid,[data-hsk-theme] .hsk-cb-topbar-ooze-menu{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-topbar-ooze-menu{border-top:var(--hsk-glass-border)!important;box-shadow:none!important}[data-hsk-theme] .hsk-cb-topbar-ooze-menu .hsk-cb-theme-2x2-grid{background:none!important;border:none!important;border-top:none!important;box-shadow:none!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}[data-hsk-theme] .hsk-cb-theme-squircle-trigger,[data-hsk-theme] .hsk-cb-theme-squircle-wrap,[data-hsk-theme] .hsk-cb-kiku-id-pill,[data-hsk-theme] .hsk-cb-kiku-id-rail .hsk-cb-sound-pill,[data-hsk-theme] .hsk-cb-squircle-btn{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-kiku-id-pill,[data-hsk-theme] .hsk-cb-squircle-btn{color:var(--hsk-chat-muted)!important}[data-hsk-theme] .hsk-cb-exit-btn:hover{background:radial-gradient(120% 90% at 30% 0%,rgba(255,255,255,.4),transparent 65%),var(--hsk-pill-bg)!important;color:#ef4444!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-detail{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-picker{background:var(--hsk-pill-bg)!important;border:var(--hsk-glass-border)!important;border-top:var(--hsk-glass-border-top)!important}[data-hsk-theme] .hsk-voice-picker[data-open]{background:linear-gradient(180deg,#ffffff1a,#fff0 50%),color-mix(in srgb,var(--hsk-chat-bg) 78%,transparent)!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-edge: rgba(0, 0, 0, .07) !important;--hsk-glass-edge-top: rgba(255, 255, 255, .9) !important;--hsk-glass-drop: rgba(0,0,0,.1) !important;--hsk-glass-sheen: rgba(255,255,255,.85) !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-edge: rgba(255, 255, 255, .1) !important;--hsk-glass-edge-top: rgba(255, 255, 255, .22) !important;--hsk-glass-drop: rgba(0,0,0,.45) !important;--hsk-glass-sheen: rgba(255,255,255,.1) !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-edge: rgba(217, 140, 85, .15) !important;--hsk-glass-edge-top: rgba(255, 200, 150, .25) !important;--hsk-glass-drop: rgba(0,0,0,.55) !important;--hsk-glass-sheen: rgba(255,200,150,.12) !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-edge: rgba(236, 72, 153, .1) !important;--hsk-glass-edge-top: rgba(255, 255, 255, .9) !important;--hsk-glass-drop: rgba(180, 30, 100, .08) !important;--hsk-glass-sheen: rgba(255,255,255,.85) !important;--hsk-glass-saturate: 185% !important;--hsk-pill-bg: rgba(255, 228, 236, .8) !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-edge: rgba(169, 113, 75, .12) !important;--hsk-glass-edge-top: rgba(255, 255, 255, .88) !important;--hsk-glass-drop: rgba(90, 55, 20, .1) !important;--hsk-glass-sheen: rgba(255,255,255,.8) !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-edge: rgba(99, 102, 241, .18) !important;--hsk-glass-edge-top: rgba(180, 185, 255, .25) !important;--hsk-glass-drop: rgba(0,0,0,.55) !important;--hsk-glass-sheen: rgba(180,190,255,.1) !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:translate(-2px)}.hsk-cb-panel[dir=rtl] .hsk-cb-back:hover:not(:disabled) .hsk-cb-back-icon{transform:scaleX(-1) translate(-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)}@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){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--waiting{opacity:.45;cursor:default}.hsk-voice-control--waiting:before,.hsk-voice-control--waiting .hsk-voice-control-icon{animation:none!important;background:none!important}.hsk-voice-control[data-control=mic]:not(.hsk-voice-control--muted):not(.hsk-voice-control--waiting):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[data-control=mic]:not(.hsk-voice-control--muted):not(.hsk-voice-control--waiting) .hsk-voice-control-icon{animation:hsk-apple-siri-mic-pulse 2.2s ease-in-out infinite}.hsk-img-sun,.hsk-img-ridge{transform-box:fill-box;transform-origin:center;transition:transform .34s cubic-bezier(.34,1.56,.64,1)}.hsk-voice-control--attach:is(:hover,:active) .hsk-img-sun{transform:translate(1px,-1.5px) scale(1.25)}.hsk-voice-control--attach:is(:hover,:active) .hsk-img-ridge{transform:translateY(-1px);transition-delay:40ms}.hsk-mic-slash{stroke-dasharray:29;animation:hsk-slash-draw .3s cubic-bezier(.65,0,.35,1) both}@keyframes hsk-slash-draw{0%{stroke-dashoffset:29}to{stroke-dashoffset:0}}.hsk-voice-control[data-control=mic].hsk-voice-control--muted .hsk-voice-control-icon{animation:hsk-icon-pop .38s cubic-bezier(.34,1.56,.64,1)}@keyframes hsk-icon-pop{0%{transform:scale(.82)}to{transform:scale(1)}}.hsk-voice-exit svg{transition:transform .32s cubic-bezier(.34,1.56,.64,1)}.hsk-voice-exit:hover svg{transform:rotate(90deg)}.hsk-snd-wave{transform-box:fill-box;transform-origin:left center}.hsk-cb-sound-pill:hover .hsk-snd-wave{animation:hsk-wave-ripple .9s ease-out infinite;animation-delay:calc(var(--hsk-wave, 0) * .14s)}.hsk-mimi-dot{transform-box:fill-box;transform-origin:center;opacity:.7}.hsk-cb-sound-pill:hover .hsk-mimi-dot,.hsk-cb-toolsheet-item:hover .hsk-mimi-dot{animation:hsk-mimi-typing .9s ease-in-out infinite;animation-delay:calc(var(--hsk-dot, 0) * .13s)}@keyframes hsk-mimi-typing{0%,60%,to{transform:translateY(0);opacity:.55}30%{transform:translateY(-1.8px);opacity:1}}@keyframes hsk-wave-ripple{0%{opacity:.25;transform:scale(.7)}45%{opacity:1;transform:scale(1.05)}to{opacity:.25;transform:scale(1)}}.hsk-snd-x{stroke-dasharray:8;animation:hsk-snd-x-draw .26s ease-out both}.hsk-snd-x+.hsk-snd-x{animation-delay:70ms}@keyframes hsk-snd-x-draw{0%{stroke-dashoffset:8}to{stroke-dashoffset:0}}@keyframes hsk-apple-siri-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes hsk-apple-siri-mic-pulse{0%,to{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-voice-control--attach:hover .hsk-img-sun,.hsk-voice-control--attach:hover .hsk-img-ridge,.hsk-voice-exit:hover svg{transform:none}.hsk-mic-slash,.hsk-snd-x,.hsk-cb-sound-pill:hover .hsk-snd-wave,.hsk-cb-sound-pill:hover .hsk-mimi-dot,.hsk-cb-toolsheet-item:hover .hsk-mimi-dot,.hsk-voice-controls .hsk-voice-control-icon{animation:none}}.hsk-cb-voice-error{animation:hsk-error-shake .26s cubic-bezier(.36,.07,.19,.97) both}@keyframes hsk-error-shake{0%,to{transform:translate(0)}22%{transform:translate(-3px)}55%{transform:translate(2px)}80%{transform:translate(-1px)}}@media(prefers-reduced-motion:reduce){.hsk-cb-voice-error{animation:none}}.hsk-cb-voice-error.hsk-cb-lang-pending{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%,to{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) * .22s)}@keyframes hsk-steam-rise{0%{transform:translateY(2px) scaleY(.5);opacity:0}35%{opacity:.95}to{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%,to{transform:scale(1) rotate(0);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}}@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) scale(1) rotate(0);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}to{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}to{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) scale(1) rotate(0)}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%,to{transform:translate(0) scale(1) rotate(0)}}@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%,to{transform:translate(-50%,-50%) rotate(38deg) scaleY(0);opacity:0}}@keyframes hsk-wing-beat-far{0%,to{transform:scaleX(1) skewY(0)}50%{transform:scaleX(.86) skewY(-4deg)}}@keyframes hsk-wing-beat-near{0%,to{transform:scaleX(1) skewY(0)}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%,to{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%,#ffffff70,#fff0 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 #ffffff80,inset 0 -3px 5px color-mix(in srgb,var(--hsk-primary, #1273e6) 30%,rgba(0,0,0,.55)),0 2px 5px #0003,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%}80%{transform:scale(.98,1.03);border-radius:50% 50% 48% 52%/52% 48%}88%,to{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%}to{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 #ffffff4d,inset 0 -1px 3px color-mix(in srgb,var(--hsk-primary, #1273e6) 24%,rgba(0,0,0,.6)),0 1px 3px #0000003d}@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 #ffffff94,inset 0 -3px 6px color-mix(in srgb,var(--hsk-primary, #1273e6) 28%,rgba(0,0,0,.5)),0 3px 7px #00000038,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)}to{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)}to{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:-.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-more{margin:0 0 4px;font-size:12.5px;color:var(--hsk-chat-muted, #9ca3af);text-align:start}.hsk-cb-terms-more a{color:var(--hsk-primary, #ff6a33);font-weight:600;text-decoration:none;unicode-bidi:isolate}.hsk-cb-terms-more a:hover{text-decoration:underline}.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:-.01em}.hsk-cb-terms-agree-btn.is-active{background:var(--hsk-primary, #ff6a33);color:#fff;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)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes hsk-theme-pill-in{0%{opacity:0;transform:scale(.94)}to{opacity:1;transform:scale(1)}}.hsk-cb-panel[dir=rtl] .hsk-cb-theme-2x2-grid{transform-origin:bottom right}@media(prefers-reduced-motion:reduce){.hsk-cb-theme-squircle-trigger{animation:none}}@keyframes hsk-theme-morph-out{0%{opacity:1;transform:scale(1) translateY(0)}to{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}to{transform:scale(1);opacity:1}}:root{--hsk-apple-bezier: cubic-bezier(.16, 1, .3, 1);--hsk-apple-exit-bezier: cubic-bezier(.4, 0, .2, 1)}@keyframes hsk-step1-exit-up{0%{opacity:1;transform:translateY(0) scale(1);filter:blur(0px)}to{opacity:0;transform:translateY(-46px) scale(.96);filter:blur(14px)}}.hsk-step1-exit{animation:hsk-step1-exit-up .32s cubic-bezier(.16,1,.3,1) forwards;pointer-events:none;will-change:transform,opacity,filter}@keyframes hsk-composer-exit-up{0%{opacity:1;transform:translateY(0);filter:blur(0px)}to{opacity:0;transform:translateY(-42px);filter:blur(12px)}}.hsk-composer-exit-up{animation:hsk-composer-exit-up .3s cubic-bezier(.16,1,.3,1) forwards;pointer-events:none;will-change:transform,opacity,filter}.hsk-lang-loader{display:flex;flex-direction:column;align-items:center;gap:28px;padding:16px 0;width:100%}.hsk-lang-loader--enter{animation:hsk-clay-in .16s steps(2,end) both}@keyframes hsk-clay-in{0%{opacity:0}to{opacity:1}}.hsk-clay{display:flex;flex-direction:column;align-items:center;gap:8px}.hsk-clay-table{display:block;width:240px;height:160px}.hsk-lang-preparing{font-size:13px;font-weight:500;letter-spacing:-.015em;color:var(--hsk-chat-muted, rgba(255, 255, 255, .44));text-align:center;margin:0;line-height:1.4}.hsk-lang-loader--enter .hsk-lang-preparing{animation:hsk-preparing-in .42s .4s cubic-bezier(.16,1,.3,1) both}.hsk-lang-loader--exit .hsk-lang-preparing{animation:hsk-preparing-out .12s cubic-bezier(.4,0,.2,1) forwards}@keyframes hsk-preparing-in{0%{opacity:0;transform:translateY(10px);filter:blur(8px)}to{opacity:1;transform:translateY(0);filter:blur(0px)}}@keyframes hsk-preparing-out{to{opacity:0;transform:translateY(4px);filter:blur(6px)}}.hsk-composer-reveal{animation:hsk-composer-in .48s cubic-bezier(.16,1,.3,1) both;will-change:transform,opacity,filter}@keyframes hsk-composer-in{0%{opacity:0;transform:translateY(36px);filter:blur(10px)}to{opacity:1;transform:translateY(0);filter:blur(0px)}}.hsk-step-enter{animation:hsk-step-enter-in .46s cubic-bezier(.16,1,.3,1) both;will-change:transform,opacity,filter}@keyframes hsk-step-enter-in{0%{opacity:0;transform:translateY(22px);filter:blur(12px)}to{opacity:1;transform:translateY(0);filter:blur(0px)}}@media(prefers-reduced-motion:reduce){.hsk-step1-exit,.hsk-composer-exit-up,.hsk-lang-loader--enter,.hsk-lang-loader--exit,.hsk-composer-reveal,.hsk-step-enter{animation:none!important}}\";\n","import { KIKU_CSS } from '../styles/cssText';\r\n\r\nconst CONTAINER_ID = 'akropolys-kiku-root';\r\nlet container: HTMLElement | null = null;\r\nlet shadow: ShadowRoot | null = null;\r\nlet styled = false;\r\n\r\nexport function kikuCss(): string {\r\n return KIKU_CSS;\r\n}\r\n\r\nfunction applyStyles(root: ShadowRoot): void {\r\n if (styled) return;\r\n styled = true;\r\n if (typeof CSSStyleSheet !== 'undefined' && 'replaceSync' in CSSStyleSheet.prototype) {\r\n try {\r\n const sheet = new CSSStyleSheet();\r\n sheet.replaceSync(KIKU_CSS);\r\n root.adoptedStyleSheets = [sheet];\r\n return;\r\n } catch {\r\n }\r\n }\r\n const style = document.createElement('style');\r\n style.textContent = KIKU_CSS;\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) {\r\n applyStyles(shadow);\r\n return shadow as unknown as HTMLElement;\r\n }\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 styled = false;\r\n}\r\n"],"mappings":"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","names":["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","MessageIcon","size","jsxs","cx","i","PaperclipIcon","ImageIcon","RetryIcon","className","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_THEME","isThemeId","value","t","themeDef","id","useKiku","subscribeLiveStream","useAkropolysContext","useCardFields","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","readAsDataURL","blob","resolve","reject","reader","downscaleImage","file","probe","scale","w","h","bitmap","canvas","cx","keepPNG","useEffect","useRef","useState","dist","a","b","pathLength","pts","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","pins","c","used","out","cur","j","jsx","jsxs","MARK_COLOR","MAX_EXPORT_DIM","MAX_PINS","PIN_LABEL_MAX","wrapLabel","ctx","text","maxWidth","lines","line","word","next","labelPlacement","xPct","topPct","top","MarkupEditor","src","onCancel","onSend","t","img","setImg","useState","loadError","setLoadError","tool","setTool","nextPin","useRef","activePin","setActivePin","pinDrag","selectionHistory","setSelectionHistory","selection","selectionId","vertexDrag","remember","prev","selecting","actions","setActions","exportError","setExportError","canvasRef","drawingRef","useEffect","el","dims","scale","markLayer","paint","live","canvas","layer","lctx","all","a","p","i","visiblePoints","r","lineH","w","l","h","x","bottom","toCanvasPoint","e","rect","strokeSize","removePin","id","closeActivePin","open","onPointerDown","hit","size","first","hitRadius","index","v","onPointerMove","offset","onPointerUp","point","done","pins","editingPin","canSend","handleSend","clean","cctx","dataUrl","drawn","marks","buildMarkRegions","normX","normY","y","hint","React","useEffect","useRef","useState","jsx","hashSeed","s","h","i","mulberry32","seed","a","smooth","t","makeNoise","rng","lat","at","x","y","xi","yi","xf","yf","b","c","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","thumpListeners","bloomListeners","bloomDoodles","start","thumpDoodles","JOLT_FRAME_MS","JOLT_FRAMES","MAX_DRIFT","MAX_TURN","getShimmerColor","normDist","isDarkMode","generateGlyphs","ink","tint","isRTL","themeId","originY","accent","noise","area","raw","fa","fb","reach","angle","ca","sa","poleX","poleY","glyphs","maxDist","jitter","reachFromDock","ir","ig","ib","d","roll","bloom","axis","isLightMode","alpha","baseColor","glyphSeed","shimmerColor","rotation","lineWidth","size","drawFn","alphaMul","BLOOM_SPAN","easeOutBack","renderDoodles","shimmerProgress","alphaScale","bloomT","isShimmering","wavePos","waveWidth","g","stroke","lw","grow","driftX","driftY","lp","settle","glint","diff","surge","glyphRng","KikuDoodles","theme","waitForContent","ref","isAnimatingRef","animFrameRef","cachedGlyphsRef","lastWidthRef","coveredHeightRef","waitingRef","cv","numeric","timer","tick","startTime","duration","now","elapsed","rawProgress","dpr","targetW","targetH","updateCanvas","cs","fullScreenH","handleResize","waitLimit","ro","scheme","handleSchemeChange","joltTimer","redraw","onThump","strength","clamp","v","m","moves","fx","fy","fr","push","tx","ty","tr","f","SHIMMER_SCALE","SHIMMER_MS","DoodleShimmer","weight","raf","vw","vh","began","loop","tri","VEIL_EXIT_MS","WorkingVeil","shown","setShown","KikuDoodles_default","React","DEFAULT_CHIPS","LANGUAGE_CHOICES","endonymFor","lang","bcp47","typed","l","hit","x","LANGUAGE_METAS","byEndonym","m","tag","name","isRTLText","s","ch","code","formatLangName","str","trimmed","getLoadingMeta","k","v","rawName","nativeName","rtl","LIVE_VOICES","VOICE_STORAGE_KEY","ONBOARDING_UI_STRINGS","DEFAULT_UI_STRINGS","UIStringsContext","key","vars","useT","extractName","raw","words","q","w","SERVER_ERROR_STRINGS","getFriendlyError","err","tr","code","SERVER_ERROR_STRINGS","str","lower","isSecureOrigin","KIKU_KEY_REVEAL_SECONDS","BASE_FONT","BASE_FONT_READY","readyBaseFont","client","cachedBaseFont","hit","p","f","preloadScriptFont","warmChrome","shopperLanguage","defaults","warmLanguage","language","res","React","useState","useEffect","useCallback","useAkropolysContext","jsx","LANGUAGE_CODES","knownLanguage","lang","bcp47","resolveFirstFamily","varRef","name","el","value","FONT_WAIT_MS","LANG_WAIT_MS","LANG_RETRY_MS","useScriptFont","shopperLanguage","theme","preloadedStrings","client","useAkropolysContext","cachedInitial","DEFAULT_UI_STRINGS","ONBOARDING_UI_STRINGS","initialStrings","chromeStrings","setChromeStrings","useState","chromeReady","setChromeReady","loadedLang","setLoadedLang","isEn","effectiveStrings","dirKey","isRTL","setIsRTL","known","getLoadingMeta","speechLang","setSpeechLang","scriptFont","setScriptFont","baseFont","setBaseFont","readyBaseFont","baseFontReady","setBaseFontReady","fontWait","setFontWait","langPending","setLangPending","openedLangRef","React","prevShopperLanguage","setPrevShopperLanguage","knownNow","cached","sourceStrings","preloadScriptFont","fontsLoadedFor","f","effectiveChromeReady","useEffect","meta","isLangEn","cancelled","holdForFonts","font","strings","families","loadFontsFor","cachedFull","cachedOnboarding","openInEnglish","tryLoad","got","resFast","prev","resFull","slow","attempt","resolve","cachedBaseFont","useScriptFontFace","fontStack","first","isVarRef","hostName","resolved","host","l","isNonLatin","latin","other","v","ch","c","fontEpoch","setFontEpoch","live","e","hostFontCovers","sample","text","ctx","hostFamily","withHost","withoutHost","t","useCallback","key","vars","s","k","tNode","part","i","m","useState","useRef","useEffect","useLayoutEffect","useCallback","useChatScroll","messages","loading","streaming","messageRefs","msgsContainerRef","lastExternalScrollRef","showJumpToBottom","setShowJumpToBottom","scrollProgress","setScrollProgress","activeMsgIdx","setActiveMsgIdx","resyncScrollRef","glideScrollRef","touchScrollingRef","stickToBottomRef","readingRef","spacerRef","anchorNodeRef","prevLenRef","pendingAnchorRef","layoutAnchorRef","followBottomRef","syncScrollRef","releaseAnchorRef","alertTick","setAlertTick","awayEpochRef","lastAlertKeyRef","dismissJumpAlertRef","resetAlertArmingRef","el","idle","settle","onTouchStart","onScroll","JUMP_THRESHOLD","STICK_ON","queued","measure","spacerH","distance","readerMoved","clearUnreadRef","max","line","active","i","node","ro","notifyNewBelow","turn","key","t","unreadBelow","setUnreadBelow","unreadBelowRef","markUnread","clearUnread","jumpAlert","setJumpAlert","jumpAlertRef","alertShownAtRef","clearAlert","resetAlertArming","dismissJumpAlert","releaseAnchor","bottom","mode","spacer","move","to","fn","followBottom","padTop","top","need","jumpToMessage","idx","targetCenter","jumpToBottom","container","added","m","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","useRef","useEffect","WINDOW_MS","MIN_CPS","MAX_CPS","RATE_EASE_MS","usePacedText","content","shown","setShown","shownRef","targetRef","rateRef","carryRef","lastRef","rafRef","step","now","dt","target","backlog","want","whole","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","copyWithSelection","useEffect","t","s","handleUseExistingKey","pub","handleCreateKey","secret","publicId","area","ok","useCallback","useChatCommands","attachments","setAttachments","setInput","send","t","handleKikuCapture","product","name","display","q","toSend","handleKikuCaptureAll","products","targets","p","names","handleKikuViewHistory","handleKikuDelete","useState","useCallback","useEffect","useRef","useAkropolysContext","ctx","analyser","duckGain","timeData","speaking","smoothed","duckSpeech","level","fadeMs","g","now","speechLevel","sum","i","v","rms","stopSpeech","useCallback","useEffect","useRef","useState","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","useCallback","useEffect","useRef","useState","INDEX_TABLE","STEP_TABLE","clampIndex","i","clampSample","v","AdpcmEncoder","pcm","n","out","pred","idx","step","diff","nib","vpdiff","decodeAdpcm","block","bytes","writeAscii","view","offset","string","i","float32ToWav","chunks","sampleRate","totalLen","c","merged","buffer","dataOffset","s","int16ToWav","INPUT_RATE","OUTPUT_RATE","START_BUFFER_SEC","REFILL_BUFFER_SEC","SCHEDULE_LEAD","FLUSH_FADE","HEARING_LEVEL","HEARING_HOLD_MS","IDLE_CLOSE_MS","WORKLET_SRC","INPUT_RATE","voiceProtocols","o","liveUrl","voiceOverride","base","path","url","v","useLiveVoice","opts","state","setState","useState","hearing","setHearing","sources","setSources","secondsLeft","setSecondsLeft","photos","setPhotos","wsRef","useRef","startedRef","openOnReadyRef","micAttachRef","lastLoudRef","botSpeakingRef","spokeLoggedRef","ctxRef","streamRef","nodeRef","analyserRef","playAtRef","replyingRef","heldRef","heldSecRef","sourcesRef","outAnalyserRef","outGainRef","outRateRef","OUTPUT_RATE","optsRef","useEffect","stream","track","readyRef","pendingRef","encoderRef","AdpcmEncoder","workletCtxRef","turnHeardRef","turnSaidRef","turns","setTurns","turnsRef","historyRef","images","setImages","imageIdRef","turnImagesRef","turnVizRef","turnStartRef","turnBotAudioChunksRef","turnUserAudioChunksRef","flushExchange","useCallback","heard","said","duration","audioUrl","blob","float32ToWav","e","userAudioUrl","int16ToWav","visualization","chirp","sendAudio","buf","pcm","peak","i","ws","flushPending","audioContext","held","AC","ctx","blobUrl","warmContext","micLevel","a","d","sum","outbound","micSpectrum","out","spectrumBins","flushPlayback","g","src","now","fadeEnd","FLUSH_FADE","schedule","chunk","at","SCHEDULE_LEAD","s","releaseHeld","dropHeld","enqueue","target","REFILL_BUFFER_SEC","START_BUFFER_SEC","holdTimerRef","holdGainRef","stopHold","startHold","teardown","finalState","t","stop","sendOpen","history","x","attachWsHandlers","abandoned","ev","prev","next","decodeAdpcm","f","chime","last","text","hotReconnect","newVoice","oldWs","currentVoiceRef","start","ctxReady","primeChimes","inAnalyser","outGain","outAnalyser","node","srcNode","attach","lastLoud","on","quietSince","id","prewarm","attachPhoto","file","store","image","downscaleImage","ask","toVoicePhase","s","NO_EARLIER","newConversation","earlierCalls","messages","conversation","turns","images","m","url","useVoiceController","voiceLang","speechLang","shopperLanguage","ttsVoice","handleSendUtterance","appendSpokenExchange","client","useAkropolysContext","voiceMode","setVoiceMode","useState","dictateState","setDictateState","voiceError","setVoiceError","voiceMuted","setVoiceMuted","voiceBlocked","setVoiceBlocked","liveVoiceName","setLiveVoiceName","stored","VOICE_STORAGE_KEY","LIVE_VOICES","v","conversationRef","useRef","chooseVoice","useCallback","name","voice","useVoiceSession","text","code","stopSpeech","apiUrl","siteId","token","kikuId","shopperName","live","useLiveVoice","image","exchange","err","canConverse","prewarm","useEffect","id","earlier","setEarlier","startVoice","mode","isSecureOrigin","before","newVoiceChat","stopVoice","voicePhase","voiceConnecting","file","React","useEffect","useRef","jsx","jsxs","BODY","MOOD","HOP","HOP_APEX","DROP_DELAY_MS","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","dropIn","dropInRef","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","dropAt","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","_","useState","Fragment","jsx","jsxs","SoundToggle","className","compact","on","setOn","useState","soundsEnabled","state","setState","toggle","next","setSoundsEnabled","chime","chimeState","cn","useCallback","useLayoutEffect","useRef","OPEN_MS","CLOSE_MS","MIN_MS","CONTENT_FROM","CONTENT_SPAN","SHAPE_FADE","clamp01","v","cubicBezier","x1","y1","x2","y2","cx","bx","ax","cy","by","ay","sx","t","sy","dx","x","i","err","d","EASE","readShell","el","b","useIslandMorph","target","trigger","shadow","radius","enabled","onClosed","shellRef","boxRef","closingRef","progressRef","rafRef","onClosedRef","paint","p","r","q","inTop","inLeft","shiftY","shiftX","top","left","right","bottom","round","sh","fade","release","prop","stop","run","to","fullMs","onDone","from","ms","start","frame","now","k","begin","tr","rect","inView","at","jsx","jsxs","droppedIn","ChatTopbar","title","logo","hasMessages","avatarState","unread","awayFromBottom","themeMenuOpen","themeMenuClosing","onThemeMenuClosed","isNarrow","currentTheme","onJumpToLatest","onReset","onClose","onToggleThemeMenu","onSelectTheme","themeAttr","below","tr","useT","barRef","React","trayRef","shadowRef","nameRef","dropIn","first","droppedIn","bar","name","dock","mark","pillMiddle","trayMotion","trayReady","setTrayReady","ric","id","cic","trayMounted","tray","useIslandMorph","isImpacting","setIsImpacting","impactColor","setImpactColor","impactGlow","setImpactGlow","triggerRef","longPressTimerRef","isLongPressRef","touchStartTimeRef","startPress","endPress","cancelPress","handleClick","e","handleImpact","splat","color","glow","jsxs","cn","jsx","ChevronLeftIcon","KikuAvatar","CloseIcon","SoundToggle","THEMES","label","Icon","React","React","jsx","jsxs","FRAME_MS","HOLD","W","H","CX","CY","LUMP","DISC_RX","DISC_RY","LOG","LOG_H","PIECES","SUSHI_R","SUSHI_GAP","lerp","a","b","k","boil","n","i","blob","p","x","y","rx","ry","turn","pts","r","mid","ctx","shade","lift","dpr","round","g","tube","h","lump","s","disc","clipBelow","log","x0","x1","left","right","sushi","t","rr","px","py","marks","strength","r0","len","cutX","score","sushiX","pieces","opened","standing","tipping","shift","c","buildLoop","f","passes","rx0","ry0","rx1","ry1","press","widest","edge","off","w","sway","LOOP","ENTER","EXIT_FADE","resolveColor","host","css","el","ClayLoader","phase","label","canvasRef","React","labelRef","run","cv","text","primary","st","paint","frame","alpha","thump","thumpDoodles","seq","fade","id","tick","jsx","jsxs","CheckMark","OnboardingView","inOnboarding","justCompleted","onboardingMood","awaitingLang","awaitingName","awaitingEntityLang","awaitingConsent","termsAgreed","shopperLanguage","pendingLanguage","shopperName","entityLangPref","chromeReady","activeChips","speechLang","t","tNode","chooseLanguage","langSwitching","isLangPreparingProp","onPrewarmLanguage","chooseEntityLang","agreeTerms","handleSend","targetLang","isEn","isLangPreparing","loadingMeta","getLoadingMeta","prevPreparing","setPrevPreparing","React","spinnerPhase","setSpinnerPhase","phaseTimers","clearPhaseTimers","showSpinner","showStep1Exiting","currentStep","picked","setPicked","countdown","setCountdown","timer","prev","displayShopperLang","endonymFor","ric","id","cn","ClayLoader","LANGUAGE_CHOICES","l","i","mode","chip","useState","useEffect","useRef","jsx","jsxs","parseThinking","text","openMatch","openIdx","openTagLength","start","contentBefore","textAfterOpen","closeMatch","closeIdx","closeTagLength","isTeamNote","stage","replyWait","seconds","ThinkingBlock","isComplete","fixedSeconds","repliedSeconds","tr","useT","startRef","useRef","setSeconds","useState","isOpen","setIsOpen","useEffect","t","finalSeconds","label","expandable","cn","o","useCallback","useEffect","useRef","useState","useDelayedClose","ms","onClosed","closing","setClosing","timer","closedRef","requestClose","closeNow","React","useAkropolysContext","React","LETTER","URL_LIKE","isRTLCode","code","lineDirection","text","minLetters","rtl","ltr","ch","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","LOCAL_IMG_REGEX","SAFE_LINK_REGEX","safeHref","url","u","imageHosts","safeImage","MEMORY_LINK_FILTER_REGEX","MEMORY_URL_FILTER_REGEX","normalizeSpacing","text","parseInline","keyPrefix","part","index","key","imageMatch","alt","e","linkMatch","linkText","TABLE_SEPARATOR_REGEX","isTableLine","line","inTable","splitTableCells","rowLine","t","c","TableWrapper","children","ref","React","scrollState","setScrollState","isDragging","setIsDragging","dragRef","checkScroll","el","rtl","travelled","atStart","atEnd","ro","onMouseDown","onMouseMove","walk","onMouseUp","renderMarkdown","content","streaming","hosts","buildMarkdown","lines","start","l","dirOf","at","lineDirection","blocks","currentTextNodes","bubbleIndex","flushTextBubble","i","standaloneImageMatch","headerMatch","level","Tag","listItems","listText","itemText","headerCells","rawBodyRows","alignments","isHeader","cell","trimmed","startColon","endColon","cells","colCount","r","finalAlignments","numericCount","val","headerRow","cIdx","bodyRows","rIdx","useEffect","useState","describeAge","getLiveValue","isFresh","isStale","labelFor","formatLiveValue","subscribeLiveValues","LIVE_FLASH_MS","jsx","jsxs","useLiveValues","keys","bump","joined","k","n","id","TITLE_KEYS","MAX_PILLS","MAX_PILL_CHARS","LiveQuoteCard","record","now","stale","fields","titleKey","rawTitle","shortTitle","quotePills","v","p","flash","LiveTable","seen","ordered","records","_","i","shown","r","useState","useRef","useEffect","useCallback","useAkropolysContext","useCardFields","Fragment","jsx","jsxs","SourceImg","src","alt","onImageClick","failed","setFailed","useState","SparkleIcon","e","SourcesCarousel","sources","onSelectSource","referencedIds","compact","targetLabel","client","useAkropolysContext","cardFields","useCardFields","railRef","useRef","showPrev","setShowPrev","showNext","setShowNext","activeIndex","setActiveIndex","referenced","s","swatches","display","measure","useCallback","el","travelled","maxScroll","idx","useEffect","ro","railStep","dir","rtl","scrollNext","scrollPrev","swatchGrid","si","cn","ChevronLeftIcon","isReferenced","detailsOf","d","ChevronRightIcon","_","i","jsx","jsxs","SmartContextPills","intent","sources","onSend","loading","tr","useT","pills","firstName","firstTwo","s","short","pill","Fragment","jsx","jsxs","MarkdownBlock","React","content","streaming","hosts","renderMarkdown","a","b","hostsOf","urls","u","useSnugWidth","ref","text","el","fit","range","lines","box","scale","style","pad","longest","r","row","observer","MessageItem","msg","idx","isLast","isLastUser","isRunEnd","runMid","runCont","isNarrow","loading","stopped","interrupted","sources","referencedIds","discussedSources","lastIntent","lastAction","vizState","setVizState","setLightboxSrc","setMarkupSrc","handleSend","handleSourceClick","onRetry","onEdit","onLongPress","hasError","retrying","t","messageRef","photosSending","workingOn","doodleTheme","api","useAkropolysContext","doodleSeed","imageHosts","s","isUser","displayContent","copied","setCopied","bubbleRef","touchStartPos","longPressTimer","pressFired","anchorFor","sel","startLongPress","targetEl","anchor","handleTouchStart","e","touch","handleTouchMove","handleTouchEnd","handleContextMenu","handleCopy","parsed","parseThinking","thinking","CALC_DISCLAIMER_REGEX","hasCalcDisclaimer","cleanContent","cn","img","i","WorkingVeil","lineDirection","MicIcon","RetryIcon","EditIcon","CheckIcon","CopyIcon","isComplete","isTeamNote","ThinkingBlock","p","LiveTable","n","msgReferencedIds","msgSources","msgIntent","hiddenIntent","SourcesCarousel","safeHref","ExternalIcon","SmartContextPills","jsx","jsxs","PromptKeyCard","keyInput","setKeyInput","minting","handleUseExistingKey","handleCreateKey","t","SparkleIcon","e","MintedKeyCard","mintedKey","copied","keyCountdown","onDismiss","copyValue","CheckIcon","CopyIcon","Fragment","jsx","jsxs","latestPicture","messages","before","i","m","ChatMessages","displayMessages","messageRefs","isNarrow","loading","streaming","sources","referencedIds","discussedSources","lastIntent","lastAction","stopped","interrupted","halted","haltedEmpty","error","errorCode","keyPhase","keyInput","setKeyInput","mintedKey","setMintedKey","setMintedPub","minting","copied","keyCountdown","handleUseExistingKey","handleCreateKey","copyValue","queuedMessage","sendQueuedNow","setLightboxSrc","setMarkupSrc","handleSend","handleSourceClick","onRetry","onEdit","onLongPress","retrying","continueGenerating","t","spacerRef","vizState","setVizState","doodleTheme","lastUserIdx","msg","idx","isLast","isUser","isLastUser","isRunEnd","runMid","runCont","key","reply","photosSending","parseThinking","workingOn","hasError","MessageItem","el","cn","ContinueIcon","getFriendlyError","PromptKeyCard","MintedKeyCard","React","useState","useRef","useEffect","useAkropolysContext","useCardFields","jsx","HSK_STAGGER_MS","HSK_FIELD_BASE_MS","JOINING_SCRIPT","splitPlaceholder","text","I","seg","s","AnimatedPlaceholder","placeholder","visible","replay","replaySeed","staggerMs","content","seed","long","units","last","fit","unit","i","Fragment","jsx","jsxs","ChatComposer","gooId","input","setInput","showKikuPicker","setShowKikuPicker","showAtPicker","setShowAtPicker","captureAllowed","discussedSources","handleSelectExtension","handleKikuCapture","handleKikuCaptureAll","handleKikuViewHistory","handleKikuDelete","attachments","removeAttachment","chromeLoading","inputLocked","langSwitching","langPending","imageInputRef","handleImageFiles","enableVision","enableVoice","canConverse","startVoice","voiceBlocked","textareaRef","classNames","handleInput","handleKeyDown","voice","voicePhase","activePlaceholder","loading","streaming","stop","handleSend","voiceError","setVoiceError","t","rail","notice","onOpenMimi","client","useAkropolysContext","cardFields","useCardFields","placeholderReplay","setPlaceholderReplay","React","toolsOpen","setToolsOpen","timer","onKey","e","placeholderText","fieldRef","useRef","phWraps","setPhWraps","useState","useEffect","field","measure","units","first","last","ro","placeholderSweepMs","splitPlaceholder","HSK_STAGGER_MS","launching","setLaunching","launchTimer","launch","cardRef","blocked","PaperclipIcon","WaveformIcon","MessageIcon","prev","SparkleIcon","src","i","BookmarkIcon","detailsOf","HistoryIcon","TrashIcon","att","XIcon","cn","o","PlusIcon","AnimatedPlaceholder","StopIcon","ArrowUpIcon","React","useEffect","useRef","useState","useEffect","useRef","jsx","parseColor","css","fallback","m","mix","a","b","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","t","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","LightboxModal","src","onClose","CloseIcon","e","Fragment","jsx","jsxs","ImageRow","images","siteId","themeAttr","rowRef","useRef","open","setOpen","useState","useEffect","row","pendingAt","i","reworked","img","WorkingVeil","LightboxModal","VoicePicker","current","choose","label","groups","chosen","LIVE_VOICES","v","rootRef","listRef","list","on","away","e","esc","o","ChevronRightIcon","g","React","cn","VoiceOverlay","stopVoice","chooseVoice","liveVoiceName","voiceSecondsLeft","voiceConnecting","voicePhase","live","earlier","newVoiceChat","voiceMuted","setVoiceMuted","voiceError","attachPhoto","onSelectSource","t","threadRef","endRef","fileRef","turns","sources","lightbox","setLightbox","rendering","turnCount","lastText","scrolledRef","KikuDoodles_default","x","EditIcon","CloseIcon","turn","SourcesCarousel","s","id","file","ImageIcon","VoiceCanvas","m","MicOffIcon","MicIcon","useRef","useEffect","useState","jsx","jsxs","WAVE_X","WAVE_SWAY","buildWave","items","anchor","nodes","centre","n","height","sway","i","d","prevY","y","mid","ConversationTimeline","activeIdx","progress","onJump","side","tr","useT","containerRef","useRef","trackRef","itemRefs","cursorRef","wave","setWave","useState","useEffect","node","cursor","track","container","containerHeight","nodeCenter","targetY","cn","item","el","useState","useEffect","useRef","useCallback","jsx","jsxs","TAPBACK_EXIT_MS","TapbackMenu","msg","rect","containerRect","anchorEl","containerEl","isUser","isRTL","canRetry","onPin","onRetry","onCopy","onClose","t","copied","setCopied","useState","menuRef","useRef","closing","requestClose","useDelayedClose","useEffect","handleKeyDown","e","handleCopyAction","useCallback","handlePinAction","chime","handleRetryAction","measuredWidth","setMeasuredWidth","w","live","setLive","liveContainer","setLiveContainer","raf","near","a","b","tick","r","p","c","bubbleColor","setBubbleColor","bg","box","container","cTop","cLeft","cWidth","bTop","bLeft","bWidth","bHeight","btnCount","capsuleWidth","capsuleHeight","thinkAbove","placeAbove","capsuleTop","anchorRight","targetX","capsuleLeft","tailOffset","anchorColor","toolIdx","cn","PinIcon","RetryIcon","CheckIcon","CopyIcon","jsx","jsxs","THEME_MENU_EXIT_MS","TRAY_EXIT_CEILING_MS","OVERLAY_EXIT_MS","ChatModal","title","logo","placeholder","backdropColor","backdropBlur","onClose","onSelectSource","chips","DEFAULT_CHIPS","theme","classNames","enableVoice","voiceLang","enableVision","ttsVoice","origin","client","useAkropolysContext","cardFields","useCardFields","messages","sources","loading","streaming","error","errorCode","lastAction","lastIntent","allowedActions","send","queuedMessage","sendQueuedNow","appendSpokenExchange","stop","stopped","interrupted","continueGenerating","reset","referencedIds","humanPending","leaveHuman","useKiku","leaveAsk","setLeaveAsk","useState","leaveRef","useRef","nudgeLeave","useCallback","useEffect","onKey","e","onPointer","hit","cls","n","msgs","msgsContainerRef","shopperName","setShopperNameState","shopperLanguage","setShopperLanguageState","entityLangPref","setEntityLangPrefState","justCompleted","setJustCompleted","preloadedStrings","setPreloadedStrings","pendingLanguage","setPendingLanguage","langSwitching","setLangSwitching","chromeReady","baseFontReady","isRTL","speechLang","scriptFont","fontStack","isNonLatin","hostFontCovers","langPending","t","tNode","useScriptFont","discussedSources","React","byRef","s","answer","m","seen","hay","aliases","name","w","out","a","named","captureAllowed","input","setInput","showKikuPicker","setShowKikuPicker","showAtPicker","setShowAtPicker","attachments","setAttachments","photoReady","imageInputRef","vizState","setVizState","lightboxSrc","setLightboxSrc","markupSrc","setMarkupSrc","termsAgreed","setTermsAgreed","onboarding","targetLang","isEn","isLangPreparing","awaitingLang","awaitingName","awaitingEntityLang","awaitingConsent","inOnboarding","inputLocked","prevPreparingForComposer","setPrevPreparingForComposer","composerHidden","setComposerHidden","composerExiting","setComposerExiting","composerRevealing","setComposerRevealing","composerWasHidden","composerHideTimer","composerRevealTimer","trimmed","timer","warmLanguage","DEFAULT_UI_STRINGS","hasLiveData","subscribeLiveStream","isNarrow","setIsNarrow","mq","apply","chooseLanguage","lang","v","animStart","MIN_ANIM_MS","cached","ONBOARDING_UI_STRINGS","preloadScriptFont","fetchP","res","resolve","elapsed","r","chooseEntityLang","mode","agreeTerms","activePlaceholder","getLoadingMeta","activeChips","onboardingMood","currentTheme","setCurrentTheme","isThemeId","saved","DEFAULT_THEME","theming","setTheming","themingTimer","nudgeRef","nudgeContent","away","openBloomedRef","box","bloomDoodles","done","shown","fire","observer","limit","handleToggleTheme","next","alsoCloseMenu","closeThemeMenuNow","customStyles","resolveTheme","hskThemeAttr","useHostFontFace","handleSendRef","textareaRef","handleSend","text","extraAttachments","forcedIntent","captureTargets","raw","picked","chime","extractName","toSend","thumb","data","queryToSend","retrying","setRetrying","handleRetryMessage","msg","target","handleEditMessage","len","retryLastMessage","keyInput","setKeyInput","keyPhase","setKeyPhase","mintedKey","setMintedKey","mintedPub","setMintedPub","copied","keyCountdown","minting","copyValue","handleUseExistingKey","handleCreateKey","useKikuKey","openMimi","key","tapbackTarget","setTapbackTarget","handleLongPressMessage","rect","isUser","el","handlePinMessage","display","handleKikuCapture","handleKikuCaptureAll","handleKikuViewHistory","handleKikuDelete","useChatCommands","voiceMode","voicePhase","voiceConnecting","voiceError","setVoiceError","voiceMuted","setVoiceMuted","voiceSecondsLeft","voiceBlocked","liveVoiceName","chooseVoice","canConverse","startVoice","stopVoice","voice","live","earlier","newVoiceChat","attachPhoto","useVoiceController","panelRef","themeMenuOpen","setThemeMenuOpen","themeMenuMark","setThemeMenuMark","themeMenuRef","mobileThemeRef","messageRefs","overlayRef","gooId","useId","themeMenuClosing","closeThemeMenu","useDelayedClose","TRAY_EXIT_CEILING_MS","THEME_MENU_EXIT_MS","handleOutside","path","isInsideRail","isInsideMobile","targetEl","isInsideTopbarMark","isInsideOoze","spacerRef","lastExternalScrollRef","showJumpToBottom","scrollProgress","activeMsgIdx","unreadBelow","jumpToMessage","jumpToBottom","useChatScroll","overlayClosing","exitOverlay","OVERLAY_EXIT_MS","closeNow","end","requestClose","useDragToDismiss","scrollbarWidth","prevOverflow","prevPadding","computedPadding","vv","root","h","resetNow","handleReset","handleSourceClick","src","lastAssistant","detailsText","detailsOf","handleSelectExtension","ext","handleKeyDown","composerHeight","singleRowFieldWidth","measureCanvasRef","getTextWidth","font","ctx","autoGrow","val","cs","textWidth","threshold","hasNewline","shouldExpand","targetHeight","handleInput","handleImageFiles","files","list","file","ready","downscaleImage","prev","removeAttachment","idx","gone","_","i","hasTranslucentBackdrop","backdropFilterStyle","wasStreaming","last","halted","tail","pacedContent","usePacedText","draining","revealing","displayMessages","inFlight","kept","isTeamNote","timelineItems","items","clean","haltedEmpty","mountTimeRef","jsx","UIStringsContext","cn","primeChimes","jsxs","LightboxModal","MarkupEditor","dataUrl","instruction","marks","preview","KikuDoodles_default","ChatTopbar","OnboardingView","ChatMessages","ChatComposer","kind","ConversationTimeline","SoundToggle","THEMES","id","label","Icon","themeDef","MessageIcon","VoiceOverlay","TapbackMenu","ta","ok","KIKU_CSS","CONTAINER_ID","container","shadow","styled","applyStyles","root","styled","sheet","KIKU_CSS","style","getShadowContainer","shadow","container","CONTAINER_ID"]}