@akropolys/kiku 2.2.16 → 2.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/embed/embed.js +79 -9
- package/dist/embed/meta.json +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37 -1
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-YFPHOGZP.mjs +0 -3
- package/dist/chunk-YFPHOGZP.mjs.map +0 -1
- package/dist/embed/chunk-6IBG6ADQ.js +0 -37
- package/dist/embed/lazy-IXQ4PCY4.js +0 -37
- package/dist/lazy-KLKJL6S2.mjs +0 -39
- package/dist/lazy-KLKJL6S2.mjs.map +0 -1
|
@@ -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/utils/voiceRecovery.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/EntityGallery.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 { initialTheme } from '../../utils/themePreference';\r\nimport React, { useState, useEffect, useLayoutEffect, useRef, useCallback, useId } from 'react';\r\nimport { flushSync } from 'react-dom';\r\nimport { THEMES, isThemeId, themeDef, DEFAULT_THEME, type ThemeId } from './themes';\r\nimport { useKiku, ChatSource, ChatAttachment, CaptureTarget, subscribeLiveStream, type ChatMessage } from '@akropolys/sdk';\r\nimport { useAkropolysContext, useCardFields } from '@akropolys/sdk';\r\nimport { detailsOf, detailsText } from '../../utils/cardDetails';\r\nimport { cn } from '../../utils/cn';\r\nimport { resolveTheme } from '../../utils/theme';\r\nimport { useHostFontFace, preloadScriptFont } from '../../utils/hostFont';\r\nimport { useDragToDismiss } from '../../utils/sheetGesture';\r\nimport { downscaleImage } from '../../utils/downscaleImage';\r\nimport { MarkupEditor } from '../MarkupEditor';\r\nimport type { KikuState } from '../KikuAvatar';\r\nimport KikuDoodles, { bloomDoodles } from '../KikuDoodles';\r\n\r\nimport {\r\n DEFAULT_CHIPS,\r\n DEFAULT_UI_STRINGS,\r\n ONBOARDING_UI_STRINGS,\r\n UIStringsContext,\r\n extractName,\r\n ChatModalProps,\r\n getLoadingMeta,\r\n type ComposerAttachment,\r\n} from './types';\r\nimport { warmLanguage } from '../../utils/chromeWarm';\r\nimport { useScriptFont } from './hooks/useScriptFont';\r\nimport { useChatScroll } from './hooks/useChatScroll';\r\nimport { usePacedText } from './hooks/usePacedText';\r\nimport { useKikuKey } from './hooks/useKikuKey';\r\nimport { useChatCommands } from './hooks/useChatCommands';\r\nimport { useVoiceController } from './hooks/useVoiceController';\r\nimport { ChatTopbar } from './ChatTopbar';\r\nimport { CloseIcon, MessageIcon } from './icons';\r\nimport { OnboardingView } from './OnboardingView';\r\n\r\nconst THEME_MENU_EXIT_MS = 240; // outlasts the 220ms exit, or the menu is removed mid-fade and pops\r\nconst TRAY_EXIT_CEILING_MS = 700;\r\nconst OVERLAY_EXIT_MS = 200;\r\nimport { chime, primeChimes } from '../../utils/chime';\r\nimport { SoundToggle } from './components/SoundToggle';\r\nimport { isTeamNote } from './components/ThinkingBlock';\r\nimport { useDelayedClose } from './hooks/useDelayedClose';\r\n\r\nconst RadarIcon = ({ size = 14 }: { size?: number }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2Z\"/>\r\n <path d=\"M12 6a6 6 0 1 0 6 6 6 6 0 0 0-6-6Z\"/>\r\n <circle cx=\"12\" cy=\"12\" r=\"2\"/>\r\n </svg>\r\n);\r\nimport { ChatMessages } from './ChatMessages';\r\nimport { ChatComposer } from './ChatComposer';\r\nimport { VoiceOverlay } from './VoiceOverlay';\r\nimport { LightboxModal } from './components/LightboxModal';\r\nimport { ConversationTimeline } from './components/ConversationTimeline';\r\nimport { TapbackMenu } from './components/TapbackMenu';\r\n\r\nexport function ChatModal({\r\n title = 'kiku',\r\n logo,\r\n placeholder = 'Ask me anything…',\r\n backdropColor,\r\n backdropBlur,\r\n onClose,\r\n onSelectSource,\r\n chips = DEFAULT_CHIPS,\r\n theme,\r\n classNames = {},\r\n enableVoice = false,\r\n voiceLang,\r\n enableVision = false,\r\n ttsVoice = 'Algenib',\r\n origin,\r\n}: ChatModalProps) {\r\n const client = useAkropolysContext();\r\n const cardFields = useCardFields();\r\n const { messages, sources, loading, streaming, error, errorCode, lastAction, lastIntent, allowedActions, send, queuedMessage, sendQueuedNow, appendSpokenExchange, stop, stopped, interrupted, continueGenerating, reset, referencedIds, humanPending, leaveHuman } = useKiku();\r\n const [leaveAsk, setLeaveAsk] = useState<'close' | 'reset' | null>(null);\r\n const leaveRef = useRef<HTMLDivElement>(null);\r\n // A side-to-side nudge when the visitor tries anything else while the warning waits for an answer.\r\n const nudgeLeave = useCallback(() => {\r\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return;\r\n leaveRef.current?.animate(\r\n [0, -7, 6, -4, 2, 0].map(x => ({ transform: `translateX(${x}px)` })),\r\n { duration: 380, easing: 'cubic-bezier(.36, .07, .19, .97)' },\r\n );\r\n }, []);\r\n useEffect(() => {\r\n if (!leaveAsk) return;\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key.length === 1 || e.key === 'Enter' || e.key === 'Backspace') nudgeLeave();\r\n };\r\n // The conversation is frozen too, so retry, edit and suggestions cannot send behind the warning.\r\n const onPointer = (e: PointerEvent) => {\r\n const hit = (cls: string) => e.composedPath().some(n => (n as Element).classList?.contains(cls));\r\n if (!hit('hsk-cb-leave') && !hit('hsk-cb-topbar')) nudgeLeave();\r\n };\r\n const msgs = msgsContainerRef.current as HTMLElement | null;\r\n msgs?.setAttribute('inert', '');\r\n document.addEventListener('keydown', onKey);\r\n document.addEventListener('pointerdown', onPointer, true);\r\n return () => {\r\n msgs?.removeAttribute('inert');\r\n document.removeEventListener('keydown', onKey);\r\n document.removeEventListener('pointerdown', onPointer, true);\r\n };\r\n }, [leaveAsk, nudgeLeave]);\r\n\r\n const [shopperName, setShopperNameState] = useState<string>(() => {\r\n try { return client.getShopperName?.() ?? ''; } catch { return ''; }\r\n });\r\n const [shopperLanguage, setShopperLanguageState] = useState<string>(() => {\r\n try { return client.getShopperLanguage?.() ?? ''; } catch { return ''; }\r\n });\r\n const [entityLangPref, setEntityLangPrefState] = useState<string>(() => {\r\n try { return client.getEntityLanguageMode?.() ?? ''; } catch { return ''; }\r\n });\r\n const [justCompleted, setJustCompleted] = useState(false);\r\n const [preloadedStrings, setPreloadedStrings] = useState<Record<string, string> | null>(null);\r\n const [pendingLanguage, setPendingLanguage] = useState<string>('');\r\n const [langSwitching, setLangSwitching] = useState(false);\r\n\r\n const {\r\n chromeReady,\r\n baseFontReady,\r\n isRTL,\r\n speechLang,\r\n scriptFont,\r\n fontStack,\r\n isNonLatin,\r\n hostFontCovers,\r\n t,\r\n tNode,\r\n } = useScriptFont({ shopperLanguage: shopperLanguage || pendingLanguage, theme, preloadedStrings });\r\n\r\n const discussedSources = React.useMemo(() => {\r\n const byRef = sources.filter(s => s.id && referencedIds.includes(s.id));\r\n const answer = [...messages].reverse().find(m => m.role === 'assistant')?.content ?? '';\r\n if (!answer) return byRef;\r\n const seen = new Set(byRef.map(s => s.id));\r\n const hay = answer.toLowerCase().replace(/\\s+/g, ' ');\r\n const aliases = (name: string) => {\r\n const n = String(name ?? '').toLowerCase().replace(/\\s+/g, ' ').trim();\r\n const w = n.split(' ');\r\n const out = [n];\r\n if (w.length > 3) out.push(w.slice(0, 3).join(' '));\r\n if (w.length > 4) out.push(w.slice(0, 4).join(' '));\r\n return out.filter(a => a.length >= 5);\r\n };\r\n const named = sources.filter(s =>\r\n s.id && !seen.has(s.id) && aliases(s.name).some(a => hay.includes(a))\r\n );\r\n return [...byRef, ...named];\r\n }, [sources, referencedIds, messages]);\r\n\r\n const captureAllowed = allowedActions === null || allowedActions.includes('capture');\r\n const [input, setInput] = useState('');\r\n const [showKikuPicker, setShowKikuPicker] = useState(false);\r\n const [showAtPicker, setShowAtPicker] = useState(false);\r\n const [attachments, setAttachments] = useState<ComposerAttachment[]>([]);\r\n const photoReady = useRef(new Map<string, Promise<string>>());\r\n const imageInputRef = useRef<HTMLInputElement>(null);\r\n const [vizState, setVizState] = useState<Record<string, 'ok' | 'err'>>({});\r\n const [lightboxData, setLightboxData] = useState<{\r\n src?: string | null;\r\n images?: import('./components/LightboxModal').LightboxImage[];\r\n initialIndex?: number;\r\n title?: string;\r\n } | null>(null);\r\n\r\n const handleOpenLightbox = useCallback((src: string | null, gallery?: import('./components/LightboxModal').LightboxGalleryData) => {\r\n if (!src && !gallery) {\r\n setLightboxData(null);\r\n return;\r\n }\r\n if (gallery) {\r\n setLightboxData({\r\n images: gallery.images,\r\n initialIndex: gallery.index ?? 0,\r\n title: gallery.title,\r\n });\r\n } else {\r\n setLightboxData({ src });\r\n }\r\n }, []);\r\n const [markupSrc, setMarkupSrc] = useState<string | null>(null);\r\n\r\n const [termsAgreed, setTermsAgreed] = useState<boolean>(() => {\r\n if (typeof window === 'undefined') return false;\r\n try {\r\n return localStorage.getItem('akropolys_terms_agreed') === 'true';\r\n } catch {\r\n return false;\r\n }\r\n });\r\n\r\n const onboarding = messages.length === 0;\r\n const targetLang = pendingLanguage || shopperLanguage;\r\n const isEn = !targetLang || targetLang.toLowerCase() === 'english' || targetLang.toLowerCase() === 'en';\r\n const isLangPreparing = langSwitching || !!pendingLanguage || (!!shopperLanguage && !chromeReady && !isEn);\r\n const awaitingLang = onboarding && !shopperLanguage && !isLangPreparing;\r\n const awaitingName = onboarding && !!shopperLanguage && !shopperName && !isLangPreparing;\r\n const awaitingEntityLang = onboarding && !!shopperLanguage && !!shopperName && !entityLangPref;\r\n const awaitingConsent = onboarding && !!shopperLanguage && !!shopperName && !!entityLangPref && !termsAgreed;\r\n const inOnboarding = awaitingLang || awaitingName || awaitingEntityLang || awaitingConsent || isLangPreparing;\r\n const inputLocked = awaitingEntityLang || awaitingConsent || isLangPreparing;\r\n\r\n const [prevPreparingForComposer, setPrevPreparingForComposer] = useState(isLangPreparing);\r\n const [composerHidden, setComposerHidden] = useState(false);\r\n const [composerExiting, setComposerExiting] = useState(false);\r\n const [composerRevealing, setComposerRevealing] = useState(false);\r\n const composerWasHidden = useRef(false);\r\n const composerHideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const composerRevealTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n if (isLangPreparing !== prevPreparingForComposer) {\r\n setPrevPreparingForComposer(isLangPreparing);\r\n if (isLangPreparing) {\r\n if (composerRevealTimer.current) clearTimeout(composerRevealTimer.current);\r\n setComposerRevealing(false);\r\n setComposerExiting(true);\r\n composerHideTimer.current = setTimeout(() => {\r\n setComposerHidden(true);\r\n setComposerExiting(false);\r\n composerWasHidden.current = true;\r\n }, 280);\r\n } else {\r\n if (composerHideTimer.current) clearTimeout(composerHideTimer.current);\r\n setComposerExiting(false);\r\n setComposerHidden(false);\r\n if (composerWasHidden.current) {\r\n composerWasHidden.current = false;\r\n setComposerRevealing(true);\r\n composerRevealTimer.current = setTimeout(() => setComposerRevealing(false), 560);\r\n }\r\n }\r\n }\r\n\r\n useEffect(() => () => {\r\n if (composerHideTimer.current) clearTimeout(composerHideTimer.current);\r\n if (composerRevealTimer.current) clearTimeout(composerRevealTimer.current);\r\n }, []);\r\n\r\n\r\n const hasLiveData = React.useMemo(\r\n () => messages.some(m => (m as any).liveKeys?.length > 0),\r\n [messages]\r\n );\r\n useEffect(() => {\r\n if (!hasLiveData) return;\r\n return subscribeLiveStream({ client });\r\n }, [hasLiveData, client]);\r\n\r\n const [isNarrow, setIsNarrow] = useState(false);\r\n useEffect(() => {\r\n const mq = window.matchMedia?.('(max-width: 1199px)');\r\n if (!mq) return;\r\n const apply = () => setIsNarrow(mq.matches);\r\n apply();\r\n mq.addEventListener?.('change', apply);\r\n return () => mq.removeEventListener?.('change', apply);\r\n }, []);\r\n\r\n const chooseLanguage = async (lang: string) => {\r\n const v = lang.trim();\r\n if (!v) {\r\n try { client.setShopperLanguage?.(''); } catch { }\r\n setShopperLanguageState('');\r\n setPendingLanguage('');\r\n setPreloadedStrings(null);\r\n return;\r\n }\r\n setPendingLanguage(v);\r\n setLangSwitching(true);\r\n\r\n const isTargetEn = v.toLowerCase() === 'english' || v.toLowerCase() === 'en';\r\n if (isTargetEn) {\r\n setPreloadedStrings(DEFAULT_UI_STRINGS);\r\n try { client.setShopperLanguage?.(v); } catch { }\r\n setShopperLanguageState(v);\r\n setPendingLanguage('');\r\n setLangSwitching(false);\r\n setJustCompleted(false);\r\n return;\r\n }\r\n\r\n const animStart = Date.now();\r\n const MIN_ANIM_MS = 1200;\r\n\r\n try {\r\n const cached = client.getCachedUIStrings?.(v, ONBOARDING_UI_STRINGS) ?? client.getCachedUIStrings?.(v, DEFAULT_UI_STRINGS);\r\n if (cached?.strings && Object.keys(cached.strings).length > 0) {\r\n setPreloadedStrings(cached.strings);\r\n if (cached.font) {\r\n await preloadScriptFont(cached.font, 800);\r\n }\r\n } else {\r\n const fetchP = client.getUIStrings?.(v, ONBOARDING_UI_STRINGS);\r\n const res = await Promise.race([\r\n fetchP,\r\n new Promise<null>((resolve) => setTimeout(() => resolve(null), 8000)),\r\n ]);\r\n if (res?.font) {\r\n await preloadScriptFont(res.font, 1200);\r\n }\r\n if (res?.strings && Object.keys(res.strings).length > 0) {\r\n setPreloadedStrings(res.strings);\r\n }\r\n }\r\n } catch { }\r\n\r\n const elapsed = Date.now() - animStart;\r\n if (elapsed < MIN_ANIM_MS) {\r\n await new Promise((r) => setTimeout(r, MIN_ANIM_MS - elapsed));\r\n }\r\n\r\n try { client.setShopperLanguage?.(v); } catch { }\r\n setShopperLanguageState(v);\r\n setPendingLanguage('');\r\n setLangSwitching(false);\r\n setJustCompleted(false);\r\n\r\n try {\r\n client.getUIStrings?.(v, DEFAULT_UI_STRINGS)?.catch?.(() => {});\r\n } catch { }\r\n };\r\n\r\n\r\n const chooseEntityLang = (mode: 'translated' | 'original') => {\r\n try { client.setEntityLanguageMode?.(mode); } catch { }\r\n setEntityLangPrefState(mode);\r\n if (termsAgreed) {\r\n setJustCompleted(true);\r\n }\r\n };\r\n\r\n const agreeTerms = () => {\r\n try {\r\n localStorage.setItem('akropolys_terms_agreed', 'true');\r\n } catch { /* noop */ }\r\n setTermsAgreed(true);\r\n setJustCompleted(true);\r\n };\r\n\r\n const activePlaceholder =\r\n isLangPreparing ? getLoadingMeta(pendingLanguage || shopperLanguage).preparing\r\n : awaitingLang ? t('langPlaceholder')\r\n : awaitingName ? t('namePlaceholder')\r\n : awaitingEntityLang ? t('entityLangPlaceholder')\r\n : awaitingConsent ? t('termsPlaceholder')\r\n : (placeholder === 'Ask me anything…' ? t('defaultPlaceholder') : placeholder);\r\n\r\n const activeChips = !chips || chips === DEFAULT_CHIPS ? [] : (Array.isArray(chips) ? chips : []);\r\n const onboardingMood: KikuState =\r\n awaitingLang ? 'curious'\r\n : awaitingName ? 'welcoming'\r\n : awaitingEntityLang ? 'guiding'\r\n : awaitingConsent ? 'focused'\r\n : 'happy';\r\n\r\n const [currentTheme, setCurrentTheme] = useState<ThemeId>(() => initialTheme(theme));\r\n\r\n const [theming, setTheming] = useState(false);\r\n const themingTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n useEffect(() => () => { if (themingTimer.current) clearTimeout(themingTimer.current); }, []);\r\n\r\n // When the doodle bloom from the dock reaches the chat, its content nudges up and away, then settles.\r\n const nudgeRef = useRef<Animation | null>(null);\r\n const nudgeContent = () => {\r\n const msgs = msgsContainerRef.current as HTMLElement | null;\r\n if (!msgs?.animate || window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return;\r\n const away = isRTL ? -3 : 3;\r\n nudgeRef.current?.cancel(); // two nudges on one element fight each other and read as a shake\r\n nudgeRef.current = msgs.animate(\r\n [\r\n { transform: 'translate(0, 0)', easing: 'cubic-bezier(.3, 0, .2, 1)' },\r\n { offset: 0.26, transform: `translate(${away}px, -6px)`, easing: 'cubic-bezier(.45, 0, .35, 1)' },\r\n { offset: 0.52, transform: `translate(${-away * 0.3}px, 1.6px)`, easing: 'cubic-bezier(.45, 0, .35, 1)' },\r\n { offset: 0.74, transform: `translate(${away * 0.1}px, -0.6px)`, easing: 'cubic-bezier(.45, 0, .55, 1)' },\r\n { transform: 'translate(0, 0)' },\r\n ],\r\n { duration: 1100, delay: 380 },\r\n );\r\n };\r\n // The first bloom waits for the greeting or messages to appear, which can lag the panel on a first open.\r\n // Text that has only just arrived must not nudge: it reads as landing in the wrong place.\r\n const openBloomedRef = useRef(false);\r\n useEffect(() => {\r\n if (openBloomedRef.current) return;\r\n const box = msgsContainerRef.current as HTMLElement | null;\r\n if (!box) {\r\n bloomDoodles();\r\n return;\r\n }\r\n let done = false;\r\n const shown = () => box.querySelector('.hsk-cb-hello-wrap, .hsk-cb-msg-group');\r\n const fire = () => {\r\n if (done) return;\r\n done = true;\r\n openBloomedRef.current = true;\r\n observer.disconnect();\r\n clearTimeout(limit);\r\n bloomDoodles();\r\n };\r\n const observer = new MutationObserver(() => { if (shown()) fire(); });\r\n observer.observe(box, { childList: true, subtree: true });\r\n const limit = window.setTimeout(fire, 2000);\r\n if (shown()) fire();\r\n return () => {\r\n done = true;\r\n observer.disconnect();\r\n clearTimeout(limit);\r\n };\r\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\r\n\r\n const handleToggleTheme = (next: ThemeId, alsoCloseMenu = false) => {\r\n setTheming(true);\r\n if (themingTimer.current) clearTimeout(themingTimer.current);\r\n themingTimer.current = setTimeout(() => setTheming(false), 420);\r\n setCurrentTheme(next);\r\n nudgeContent();\r\n if (alsoCloseMenu) closeThemeMenuNow();\r\n try { localStorage.setItem('akropolys_theme', next); } catch { /* noop */ }\r\n };\r\n\r\n const { vars: customStyles } = resolveTheme(theme);\r\n const hskThemeAttr = currentTheme;\r\n useHostFontFace(theme);\r\n\r\n const handleSendRef = useRef<(text: string) => void>(() => {});\r\n const textareaRef = useRef<HTMLTextAreaElement>(null);\r\n\r\n const handleSend = async (text?: string, extraAttachments?: ChatAttachment[], forcedIntent?: string, captureTargets?: CaptureTarget[]) => {\r\n const raw = (text ?? input).trim();\r\n const picked = extraAttachments ?? attachments;\r\n if ((!raw && picked.length === 0) || !chromeReady || queuedMessage) return;\r\n\r\n chime('send');\r\n\r\n if (awaitingName) {\r\n if (!raw) return;\r\n const name = extractName(raw) || raw.slice(0, 40);\r\n try { client.setShopperName?.(name); } catch { }\r\n setShopperNameState(name);\r\n setInput('');\r\n return;\r\n }\r\n if (awaitingLang) {\r\n if (!raw || langSwitching) return;\r\n setInput('');\r\n void chooseLanguage(raw);\r\n return;\r\n }\r\n if (inputLocked) {\r\n setInput('');\r\n return;\r\n }\r\n\r\n setShowKikuPicker(false);\r\n setShowAtPicker(false);\r\n setInput('');\r\n setAttachments([]);\r\n // A photo sent before its copy is ready waits for it here, out of sight.\r\n const toSend: ChatAttachment[] = (await Promise.all(picked.map(async ({ thumb, ...a }: ComposerAttachment) => {\r\n const data = a.data || (thumb ? await photoReady.current.get(thumb)?.catch(() => '') : '') || '';\r\n if (thumb) URL.revokeObjectURL(thumb);\r\n return { ...a, data };\r\n }))).filter(a => a.data);\r\n const queryToSend = raw || (toSend.some(a => a.type === 'image') ? 'Analyze this image' : 'What is this?');\r\n await send(queryToSend, raw, toSend.length > 0 ? toSend : undefined, forcedIntent, captureTargets);\r\n };\r\n\r\n const [retrying, setRetrying] = useState(false);\r\n\r\n const handleRetryMessage = useCallback(async (msg?: ChatMessage) => {\r\n const target = (msg && msg.role === 'user') ? msg : [...messages].reverse().find(m => m.role === 'user');\r\n if (!target?.content) return;\r\n setRetrying(true);\r\n try {\r\n await handleSend(target.content);\r\n } finally {\r\n setRetrying(false);\r\n }\r\n }, [messages, handleSend]);\r\n\r\n const handleEditMessage = useCallback((msg: ChatMessage) => {\r\n if (!msg?.content) return;\r\n setInput(msg.content);\r\n setTimeout(() => {\r\n if (textareaRef.current) {\r\n textareaRef.current.focus();\r\n const len = msg.content.length;\r\n try {\r\n textareaRef.current.setSelectionRange(len, len);\r\n } catch {}\r\n }\r\n }, 50);\r\n }, [setInput, textareaRef]);\r\n\r\n const retryLastMessage = useCallback(async () => {\r\n await handleRetryMessage();\r\n }, [handleRetryMessage]);\r\n\r\n const {\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 } = useKikuKey(lastAction, retryLastMessage);\r\n\r\n // The key rides in the address fragment, which never leaves the browser; MiMi takes it and clears it.\r\n const openMimi = useCallback(() => {\r\n const key = client?.getKikuKey?.();\r\n if (key) window.open(`https://mimi.akropolys.cloud/#k=${encodeURIComponent(key)}`, '_blank', 'noopener');\r\n }, [client]);\r\n\r\n const [tapbackTarget, setTapbackTarget] = useState<{\r\n msg: any;\r\n rect: { top: number; left: number; width: number; height: number };\r\n isUser: boolean;\r\n el?: HTMLElement;\r\n } | null>(null);\r\n\r\n const handleLongPressMessage = useCallback((\r\n msg: any,\r\n rect: { top: number; left: number; width: number; height: number },\r\n isUser: boolean,\r\n el?: HTMLElement\r\n ) => {\r\n setTapbackTarget({ msg, rect, isUser, el });\r\n }, []);\r\n\r\n const handlePinMessage = useCallback(async (msg: any) => {\r\n // Pinning an earlier pin must not stack the command onto itself.\r\n const text = (msg.content || '').replace(/^(@kiku pin\\s*)+/i, '');\r\n const snippet = text.slice(0, 50).replace(/\\n+/g, ' ');\r\n const display = `@kiku pin ${snippet}`;\r\n await send(text || 'pin message', display, undefined, 'capture');\r\n }, [send]);\r\n\r\n const {\r\n handleKikuCapture,\r\n handleKikuCaptureAll,\r\n handleKikuViewHistory,\r\n handleKikuDelete,\r\n } = useChatCommands({\r\n attachments,\r\n setAttachments,\r\n setInput,\r\n send,\r\n t,\r\n });\r\n\r\n const {\r\n voiceMode,\r\n voicePhase,\r\n voiceConnecting,\r\n voiceError,\r\n setVoiceError,\r\n voiceMuted,\r\n setVoiceMuted,\r\n voiceSecondsLeft,\r\n voiceBlocked,\r\n liveVoiceName,\r\n chooseVoice,\r\n canConverse,\r\n startVoice,\r\n stopVoice,\r\n voice,\r\n live,\r\n earlier,\r\n newVoiceChat,\r\n attachPhoto,\r\n } = useVoiceController({\r\n voiceLang,\r\n speechLang,\r\n shopperLanguage,\r\n ttsVoice,\r\n messages,\r\n handleSendUtterance: (text) => handleSendRef.current(text),\r\n appendSpokenExchange,\r\n });\r\n\r\n const panelRef = useRef<HTMLDivElement>(null);\r\n const [themeMenuOpen, setThemeMenuOpen] = useState(false);\r\n // The grid marks the theme it opened on; a pick just closes it rather than moving the mark first.\r\n const [themeMenuMark, setThemeMenuMark] = useState<ThemeId | null>(null);\r\n const themeMenuRef = useRef<HTMLDivElement>(null);\r\n const mobileThemeRef = useRef<HTMLDivElement>(null);\r\n\r\n const messageRefs = useRef<(HTMLDivElement | null)[]>([]);\r\n const overlayRef = useRef<HTMLDivElement>(null);\r\n const gooId = `hsk-goo-${useId()}`;\r\n\r\n const {\r\n closing: themeMenuClosing,\r\n requestClose: closeThemeMenu,\r\n closeNow: closeThemeMenuNow,\r\n } = useDelayedClose(isNarrow ? TRAY_EXIT_CEILING_MS : THEME_MENU_EXIT_MS, () => setThemeMenuOpen(false));\r\n\r\n useEffect(() => {\r\n if (!themeMenuOpen) return;\r\n const handleOutside = (e: MouseEvent | TouchEvent) => {\r\n const path = (e.composedPath ? e.composedPath() : []) as EventTarget[];\r\n const isInsideRail = themeMenuRef.current && (path.includes(themeMenuRef.current) || themeMenuRef.current.contains(e.target as Node));\r\n const isInsideMobile = mobileThemeRef.current && (path.includes(mobileThemeRef.current) || mobileThemeRef.current.contains(e.target as Node));\r\n const targetEl = e.target as HTMLElement | null;\r\n const isInsideTopbarMark = targetEl?.closest?.('.hsk-cb-topbar-mark');\r\n const isInsideOoze = targetEl?.closest?.('.hsk-cb-topbar-ooze-menu') || path.some((el: any) => el?.classList?.contains?.('hsk-cb-topbar-ooze-menu'));\r\n\r\n if (isInsideRail || isInsideMobile || isInsideTopbarMark || isInsideOoze) {\r\n return;\r\n }\r\n closeThemeMenu();\r\n };\r\n document.addEventListener('mousedown', handleOutside);\r\n document.addEventListener('touchstart', handleOutside, { passive: true });\r\n return () => {\r\n document.removeEventListener('mousedown', handleOutside);\r\n document.removeEventListener('touchstart', handleOutside);\r\n };\r\n }, [themeMenuOpen]);\r\n\r\n const {\r\n msgsContainerRef,\r\n spacerRef,\r\n lastExternalScrollRef,\r\n showJumpToBottom,\r\n scrollProgress,\r\n activeMsgIdx,\r\n unreadBelow,\r\n jumpToMessage,\r\n jumpToBottom,\r\n } = useChatScroll({ messages, loading, streaming, messageRefs });\r\n\r\n const { closing: overlayClosing, requestClose: exitOverlay } = useDelayedClose(OVERLAY_EXIT_MS, onClose);\r\n // end=true tells the team the visitor is done; otherwise the request is kept for when they come back.\r\n const closeNow = useCallback((end: boolean) => {\r\n if (end) leaveHuman();\r\n setThemeMenuOpen(false);\r\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) onClose();\r\n else exitOverlay();\r\n }, [exitOverlay, onClose, leaveHuman]);\r\n // While a person is on the request, the visitor chooses whether to keep it or end it.\r\n const requestClose = useCallback(() => {\r\n if (leaveAsk) nudgeLeave();\r\n else if (humanPending) setLeaveAsk('close');\r\n else closeNow(false);\r\n }, [humanPending, closeNow, leaveAsk, nudgeLeave]);\r\n\r\n useDragToDismiss({\r\n panel: useCallback(() => panelRef.current, []),\r\n scroller: useCallback(() => msgsContainerRef.current, []),\r\n onDismiss: onClose,\r\n quiescent: useCallback(() => performance.now() - lastExternalScrollRef.current > 90, []),\r\n });\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\r\n const prevOverflow = document.body.style.overflow;\r\n const prevPadding = document.body.style.paddingRight;\r\n\r\n if (scrollbarWidth > 0) {\r\n const computedPadding = parseFloat(window.getComputedStyle(document.body).paddingRight) || 0;\r\n document.body.style.paddingRight = `${computedPadding + scrollbarWidth}px`;\r\n document.documentElement.style.setProperty('--hsk-scrollbar-width', `${scrollbarWidth}px`);\r\n }\r\n\r\n document.body.style.overflow = 'hidden';\r\n\r\n return () => {\r\n document.body.style.overflow = prevOverflow;\r\n document.body.style.paddingRight = prevPadding;\r\n document.documentElement.style.removeProperty('--hsk-scrollbar-width');\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n const vv = window.visualViewport;\r\n if (!vv) return;\r\n const root = document.documentElement;\r\n const apply = () => { root.style.setProperty('--hsk-vvh', `${vv.height}px`); };\r\n apply();\r\n vv.addEventListener('resize', apply);\r\n vv.addEventListener('scroll', apply);\r\n return () => {\r\n vv.removeEventListener('resize', apply);\r\n vv.removeEventListener('scroll', apply);\r\n root.style.removeProperty('--hsk-vvh');\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n const h = (e: KeyboardEvent) => {\r\n if (e.key !== 'Escape') return;\r\n if (lightboxData) { setLightboxData(null); return; }\r\n requestClose();\r\n };\r\n document.addEventListener('keydown', h);\r\n return () => document.removeEventListener('keydown', h);\r\n }, [lightboxData, requestClose]);\r\n\r\n const resetNow = useCallback((end: boolean) => {\r\n if (end) leaveHuman();\r\n reset();\r\n setKeyPhase('idle');\r\n }, [reset, setKeyPhase, leaveHuman]);\r\n const handleReset = useCallback(() => {\r\n if (leaveAsk) nudgeLeave();\r\n else if (humanPending) setLeaveAsk('reset');\r\n else resetNow(false);\r\n }, [humanPending, resetNow, leaveAsk, nudgeLeave]);\r\n\r\n const handleSourceClick = (src: ChatSource) => {\r\n onSelectSource?.(src);\r\n const lastAssistant = [...messages].reverse().find(m => m.role === 'assistant');\r\n if (lastAssistant && lastAssistant.content.trim().endsWith('?')) {\r\n send(t('cardClickAnswer', { name: src.name }));\r\n return;\r\n }\r\n send(t('cardClickQuery', { name: src.name, details: detailsText(detailsOf(src, cardFields)) }));\r\n };\r\n\r\n const handleSelectExtension = (ext: string) => {\r\n setInput(ext + ' ');\r\n setShowAtPicker(false);\r\n setShowKikuPicker(true);\r\n if (textareaRef.current) textareaRef.current.focus();\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\r\n if (e.key === 'Escape' && showKikuPicker) { e.preventDefault(); setShowKikuPicker(false); return; }\r\n if (e.key === 'Escape' && showAtPicker) { e.preventDefault(); setShowAtPicker(false); return; }\r\n if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { e.preventDefault(); handleSend(); }\r\n };\r\n\r\n const composerHeight = useRef(28);\r\n const singleRowFieldWidth = useRef(280);\r\n const measureCanvasRef = useRef<HTMLCanvasElement | null>(null);\r\n\r\n const getTextWidth = (text: string, font: string): number => {\r\n try {\r\n if (!measureCanvasRef.current && typeof document !== 'undefined') {\r\n measureCanvasRef.current = document.createElement('canvas');\r\n }\r\n const ctx = measureCanvasRef.current?.getContext('2d');\r\n if (!ctx) return text.length * 8.5;\r\n ctx.font = font;\r\n return ctx.measureText(text).width;\r\n } catch {\r\n return text.length * 8.5;\r\n }\r\n };\r\n\r\n const autoGrow = (el: HTMLTextAreaElement) => {\r\n const box = el.closest('.hsk-cb-input-box') as HTMLElement | null;\r\n if (!box) return;\r\n\r\n const val = el.value;\r\n const isCurrentlyExpanded = box.dataset.expanded === 'true';\r\n\r\n if (!isCurrentlyExpanded && el.clientWidth > 50) {\r\n singleRowFieldWidth.current = el.clientWidth;\r\n }\r\n\r\n const cs = window.getComputedStyle(el);\r\n const font = cs.font || `${cs.fontSize || '16px'} ${cs.fontFamily || 'Geist, sans-serif'}`;\r\n const textWidth = getTextWidth(val, font);\r\n\r\n const threshold = Math.max(120, singleRowFieldWidth.current - 14);\r\n const hasNewline = val.includes('\\n');\r\n const shouldExpand = Boolean(val && (hasNewline || textWidth > threshold));\r\n\r\n if (box.dataset.expanded !== (shouldExpand ? 'true' : 'false')) {\r\n box.dataset.expanded = shouldExpand ? 'true' : 'false';\r\n }\r\n\r\n if (!val) {\r\n composerHeight.current = 28;\r\n el.style.height = '';\r\n return;\r\n }\r\n\r\n if (!shouldExpand) {\r\n composerHeight.current = 28;\r\n el.style.height = '';\r\n return;\r\n }\r\n\r\n el.style.height = 'auto';\r\n const targetHeight = Math.max(28, Math.min(el.scrollHeight, 140));\r\n composerHeight.current = targetHeight;\r\n el.style.height = `${targetHeight}px`;\r\n };\r\n\r\n useEffect(() => {\r\n if (textareaRef.current) autoGrow(textareaRef.current);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [input]);\r\n\r\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n const val = e.target.value;\r\n setInput(val);\r\n if (voiceError) setVoiceError('');\r\n const trimmed = val.trim();\r\n setShowAtPicker(trimmed === '@');\r\n setShowKikuPicker(/^@kiku\\s*$/i.test(trimmed));\r\n };\r\n\r\n useEffect(() => {\r\n handleSendRef.current = (text: string) => { void handleSend(text); };\r\n });\r\n\r\n const handleImageFiles = async (files: FileList | null) => {\r\n if (!files || files.length === 0) return;\r\n const list = Array.from(files);\r\n for (const file of list) {\r\n if (!file.type.startsWith('image/')) continue;\r\n const thumb = URL.createObjectURL(file);\r\n const ready = downscaleImage(file);\r\n photoReady.current.set(thumb, ready);\r\n setAttachments(prev => [...prev, { type: 'image', data: '', thumb }]);\r\n ready\r\n .then(data => setAttachments(prev => prev.map(a => (a.thumb === thumb ? { ...a, data } : a))))\r\n .catch(() => setAttachments(prev => prev.filter(a => a.thumb !== thumb)))\r\n .finally(() => photoReady.current.delete(thumb));\r\n }\r\n };\r\n\r\n const removeAttachment = (idx: number) => {\r\n setAttachments(prev => {\r\n const gone = prev[idx]?.thumb;\r\n if (gone) URL.revokeObjectURL(gone);\r\n return prev.filter((_, i) => i !== idx);\r\n });\r\n };\r\n\r\n const hasTranslucentBackdrop = backdropColor && (backdropColor.includes('rgba') || backdropColor.includes('hsla') || backdropColor === 'transparent');\r\n const backdropFilterStyle = (backdropBlur || hasTranslucentBackdrop) ? {\r\n backdropFilter: `blur(${typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur || '20px')})`,\r\n WebkitBackdropFilter: `blur(${typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur || '20px')})`,\r\n } : {};\r\n const wasStreaming = useRef(false);\r\n useEffect(() => {\r\n if (wasStreaming.current && !streaming) {\r\n const last = messages[messages.length - 1];\r\n if (last && last.role !== 'user') chime('reply');\r\n }\r\n wasStreaming.current = streaming;\r\n }, [streaming, messages]);\r\n\r\n const halted = (stopped || interrupted) && !loading && !streaming;\r\n\r\n const tail = messages[messages.length - 1];\r\n const pacedContent = usePacedText(tail?.role === 'assistant' ? tail.content ?? '' : '');\r\n const draining = tail?.role === 'assistant' && pacedContent.length < (tail.content?.length ?? 0);\r\n const revealing = streaming || draining;\r\n\r\n const displayMessages = React.useMemo(() => {\r\n const inFlight = loading || streaming;\r\n const kept = messages.filter((m, i) => {\r\n if (m.role !== 'assistant') return true;\r\n const isLastMsg = i === messages.length - 1;\r\n if (isLastMsg && inFlight) return true;\r\n const hasBody = !!m.content || !!m.visualization || m.visualizing ||\r\n (m.knowledgeImages?.length ?? 0) > 0 || (m.referencedIds?.length ?? 0) > 0 || isTeamNote(m.statusStage);\r\n return hasBody;\r\n });\r\n const last = kept.length - 1;\r\n if (last < 0 || kept[last].role !== 'assistant') return kept;\r\n if (kept[last] !== messages[messages.length - 1]) return kept;\r\n // stream end is not reveal end; dropping paced content here prints the rest in one frame\r\n const draining = pacedContent.length < (kept[last].content?.length ?? 0);\r\n if (!inFlight && !draining) return kept;\r\n return kept.map((m, i) => (i === last ? { ...m, content: pacedContent } : m));\r\n }, [messages, loading, streaming, pacedContent]);\r\n\r\n const timelineItems = React.useMemo(() => {\r\n const items: Array<{ idx: number; text: string }> = [];\r\n displayMessages.forEach((m, idx) => {\r\n if (m.role === 'user' && !!m.content.trim()) {\r\n const clean = m.content.replace(/^@kiku\\s*/i, '').replace(/\\s+/g, ' ').trim();\r\n items.push({\r\n idx,\r\n text: clean.length > 28 ? clean.slice(0, 27).trimEnd() + '…' : clean,\r\n });\r\n }\r\n });\r\n return items;\r\n }, [displayMessages]);\r\n\r\n const haltedEmpty =\r\n halted && displayMessages[displayMessages.length - 1]?.role !== 'assistant';\r\n\r\n const mountTimeRef = useRef(Date.now());\r\n useEffect(() => {\r\n mountTimeRef.current = Date.now();\r\n }, []);\r\n\r\n return (\r\n <UIStringsContext.Provider value={t}>\r\n <div\r\n ref={overlayRef}\r\n className={cn(\"hsk-cb-overlay\", origin && \"hsk-cb-overlay--grows\", overlayClosing && \"hsk-cb-overlay--closing\", classNames.overlay)}\r\n onPointerDown={e => {\r\n primeChimes();\r\n if (e.target === e.currentTarget) {\r\n (overlayRef.current as any)._ptrDown = true;\r\n }\r\n }}\r\n onClick={e => {\r\n if (e.target === e.currentTarget && (overlayRef.current as any)?._ptrDown && Date.now() - mountTimeRef.current > 200) {\r\n requestClose();\r\n }\r\n if (overlayRef.current) (overlayRef.current as any)._ptrDown = false;\r\n }}\r\n data-hsk-theme={hskThemeAttr}\r\n data-hsk-theming={theming ? '' : undefined}\r\n style={{\r\n ...(backdropFilterStyle),\r\n ...(backdropColor ? { background: backdropColor } : {}),\r\n ...(origin ? {\r\n '--hsk-ox': `${origin.x}px`,\r\n '--hsk-oy': `${origin.y}px`,\r\n } as React.CSSProperties : {}),\r\n ...customStyles,\r\n }}\r\n >\r\n <div\r\n ref={panelRef}\r\n className={cn(\"hsk-cb-panel\", classNames.panel)}\r\n dir={isRTL ? 'rtl' : 'ltr'}\r\n lang={speechLang || undefined}\r\n data-script={isNonLatin ? 'nonlatin' : 'latin'}\r\n data-host-font={hostFontCovers ? 'covers' : 'gap'}\r\n data-nastaliq={(scriptFont?.family === 'Noto Nastaliq Urdu' || shopperLanguage?.toLowerCase() === 'urdu' || shopperLanguage?.toLowerCase() === 'ur' || shopperLanguage === 'اردو') ? 'true' : undefined}\r\n style={fontStack ? ({ '--hsk-font': fontStack } as React.CSSProperties) : undefined}\r\n onClick={e => {\r\n e.stopPropagation();\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === 'IMG' && (target.classList.contains('hsk-markdown-img') || target.classList.contains('hsk-cb-user-img-thumb'))) {\r\n const src = (target as HTMLImageElement).src;\r\n if (src) handleOpenLightbox(src);\r\n }\r\n }}\r\n >\r\n <LightboxModal\r\n src={lightboxData?.src}\r\n images={lightboxData?.images}\r\n initialIndex={lightboxData?.initialIndex}\r\n title={lightboxData?.title}\r\n onClose={() => setLightboxData(null)}\r\n />\r\n\r\n {markupSrc && (\r\n <div className=\"hsk-markup-overlay\">\r\n <MarkupEditor\r\n src={markupSrc}\r\n t={t as (key: string, vars?: Record<string, string>) => string}\r\n onCancel={() => setMarkupSrc(null)}\r\n onSend={(dataUrl, instruction, marks, preview) => {\r\n setMarkupSrc(null);\r\n handleSend(\r\n instruction,\r\n [{ type: 'image', data: dataUrl, annotated: true, marks, instructed: true, preview }],\r\n );\r\n }}\r\n />\r\n </div>\r\n )}\r\n\r\n <div className=\"hsk-cb-main\">\r\n <KikuDoodles seed={(client as any)?.api?.siteId ?? ''} theme={hskThemeAttr} dir={isRTL ? 'rtl' : 'ltr'} waitForContent />\r\n\r\n <ChatTopbar\r\n title={title}\r\n logo={logo}\r\n hasMessages={messages.length > 0}\r\n avatarState={streaming ? 'speaking' : loading ? 'thinking' : 'idle'}\r\n unread={unreadBelow}\r\n awayFromBottom={showJumpToBottom}\r\n themeMenuOpen={themeMenuOpen}\r\n themeMenuClosing={themeMenuClosing}\r\n onThemeMenuClosed={closeThemeMenuNow}\r\n isNarrow={isNarrow}\r\n currentTheme={currentTheme}\r\n onJumpToLatest={jumpToBottom}\r\n onReset={handleReset}\r\n onClose={requestClose}\r\n onToggleThemeMenu={() => (themeMenuOpen ? closeThemeMenu() : setThemeMenuOpen(true))}\r\n onSelectTheme={(t) => { handleToggleTheme(t, true); }}\r\n themeAttr={hskThemeAttr}\r\n />\r\n\r\n <div className=\"hsk-cb-msgs\" ref={msgsContainerRef as any}>\r\n {displayMessages.length === 0 ? (\r\n <OnboardingView\r\n theme={hskThemeAttr}\r\n inOnboarding={inOnboarding}\r\n justCompleted={justCompleted}\r\n onboardingMood={onboardingMood}\r\n awaitingLang={awaitingLang}\r\n awaitingName={awaitingName}\r\n awaitingEntityLang={awaitingEntityLang}\r\n awaitingConsent={awaitingConsent}\r\n termsAgreed={termsAgreed}\r\n shopperLanguage={shopperLanguage}\r\n pendingLanguage={pendingLanguage}\r\n shopperName={shopperName}\r\n entityLangPref={entityLangPref}\r\n chromeReady={chromeReady && baseFontReady}\r\n activeChips={activeChips}\r\n speechLang={speechLang}\r\n t={t}\r\n tNode={tNode}\r\n chooseLanguage={chooseLanguage}\r\n langSwitching={langSwitching}\r\n isLangPreparing={isLangPreparing}\r\n onPrewarmLanguage={(lang) => warmLanguage(client, lang, DEFAULT_UI_STRINGS)}\r\n chooseEntityLang={chooseEntityLang}\r\n agreeTerms={agreeTerms}\r\n handleSend={handleSend}\r\n />\r\n ) : (\r\n <ChatMessages\r\n doodleTheme={hskThemeAttr}\r\n displayMessages={displayMessages}\r\n messageRefs={messageRefs}\r\n isNarrow={isNarrow}\r\n loading={loading}\r\n streaming={revealing}\r\n sources={sources}\r\n referencedIds={referencedIds}\r\n discussedSources={discussedSources}\r\n lastIntent={lastIntent}\r\n lastAction={lastAction}\r\n stopped={stopped}\r\n interrupted={interrupted}\r\n halted={halted}\r\n haltedEmpty={haltedEmpty}\r\n error={error}\r\n errorCode={errorCode}\r\n keyPhase={keyPhase}\r\n keyInput={keyInput}\r\n setKeyInput={setKeyInput}\r\n mintedKey={mintedKey}\r\n setMintedKey={setMintedKey}\r\n setMintedPub={setMintedPub}\r\n minting={minting}\r\n copied={copied}\r\n keyCountdown={keyCountdown}\r\n handleUseExistingKey={handleUseExistingKey}\r\n handleCreateKey={handleCreateKey}\r\n copyValue={copyValue}\r\n queuedMessage={queuedMessage}\r\n sendQueuedNow={sendQueuedNow}\r\n setLightboxSrc={handleOpenLightbox}\r\n setMarkupSrc={setMarkupSrc}\r\n handleSend={handleSend}\r\n handleSourceClick={handleSourceClick}\r\n onRetry={handleRetryMessage}\r\n onEdit={handleEditMessage}\r\n onLongPress={handleLongPressMessage}\r\n retrying={retrying}\r\n continueGenerating={continueGenerating}\r\n t={t}\r\n spacerRef={spacerRef}\r\n vizState={vizState}\r\n setVizState={setVizState}\r\n messages={messages}\r\n />\r\n )}\r\n </div>\r\n\r\n {!composerHidden && (\r\n <div\r\n className={cn(\r\n 'hsk-cb-composer-wrapper',\r\n composerExiting && 'hsk-composer-exit-up',\r\n composerRevealing && 'hsk-composer-reveal',\r\n )}\r\n >\r\n <ChatComposer\r\n notice={leaveAsk && (\r\n <div className=\"hsk-cb-leave\" role=\"alertdialog\" ref={leaveRef}>\r\n <span>{t('leaveHumanWarning')}</span>\r\n <button type=\"button\" className=\"hsk-cb-leave-btn\" onClick={() => setLeaveAsk(null)}>{t('leaveHumanStay')}</button>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-leave-btn hsk-cb-leave-btn--end\"\r\n onClick={() => { const kind = leaveAsk; setLeaveAsk(null); if (kind === 'reset') resetNow(true); else closeNow(true); }}\r\n >\r\n {t('leaveHumanConfirm')}\r\n </button>\r\n </div>\r\n )}\r\n gooId={gooId}\r\n input={input}\r\n setInput={setInput}\r\n showKikuPicker={showKikuPicker}\r\n setShowKikuPicker={setShowKikuPicker}\r\n showAtPicker={showAtPicker}\r\n setShowAtPicker={setShowAtPicker}\r\n captureAllowed={captureAllowed}\r\n discussedSources={discussedSources}\r\n handleSelectExtension={handleSelectExtension}\r\n handleKikuCapture={handleKikuCapture}\r\n handleKikuCaptureAll={handleKikuCaptureAll}\r\n handleKikuViewHistory={handleKikuViewHistory}\r\n handleKikuDelete={handleKikuDelete}\r\n attachments={attachments}\r\n removeAttachment={removeAttachment}\r\n chromeLoading={!chromeReady}\r\n imageInputRef={imageInputRef}\r\n handleImageFiles={handleImageFiles}\r\n enableVision={enableVision && !inOnboarding}\r\n enableVoice={enableVoice && !inOnboarding}\r\n canConverse={canConverse}\r\n startVoice={startVoice}\r\n inputLocked={inputLocked}\r\n voiceBlocked={voiceBlocked}\r\n textareaRef={textareaRef}\r\n classNames={classNames}\r\n handleInput={handleInput}\r\n handleKeyDown={handleKeyDown}\r\n voice={voice}\r\n voicePhase={voicePhase}\r\n activePlaceholder={activePlaceholder}\r\n loading={loading}\r\n streaming={streaming}\r\n stop={stop}\r\n handleSend={handleSend}\r\n voiceError={voiceError}\r\n setVoiceError={setVoiceError}\r\n langSwitching={langSwitching || isLangPreparing}\r\n t={t}\r\n onOpenMimi={client?.getKikuKey?.() ? openMimi : undefined}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n\r\n {voiceMode !== 'converse' && (\r\n <ConversationTimeline\r\n items={timelineItems}\r\n activeIdx={activeMsgIdx}\r\n progress={scrollProgress}\r\n onJump={jumpToMessage}\r\n side={isRTL ? 'left' : 'right'}\r\n />\r\n )}\r\n\r\n\r\n <div className={cn(\"hsk-cb-kiku-id-rail\", isRTL ? \"hsk-cb-kiku-id-rail--right\" : \"hsk-cb-kiku-id-rail--left\")}>\r\n <div className=\"hsk-cb-dock-frost\" aria-hidden=\"true\" />\r\n <SoundToggle />\r\n\r\n {/* One pill that grows into the theme grid and shrinks back, like the voices pill. */}\r\n <div className={cn(\"hsk-cb-theme-squircle-wrap\", themeMenuOpen && !themeMenuClosing && \"is-open\")} ref={themeMenuRef}>\r\n <div\r\n className=\"hsk-cb-theme-2x2-grid\"\r\n role=\"dialog\"\r\n aria-label=\"Theme selector\"\r\n ref={(el) => { if (el) el.inert = !themeMenuOpen || themeMenuClosing; }}\r\n >\r\n {THEMES.map(({ id, label, Icon }) => (\r\n <button\r\n key={id}\r\n type=\"button\"\r\n className={cn(\"hsk-cb-theme-grid-item\", (themeMenuMark ?? currentTheme) === id && \"is-active\")}\r\n onClick={(e) => { e.stopPropagation(); handleToggleTheme(id, true); }}\r\n >\r\n <Icon />\r\n <span>{label}</span>\r\n </button>\r\n ))}\r\n </div>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-theme-squircle-trigger\"\r\n onClick={() => {\r\n if (themeMenuOpen) { closeThemeMenuNow(); return; }\r\n setThemeMenuMark(currentTheme);\r\n setThemeMenuOpen(true);\r\n }}\r\n aria-label=\"Themes\"\r\n aria-expanded={themeMenuOpen}\r\n >\r\n <span className=\"hsk-cb-theme-trigger-icon\">\r\n {React.createElement(themeDef(currentTheme).Icon)}\r\n </span>\r\n <span className=\"hsk-cb-theme-trigger-label\">\r\n {themeDef(currentTheme).label}\r\n </span>\r\n </button>\r\n </div>\r\n\r\n {/* MiMi is where a visitor reads their conversations with a team; it opens already unlocked. */}\r\n {client?.getKikuKey?.() && (\r\n <button type=\"button\" className=\"hsk-cb-sound-pill\" onClick={openMimi}>\r\n <MessageIcon size={13} />\r\n <span>MiMi</span>\r\n </button>\r\n )}\r\n </div>\r\n\r\n {voiceMode === 'converse' && (\r\n <VoiceOverlay\r\n siteId={(client as any)?.api?.siteId ?? ''}\r\n themeAttr={hskThemeAttr}\r\n stopVoice={stopVoice}\r\n chooseVoice={chooseVoice}\r\n liveVoiceName={liveVoiceName}\r\n voiceSecondsLeft={voiceSecondsLeft}\r\n voiceConnecting={voiceConnecting}\r\n voicePhase={voicePhase}\r\n live={live}\r\n earlier={earlier}\r\n newVoiceChat={newVoiceChat}\r\n voiceMuted={voiceMuted}\r\n setVoiceMuted={setVoiceMuted}\r\n voiceError={voiceError}\r\n attachPhoto={attachPhoto}\r\n onSelectSource={(src: ChatSource) => {\r\n onSelectSource?.(src);\r\n live.ask(t('cardClickQuery', { name: src.name, details: detailsText(detailsOf(src, cardFields)) }));\r\n }}\r\n t={t}\r\n />\r\n )}\r\n\r\n {tapbackTarget && (\r\n <TapbackMenu\r\n msg={tapbackTarget.msg}\r\n rect={tapbackTarget.rect}\r\n anchorEl={tapbackTarget.el}\r\n containerEl={panelRef.current}\r\n containerRect={panelRef.current?.getBoundingClientRect()}\r\n isUser={tapbackTarget.isUser}\r\n isRTL={isRTL}\r\n canRetry={!loading && !streaming}\r\n onPin={handlePinMessage}\r\n onRetry={handleRetryMessage}\r\n onCopy={async (text) => {\r\n if (!text) return false;\r\n try {\r\n await navigator.clipboard.writeText(text);\r\n return true;\r\n } catch { }\r\n try {\r\n const ta = document.createElement('textarea');\r\n ta.value = text;\r\n ta.setAttribute('readonly', '');\r\n ta.style.cssText = 'position:fixed;top:0;left:0;opacity:0;pointer-events:none';\r\n document.body.appendChild(ta);\r\n ta.select();\r\n ta.setSelectionRange(0, text.length);\r\n const ok = document.execCommand('copy');\r\n document.body.removeChild(ta);\r\n return ok;\r\n } catch {\r\n return false;\r\n }\r\n }}\r\n onClose={() => setTapbackTarget(null)}\r\n t={t}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n </UIStringsContext.Provider>\r\n );\r\n}\r\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 { DEFAULT_THEME, isThemeId } from '../../utils/themePreference';\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: 'Wait',\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 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';\r\nimport type { ScriptFont, AkropolysTheme } from '@akropolys/sdk';\r\nimport { useAkropolysContext } from '@akropolys/sdk';\r\nimport { useScriptFontFace, preloadScriptFont, loadFontsFor, fontsLoadedFor } from '../../../utils/hostFont';\r\nimport { cachedBaseFont, readyBaseFont } from '../../../utils/chromeWarm';\r\nimport { DEFAULT_UI_STRINGS, ONBOARDING_UI_STRINGS, getLoadingMeta, type UIStringKey } from '../types';\r\n\r\nexport interface UseScriptFontOptions {\r\n shopperLanguage: string;\r\n theme?: 'light' | 'dark' | AkropolysTheme;\r\n preloadedStrings?: Record<string, string> | null;\r\n}\r\n\r\nconst LANGUAGE_CODES: Record<string, string> = {\r\n english: 'en', en: 'en',\r\n swahili: 'sw', kiswahili: 'sw', sw: 'sw',\r\n french: 'fr', français: 'fr', francais: 'fr', fr: 'fr',\r\n spanish: 'es', español: 'es', espanol: 'es', es: 'es',\r\n arabic: 'ar', 'العربية': 'ar', ar: 'ar',\r\n portuguese: 'pt', português: 'pt', pt: 'pt',\r\n hindi: 'hi', 'हिन्दी': 'hi', hi: 'hi',\r\n chinese: 'zh', '中文': 'zh', zh: 'zh',\r\n japanese: 'ja', '日本語': 'ja', ja: 'ja',\r\n urdu: 'ur', 'اردو': 'ur', ur: 'ur',\r\n burmese: 'my', burma: 'my', myanmar: 'my', 'မြန်မာ': 'my', 'မြန်မာဘာသာ': 'my', my: 'my',\r\n khmer: 'km', cambodian: 'km', 'ភាសាខ្មែរ': 'km', 'ខ្មែរ': 'km', km: 'km',\r\n persian: 'fa', farsi: 'fa', 'فارسی': 'fa', fa: 'fa', fas: 'fa',\r\n malay: 'ms', bahasa: 'ms', indonesian: 'id', 'bahasa melayu': 'ms', 'bahasa indonesia': 'id', ms: 'ms', id: 'id',\r\n amharic: 'am', 'አማርኛ': 'am', am: 'am',\r\n};\r\n\r\n// Direction and speech language only; the words come from /ui-strings (cached per language by the sdk).\r\nfunction knownLanguage(lang: string): { dir: 'ltr' | 'rtl'; bcp47: string } | null {\r\n const bcp47 = lang ? LANGUAGE_CODES[lang.trim().toLowerCase()] : undefined;\r\n if (!bcp47) return null;\r\n return { dir: bcp47 === 'ar' || bcp47 === 'ur' || bcp47 === 'fa' ? 'rtl' : 'ltr', bcp47 };\r\n}\r\n\r\nfunction resolveFirstFamily(varRef: string): string {\r\n const name = /var\\(\\s*(--[\\w-]+)/.exec(varRef)?.[1];\r\n if (!name || typeof document === 'undefined') return '';\r\n for (const el of [document.documentElement, document.body]) {\r\n const value = el ? getComputedStyle(el).getPropertyValue(name).trim() : '';\r\n if (value) return value.split(',')[0].trim();\r\n }\r\n return '';\r\n}\r\n\r\n// The clay page holds until the next page's letters are drawn in their own font, but never longer than this.\r\nconst FONT_WAIT_MS = 5000;\r\n\r\n// The chat waits for its language; a failed load is tried again at these gaps, the last one repeating.\r\nconst LANG_RETRY_MS = [5000, 15000, 45000, 120000];\r\n\r\nexport function useScriptFont({ shopperLanguage, theme, preloadedStrings }: UseScriptFontOptions) {\r\n const client = useAkropolysContext();\r\n const cachedInitial = shopperLanguage ? (\r\n client?.getCachedUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS) ??\r\n client?.getCachedUIStrings?.(shopperLanguage, ONBOARDING_UI_STRINGS)\r\n ) : null;\r\n const initialStrings = (preloadedStrings && Object.keys(preloadedStrings).length > 0)\r\n ? preloadedStrings\r\n : (cachedInitial?.strings ?? {});\r\n const [chromeStrings, setChromeStrings] = useState<Record<string, string>>(() => initialStrings);\r\n const [chromeReady, setChromeReady] = useState<boolean>(() => !shopperLanguage || (preloadedStrings && Object.keys(preloadedStrings).length > 0) || !!cachedInitial?.complete);\r\n const [loadedLang, setLoadedLang] = useState<string>(() => {\r\n if (preloadedStrings && Object.keys(preloadedStrings).length > 0) return shopperLanguage;\r\n if (cachedInitial?.complete) return shopperLanguage;\r\n const isEn = !shopperLanguage || knownLanguage(shopperLanguage)?.bcp47 === 'en';\r\n return isEn ? (shopperLanguage || 'en') : '';\r\n });\r\n\r\n const isEn = !shopperLanguage || knownLanguage(shopperLanguage)?.bcp47 === 'en';\r\n let effectiveStrings = chromeStrings;\r\n if (preloadedStrings && Object.keys(preloadedStrings).length > 0) {\r\n effectiveStrings = { ...chromeStrings, ...preloadedStrings };\r\n }\r\n\r\n const dirKey = shopperLanguage ? `akropolys_ui_dir_${shopperLanguage.toLowerCase()}` : '';\r\n const [isRTL, setIsRTL] = useState<boolean>(() => {\r\n if (cachedInitial?.dir) return cachedInitial.dir === 'rtl';\r\n const known = knownLanguage(shopperLanguage);\r\n if (known) return known.dir === 'rtl';\r\n const meta = getLoadingMeta(shopperLanguage);\r\n if (meta?.rtl) return true;\r\n if (typeof window === 'undefined' || !dirKey) return false;\r\n try { return localStorage.getItem(dirKey) === 'rtl'; } catch { return false; }\r\n });\r\n const [speechLang, setSpeechLang] = useState(() => {\r\n return cachedInitial?.bcp47 || knownLanguage(shopperLanguage)?.bcp47 || '';\r\n });\r\n const [scriptFont, setScriptFont] = useState<ScriptFont | null>(() => cachedInitial?.font ?? null);\r\n const [baseFont, setBaseFont] = useState<ScriptFont | null>(() => readyBaseFont(client));\r\n const [baseFontReady, setBaseFontReady] = useState<boolean>(true);\r\n const [fontWait, setFontWait] = useState(false);\r\n const openedLangRef = React.useRef(shopperLanguage);\r\n\r\n // Sync synchronously during render if shopperLanguage changes, preventing any 1-frame flash of old strings\r\n const [prevShopperLanguage, setPrevShopperLanguage] = useState(shopperLanguage);\r\n if (shopperLanguage !== prevShopperLanguage) {\r\n setPrevShopperLanguage(shopperLanguage);\r\n const knownNow = knownLanguage(shopperLanguage);\r\n if (knownNow) {\r\n setIsRTL(knownNow.dir === 'rtl');\r\n setSpeechLang(knownNow.bcp47);\r\n }\r\n const cached = shopperLanguage ? (\r\n client?.getCachedUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS) ??\r\n client?.getCachedUIStrings?.(shopperLanguage, ONBOARDING_UI_STRINGS)\r\n ) : null;\r\n const sourceStrings = (preloadedStrings && Object.keys(preloadedStrings).length > 0)\r\n ? preloadedStrings\r\n : cached?.strings;\r\n if (sourceStrings && Object.keys(sourceStrings).length > 0) {\r\n setChromeStrings(sourceStrings);\r\n effectiveStrings = sourceStrings;\r\n if (cached) {\r\n if (cached.font) setScriptFont(cached.font);\r\n if (cached.dir) setIsRTL(cached.dir === 'rtl');\r\n if (cached.bcp47) setSpeechLang(cached.bcp47);\r\n }\r\n if (cached?.font) void preloadScriptFont(cached.font);\r\n setFontWait(!fontsLoadedFor([cached?.font?.family, baseFont?.family].filter((f): f is string => !!f), sourceStrings));\r\n setLoadedLang(shopperLanguage);\r\n setChromeReady(true);\r\n }\r\n }\r\n\r\n const effectiveChromeReady = isEn || (!fontWait && (\r\n (loadedLang.toLowerCase() === shopperLanguage.toLowerCase() && chromeReady) ||\r\n Object.keys(effectiveStrings).length > 0\r\n ));\r\n\r\n useEffect(() => {\r\n if (!shopperLanguage) {\r\n setSpeechLang('');\r\n setScriptFont(null);\r\n setChromeStrings({});\r\n setLoadedLang('');\r\n setChromeReady(true);\r\n setIsRTL(false);\r\n return;\r\n }\r\n const known = knownLanguage(shopperLanguage);\r\n const meta = getLoadingMeta(shopperLanguage);\r\n const isLangEn = known?.bcp47 === 'en';\r\n let cancelled = false;\r\n\r\n // Only a language picked during this visit holds the clay page; a returning visitor's page is never covered.\r\n const holdForFonts = (font: ScriptFont | null | undefined, strings: Record<string, string>) => {\r\n const families = [font?.family, baseFont?.family].filter((f): f is string => !!f);\r\n if (shopperLanguage === openedLangRef.current || fontsLoadedFor(families, strings)) {\r\n setFontWait(false);\r\n return;\r\n }\r\n setFontWait(true);\r\n loadFontsFor(families, strings, FONT_WAIT_MS).then(() => {\r\n if (!cancelled) setFontWait(false);\r\n });\r\n };\r\n\r\n const cachedFull = client?.getCachedUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS);\r\n if (cachedFull?.strings && Object.keys(cachedFull.strings).length > 0) {\r\n setChromeStrings(cachedFull.strings);\r\n setIsRTL(cachedFull.dir === 'rtl');\r\n setSpeechLang(cachedFull.bcp47 || known?.bcp47 || '');\r\n if (cachedFull.font) {\r\n void preloadScriptFont(cachedFull.font);\r\n setScriptFont(cachedFull.font);\r\n }\r\n holdForFonts(cachedFull.font, cachedFull.strings);\r\n setLoadedLang(shopperLanguage);\r\n setChromeReady(true);\r\n return () => {\r\n cancelled = true;\r\n };\r\n }\r\n\r\n const cachedOnboarding = client?.getCachedUIStrings?.(shopperLanguage, ONBOARDING_UI_STRINGS);\r\n if (cachedOnboarding?.strings && Object.keys(cachedOnboarding.strings).length > 0) {\r\n setChromeStrings(cachedOnboarding.strings);\r\n setIsRTL(cachedOnboarding.dir === 'rtl');\r\n setSpeechLang(cachedOnboarding.bcp47 || known?.bcp47 || '');\r\n if (cachedOnboarding.font) {\r\n void preloadScriptFont(cachedOnboarding.font);\r\n setScriptFont(cachedOnboarding.font);\r\n }\r\n holdForFonts(cachedOnboarding.font, cachedOnboarding.strings);\r\n setLoadedLang(shopperLanguage);\r\n setChromeReady(true);\r\n } else {\r\n setFontWait(false);\r\n setChromeStrings({});\r\n if (known) {\r\n setIsRTL(known.dir === 'rtl');\r\n setSpeechLang(known.bcp47);\r\n } else {\r\n if (meta?.rtl) setIsRTL(true);\r\n }\r\n if (!isLangEn) {\r\n setChromeReady(false);\r\n }\r\n }\r\n\r\n const tryLoad = async (): Promise<boolean> => {\r\n let got = false;\r\n try {\r\n if (!cachedOnboarding?.strings) {\r\n const resFast = await client.getUIStrings?.(shopperLanguage, ONBOARDING_UI_STRINGS);\r\n if (!cancelled && resFast?.complete) {\r\n setFontWait(true);\r\n setChromeStrings(prev => ({ ...prev, ...resFast.strings }));\r\n setIsRTL(resFast.dir === 'rtl');\r\n setSpeechLang(resFast.bcp47 || known?.bcp47 || '');\r\n try { localStorage.setItem(dirKey, resFast.dir); } catch { }\r\n if (resFast.font) void preloadScriptFont(resFast.font);\r\n const families = [resFast.font?.family, baseFont?.family].filter((f): f is string => !!f);\r\n await loadFontsFor(families, resFast.strings, FONT_WAIT_MS);\r\n if (!cancelled) {\r\n if (resFast.font) setScriptFont(resFast.font);\r\n setLoadedLang(shopperLanguage);\r\n setChromeReady(true);\r\n setFontWait(false);\r\n }\r\n }\r\n }\r\n\r\n const resFull = await client.getUIStrings?.(shopperLanguage, DEFAULT_UI_STRINGS);\r\n if (!cancelled && resFull?.complete) {\r\n got = true;\r\n setChromeStrings(prev => ({ ...prev, ...resFull.strings }));\r\n if (resFull.font) {\r\n await preloadScriptFont(resFull.font, 1200);\r\n if (!cancelled) setScriptFont(resFull.font);\r\n }\r\n }\r\n } catch {\r\n return false;\r\n }\r\n return got;\r\n };\r\n\r\n (async () => {\r\n for (let attempt = 0; !cancelled; attempt++) {\r\n if (await tryLoad()) break;\r\n const gap = LANG_RETRY_MS[Math.min(attempt, LANG_RETRY_MS.length - 1)];\r\n await new Promise(resolve => window.setTimeout(resolve, gap));\r\n }\r\n })();\r\n return () => {\r\n cancelled = true;\r\n };\r\n }, [shopperLanguage, client, dirKey]);\r\n\r\n useEffect(() => {\r\n let cancelled = false;\r\n (async () => {\r\n try {\r\n const f = await cachedBaseFont(client);\r\n if (!cancelled && f) setBaseFont(f);\r\n } catch {\r\n\r\n }\r\n if (!cancelled) setBaseFontReady(true);\r\n })();\r\n return () => { cancelled = true; };\r\n }, [client]);\r\n\r\n useScriptFontFace(scriptFont);\r\n useScriptFontFace(baseFont);\r\n\r\n const fontStack = React.useMemo(() => {\r\n const declared = typeof theme === 'object' && theme?.fontFamily ? theme.fontFamily : '';\r\n const first = declared.split(',')[0].trim();\r\n const isVarRef = /^var\\(/i.test(first);\r\n const hostName = first.replace(/^['\"]|['\"]$/g, '');\r\n const resolved = isVarRef ? resolveFirstFamily(first) : '';\r\n const host = isVarRef\r\n ? (resolved ? `${resolved}, ` : '')\r\n : (hostName ? `\"${hostName}\", ` : '');\r\n\r\n if (scriptFont) {\r\n return `\"${scriptFont.family}\", ${host}\"Geist\", system-ui, sans-serif`;\r\n }\r\n\r\n const l = shopperLanguage ? shopperLanguage.trim().toLowerCase() : '';\r\n if (l === 'japanese' || l === 'ja' || l === '日本語') {\r\n return `${host}\"Geist\", \"Hiragino Sans\", \"Hiragino Kaku Gothic ProN\", \"Yu Gothic\", \"Meiryo\", system-ui, sans-serif`;\r\n }\r\n if (l === 'chinese' || l === 'zh' || l === '中文') {\r\n return `${host}\"Geist\", \"PingFang SC\", \"Microsoft YaHei\", \"Hiragino Sans GB\", system-ui, sans-serif`;\r\n }\r\n if (l === 'urdu' || l === 'ur' || l === 'اردو') {\r\n return `\"Noto Nastaliq Urdu\", ${host}\"IBM Plex Sans Arabic\", \"Geist\", system-ui, sans-serif`;\r\n }\r\n if (l === 'arabic' || l === 'ar' || l === 'العربية') {\r\n return `\"IBM Plex Sans Arabic\", ${host}\"Geist\", system-ui, sans-serif`;\r\n }\r\n if (l === 'hindi' || l === 'hi' || l === 'हिन्दी') {\r\n return `\"Hind\", ${host}\"Geist\", system-ui, sans-serif`;\r\n }\r\n\r\n return undefined;\r\n }, [scriptFont, shopperLanguage, typeof theme === 'object' && theme ? theme.fontFamily : undefined]);\r\n\r\n const isNonLatin = React.useMemo(() => {\r\n let latin = 0;\r\n let other = 0;\r\n for (const v of Object.values(chromeStrings)) {\r\n for (const ch of v) {\r\n const c = ch.codePointAt(0) ?? 0;\r\n if (c < 0x00c0) continue;\r\n if (!/\\p{L}/u.test(ch)) continue;\r\n if (c <= 0x024f) latin++;\r\n else other++;\r\n }\r\n }\r\n return other > latin;\r\n }, [chromeStrings]);\r\n\r\n const [fontEpoch, setFontEpoch] = useState(0);\r\n useEffect(() => {\r\n if (typeof document === 'undefined' || !(document as any).fonts?.ready) return;\r\n let live = true;\r\n (document as any).fonts.ready.then(() => {\r\n if (live) setFontEpoch(e => e + 1);\r\n });\r\n return () => { live = false; };\r\n }, [scriptFont]);\r\n\r\n const hostFontCovers = React.useMemo(() => {\r\n if (!isNonLatin || typeof document === 'undefined') return true;\r\n const declared = typeof theme === 'object' && theme?.fontFamily ? theme.fontFamily : '';\r\n const first = declared.split(',')[0].trim();\r\n if (!first) return false;\r\n let sample = '';\r\n for (const v of Object.values(chromeStrings)) {\r\n if (v) { sample = v; break; }\r\n }\r\n if (!sample) return true;\r\n const text = sample.replace(/\\s+/g, '');\r\n if (!text) return true;\r\n try {\r\n const canvas = document.createElement('canvas');\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return true;\r\n const hostFamily = first.startsWith('var(')\r\n ? getComputedStyle(document.documentElement).getPropertyValue(first.slice(4, -1).trim()).trim() || first\r\n : first;\r\n ctx.font = `16px ${hostFamily}, __akropolys_nonexistent_font__`;\r\n const withHost = ctx.measureText(text).width;\r\n ctx.font = '16px __akropolys_nonexistent_font__';\r\n const withoutHost = ctx.measureText(text).width;\r\n return Math.abs(withHost - withoutHost) > 1;\r\n } catch {\r\n return true;\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isNonLatin, chromeStrings, typeof theme === 'object' && theme ? theme.fontFamily : undefined, fontEpoch]);\r\n\r\n const t = useCallback((key: UIStringKey, vars?: Record<string, string>): string => {\r\n let s: string = effectiveStrings[key] || chromeStrings[key] || DEFAULT_UI_STRINGS[key] || key;\r\n if (vars) {\r\n for (const [k, v] of Object.entries(vars)) s = s.split(`{${k}}`).join(v);\r\n }\r\n return s;\r\n }, [effectiveStrings, chromeStrings]);\r\n\r\n const tNode = useCallback((key: UIStringKey, vars?: Record<string, string>) => {\r\n let s = effectiveStrings[key] || chromeStrings[key] || DEFAULT_UI_STRINGS[key] || key;\r\n return s.split(/(\\{[a-zA-Z]+\\})/g).map((part, i) => {\r\n const m = part.match(/^\\{([a-zA-Z]+)\\}$/);\r\n if (m && vars?.[m[1]] !== undefined) return <bdi key={i}>{vars[m[1]]}</bdi>;\r\n return <React.Fragment key={i}>{part}</React.Fragment>;\r\n });\r\n }, [effectiveStrings, chromeStrings]);\r\n\r\n return {\r\n chromeStrings,\r\n chromeReady: effectiveChromeReady,\r\n isRTL,\r\n speechLang,\r\n scriptFont,\r\n fontStack,\r\n isNonLatin,\r\n hostFontCovers,\r\n baseFontReady,\r\n t,\r\n tNode,\r\n };\r\n}\r\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';\r\nimport { chime, primeChimes } from './chime';\r\nimport { AdpcmEncoder, decodeAdpcm } from './adpcm';\r\nimport { float32ToWav, int16ToWav } from './wav';\r\nimport { downscaleImage } from './downscaleImage';\r\nimport { VoiceRecovery, recoveredTurns } from './voiceRecovery';\r\n\r\nexport type LiveState = 'idle' | 'connecting' | 'listening' | 'thinking' | 'speaking' | 'ended';\r\n\r\nexport interface LiveSource {\r\n id?: string;\r\n url?: string;\r\n name: string;\r\n image?: string;\r\n images?: import('@akropolys/sdk').EntityImageInput[];\r\n fields?: Record<string, any>;\r\n}\r\n\r\nexport interface LiveVoiceExchange {\r\n heard: string;\r\n said: string;\r\n duration?: number;\r\n userAudioUrl?: string;\r\n audioUrl?: string;\r\n // Photos attached and the image rendered this turn, so chat keeps them after voice closes.\r\n images?: string[];\r\n visualization?: string;\r\n}\r\n\r\nexport interface LiveVoiceOptions {\r\n apiUrl: string;\r\n siteId: string;\r\n\r\n token: string;\r\n // The site server's signature over kikuId, for sites that require one.\r\n proof?: string;\r\n kikuId?: string;\r\n // The chat session: a photo parked here is the scene the voice model edits.\r\n sessionId?: string;\r\n name?: string;\r\n storeScene?: (image: string) => Promise<boolean>;\r\n\r\n language?: string;\r\n voice?: string;\r\n\r\n onExchange?: (exchange: LiveVoiceExchange) => void;\r\n onRefused?: (code: string) => void;\r\n onError?: (code: string) => void;\r\n\r\n muted?: boolean;\r\n}\r\n\r\nconst INPUT_RATE = 16000;\r\nconst OUTPUT_RATE = 24000;\r\nconst START_BUFFER_SEC = 0.08;\r\nconst REFILL_BUFFER_SEC = 0.12;\r\nconst SCHEDULE_LEAD = 0.03;\r\nconst FLUSH_FADE = 0.08;\r\nconst MAX_PENDING_CHUNKS = 250; // 10s of 40ms chunks held until the server is ready\r\nconst HEARING_LEVEL = 0.12;\r\nconst HEARING_HOLD_MS = 500;\r\nconst IDLE_CLOSE_MS = 60_000;\r\n\r\nconst WORKLET_SRC = `\r\nclass KikuCapture extends AudioWorkletProcessor {\r\n constructor() {\r\n super();\r\n this._ratio = sampleRate / ${INPUT_RATE};\r\n this._chunk = ${Math.round(INPUT_RATE * 0.04)};\r\n this._acc = new Int16Array(this._chunk);\r\n this._n = 0;\r\n this._pos = 0;\r\n }\r\n process(inputs) {\r\n const ch = inputs[0] && inputs[0][0];\r\n if (!ch) return true;\r\n while (this._pos < ch.length) {\r\n const i = this._pos | 0;\r\n const frac = this._pos - i;\r\n const a = ch[i];\r\n const b = i + 1 < ch.length ? ch[i + 1] : a;\r\n const s = a + (b - a) * frac;\r\n const c = s < -1 ? -1 : s > 1 ? 1 : s;\r\n this._acc[this._n++] = c < 0 ? c * 0x8000 : c * 0x7fff;\r\n if (this._n === this._chunk) {\r\n this.port.postMessage(this._acc.buffer, [this._acc.buffer]);\r\n this._acc = new Int16Array(this._chunk);\r\n this._n = 0;\r\n }\r\n this._pos += this._ratio;\r\n }\r\n this._pos -= ch.length;\r\n return true;\r\n }\r\n}\r\nregisterProcessor('kiku-capture', KikuCapture);\r\n`;\r\n\r\n// A browser cannot set headers on a socket, so the key and the proof ride as subprotocols and stay out of the address.\r\nfunction voiceProtocols(o: LiveVoiceOptions): string[] {\r\n return o.proof ? ['akropolys.token.' + o.token, 'akropolys.proof.' + o.proof] : ['akropolys.token.' + o.token];\r\n}\r\n\r\nfunction liveUrl(o: LiveVoiceOptions, voiceOverride?: string): string {\r\n const base = o.apiUrl.replace(/\\/+$/, '');\r\n const path = base.endsWith('/voice/live') ? base : base + '/voice/live';\r\n const url = new URL(path, window.location.href);\r\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\r\n url.searchParams.set('siteId', o.siteId);\r\n if (o.kikuId) url.searchParams.set('kikuId', o.kikuId);\r\n if (o.sessionId) url.searchParams.set('sessionId', o.sessionId);\r\n if (o.name) url.searchParams.set('name', o.name);\r\n if (o.language) url.searchParams.set('language', o.language);\r\n url.searchParams.set('codec', 'adpcm');\r\n const v = voiceOverride || o.voice;\r\n if (v) url.searchParams.set('voice', v);\r\n return url.toString();\r\n}\r\n\r\nexport interface LiveTurn {\r\n role: 'user' | 'assistant';\r\n text: string;\r\n done: boolean;\r\n}\r\n\r\n// One square in the image row: an attached photo, or a render (pending while it is made).\r\nexport interface LiveImage {\r\n id: number;\r\n url: string;\r\n pending: boolean;\r\n // A photo the visitor attached, still uploading.\r\n sending?: boolean;\r\n}\r\n\r\nexport function useLiveVoice(opts: LiveVoiceOptions) {\r\n const [state, setState] = useState<LiveState>('idle');\r\n const [hearing, setHearing] = useState(false);\r\n const [sources, setSources] = useState<LiveSource[]>([]);\r\n const [secondsLeft, setSecondsLeft] = useState<number | null>(null);\r\n const [photos, setPhotos] = useState(false);\r\n\r\n const wsRef = useRef<WebSocket | null>(null);\r\n const startedRef = useRef(false);\r\n const recoveryRef = useRef(new VoiceRecovery());\r\n const recoverRef = useRef<() => boolean>(() => false);\r\n const retryTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const connectTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const hasConnectedRef = useRef(false);\r\n const lastCaptureRef = useRef(0);\r\n const captureResumeAtRef = useRef(0);\r\n const openOnReadyRef = useRef(false);\r\n const micAttachRef = useRef<(() => void) | null>(null);\r\n const lastLoudRef = useRef(0);\r\n const botSpeakingRef = useRef(false);\r\n const spokeLoggedRef = useRef(false);\r\n const ctxRef = useRef<AudioContext | null>(null);\r\n const streamRef = useRef<MediaStream | null>(null);\r\n const nodeRef = useRef<AudioWorkletNode | null>(null);\r\n const analyserRef = useRef<AnalyserNode | null>(null);\r\n\r\n const playAtRef = useRef(0);\r\n const replyingRef = useRef(false);\r\n const heldRef = useRef<Float32Array[]>([]);\r\n const heldSecRef = useRef(0);\r\n const sourcesRef = useRef<Set<AudioBufferSourceNode>>(new Set());\r\n const outAnalyserRef = useRef<AnalyserNode | null>(null);\r\n const outGainRef = useRef<GainNode | null>(null);\r\n const outRateRef = useRef(OUTPUT_RATE);\r\n\r\n const optsRef = useRef(opts);\r\n useEffect(() => {\r\n optsRef.current = opts;\r\n const stream = streamRef.current;\r\n if (stream) {\r\n for (const track of stream.getAudioTracks()) {\r\n track.enabled = !opts.muted;\r\n }\r\n }\r\n }, [opts]);\r\n\r\n const readyRef = useRef(false);\r\n const pendingRef = useRef<ArrayBuffer[]>([]);\r\n const encoderRef = useRef(new AdpcmEncoder());\r\n const workletCtxRef = useRef<Promise<AudioContext | null> | null>(null);\r\n\r\n const turnHeardRef = useRef('');\r\n const turnSaidRef = useRef('');\r\n const [turns, setTurns] = useState<LiveTurn[]>([]);\r\n const turnsRef = useRef<LiveTurn[]>([]);\r\n turnsRef.current = turns;\r\n // Earlier calls in this chat, handed to each new socket so the model remembers them.\r\n const historyRef = useRef<LiveTurn[]>([]);\r\n const [images, setImages] = useState<LiveImage[]>([]);\r\n const imageIdRef = useRef(0);\r\n // What this turn showed, handed to chat with the exchange.\r\n const turnImagesRef = useRef<string[]>([]);\r\n const turnVizRef = useRef<string | undefined>(undefined);\r\n const turnStartRef = useRef<number | null>(null);\r\n const turnBotAudioChunksRef = useRef<Float32Array[]>([]);\r\n const turnUserAudioChunksRef = useRef<Int16Array[]>([]);\r\n\r\n const flushExchange = useCallback(() => {\r\n const heard = turnHeardRef.current.trim();\r\n const said = turnSaidRef.current.trim();\r\n const duration = turnStartRef.current ? Math.max(0.1, (Date.now() - turnStartRef.current) / 1000) : undefined;\r\n\r\n let audioUrl: string | undefined;\r\n if (turnBotAudioChunksRef.current.length > 0) {\r\n try {\r\n const blob = float32ToWav(turnBotAudioChunksRef.current, outRateRef.current);\r\n audioUrl = URL.createObjectURL(blob);\r\n } catch (e) {\r\n console.error('[kiku] failed to encode bot audio wav:', e);\r\n }\r\n }\r\n\r\n let userAudioUrl: string | undefined;\r\n if (turnUserAudioChunksRef.current.length > 0) {\r\n try {\r\n const blob = int16ToWav(turnUserAudioChunksRef.current, INPUT_RATE);\r\n userAudioUrl = URL.createObjectURL(blob);\r\n } catch (e) {\r\n console.error('[kiku] failed to encode user audio wav:', e);\r\n }\r\n }\r\n\r\n const images = turnImagesRef.current.length ? turnImagesRef.current : undefined;\r\n const visualization = turnVizRef.current;\r\n\r\n turnHeardRef.current = '';\r\n turnSaidRef.current = '';\r\n turnStartRef.current = null;\r\n turnBotAudioChunksRef.current = [];\r\n turnUserAudioChunksRef.current = [];\r\n turnImagesRef.current = [];\r\n turnVizRef.current = undefined;\r\n\r\n if (!heard && !said && !images && !visualization) return;\r\n optsRef.current.onExchange?.({ heard, said, duration, userAudioUrl, audioUrl, images, visualization });\r\n }, []);\r\n\r\n const chirp = useCallback(() => {\r\n // Silent - no synthetic beeps during live voice\r\n }, []);\r\n\r\n const sendAudio = useCallback((buf: ArrayBuffer) => {\r\n lastCaptureRef.current = Date.now();\r\n if (optsRef.current.muted) return;\r\n const pcm = new Int16Array(buf);\r\n let peak = 0;\r\n for (let i = 0; i < pcm.length; i += 8) {\r\n const v = Math.abs(pcm[i]);\r\n if (v > peak) peak = v;\r\n }\r\n if (peak > 1200) lastLoudRef.current = Date.now();\r\n const ws = wsRef.current;\r\n if (!readyRef.current || !ws || ws.readyState !== WebSocket.OPEN) return;\r\n // A half-open socket can stay OPEN while its queue grows without bound.\r\n if (ws.bufferedAmount > 256 * 1024) {\r\n if (!recoverRef.current()) optsRef.current.onError?.('connection');\r\n return;\r\n }\r\n turnUserAudioChunksRef.current.push(new Int16Array(buf.slice(0)));\r\n try { ws.send(encoderRef.current.encode(new Int16Array(buf))); }\r\n catch { if (!recoverRef.current()) optsRef.current.onError?.('connection'); }\r\n }, []);\r\n\r\n const flushPending = useCallback(() => {\r\n pendingRef.current = [];\r\n }, []);\r\n\r\n // Built once per context and reused, so tapping voice only waits for the mic.\r\n const audioContext = useCallback((): Promise<AudioContext | null> => {\r\n const held = ctxRef.current;\r\n if (workletCtxRef.current && held && held.state !== 'closed') return workletCtxRef.current;\r\n const AC: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\r\n if (!AC) return Promise.resolve(null);\r\n const ctx = new AC({ latencyHint: 'interactive', sampleRate: OUTPUT_RATE });\r\n ctxRef.current = ctx;\r\n const blobUrl = URL.createObjectURL(new Blob([WORKLET_SRC], { type: 'application/javascript' }));\r\n workletCtxRef.current = ctx.audioWorklet.addModule(blobUrl)\r\n .then(() => ctx)\r\n .catch(() => null)\r\n .finally(() => URL.revokeObjectURL(blobUrl));\r\n return workletCtxRef.current;\r\n }, []);\r\n\r\n const warmContext = useCallback(() => {\r\n if (typeof window === 'undefined') return;\r\n void audioContext();\r\n }, [audioContext]);\r\n\r\n const micLevel = useCallback(() => {\r\n const a = analyserRef.current;\r\n if (!a) return 0;\r\n const d = new Uint8Array(a.fftSize);\r\n a.getByteTimeDomainData(d);\r\n let sum = 0;\r\n for (let i = 0; i < d.length; i++) { const v = (d[i] - 128) / 128; sum += v * v; }\r\n return Math.min(1, Math.sqrt(sum / d.length) * 4);\r\n }, []);\r\n\r\n const outbound = state === 'speaking' || state === 'thinking';\r\n\r\n const micSpectrum = useCallback((out: Uint8Array) => {\r\n const a = outbound ? outAnalyserRef.current : analyserRef.current;\r\n if (!a || out.length !== a.frequencyBinCount) return false;\r\n a.getByteFrequencyData(out as Uint8Array<ArrayBuffer>);\r\n return true;\r\n }, [outbound]);\r\n\r\n const spectrumBins = useCallback(\r\n () => (outbound ? outAnalyserRef.current : analyserRef.current)?.frequencyBinCount ?? 0,\r\n [outbound]\r\n );\r\n\r\n const flushPlayback = useCallback(() => {\r\n const g = outGainRef.current;\r\n const ctx = ctxRef.current;\r\n if (!g || !ctx || ctx.state === 'closed') {\r\n playAtRef.current = 0;\r\n for (const src of sourcesRef.current) {\r\n try { src.onended = null; src.stop(); } catch { }\r\n }\r\n sourcesRef.current.clear();\r\n return;\r\n }\r\n const now = ctx.currentTime;\r\n const fadeEnd = now + FLUSH_FADE;\r\n g.gain.cancelScheduledValues(now);\r\n g.gain.setValueAtTime(g.gain.value, now);\r\n g.gain.linearRampToValueAtTime(0, fadeEnd);\r\n g.gain.setValueAtTime(1, fadeEnd);\r\n for (const src of sourcesRef.current) {\r\n try { src.onended = null; src.stop(fadeEnd); } catch { }\r\n }\r\n sourcesRef.current.clear();\r\n playAtRef.current = fadeEnd; // next turn must not open inside the fade\r\n }, []);\r\n\r\n const schedule = useCallback((chunk: Float32Array) => {\r\n const ctx = ctxRef.current;\r\n const out = outAnalyserRef.current;\r\n if (!ctx || !out || chunk.length === 0) return;\r\n if (ctx.state === 'suspended') {\r\n ctx.resume().catch(() => {});\r\n }\r\n\r\n const buf = ctx.createBuffer(1, chunk.length, outRateRef.current);\r\n buf.getChannelData(0).set(chunk);\r\n\r\n const src = ctx.createBufferSource();\r\n src.buffer = buf;\r\n src.connect(out);\r\n\r\n const now = ctx.currentTime;\r\n const at = playAtRef.current > now ? playAtRef.current : now + SCHEDULE_LEAD;\r\n src.start(at);\r\n playAtRef.current = at + buf.duration;\r\n\r\n sourcesRef.current.add(src);\r\n src.onended = () => {\r\n sourcesRef.current.delete(src);\r\n if (sourcesRef.current.size === 0) {\r\n playAtRef.current = 0;\r\n replyingRef.current = false;\r\n setState(s => (s === 'speaking' ? 'listening' : s));\r\n }\r\n };\r\n setState(s => (s === 'speaking' || s === 'idle' || s === 'ended' ? s : 'speaking'));\r\n }, []);\r\n\r\n const releaseHeld = useCallback(() => {\r\n const held = heldRef.current;\r\n heldRef.current = [];\r\n heldSecRef.current = 0;\r\n for (const chunk of held) schedule(chunk);\r\n }, [schedule]);\r\n\r\n const dropHeld = useCallback(() => {\r\n heldRef.current = [];\r\n heldSecRef.current = 0;\r\n }, []);\r\n\r\n const enqueue = useCallback((chunk: Float32Array) => {\r\n const ctx = ctxRef.current;\r\n if (!ctx || chunk.length === 0) return;\r\n const playing = playAtRef.current > ctx.currentTime;\r\n if (playing && heldRef.current.length === 0) {\r\n schedule(chunk);\r\n return;\r\n }\r\n const target = replyingRef.current ? REFILL_BUFFER_SEC : START_BUFFER_SEC;\r\n heldRef.current.push(chunk);\r\n heldSecRef.current += chunk.length / outRateRef.current;\r\n if (heldSecRef.current >= target) {\r\n replyingRef.current = true;\r\n releaseHeld();\r\n }\r\n }, [schedule, releaseHeld]);\r\n\r\n const holdTimerRef = useRef<any>(null);\r\n const holdGainRef = useRef<GainNode | null>(null);\r\n\r\n const stopHold = useCallback(() => {\r\n if (holdTimerRef.current) {\r\n clearInterval(holdTimerRef.current);\r\n holdTimerRef.current = null;\r\n }\r\n const g = holdGainRef.current;\r\n const ctx = ctxRef.current;\r\n if (g && ctx && ctx.state !== 'closed') {\r\n const now = ctx.currentTime;\r\n try {\r\n g.gain.cancelScheduledValues(now);\r\n g.gain.setValueAtTime(g.gain.value, now);\r\n g.gain.linearRampToValueAtTime(0.0001, now + 0.04);\r\n } catch {}\r\n setTimeout(() => {\r\n try { g.disconnect(); } catch {}\r\n if (holdGainRef.current === g) holdGainRef.current = null;\r\n }, 50);\r\n }\r\n }, []);\r\n\r\n const startHold = useCallback(() => {}, []);\r\n\r\n const teardown = useCallback((finalState: LiveState) => {\r\n if (retryTimerRef.current !== null) clearTimeout(retryTimerRef.current);\r\n if (connectTimerRef.current !== null) clearTimeout(connectTimerRef.current);\r\n retryTimerRef.current = connectTimerRef.current = null;\r\n hasConnectedRef.current = false;\r\n captureResumeAtRef.current = 0;\r\n flushExchange();\r\n const closing = wsRef.current;\r\n wsRef.current = null;\r\n try { closing?.close(); } catch { }\r\n readyRef.current = false;\r\n pendingRef.current = [];\r\n workletCtxRef.current = null;\r\n replyingRef.current = false;\r\n heldRef.current = [];\r\n heldSecRef.current = 0;\r\n stopHold();\r\n flushPlayback();\r\n micAttachRef.current = null;\r\n if (nodeRef.current) nodeRef.current.port.onmessage = null;\r\n nodeRef.current?.disconnect();\r\n nodeRef.current = null;\r\n streamRef.current?.getTracks().forEach(t => t.stop());\r\n streamRef.current = null;\r\n analyserRef.current = null;\r\n outAnalyserRef.current = null;\r\n outGainRef.current = null;\r\n ctxRef.current?.close().catch(() => { });\r\n ctxRef.current = null;\r\n setState(finalState);\r\n setHearing(false);\r\n setSources([]);\r\n startedRef.current = false;\r\n openOnReadyRef.current = false;\r\n }, [flushExchange, flushPlayback, stopHold]);\r\n\r\n const stop = useCallback(() => {\r\n try { wsRef.current?.send(JSON.stringify({ type: 'close' })); } catch { }\r\n try { wsRef.current?.close(); } catch { }\r\n teardown('idle');\r\n }, [teardown]);\r\n\r\n const sendOpen = useCallback((ws: WebSocket) => {\r\n const history = [...historyRef.current, ...turnsRef.current.filter(x => x.done)]\r\n .filter(x => x.text)\r\n .map(x => ({ role: x.role, text: x.text }));\r\n try { ws.send(JSON.stringify({ type: 'open', history })); } catch { }\r\n }, []);\r\n\r\n const attachWsHandlers = useCallback((ws: WebSocket) => {\r\n let abandoned = false;\r\n if (connectTimerRef.current !== null) clearTimeout(connectTimerRef.current);\r\n connectTimerRef.current = setTimeout(() => {\r\n if (wsRef.current !== ws || readyRef.current) return;\r\n if (!recoverRef.current()) {\r\n optsRef.current.onError?.('connection');\r\n stop();\r\n }\r\n }, 30_000);\r\n ws.binaryType = 'arraybuffer';\r\n encoderRef.current = new AdpcmEncoder();\r\n ws.onopen = () => {\r\n if (wsRef.current !== ws || !openOnReadyRef.current) return;\r\n openOnReadyRef.current = false;\r\n sendOpen(ws);\r\n };\r\n ws.onmessage = ev => {\r\n if (wsRef.current !== ws) return;\r\n if (ev.data instanceof ArrayBuffer) {\r\n if (!botSpeakingRef.current) {\r\n botSpeakingRef.current = true;\r\n const said = turnSaidRef.current.trim();\r\n if (said) {\r\n setTurns(prev => {\r\n const next = prev.slice();\r\n for (let i = next.length - 1; i >= 0; i--) {\r\n if (next[i].role === 'user' && !next[i].done) next[i] = { ...next[i], done: true };\r\n }\r\n next.push({ role: 'assistant', text: said, done: false });\r\n return next;\r\n });\r\n }\r\n }\r\n if (!spokeLoggedRef.current && lastLoudRef.current) {\r\n spokeLoggedRef.current = true;\r\n console.log('[kiku] wait from last speech to first audio: ' + (Date.now() - lastLoudRef.current) + 'ms');\r\n }\r\n stopHold();\r\n const pcm = decodeAdpcm(ev.data);\r\n turnBotAudioChunksRef.current.push(pcm.slice());\r\n enqueue(pcm);\r\n return;\r\n }\r\n let f: any;\r\n try { f = JSON.parse(ev.data); } catch { return; }\r\n switch (f.type) {\r\n case 'ready':\r\n if (connectTimerRef.current !== null) clearTimeout(connectTimerRef.current);\r\n connectTimerRef.current = null;\r\n hasConnectedRef.current = true;\r\n lastCaptureRef.current = Date.now();\r\n if (f.sampleRate) {\r\n outRateRef.current = f.sampleRate;\r\n if (f.sampleRate !== OUTPUT_RATE) {\r\n console.warn(`[kiku] live audio rate ${f.sampleRate} != context ${OUTPUT_RATE}; per-buffer resampling will click at every chunk seam`);\r\n }\r\n }\r\n if (typeof f.secondsLeft === 'number') setSecondsLeft(f.secondsLeft);\r\n setPhotos(f.photos === true);\r\n readyRef.current = true;\r\n setState('listening');\r\n flushPending();\r\n micAttachRef.current?.();\r\n micAttachRef.current = null;\r\n // A designed tone, not the model clearing its throat.\r\n chime('connect', true);\r\n break;\r\n case 'hearing':\r\n if (!turnStartRef.current) turnStartRef.current = Date.now();\r\n setHearing(true);\r\n break;\r\n case 'thinking':\r\n if (!turnStartRef.current) turnStartRef.current = Date.now();\r\n setHearing(false);\r\n setState('thinking');\r\n startHold();\r\n if (f.tool === 'visualize') {\r\n setImages(prev => (prev.some(i => i.pending) ? prev : [...prev, { id: ++imageIdRef.current, url: '', pending: true }]));\r\n }\r\n break;\r\n case 'viz':\r\n // A url fills the waiting square; none means the render failed and the square goes.\r\n if (typeof f.url === 'string' && f.url) {\r\n turnVizRef.current = f.url;\r\n setImages(prev => prev.map(i => (i.pending ? { ...i, url: f.url, pending: false } : i)));\r\n } else {\r\n setImages(prev => prev.filter(i => !i.pending));\r\n }\r\n break;\r\n case 'heard':\r\n if (sourcesRef.current.size === 0) playAtRef.current = 0;\r\n if (!turnStartRef.current) {\r\n turnStartRef.current = Date.now();\r\n chime('heard');\r\n }\r\n turnHeardRef.current += f.text;\r\n setTurns(prev => {\r\n const next = prev.slice();\r\n const last = next[next.length - 1];\r\n if (last && last.role === 'user' && !last.done) {\r\n next[next.length - 1] = { ...last, text: turnHeardRef.current.trim() };\r\n } else {\r\n next.push({ role: 'user', text: turnHeardRef.current.trim(), done: false });\r\n }\r\n return next;\r\n });\r\n setHearing(false);\r\n setState('thinking');\r\n startHold();\r\n break;\r\n case 'said':\r\n turnSaidRef.current += f.text;\r\n if (!botSpeakingRef.current) break;\r\n setTurns(prev => {\r\n const next = prev.slice();\r\n for (let i = next.length - 1; i >= 0; i--) {\r\n if (next[i].role === 'user' && !next[i].done) next[i] = { ...next[i], done: true };\r\n }\r\n const last = next[next.length - 1];\r\n const text = turnSaidRef.current.trim();\r\n if (last && last.role === 'assistant' && !last.done) {\r\n next[next.length - 1] = { ...last, text };\r\n } else {\r\n next.push({ role: 'assistant', text, done: false });\r\n }\r\n return next;\r\n });\r\n break;\r\n case 'interrupted':\r\n replyingRef.current = false;\r\n dropHeld();\r\n stopHold();\r\n flushPlayback();\r\n chime('interrupt');\r\n setHearing(false);\r\n setState('listening');\r\n break;\r\n case 'turn_complete':\r\n spokeLoggedRef.current = false;\r\n botSpeakingRef.current = false;\r\n lastLoudRef.current = 0;\r\n setTurns(prev => prev.map(x => (x.done ? x : { ...x, done: true })));\r\n releaseHeld();\r\n replyingRef.current = false;\r\n stopHold();\r\n setHearing(false);\r\n flushExchange();\r\n break;\r\n case 'sources':\r\n if (Array.isArray(f.sources) && f.sources.length) setSources(f.sources);\r\n break;\r\n case 'seconds':\r\n if (typeof f.secondsLeft === 'number') setSecondsLeft(f.secondsLeft);\r\n break;\r\n case 'refused':\r\n optsRef.current.onRefused?.(f.code || 'guest');\r\n stop();\r\n break;\r\n case 'error':\r\n if (f.code === 'session_expiring' && recoverRef.current()) return;\r\n optsRef.current.onError?.(f.code || 'unavailable');\r\n stop();\r\n break;\r\n }\r\n };\r\n\r\n ws.onclose = ev => {\r\n if (wsRef.current !== ws) return;\r\n if (connectTimerRef.current !== null) clearTimeout(connectTimerRef.current);\r\n connectTimerRef.current = null;\r\n if (VoiceRecovery.canRetry(ev.code) && recoverRef.current()) return;\r\n if (ev.code === 4402) {\r\n abandoned = true;\r\n optsRef.current.onError?.(ev.reason === 'site' ? 'siteLimit' : 'limit');\r\n }\r\n teardown('ended');\r\n };\r\n // Browsers follow errors with close; decide there so an error cannot tear down\r\n // the microphone before a recoverable close is handled.\r\n ws.onerror = () => { if (!abandoned && wsRef.current === ws) console.warn('[kiku] voice transport interrupted'); };\r\n }, [dropHeld, enqueue, flushExchange, flushPending, flushPlayback, releaseHeld, sendOpen, startHold, stopHold, stop, teardown]);\r\n\r\n const hotReconnect = useCallback((newVoice?: string) => {\r\n const oldWs = wsRef.current;\r\n wsRef.current = null; // ignore late frames and close events from the old socket\r\n readyRef.current = false;\r\n // Keep what was actually heard/spoken, including an interrupted final turn.\r\n turnsRef.current = recoveredTurns(turnsRef.current, turnHeardRef.current, turnSaidRef.current);\r\n setTurns(turnsRef.current);\r\n setImages(prev => prev.filter(image => !image.pending));\r\n flushExchange();\r\n botSpeakingRef.current = false;\r\n spokeLoggedRef.current = false;\r\n replyingRef.current = false;\r\n dropHeld();\r\n setState('connecting');\r\n flushPlayback();\r\n stopHold();\r\n if (oldWs) {\r\n try { oldWs.send(JSON.stringify({ type: 'close' })); } catch { }\r\n try { oldWs.close(); } catch { }\r\n }\r\n const o = optsRef.current;\r\n // A new socket arms and waits; the shopper already tapped, so claim it on open.\r\n openOnReadyRef.current = true;\r\n const ws = new WebSocket(liveUrl(o, newVoice), voiceProtocols(o));\r\n wsRef.current = ws;\r\n attachWsHandlers(ws);\r\n }, [attachWsHandlers, dropHeld, flushExchange, flushPlayback, stopHold]);\r\n\r\n const recover = useCallback(() => {\r\n if (!startedRef.current || !hasConnectedRef.current || !nodeRef.current) return false;\r\n if (retryTimerRef.current !== null) return true;\r\n const delay = recoveryRef.current.nextDelay();\r\n if (delay === null) {\r\n optsRef.current.onError?.('connection');\r\n stop();\r\n return true;\r\n }\r\n const oldWs = wsRef.current;\r\n wsRef.current = null;\r\n readyRef.current = false;\r\n if (connectTimerRef.current !== null) clearTimeout(connectTimerRef.current);\r\n connectTimerRef.current = null;\r\n try { oldWs?.close(); } catch { }\r\n flushPlayback();\r\n dropHeld();\r\n stopHold();\r\n setHearing(false);\r\n setState('connecting');\r\n retryTimerRef.current = setTimeout(() => {\r\n retryTimerRef.current = null;\r\n if (startedRef.current) hotReconnect();\r\n }, delay);\r\n return true;\r\n }, [dropHeld, flushPlayback, hotReconnect, stop, stopHold]);\r\n recoverRef.current = recover;\r\n\r\n // Mobile browsers can suspend the audio context without closing the socket.\r\n // Resume capture while visible, and surface a failure if the microphone stays dead.\r\n useEffect(() => {\r\n const checkCapture = () => {\r\n if (!startedRef.current || !readyRef.current || !nodeRef.current || document.visibilityState === 'hidden') return;\r\n const ctx = ctxRef.current;\r\n if (!ctx) return;\r\n const now = Date.now();\r\n if (now - lastCaptureRef.current < 10_000) { captureResumeAtRef.current = 0; return; }\r\n if (!captureResumeAtRef.current) {\r\n captureResumeAtRef.current = now;\r\n void ctx.resume().catch(() => {});\r\n } else if (now - captureResumeAtRef.current > 10_000) {\r\n optsRef.current.onError?.('audio-capture');\r\n stop();\r\n }\r\n };\r\n const timer = window.setInterval(checkCapture, 2_000);\r\n document.addEventListener('visibilitychange', checkCapture);\r\n return () => { clearInterval(timer); document.removeEventListener('visibilitychange', checkCapture); };\r\n }, [stop]);\r\n\r\n const currentVoiceRef = useRef(opts.voice);\r\n useEffect(() => {\r\n if (currentVoiceRef.current !== opts.voice) {\r\n currentVoiceRef.current = opts.voice;\r\n if (wsRef.current && (state === 'listening' || state === 'thinking' || state === 'speaking')) {\r\n hotReconnect(opts.voice);\r\n }\r\n }\r\n }, [opts.voice, state, hotReconnect]);\r\n\r\n const start = useCallback(async (history: LiveTurn[] = []) => {\r\n if (startedRef.current && (wsRef.current || retryTimerRef.current !== null)) return;\r\n startedRef.current = true;\r\n recoveryRef.current = new VoiceRecovery();\r\n hasConnectedRef.current = false;\r\n setState('connecting');\r\n const o = optsRef.current;\r\n pendingRef.current = [];\r\n // This call's own turns; earlier calls arrive as history and are shown by the overlay.\r\n historyRef.current = history;\r\n turnsRef.current = [];\r\n setTurns([]);\r\n setImages([]);\r\n turnHeardRef.current = '';\r\n turnSaidRef.current = '';\r\n\r\n // Resumed inside the tap, the one moment a browser allows it.\r\n const ctxReady = audioContext();\r\n ctxRef.current?.resume().catch(() => {});\r\n primeChimes();\r\n\r\n let ws = wsRef.current;\r\n if (ws && ws.readyState === WebSocket.OPEN) {\r\n sendOpen(ws);\r\n } else if (ws && ws.readyState === WebSocket.CONNECTING) {\r\n openOnReadyRef.current = true;\r\n } else {\r\n ws = new WebSocket(liveUrl(o), voiceProtocols(o));\r\n wsRef.current = ws;\r\n openOnReadyRef.current = true;\r\n attachWsHandlers(ws);\r\n }\r\n\r\n let stream: MediaStream;\r\n try {\r\n if (!navigator.mediaDevices?.getUserMedia) throw { name: 'NotAllowedError' };\r\n stream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n autoGainControl: true,\r\n },\r\n });\r\n } catch (e: any) {\r\n try { ws.close(); } catch { }\r\n wsRef.current = null;\r\n setState('idle');\r\n o.onError?.(e?.name === 'NotAllowedError' ? 'not-allowed' : 'audio-capture');\r\n return;\r\n }\r\n if (wsRef.current !== ws) {\r\n stream.getTracks().forEach(t => t.stop());\r\n return;\r\n }\r\n streamRef.current = stream;\r\n for (const track of stream.getAudioTracks()) {\r\n track.enabled = !optsRef.current.muted;\r\n }\r\n\r\n const ctx = await ctxReady;\r\n if (wsRef.current !== ws) {\r\n stream.getTracks().forEach(t => t.stop());\r\n return;\r\n }\r\n if (!ctx) {\r\n optsRef.current.onError?.('audio-worklet');\r\n stop();\r\n return;\r\n }\r\n if (ctx.state === 'suspended') {\r\n ctx.resume().catch(() => {});\r\n }\r\n\r\n const inAnalyser = ctx.createAnalyser();\r\n inAnalyser.fftSize = 1024;\r\n inAnalyser.smoothingTimeConstant = 0.25;\r\n analyserRef.current = inAnalyser;\r\n\r\n const outGain = ctx.createGain();\r\n outGain.gain.value = 1;\r\n outGain.connect(ctx.destination);\r\n outGainRef.current = outGain;\r\n\r\n const outAnalyser = ctx.createAnalyser();\r\n outAnalyser.fftSize = 1024;\r\n outAnalyser.smoothingTimeConstant = 0.25;\r\n outAnalyser.connect(outGain);\r\n outAnalyserRef.current = outAnalyser;\r\n\r\n try {\r\n const node = new AudioWorkletNode(ctx, 'kiku-capture');\r\n nodeRef.current = node;\r\n node.port.onmessage = e => sendAudio(e.data);\r\n const srcNode = ctx.createMediaStreamSource(stream);\r\n const attach = () => {\r\n if (wsRef.current !== ws || !nodeRef.current) return;\r\n try { srcNode.connect(inAnalyser); } catch { }\r\n try { srcNode.connect(node); } catch { }\r\n };\r\n if (readyRef.current) {\r\n attach();\r\n } else {\r\n micAttachRef.current = attach;\r\n }\r\n } catch {\r\n optsRef.current.onError?.('audio-worklet');\r\n stop();\r\n }\r\n }, [attachWsHandlers, audioContext, sendAudio, sendOpen, stop]);\r\n\r\n // The model sends no partial transcripts, so \"hearing\" comes from the mic itself.\r\n useEffect(() => {\r\n if (state !== 'listening') {\r\n setHearing(false);\r\n return;\r\n }\r\n let lastLoud = 0;\r\n let on = false;\r\n // Replies re-enter listening, so this clock only runs while nobody is talking.\r\n const quietSince = Date.now();\r\n const id = window.setInterval(() => {\r\n const now = Date.now();\r\n if (!optsRef.current.muted && micLevel() > HEARING_LEVEL) lastLoud = now;\r\n if (now - Math.max(lastLoud, quietSince) > IDLE_CLOSE_MS) {\r\n window.clearInterval(id);\r\n optsRef.current.onError?.('idle');\r\n stop();\r\n return;\r\n }\r\n const next = now - lastLoud < HEARING_HOLD_MS;\r\n if (next !== on) {\r\n on = next;\r\n setHearing(next);\r\n }\r\n }, 100);\r\n return () => window.clearInterval(id);\r\n }, [state, micLevel, stop]);\r\n\r\n const prewarm = useCallback(() => {\r\n warmContext();\r\n }, [warmContext]);\r\n\r\n useEffect(() => () => { stop(); }, [stop]);\r\n\r\n useEffect(() => {\r\n const stream = streamRef.current;\r\n if (!stream) return;\r\n for (const track of stream.getAudioTracks()) track.enabled = !opts.muted;\r\n }, [opts.muted, state]);\r\n\r\n const attachPhoto = useCallback(async (file: File): Promise<boolean> => {\r\n const store = optsRef.current.storeScene;\r\n if (!store || !file.type.startsWith('image/')) return false;\r\n let image: string;\r\n try {\r\n image = await downscaleImage(file);\r\n } catch {\r\n return false;\r\n }\r\n const id = ++imageIdRef.current;\r\n setImages(prev => [...prev, { id, url: image, pending: false, sending: true }]);\r\n if (!(await store(image))) {\r\n setImages(prev => prev.filter(i => i.id !== id));\r\n return false;\r\n }\r\n setImages(prev => prev.map(i => (i.id === id ? { ...i, sending: false } : i)));\r\n turnImagesRef.current.push(image);\r\n const ws = wsRef.current;\r\n if (ws && ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({\r\n type: 'text',\r\n text: '(The visitor just attached a photo. You cannot see it. In one short sentence, ask what they would like changed in it.)',\r\n }));\r\n }\r\n return true;\r\n }, []);\r\n\r\n // A typed question into the live call — how a tapped card asks about itself.\r\n const ask = useCallback((text: string) => {\r\n const ws = wsRef.current;\r\n if (ws && ws.readyState === WebSocket.OPEN && text.trim()) ws.send(JSON.stringify({ type: 'text', text }));\r\n }, []);\r\n\r\n return { state, phase: state, hearing, sources, secondsLeft, photos, turns, images, micLevel, micSpectrum, spectrumBins, start, stop, prewarm, attachPhoto, ask };\r\n}\r\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","// Two automatic recoveries per user-started call; ready frames do not reset the budget.\r\nexport class VoiceRecovery {\r\n private attempts = 0;\r\n\r\n static canRetry(code: number): boolean {\r\n return code === 1006 || code === 1011 || code === 1012 || code === 1013;\r\n }\r\n\r\n nextDelay(): number | null {\r\n return [500, 1500][this.attempts++] ?? null;\r\n }\r\n}\r\n\r\ninterface Turn { role: 'user' | 'assistant'; text: string; done: boolean }\r\n\r\n// React may not have rendered the last transcript before a transport closes.\r\nexport function recoveredTurns(turns: Turn[], heard: string, said: string): Turn[] {\r\n const result = turns.map(turn => ({ ...turn }));\r\n for (const [role, text] of [['user', heard], ['assistant', said]] as const) {\r\n if (!text.trim()) continue;\r\n let index = -1;\r\n for (let i = result.length - 1; i >= 0; i--) {\r\n if (result[i].role === role && !result[i].done) { index = i; break; }\r\n }\r\n // A user turn is marked done when the assistant starts speaking.\r\n if (index < 0 && role === 'user') {\r\n const lastUser = result.map(turn => turn.role).lastIndexOf('user');\r\n if (lastUser >= 0 && result[lastUser].text === text.trim()) continue;\r\n }\r\n if (index >= 0) result[index].text = text.trim();\r\n else result.push({ role, text: text.trim(), done: true });\r\n }\r\n return result.map(turn => ({ ...turn, done: true }));\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 theme?: string;\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 theme,\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 theme={theme}\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';\r\nimport { thumpDoodles } from '../KikuDoodles';\r\n\r\nexport type ClayPhase = 'enter' | 'steady' | 'exit';\r\n\r\nconst FRAME_MS = 83;\r\nconst HOLD = 2;\r\nconst W = 240;\r\nconst H = 160;\r\nconst CX = W / 2;\r\nconst CY = H / 2;\r\nconst LUMP = 24;\r\nconst DISC_RX = 50;\r\nconst DISC_RY = 56;\r\nconst LOG = 124;\r\nconst LOG_H = 22;\r\nconst PIECES = 6;\r\nconst SUSHI_R = 13;\r\nconst SUSHI_GAP = 30;\r\n\r\ninterface Paint {\r\n ctx: CanvasRenderingContext2D;\r\n dpr: number;\r\n n: number;\r\n clay: string;\r\n light: string;\r\n dark: string;\r\n ink: string;\r\n}\r\n\r\ninterface Frame {\r\n draw: (p: Paint) => void;\r\n thump?: number;\r\n hold?: number;\r\n}\r\n\r\nconst lerp = (a: number, b: number, k: number) => a + (b - a) * k;\r\nconst boil = (n: number, i: number) => Math.sin(n * 12.9898 + i * 78.233) * 0.5;\r\n\r\nfunction blob(p: Paint, x: number, y: number, rx: number, ry: number, turn = 0) {\r\n const pts: [number, number][] = [];\r\n for (let i = 0; i < 16; i++) {\r\n const a = (i / 16) * Math.PI * 2;\r\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;\r\n pts.push([x + Math.cos(a + turn) * rx * r, y + Math.sin(a + turn) * ry * r]);\r\n }\r\n const mid = (a: [number, number], b: [number, number]) => [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2] as const;\r\n const { ctx } = p;\r\n ctx.beginPath();\r\n ctx.moveTo(...mid(pts[15], pts[0]));\r\n for (let i = 0; i < 16; i++) ctx.quadraticCurveTo(pts[i][0], pts[i][1], ...mid(pts[i], pts[(i + 1) % 16]));\r\n ctx.closePath();\r\n}\r\n\r\nfunction shade(p: Paint, lift: number) {\r\n const { ctx, dpr } = p;\r\n ctx.shadowColor = `rgba(0,0,0,${0.5 - lift * 0.22})`;\r\n ctx.shadowBlur = (4 + lift * 14) * dpr;\r\n ctx.shadowOffsetX = (1.5 + lift * 13) * dpr;\r\n ctx.shadowOffsetY = (2.5 + lift * 17) * dpr;\r\n}\r\n\r\nfunction round(p: Paint, x: number, y: number, r: number) {\r\n const g = p.ctx.createRadialGradient(x - r * 0.35, y - r * 0.4, 0, x, y, r * 1.15);\r\n g.addColorStop(0, p.light);\r\n g.addColorStop(0.35, p.clay);\r\n g.addColorStop(1, p.dark);\r\n return g;\r\n}\r\n\r\nfunction tube(p: Paint, y: number, h: number) {\r\n const g = p.ctx.createLinearGradient(0, y - h / 2, 0, y + h / 2);\r\n g.addColorStop(0, p.clay);\r\n g.addColorStop(0.25, p.light);\r\n g.addColorStop(0.5, p.clay);\r\n g.addColorStop(1, p.dark);\r\n return g;\r\n}\r\n\r\nfunction lump(p: Paint, r: number, lift = 0) {\r\n const { ctx } = p;\r\n const s = r * (1 + lift * 0.3);\r\n ctx.save();\r\n shade(p, lift);\r\n ctx.fillStyle = round(p, CX, CY, s);\r\n blob(p, CX, CY, s, s, p.n * 0.03);\r\n ctx.fill();\r\n ctx.restore();\r\n}\r\n\r\nfunction disc(p: Paint, rx: number, ry: number, clipBelow?: number) {\r\n const { ctx } = p;\r\n ctx.save();\r\n if (clipBelow !== undefined) {\r\n ctx.beginPath();\r\n ctx.rect(0, 0, W, clipBelow);\r\n ctx.clip();\r\n }\r\n shade(p, 0);\r\n ctx.fillStyle = round(p, CX, CY, Math.max(rx, ry));\r\n blob(p, CX, CY, rx, ry);\r\n ctx.fill();\r\n ctx.restore();\r\n}\r\n\r\nfunction log(p: Paint, x0: number, x1: number, y: number, h: number, left = h / 2, right = h / 2) {\r\n const { ctx } = p;\r\n ctx.save();\r\n shade(p, 0);\r\n ctx.fillStyle = tube(p, y, h);\r\n ctx.beginPath();\r\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]);\r\n ctx.fill();\r\n ctx.restore();\r\n}\r\n\r\nfunction sushi(p: Paint, x: number, y: number, r: number, lift = 0) {\r\n const { ctx } = p;\r\n const s = r * (1 + lift * 0.2);\r\n ctx.save();\r\n shade(p, lift);\r\n ctx.fillStyle = round(p, x, y, s);\r\n ctx.beginPath();\r\n ctx.arc(x, y, s, 0, Math.PI * 2);\r\n ctx.fill();\r\n ctx.restore();\r\n ctx.save();\r\n ctx.strokeStyle = p.dark;\r\n ctx.lineWidth = 1.4;\r\n ctx.lineCap = 'round';\r\n ctx.beginPath();\r\n for (let t = 0; t <= 1.001; t += 0.04) {\r\n const a = t * Math.PI * 5 + x * 0.3;\r\n const rr = (1.5 + t * (r - 4)) * (1 + lift * 0.2);\r\n const px = x + Math.cos(a) * rr;\r\n const py = y + Math.sin(a) * rr;\r\n if (t === 0) ctx.moveTo(px, py);\r\n else ctx.lineTo(px, py);\r\n }\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n\r\nfunction marks(p: Paint, strength: number) {\r\n const { ctx } = p;\r\n ctx.save();\r\n ctx.strokeStyle = `rgba(${p.ink},${0.55 * strength})`;\r\n ctx.lineWidth = 2;\r\n ctx.lineCap = 'round';\r\n for (let i = 0; i < 7; i++) {\r\n const a = (i / 7) * Math.PI * 2 + 0.14;\r\n const r0 = 38 + (1 - strength) * 8;\r\n const len = i % 2 ? 5 : 8;\r\n ctx.beginPath();\r\n ctx.moveTo(CX + Math.cos(a) * r0, CY + Math.sin(a) * r0);\r\n ctx.lineTo(CX + Math.cos(a) * (r0 + len), CY + Math.sin(a) * (r0 + len));\r\n ctx.stroke();\r\n }\r\n ctx.restore();\r\n}\r\n\r\nconst cutX = (i: number) => CX - LOG / 2 + (LOG * i) / PIECES;\r\n\r\nfunction score(p: Paint, x: number) {\r\n const { ctx } = p;\r\n ctx.save();\r\n ctx.strokeStyle = p.dark;\r\n ctx.lineWidth = 1.5;\r\n ctx.lineCap = 'round';\r\n ctx.beginPath();\r\n ctx.moveTo(x, CY - LOG_H / 2 + 2);\r\n ctx.lineTo(x + boil(p.n, x) * 1.5, CY + LOG_H / 2 - 2);\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\nconst sushiX = (i: number) => CX + (i - (PIECES - 1) / 2) * SUSHI_GAP;\r\n\r\nfunction pieces(p: Paint, opened: number, standing = -1, tipping = -1) {\r\n for (let i = 0; i < PIECES; i++) {\r\n let shift = 0;\r\n for (let c = 0; c < opened; c++) shift += i <= c ? -2 : 2;\r\n const x0 = cutX(i) + shift;\r\n const x1 = cutX(i + 1) + shift;\r\n if (i === tipping) sushi(p, lerp((x0 + x1) / 2, sushiX(i), 0.5), CY - 4, SUSHI_R, 0.5);\r\n else if (i <= standing) sushi(p, sushiX(i), CY, SUSHI_R);\r\n else log(p, x0, x1, CY, LOG_H, i === 0 ? LOG_H / 2 : 2, i === PIECES - 1 ? LOG_H / 2 : 2);\r\n }\r\n}\r\n\r\nfunction buildLoop(): Frame[] {\r\n const f: Frame[] = [];\r\n for (let i = 0; i < 5; i++) f.push({ draw: p => lump(p, LUMP) });\r\n\r\n const passes = [[LUMP, LUMP, 34, 38], [34, 38, 44, 48], [44, 48, DISC_RX, DISC_RY]];\r\n for (const [rx0, ry0, rx1, ry1] of passes) {\r\n for (let i = 0; i < 3; i++) {\r\n const k = (i + 1) / 3;\r\n const press = i === 0 ? 1.05 : 1;\r\n f.push({\r\n hold: 1,\r\n thump: i === 0 ? 0.25 : undefined,\r\n draw: p => disc(p, lerp(rx0, rx1, k), lerp(ry0, ry1, k) * press),\r\n });\r\n }\r\n f.push({ hold: 1, draw: p => disc(p, rx1, ry1) });\r\n }\r\n\r\n let widest = 0;\r\n for (let i = 0; i < 12; i++) {\r\n const k = (i + 1) / 12;\r\n const edge = lerp(CY + DISC_RY, CY - DISC_RY, k);\r\n const h = lerp(8, 24, k);\r\n const off = (edge - CY) / DISC_RY;\r\n widest = Math.max(widest, 2 * DISC_RX * Math.sqrt(Math.max(0, 1 - off * off)), 30);\r\n const w = widest;\r\n f.push({\r\n draw: p => {\r\n if (k < 1) disc(p, DISC_RX, DISC_RY, edge - h * 0.3);\r\n log(p, CX - w / 2, CX + w / 2, edge, h);\r\n },\r\n });\r\n }\r\n for (const k of [0.5, 1]) {\r\n f.push({ draw: p => log(p, CX - DISC_RX, CX + DISC_RX, lerp(CY - DISC_RY, CY, k), 24) });\r\n }\r\n for (let i = 0; i < 6; i++) {\r\n const k = (i + 1) / 6;\r\n const w = lerp(2 * DISC_RX, LOG, k);\r\n const h = lerp(24, LOG_H, k);\r\n const sway = i % 2 ? 2 : -2;\r\n f.push({ draw: p => log(p, CX - w / 2 + sway, CX + w / 2 + sway, CY, h) });\r\n }\r\n\r\n for (let c = 1; c < PIECES; c++) {\r\n f.push({ draw: p => { pieces(p, c - 1); score(p, cutX(c)); } });\r\n f.push({ thump: 0.35, draw: p => pieces(p, c) });\r\n }\r\n f.push({ draw: p => pieces(p, PIECES - 1) });\r\n\r\n for (let i = 0; i < PIECES; i++) {\r\n f.push({ thump: 0.12, draw: p => pieces(p, PIECES - 1, i - 1, i) });\r\n }\r\n for (let i = 0; i < 4; i++) f.push({ draw: p => pieces(p, PIECES - 1, PIECES - 1) });\r\n\r\n for (const k of [0.35, 0.7, 1]) {\r\n f.push({\r\n draw: p => {\r\n for (let i = 0; i < PIECES; i++) sushi(p, lerp(sushiX(i), CX, k), CY, lerp(SUSHI_R, 10, k), 0.4);\r\n },\r\n });\r\n }\r\n f.push({ thump: 1, draw: p => { lump(p, LUMP * 1.3); marks(p, 1); } });\r\n f.push({ draw: p => { lump(p, LUMP * 1.12); marks(p, 0.4); } });\r\n f.push({ draw: p => lump(p, LUMP * 1.04) });\r\n return f;\r\n}\r\n\r\nconst LOOP = buildLoop();\r\n\r\nconst ENTER: Frame[] = [\r\n ...[1.6, 1.25, 0.9, 0.5, 0.18].map(lift => ({ draw: (p: Paint) => lump(p, LUMP, lift) })),\r\n { thump: 0.7, draw: (p: Paint) => { lump(p, LUMP * 1.24); marks(p, 1); } },\r\n { draw: (p: Paint) => { lump(p, LUMP * 1.08); marks(p, 0.4); } },\r\n];\r\n\r\nconst EXIT_FADE = [1, 0.7, 0.35, 0];\r\n\r\nfunction resolveColor(host: HTMLElement, css: string) {\r\n const el = document.createElement('span');\r\n el.style.display = 'none';\r\n el.style.color = css;\r\n host.parentElement?.appendChild(el);\r\n const c = getComputedStyle(el).color;\r\n el.remove();\r\n return c;\r\n}\r\n\r\n// Clay on the table, seen from above: rolled flat, rolled back into a log, sliced and stood up, squashed together again.\r\nexport function ClayLoader({ phase, label, theme }: { phase: ClayPhase; label: React.ReactNode; theme?: string }) {\r\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\r\n const labelRef = React.useRef<HTMLParagraphElement>(null);\r\n const run = React.useRef({ n: 0, at: 0, held: 0, entered: false, last: LOOP[0] });\r\n\r\n React.useEffect(() => {\r\n const cv = canvasRef.current;\r\n const text = labelRef.current;\r\n const ctx = cv?.getContext('2d');\r\n if (!cv || !ctx || !text) return;\r\n\r\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\r\n cv.width = W * dpr;\r\n cv.height = H * dpr;\r\n const primary = 'var(--hsk-primary, #ff6a33)';\r\n const p: Paint = {\r\n ctx,\r\n dpr,\r\n n: 0,\r\n clay: resolveColor(cv, primary),\r\n light: resolveColor(cv, `color-mix(in srgb, ${primary} 55%, white)`),\r\n dark: resolveColor(cv, `color-mix(in srgb, ${primary} 70%, black)`),\r\n ink: getComputedStyle(cv).getPropertyValue('--hsk-doodle-ink').trim() || '31, 31, 31',\r\n };\r\n const st = run.current;\r\n let paintedPrimary = '';\r\n const refreshPalette = () => {\r\n // Theme custom properties interpolate: sampling only at the switch keeps the old color.\r\n const color = getComputedStyle(cv).getPropertyValue('--hsk-primary').trim() || '#ff6a33';\r\n if (color === paintedPrimary) return;\r\n paintedPrimary = color;\r\n p.clay = resolveColor(cv, color);\r\n p.light = resolveColor(cv, `color-mix(in srgb, ${color} 55%, white)`);\r\n p.dark = resolveColor(cv, `color-mix(in srgb, ${color} 70%, black)`);\r\n p.ink = getComputedStyle(cv).getPropertyValue('--hsk-doodle-ink').trim() || '31, 31, 31';\r\n };\r\n\r\n const paint = (frame: Frame, alpha = 1) => {\r\n refreshPalette();\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n ctx.clearRect(0, 0, W, H);\r\n ctx.globalAlpha = alpha;\r\n p.n = st.n++;\r\n frame.draw(p);\r\n ctx.globalAlpha = 1;\r\n };\r\n const thump = (strength: number) => {\r\n const r = cv.getBoundingClientRect();\r\n thumpDoodles({ x: r.left + r.width / 2, y: r.top + r.height / 2, strength });\r\n text.style.translate = '0 1px';\r\n text.style.rotate = `${boil(st.n, 4) * 0.8}deg`;\r\n };\r\n\r\n if (window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches) {\r\n paint(LOOP[0]);\r\n // Keep the static frame's palette in sync through the theme transition too.\r\n const repaint = window.setInterval(() => paint(LOOP[0]), FRAME_MS);\r\n return () => clearInterval(repaint);\r\n }\r\n\r\n let seq: Frame[] | null = phase === 'exit' ? null : phase === 'enter' && !st.entered ? ENTER : LOOP;\r\n if (seq) st.at = 0;\r\n let fade = 0;\r\n let id = 0;\r\n\r\n const tick = () => {\r\n text.style.translate = '';\r\n text.style.rotate = '';\r\n if (!seq) {\r\n if (fade === 0) thump(0.6);\r\n paint(st.last, EXIT_FADE[fade]);\r\n if (++fade >= EXIT_FADE.length) clearInterval(id);\r\n return;\r\n }\r\n const frame = seq[st.at];\r\n paint(frame);\r\n st.last = frame;\r\n if (frame.thump && st.held === 0) thump(frame.thump);\r\n if (seq === LOOP && ++st.held < (frame.hold ?? HOLD)) return;\r\n st.held = 0;\r\n if (++st.at < seq.length) return;\r\n if (seq === ENTER) st.entered = true;\r\n seq = LOOP;\r\n st.at = 0;\r\n };\r\n\r\n tick();\r\n id = window.setInterval(tick, FRAME_MS);\r\n return () => clearInterval(id);\r\n }, [phase === 'exit', theme]);\r\n\r\n return (\r\n <div className=\"hsk-clay\">\r\n <canvas className=\"hsk-clay-table\" ref={canvasRef} aria-hidden=\"true\" />\r\n <p className=\"hsk-lang-preparing\" ref={labelRef}>{label}</p>\r\n </div>\r\n );\r\n}\r\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, gallery?: import('./LightboxModal').LightboxGalleryData) => 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 isLiveStreaming = isLast && (loading || streaming);\r\n const msgReferencedIds = isLiveStreaming ? referencedIds : (msg.referencedIds ?? []);\r\n const msgSources = isLiveStreaming ? 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 } from 'react';\r\nimport { normalizeEntityImages, type ChatSource } from '@akropolys/sdk';\r\nimport { SparkleIcon } from '../icons';\r\nimport type { LightboxGalleryData } from './LightboxModal';\r\n\r\nexport function EntityGallery({\r\n source,\r\n onImageClick,\r\n}: {\r\n source: ChatSource;\r\n onImageClick?: (url: string, gallery?: LightboxGalleryData) => void;\r\n}) {\r\n const images = normalizeEntityImages(source.images ?? source.fields?.images, source.image, source.url);\r\n const [failed, setFailed] = useState(false);\r\n const cover = source.image || images[0]?.url;\r\n\r\n if (!cover) return <div className=\"hsk-cb-src-imgwrap-empty\"><SparkleIcon /></div>;\r\n\r\n const handleClick = (e: React.MouseEvent) => {\r\n e.stopPropagation();\r\n if (!onImageClick) return;\r\n const initialIndex = Math.max(0, images.findIndex(i => i.url === cover));\r\n if (images.length > 1) {\r\n onImageClick(cover, {\r\n images: images.map(img => ({ url: img.url, caption: img.caption, alt: img.alt })),\r\n index: initialIndex,\r\n title: source.name,\r\n });\r\n } else {\r\n onImageClick(cover);\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-src-imgwrap hsk-gallery-cover\"\r\n aria-label={images.length > 1 ? `View ${images.length} images of ${source.name}` : `View image of ${source.name}`}\r\n onClick={handleClick}\r\n >\r\n {failed ? (\r\n <SparkleIcon />\r\n ) : (\r\n <img\r\n src={cover}\r\n alt={images.find(i => i.url === cover)?.alt || source.name}\r\n loading=\"lazy\"\r\n onError={() => setFailed(true)}\r\n />\r\n )}\r\n {images.length > 1 && (\r\n <span className=\"hsk-gallery-count\">\r\n {Math.max(0, images.findIndex(i => i.url === cover)) + 1} / {images.length}\r\n </span>\r\n )}\r\n </button>\r\n );\r\n}\r\n","import { EntityGallery } from './EntityGallery';\r\nimport React, { useState, useRef, useEffect, useCallback } from 'react';\r\nimport type { ChatSource } from '@akropolys/sdk';\r\nimport { normalizeEntityImages, 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, gallery?: import('./LightboxModal').LightboxGalleryData) => 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 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 entities = referenced.filter(s => !s.swatch);\r\n\r\n const isSingleEntity = entities.length === 1;\r\n\r\n const display = isSingleEntity\r\n ? entities.flatMap(source => {\r\n const images = normalizeEntityImages(source.images ?? source.fields?.images, source.image, source.url);\r\n return images.length\r\n ? images.map((image, idx) => ({\r\n source,\r\n image,\r\n photoIndex: idx,\r\n totalPhotos: images.length,\r\n }))\r\n : [{ source, image: undefined, photoIndex: 0, totalPhotos: 0 }];\r\n })\r\n : entities.map(source => {\r\n const images = normalizeEntityImages(source.images ?? source.fields?.images, source.image, source.url);\r\n return {\r\n source,\r\n image: images[0],\r\n photoIndex: 0,\r\n totalPhotos: images.length,\r\n };\r\n });\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 ?? src.url ?? 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(({ source: src, image, photoIndex, totalPhotos }, si) => {\r\n const isReferenced = !!(src.id && referencedIds.includes(src.id));\r\n return (\r\n <div\r\n key={`${src.id ?? src.url ?? si}:${image?.url ?? photoIndex}`}\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 <EntityGallery\r\n source={\r\n isSingleEntity\r\n ? (image ? { ...src, image: image.url, images: [image] } : src)\r\n : src\r\n }\r\n onImageClick={onImageClick}\r\n />\r\n <div className=\"hsk-cb-src-info\">\r\n <div className=\"hsk-cb-src-name\">{src.name}</div>\r\n {isSingleEntity && image?.caption ? (\r\n <div className=\"hsk-cb-src-detail\">{image.caption}</div>\r\n ) : isSingleEntity && totalPhotos > 1 ? (\r\n <div className=\"hsk-cb-src-detail\">{`Photo ${photoIndex + 1} of ${totalPhotos}`}</div>\r\n ) : null}\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, gallery?: import('./components/LightboxModal').LightboxGalleryData) => 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';\r\nimport { createPortal } from 'react-dom';\r\nimport { useAkropolysContext, useCardFields, type ChatSource, type ChatAttachment } from '@akropolys/sdk';\r\nimport { cn } from '../../utils/cn';\r\nimport { detailsOf } from '../../utils/cardDetails';\r\nimport {\r\n SparkleIcon,\r\n BookmarkIcon,\r\n HistoryIcon,\r\n TrashIcon,\r\n PaperclipIcon,\r\n MessageIcon,\r\n WaveformIcon,\r\n StopIcon,\r\n ArrowUpIcon,\r\n PlusIcon,\r\n XIcon,\r\n} from './icons';\r\nimport { ListeningWave } from './components/ListeningWave';\r\nimport { AnimatedPlaceholder, HSK_STAGGER_MS, splitPlaceholder } from './components/AnimatedPlaceholder';\r\nimport type { UIStringKey, VoicePhase, ComposerAttachment } from './types';\r\n\r\nexport interface ChatComposerProps {\r\n gooId: string;\r\n input: string;\r\n setInput: React.Dispatch<React.SetStateAction<string>>;\r\n showKikuPicker: boolean;\r\n setShowKikuPicker: (show: boolean) => void;\r\n showAtPicker: boolean;\r\n setShowAtPicker: (show: boolean) => void;\r\n captureAllowed: boolean;\r\n discussedSources: ChatSource[];\r\n handleSelectExtension: (ext: string) => void;\r\n handleKikuCapture: (product: ChatSource) => void;\r\n handleKikuCaptureAll: (products: ChatSource[]) => void;\r\n handleKikuViewHistory: () => void;\r\n handleKikuDelete: () => void;\r\n attachments: ComposerAttachment[];\r\n removeAttachment: (idx: number) => void;\r\n chromeLoading: boolean;\r\n inputLocked: boolean;\r\n imageInputRef: React.RefObject<HTMLInputElement | null>;\r\n handleImageFiles: (files: FileList | null) => void;\r\n enableVision: boolean;\r\n enableVoice: boolean;\r\n canConverse: boolean;\r\n startVoice: (mode: 'dictate' | 'converse') => void;\r\n voiceBlocked: boolean;\r\n textareaRef: React.RefObject<HTMLTextAreaElement | null>;\r\n classNames?: { input?: string; sendButton?: string };\r\n handleInput: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\r\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\r\n voice: {\r\n active: boolean;\r\n supported: boolean;\r\n spectrumBins: () => number;\r\n micSpectrum: (out: Uint8Array) => boolean;\r\n };\r\n voicePhase: VoicePhase;\r\n activePlaceholder: string;\r\n loading: boolean;\r\n streaming: boolean;\r\n stop: () => void;\r\n handleSend: (text?: string) => Promise<void>;\r\n voiceError: string;\r\n setVoiceError?: (err: string) => void;\r\n langSwitching?: boolean;\r\n t: (key: UIStringKey, vars?: Record<string, string>) => string;\r\n rail?: React.ReactNode;\r\n notice?: React.ReactNode; // sits on the input's top edge, like a status pill on a reply\r\n onOpenMimi?: () => void;\r\n}\r\n\r\nexport function ChatComposer({\r\n gooId,\r\n input,\r\n setInput,\r\n showKikuPicker,\r\n setShowKikuPicker,\r\n showAtPicker,\r\n setShowAtPicker,\r\n captureAllowed,\r\n discussedSources,\r\n handleSelectExtension,\r\n handleKikuCapture,\r\n handleKikuCaptureAll,\r\n handleKikuViewHistory,\r\n handleKikuDelete,\r\n attachments,\r\n removeAttachment,\r\n chromeLoading,\r\n inputLocked,\r\n langSwitching = false,\r\n imageInputRef,\r\n handleImageFiles,\r\n enableVision,\r\n enableVoice,\r\n canConverse,\r\n startVoice,\r\n voiceBlocked,\r\n textareaRef,\r\n classNames = {},\r\n handleInput,\r\n handleKeyDown,\r\n voice,\r\n voicePhase,\r\n activePlaceholder,\r\n loading,\r\n streaming,\r\n stop,\r\n handleSend,\r\n voiceError,\r\n setVoiceError,\r\n t,\r\n rail,\r\n notice,\r\n onOpenMimi,\r\n}: ChatComposerProps) {\r\n const client = useAkropolysContext();\r\n const cardFields = useCardFields();\r\n const [placeholderReplay, setPlaceholderReplay] = React.useState(0);\r\n const [toolsOpen, setToolsOpen] = React.useState(false);\r\n\r\n React.useEffect(() => {\r\n if (!voiceError) return;\r\n const timer = setTimeout(() => {\r\n setVoiceError?.('');\r\n }, 6000);\r\n return () => clearTimeout(timer);\r\n }, [voiceError, setVoiceError]);\r\n\r\n const toolsheetRef = React.useRef<HTMLDivElement>(null);\r\n\r\n React.useEffect(() => {\r\n if (!toolsOpen) return;\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') setToolsOpen(false);\r\n };\r\n const handleOutside = (e: MouseEvent | TouchEvent) => {\r\n const path = (e.composedPath ? e.composedPath() : []) as EventTarget[];\r\n const targetEl = e.target as HTMLElement | null;\r\n const isInsideToggle = targetEl?.closest?.('.hsk-cb-tools-toggle') || path.some((el: any) => el?.classList?.contains?.('hsk-cb-tools-toggle'));\r\n const isInsideSheet = toolsheetRef.current && (path.includes(toolsheetRef.current) || toolsheetRef.current.contains(e.target as Node));\r\n if (isInsideToggle || isInsideSheet) {\r\n return;\r\n }\r\n setToolsOpen(false);\r\n };\r\n window.addEventListener('keydown', onKey);\r\n document.addEventListener('mousedown', handleOutside);\r\n document.addEventListener('touchstart', handleOutside, { passive: true });\r\n return () => {\r\n window.removeEventListener('keydown', onKey);\r\n document.removeEventListener('mousedown', handleOutside);\r\n document.removeEventListener('touchstart', handleOutside);\r\n };\r\n }, [toolsOpen]);\r\n\r\n const placeholderText = activePlaceholder || 'Ask me anything…';\r\n\r\n const fieldRef = useRef<HTMLDivElement>(null);\r\n const [phWraps, setPhWraps] = useState(() => placeholderText.length > 26); // a first guess the measurement corrects\r\n useEffect(() => {\r\n const field = fieldRef.current;\r\n if (!field || input) return;\r\n const measure = () => {\r\n const units = field.querySelectorAll<HTMLElement>('.hsk-animated-placeholder__char');\r\n if (units.length < 2) return setPhWraps(false);\r\n const first = units[0].offsetTop;\r\n const last = units[units.length - 1].offsetTop;\r\n setPhWraps(last - first > units[0].offsetHeight / 2);\r\n };\r\n measure();\r\n const ro = new ResizeObserver(measure);\r\n ro.observe(field);\r\n return () => ro.disconnect();\r\n }, [placeholderText, input]);\r\n const placeholderSweepMs =\r\n Math.max(splitPlaceholder(placeholderText).length - 1, 0) * HSK_STAGGER_MS;\r\n\r\n // the kite tears through the seam, the seam heals, a fresh kite glides in\r\n const [launching, setLaunching] = useState(false);\r\n const launchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const launch = () => {\r\n if (launchTimer.current) clearTimeout(launchTimer.current);\r\n setLaunching(true);\r\n launchTimer.current = setTimeout(() => {\r\n setLaunching(false);\r\n launchTimer.current = null;\r\n }, 550);\r\n };\r\n useEffect(() => () => { if (launchTimer.current) clearTimeout(launchTimer.current); }, []);\r\n\r\n // While a notice asks for a decision, the input takes no typing or clicks.\r\n const cardRef = useRef<HTMLDivElement>(null);\r\n const blocked = !!notice;\r\n useEffect(() => { cardRef.current?.toggleAttribute('inert', blocked); }, [blocked]);\r\n\r\n return (\r\n <div className=\"hsk-cb-input-wrap\" data-tools-open={toolsOpen ? 'true' : undefined}>\r\n {toolsOpen && (\r\n <>\r\n <div\r\n className=\"hsk-cb-toolsheet-scrim\"\r\n onClick={() => setToolsOpen(false)}\r\n aria-hidden=\"true\"\r\n />\r\n <div className=\"hsk-cb-toolsheet-wrap\" ref={toolsheetRef}>\r\n <div className=\"hsk-cb-toolsheet\" role=\"menu\">\r\n {enableVision && (\r\n <button\r\n className=\"hsk-cb-toolsheet-item\"\r\n role=\"menuitem\"\r\n onClick={() => { setToolsOpen(false); imageInputRef.current?.click(); }}\r\n disabled={loading}\r\n >\r\n <PaperclipIcon />\r\n <span>{t('attachImage')}</span>\r\n </button>\r\n )}\r\n {enableVoice && canConverse && (\r\n <button\r\n className=\"hsk-cb-toolsheet-item\"\r\n role=\"menuitem\"\r\n onClick={() => {\r\n setToolsOpen(false);\r\n if (voiceBlocked) setVoiceError?.(t('errAccountRequired'));\r\n else startVoice('converse');\r\n }}\r\n disabled={loading || chromeLoading}\r\n >\r\n <WaveformIcon />\r\n <span>{t('voiceModeStart')}</span>\r\n </button>\r\n )}\r\n {onOpenMimi && (\r\n <button className=\"hsk-cb-toolsheet-item\" role=\"menuitem\" onClick={onOpenMimi}>\r\n <MessageIcon />\r\n <span>MiMi</span>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </>\r\n )}\r\n {notice}\r\n <div className=\"hsk-cb-input-card\" ref={cardRef}>\r\n {(/^@kiku\\b/i.test(input) || showKikuPicker || showAtPicker) && (\r\n <div className=\"hsk-cb-docked-header\">\r\n <span className=\"hsk-cb-docked-sub\">{t('captureAndRemember')}</span>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-close\"\r\n onClick={() => {\r\n setInput(prev => prev.replace(/^@kiku\\s*/i, ''));\r\n setShowKikuPicker(false);\r\n setShowAtPicker(false);\r\n }}\r\n aria-label=\"Close mode\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n )}\r\n\r\n {(showKikuPicker || showAtPicker) && (\r\n <div className=\"hsk-cb-docked-options\" onMouseDown={e => e.preventDefault()}>\r\n {showAtPicker && captureAllowed && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => handleSelectExtension('@kiku')}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><SparkleIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">kiku</span>\r\n <span className=\"hsk-cb-docked-option-desc\">capture & remember</span>\r\n </button>\r\n )}\r\n\r\n {showKikuPicker && captureAllowed && (\r\n <>\r\n {discussedSources.map((src, i) => (\r\n <button\r\n key={src.id ?? i}\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuCapture(src); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\">\r\n {src.image ? <img src={src.image} alt=\"\" /> : <BookmarkIcon />}\r\n </span>\r\n <span className=\"hsk-cb-docked-option-title\">{src.name}</span>\r\n {detailsOf(src, cardFields)[0] && (\r\n <span className=\"hsk-cb-docked-option-detail\">{detailsOf(src, cardFields)[0].value}</span>\r\n )}\r\n </button>\r\n ))}\r\n {discussedSources.length > 1 && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuCaptureAll(discussedSources); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><BookmarkIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">{t('captureAll', { count: String(discussedSources.length) })}</span>\r\n </button>\r\n )}\r\n {discussedSources.length === 0 && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuCapture({ name: 'current page', id: undefined }); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><BookmarkIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">{t('captureCurrentPage')}</span>\r\n </button>\r\n )}\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuViewHistory(); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><HistoryIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">{t('whatHaveYouSaved')}</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-docked-option\"\r\n onClick={() => { handleKikuDelete(); setShowKikuPicker(false); }}\r\n >\r\n <span className=\"hsk-cb-docked-option-icon\"><TrashIcon /></span>\r\n <span className=\"hsk-cb-docked-option-title\">{t('deleteThis')}</span>\r\n </button>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n\r\n {attachments.length > 0 && (\r\n <div className=\"hsk-cb-img-strip\">\r\n {attachments.map((att, i) => (\r\n <div key={i} className=\"hsk-cb-img-thumb-wrap\">\r\n <img src={att.thumb || att.data} alt={`attachment ${i + 1}`} className=\"hsk-cb-img-thumb\" />\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-img-thumb-remove\"\r\n onClick={() => removeAttachment(i)}\r\n aria-label=\"Remove image\"\r\n >\r\n <XIcon size={10} />\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div\r\n className={cn(\"hsk-cb-input-box\", chromeLoading && \"hsk-cb-input-box--waiting\")}\r\n data-cascade={placeholderReplay % 2 ? 'b' : 'a'}\r\n data-tools={toolsOpen ? 'open' : 'closed'}\r\n style={{ '--hsk-text-sweep': `${placeholderSweepMs}ms` } as React.CSSProperties}\r\n >\r\n <input\r\n ref={imageInputRef as any}\r\n type=\"file\"\r\n accept=\"image/*\"\r\n className=\"hsk-sr-only\"\r\n onChange={e => {\r\n handleImageFiles(e.target.files);\r\n e.target.value = '';\r\n }}\r\n />\r\n {(enableVision || (enableVoice && canConverse)) && (\r\n <button\r\n className={cn('hsk-cb-tools-toggle', toolsOpen && 'hsk-cb-tools-toggle--open')}\r\n onClick={() => setToolsOpen(o => !o)}\r\n disabled={loading || chromeLoading}\r\n aria-label={toolsOpen ? 'Close options' : 'More options'}\r\n aria-expanded={toolsOpen}\r\n >\r\n <PlusIcon />\r\n </button>\r\n )}\r\n <>\r\n {enableVision && (\r\n <button\r\n className=\"hsk-cb-attach-btn\"\r\n onClick={() => imageInputRef.current?.click()}\r\n disabled={loading}\r\n aria-label=\"Attach image\"\r\n >\r\n <PaperclipIcon />\r\n </button>\r\n )}\r\n </>\r\n <div className=\"hsk-cb-field\" ref={fieldRef} data-ph-lines={!input && phWraps ? '2' : undefined}>\r\n <textarea\r\n ref={textareaRef as any}\r\n value={input}\r\n onChange={handleInput}\r\n onKeyDown={handleKeyDown}\r\n rows={1}\r\n placeholder=\"\"\r\n className={cn(\"hsk-cb-textarea\", classNames.input)}\r\n aria-label={activePlaceholder}\r\n disabled={inputLocked || (loading && !streaming) || langSwitching}\r\n />\r\n <AnimatedPlaceholder\r\n placeholder={activePlaceholder}\r\n visible={!input}\r\n staggerMs={HSK_STAGGER_MS}\r\n replaySeed={placeholderReplay}\r\n />\r\n </div>\r\n {enableVoice && canConverse && (\r\n <button\r\n className={cn(\"hsk-cb-voice-mode-btn\", voiceBlocked && \"hsk-cb-voice-mode-btn--blocked\")}\r\n onClick={() => voiceBlocked ? setVoiceError?.(t('errAccountRequired')) : startVoice('converse')}\r\n disabled={loading || chromeLoading}\r\n aria-label=\"Voice conversation\"\r\n >\r\n <WaveformIcon />\r\n </button>\r\n )}\r\n {(loading || streaming) && !launching ? (\r\n <button\r\n className={cn(\"hsk-cb-send\", \"hsk-cb-send--stop\", classNames.sendButton)}\r\n onClick={stop}\r\n aria-label=\"Stop generating\"\r\n >\r\n <StopIcon />\r\n </button>\r\n ) : (\r\n <button\r\n className={cn(\r\n \"hsk-cb-send\",\r\n launching && \"is-launching\",\r\n classNames.sendButton\r\n )}\r\n onClick={() => {\r\n launch();\r\n handleSend();\r\n }}\r\n disabled={langSwitching || inputLocked || chromeLoading || (!input.trim() && attachments.length === 0)}\r\n aria-label=\"Send message\"\r\n >\r\n <svg width=\"0\" height=\"0\" aria-hidden=\"true\" focusable=\"false\" style={{ position: 'absolute' }}>\r\n <defs>\r\n <filter id={gooId}>\r\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"1.6\" result=\"blur\" />\r\n <feColorMatrix in=\"blur\" type=\"matrix\"\r\n values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 16 -7\" result=\"goo\" />\r\n <feBlend in=\"SourceGraphic\" in2=\"goo\" />\r\n </filter>\r\n </defs>\r\n </svg>\r\n <span className=\"hsk-cb-send-sheath\" aria-hidden=\"true\" />\r\n <span className=\"hsk-cb-send-stage\" style={{ filter: `url(#${gooId})` }}>\r\n <span className=\"hsk-cb-send-seam\" aria-hidden=\"true\" />\r\n <span className=\"hsk-cb-send-kite\">\r\n <ArrowUpIcon />\r\n </span>\r\n </span>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n {voiceBlocked ? (\r\n <div className=\"hsk-cb-voice-error\" role=\"status\" onClick={() => setVoiceError?.('')}>\r\n <span>{t('errAccountRequired')}</span>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-voice-error-dismiss\"\r\n onClick={(e) => { e.stopPropagation(); setVoiceError?.(''); }}\r\n aria-label=\"Dismiss error\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n ) : voiceError && (\r\n <div className=\"hsk-cb-voice-error\" role=\"status\" onClick={() => setVoiceError?.('')}>\r\n <span>{t(voiceError as UIStringKey)}</span>\r\n <button\r\n type=\"button\"\r\n className=\"hsk-cb-voice-error-dismiss\"\r\n onClick={(e) => { e.stopPropagation(); setVoiceError?.(''); }}\r\n aria-label=\"Dismiss error\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\nexport interface AnimatedPlaceholderProps {\r\n text?: string;\r\n placeholder?: string;\r\n visible?: boolean;\r\n replay?: number;\r\n replaySeed?: number;\r\n staggerMs?: number;\r\n}\r\n\r\nexport const HSK_STAGGER_MS = 16;\r\n\r\nconst HSK_FIELD_BASE_MS = 110;\r\n\r\nconst JOINING_SCRIPT = /[-ۿ܀-ݏ߀-߿ࡠ-ࣿﭐ-﷿ﹰ-]/;\r\n\r\ntype GraphemeSegmenter = {\r\n segment(input: string): Iterable<{ segment: string }>;\r\n};\r\ntype IntlWithSegmenter = typeof Intl & {\r\n Segmenter?: new (locale?: string, options?: { granularity: string }) => GraphemeSegmenter;\r\n};\r\n\r\nexport function splitPlaceholder(text: string): string[] {\r\n if (!text) return [];\r\n\r\n if (JOINING_SCRIPT.test(text)) return text.split(/(\\s+)/).filter(Boolean);\r\n\r\n const I = typeof Intl !== 'undefined' ? (Intl as IntlWithSegmenter) : undefined;\r\n if (I?.Segmenter) {\r\n const seg = new I.Segmenter(undefined, { granularity: 'grapheme' });\r\n return Array.from(seg.segment(text), s => s.segment);\r\n }\r\n\r\n return text.split(/(\\s+)/).filter(Boolean);\r\n}\r\n\r\nexport function AnimatedPlaceholder({\r\n text,\r\n placeholder,\r\n visible = true,\r\n replay = 0,\r\n replaySeed,\r\n staggerMs = HSK_STAGGER_MS,\r\n}: AnimatedPlaceholderProps) {\r\n if (!visible) return null;\r\n const content = text || placeholder || '';\r\n if (!content) return null;\r\n const seed = replaySeed !== undefined ? replaySeed : replay;\r\n\r\n const 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 theme={themeAttr}\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';\nimport type { VoicePhase } from '../utils/voiceSession';\n\nexport interface VoiceCanvasProps {\n phase: VoicePhase;\n theme?: string;\n\n level: () => number;\n\n spectrum?: (out: Uint8Array) => boolean;\n\n bins?: () => number;\n className?: string;\n}\n\ntype RGB = [number, number, number];\n\nfunction parseColor(css: string, fallback: RGB): RGB {\n const hex = css.trim().match(/^#([\\da-f]{3}|[\\da-f]{6})$/i);\n if (hex) {\n const value = hex[1].length === 3 ? hex[1].split('').map(c => c + c).join('') : hex[1];\n return [parseInt(value.slice(0, 2), 16), parseInt(value.slice(2, 4), 16), parseInt(value.slice(4, 6), 16)];\n }\n const m = css.match(/-?[\\d.]+/g);\n if (!m || m.length < 3) return fallback;\n return [Number(m[0]), Number(m[1]), Number(m[2])];\n}\n\nfunction mix(a: RGB, b: RGB, t: number): RGB {\n return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];\n}\n\nfunction rgba(c: RGB, alpha: number): string {\n return `rgba(${c[0] | 0}, ${c[1] | 0}, ${c[2] | 0}, ${alpha})`;\n}\n\nconst BANDS = 24;\nconst SPECTRUM_FRACTION = 0.42;\n\nexport function VoiceCanvas({ phase, theme, level, spectrum, bins, className }: VoiceCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const phaseRef = useRef(phase);\n const levelRef = useRef(level);\n const spectrumRef = useRef(spectrum);\n const binsRef = useRef(bins);\n useEffect(() => { phaseRef.current = phase; }, [phase]);\n useEffect(() => { levelRef.current = level; }, [level]);\n useEffect(() => { spectrumRef.current = spectrum; }, [spectrum]);\n useEffect(() => { binsRef.current = bins; }, [bins]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const style = getComputedStyle(canvas);\n const accent = parseColor(style.getPropertyValue('--hsk-primary') || '', [255, 106, 51]);\n const ink = parseColor(style.getPropertyValue('--hsk-chat-text') || '', [31, 31, 31]);\n\n let raf = 0;\n let w = 0;\n let h = 0;\n\n const resize = () => {\n const dpr = Math.min(window.devicePixelRatio || 1, 3);\n const rect = canvas.getBoundingClientRect();\n w = Math.max(1, rect.width);\n h = Math.max(1, rect.height);\n canvas.width = Math.round(w * dpr);\n canvas.height = Math.round(h * dpr);\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n };\n resize();\n const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(resize) : null;\n ro?.observe(canvas);\n window.addEventListener('resize', resize);\n\n const reduced = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false;\n\n const bands = new Float32Array(BANDS);\n let strokes: CanvasGradient[] = [];\n let glow: CanvasGradient | null = null;\n let strokesFor = -1;\n let freqBuf: Uint8Array | null = null;\n let amp = 0;\n let sweep = 0;\n const start = performance.now();\n\n const follow = (cur: number, target: number, attack: number, release: number) =>\n cur + (target - cur) * (target > cur ? attack : release);\n\n const readSpectrum = () => {\n const read = spectrumRef.current;\n const n = binsRef.current?.() ?? 0;\n if (!read || !n) return false;\n if (!freqBuf || freqBuf.length !== n) freqBuf = new Uint8Array(n);\n if (!read(freqBuf)) return false;\n\n const usable = Math.max(BANDS, Math.floor(n * SPECTRUM_FRACTION));\n const per = usable / BANDS;\n for (let b = 0; b < BANDS; b++) {\n const from = Math.floor(b * per);\n const to = Math.max(from + 1, Math.floor((b + 1) * per));\n let sum = 0;\n for (let i = from; i < to; i++) sum += freqBuf[i];\n const v = sum / (to - from) / 255;\n bands[b] = follow(bands[b], v, reduced ? 0.2 : 0.55, reduced ? 0.06 : 0.14);\n }\n return true;\n };\n\n const synthesizeBands = (t: number, energy: number) => {\n for (let b = 0; b < BANDS; b++) {\n const m = b / (BANDS - 1);\n const shape = Math.pow(1 - m, 1.6) * (0.75 + 0.25 * Math.sin(t * 3.1 + b * 0.7));\n bands[b] = follow(bands[b], shape * energy, 0.3, 0.12);\n }\n };\n\n const bandAt = (m: number) => {\n const x = Math.min(BANDS - 1, Math.max(0, m * (BANDS - 1)));\n const i = Math.floor(x);\n const f = x - i;\n const a = bands[i];\n const b = bands[Math.min(BANDS - 1, i + 1)];\n return a + (b - a) * f * f * (3 - 2 * f);\n };\n\n const draw = (now: number) => {\n raf = requestAnimationFrame(draw);\n const t = (now - start) / 1000;\n const p = phaseRef.current;\n\n const live = Math.min(1, levelRef.current());\n const floor = p === 'speaking' ? 0.42 : p === 'listening' ? 0.3 : p === 'thinking' ? 0.28 : 0.12;\n amp = follow(amp, Math.max(floor, live), reduced ? 0.1 : 0.5, reduced ? 0.05 : 0.11);\n\n if (!readSpectrum()) synthesizeBands(t, Math.max(0.25, amp));\n\n ctx.clearRect(0, 0, w, h);\n const cy = h / 2;\n\n sweep = p === 'thinking' ? (sweep + 0.012) % 1.6 : 0;\n\n const layers = 3;\n if (strokesFor !== w) {\n strokes = [];\n for (let l = 0; l < layers; l++) {\n const depth = l / (layers - 1 || 1);\n const hue = mix(accent, ink, depth * 0.5);\n const g = ctx.createLinearGradient(0, 0, w, 0);\n g.addColorStop(0, rgba(hue, 0));\n g.addColorStop(0.5, rgba(hue, 0.9 - depth * 0.35));\n g.addColorStop(1, rgba(hue, 0));\n strokes.push(g);\n }\n glow = ctx.createLinearGradient(0, 0, w, 0);\n glow.addColorStop(0, rgba(accent, 0));\n glow.addColorStop(0.5, rgba(accent, 0.14));\n glow.addColorStop(1, rgba(accent, 0));\n strokesFor = w;\n }\n const maxAmp = h * 0.32;\n const step = Math.max(4, w / 130);\n\n for (let l = 0; l < layers; l++) {\n const depth = l / (layers - 1 || 1);\n const lag = l * 0.055;\n const scale = 1 - depth * 0.22;\n\n ctx.beginPath();\n let px = 0;\n let py = cy;\n for (let x = 0; x <= w; x += step) {\n const u = x / w;\n const envelope = Math.pow(Math.sin(Math.PI * u), 0.85);\n const focus = p === 'thinking'\n ? Math.exp(-Math.pow((u - (sweep - 0.3)) * 4.5, 2))\n : 1;\n\n const band = bandAt(Math.abs(u - 0.5) * 2);\n const tl = t - lag;\n const ripple =\n Math.sin(u * Math.PI * 2 * 2.1 + tl * 7.4) * 0.66 +\n Math.sin(u * Math.PI * 2 * 3.7 - tl * 5.6) * 0.26 +\n Math.sin(u * Math.PI * 2 * 5.9 + tl * 9.1) * 0.08;\n\n const y =\n cy +\n envelope * focus * scale * maxAmp * amp * (0.6 + band * 1.1) * ripple +\n Math.sin(u * Math.PI * 2 * 0.6 + (t - lag) * 2.2) * envelope * h * 0.01;\n\n if (x === 0) {\n ctx.moveTo(x, y);\n } else {\n ctx.quadraticCurveTo(px, py, (px + x) / 2, (py + y) / 2);\n }\n px = x;\n py = y;\n }\n ctx.quadraticCurveTo(px, py, w, py);\n\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n const width = (l === 0 ? 3 : 1.6) * (1 + amp * 0.6);\n if (l === 0) {\n ctx.strokeStyle = glow!;\n ctx.lineWidth = width * 5;\n ctx.stroke();\n }\n ctx.strokeStyle = strokes[l];\n ctx.lineWidth = width;\n ctx.stroke();\n }\n };\n\n raf = requestAnimationFrame(draw);\n return () => {\n cancelAnimationFrame(raf);\n ro?.disconnect();\n window.removeEventListener('resize', resize);\n };\n }, [theme]);\n\n return <canvas ref={canvasRef} className={className} aria-hidden=\"true\" />;\n}\n","import React, { useState, useEffect, useRef } from 'react';\r\nimport { CloseIcon, ChevronLeftIcon, ChevronRightIcon } from '../icons';\r\n\r\nexport interface LightboxImage {\r\n url: string;\r\n caption?: string;\r\n alt?: string;\r\n}\r\n\r\nexport interface LightboxGalleryData {\r\n images: LightboxImage[];\r\n index?: number;\r\n title?: string;\r\n}\r\n\r\nexport interface LightboxModalProps {\r\n src?: string | null;\r\n images?: LightboxImage[];\r\n initialIndex?: number;\r\n title?: string;\r\n onClose: () => void;\r\n}\r\n\r\nexport function LightboxModal({ src, images, initialIndex = 0, title, onClose }: LightboxModalProps) {\r\n const list: LightboxImage[] = images && images.length > 0\r\n ? images\r\n : (src ? [{ url: src }] : []);\r\n\r\n const [index, setIndex] = useState(initialIndex);\r\n const touchX = useRef<number | null>(null);\r\n\r\n useEffect(() => {\r\n setIndex(Math.min(Math.max(0, initialIndex), Math.max(0, list.length - 1)));\r\n }, [initialIndex, list.length]);\r\n\r\n useEffect(() => {\r\n if (list.length === 0) return;\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') onClose();\r\n if (list.length > 1) {\r\n if (e.key === 'ArrowLeft') setIndex(i => (i - 1 + list.length) % list.length);\r\n if (e.key === 'ArrowRight') setIndex(i => (i + 1) % list.length);\r\n }\r\n };\r\n window.addEventListener('keydown', handleKeyDown);\r\n return () => window.removeEventListener('keydown', handleKeyDown);\r\n }, [list.length, onClose]);\r\n\r\n if (list.length === 0) return null;\r\n\r\n const current = list[index] || list[0];\r\n const step = (dir: number) => setIndex(i => (i + dir + list.length) % list.length);\r\n\r\n return (\r\n <div className=\"hsk-lightbox\" onClick={onClose} role=\"dialog\" aria-modal=\"true\" aria-label={title || 'Image preview'}>\r\n <button className=\"hsk-lightbox-close\" onClick={onClose} aria-label=\"Close image\">\r\n <CloseIcon />\r\n </button>\r\n\r\n {title && (\r\n <div className=\"hsk-lightbox-top\" onClick={e => e.stopPropagation()}>\r\n <span className=\"hsk-lightbox-title\">{title}</span>\r\n </div>\r\n )}\r\n\r\n <div\r\n className=\"hsk-lightbox-stage\"\r\n onClick={e => e.stopPropagation()}\r\n onTouchStart={e => { touchX.current = e.touches[0]?.clientX ?? null; }}\r\n onTouchEnd={e => {\r\n const end = e.changedTouches[0]?.clientX;\r\n if (touchX.current !== null && end !== undefined && Math.abs(end - touchX.current) > 40) {\r\n step(end < touchX.current ? 1 : -1);\r\n }\r\n touchX.current = null;\r\n }}\r\n >\r\n {list.length > 1 && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-lightbox-nav hsk-lightbox-nav--prev\"\r\n onClick={() => step(-1)}\r\n aria-label=\"Previous image\"\r\n >\r\n <ChevronLeftIcon />\r\n </button>\r\n )}\r\n\r\n <div className=\"hsk-lightbox-content\">\r\n <img\r\n key={current.url}\r\n src={current.url}\r\n alt={current.alt || title || ''}\r\n className=\"hsk-lightbox-img\"\r\n />\r\n {current.caption && (\r\n <div className=\"hsk-lightbox-caption\">{current.caption}</div>\r\n )}\r\n </div>\r\n\r\n {list.length > 1 && (\r\n <button\r\n type=\"button\"\r\n className=\"hsk-lightbox-nav hsk-lightbox-nav--next\"\r\n onClick={() => step(1)}\r\n aria-label=\"Next image\"\r\n >\r\n <ChevronRightIcon />\r\n </button>\r\n )}\r\n </div>\r\n\r\n {list.length > 1 && (\r\n <div className=\"hsk-lightbox-bottom\" onClick={e => e.stopPropagation()}>\r\n <div className=\"hsk-lightbox-counter\">\r\n {index + 1} / {list.length}\r\n </div>\r\n </div>\r\n )}\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) backwards}@keyframes hsk-input-dock{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}.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)}.hsk-cb-main{position:relative;flex:1;min-width:0;display:flex;flex-direction:column;height:100%;overflow:hidden}@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;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;--hsk-tl-gutter: 28px;position:relative;padding-left:var(--hsk-tl-gutter)!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) - var(--hsk-tl-gutter, 28px) - 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));transform:translate(calc(10px + var(--hsk-tl-d) * 7px));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(10px + 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(10px + var(--hsk-tl-d) * 7px - 2px))}.hsk-cb-tl-item:hover .hsk-cb-tl-dot{transform:translate(calc(10px + var(--hsk-tl-d) * 7px - 2px)) 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[data-tools-open=true]{z-index:20!important}.hsk-cb-input-wrap:after{display:none!important}.hsk-cb-input-card{position:relative;z-index:1001;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}@media(max-width:640px){.hsk-cb-tools-toggle{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;border:none;background:var(--hsk-surface-1, rgba(0,0,0,.06));color:var(--hsk-chat-muted, #5f6368);cursor:pointer;flex-shrink:0;transition:background .16s,color .16s,transform .22s cubic-bezier(.34,1.56,.64,1)}.hsk-cb-tools-toggle:active{transform:scale(.91)}.hsk-cb-tools-toggle--open{background:color-mix(in srgb,var(--hsk-primary, #ff6a33) 14%,transparent);color:var(--hsk-primary, #ff6a33);transform:rotate(45deg)}[data-hsk-theme] .hsk-cb-tools-toggle{background:var(--hsk-surface-1)!important;color:var(--hsk-chat-muted)!important}[data-hsk-theme] .hsk-cb-tools-toggle--open{background:color-mix(in srgb,var(--hsk-primary) 14%,transparent)!important;color:var(--hsk-primary)!important}.hsk-cb-input-box{grid-template-columns:auto 1fr auto}.hsk-cb-input-box>.hsk-cb-tools-toggle{grid-column:1;grid-row:1;display:inline-flex}.hsk-cb-input-box>.hsk-cb-field{grid-column:2;grid-row:1}.hsk-cb-input-box>.hsk-cb-send,.hsk-cb-input-box>.hsk-chat-send{grid-column:3;grid-row:1}.hsk-cb-input-box>.hsk-cb-attach-btn,.hsk-cb-input-box>.hsk-cb-voice-mode-btn{display:none!important}.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-tools-toggle,.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-toolsheet-wrap{position:absolute;bottom:calc(100% - 6px);inset-inline-start:var(--hsk-composer-pad-x, 14px);inset-inline-end:auto;z-index:1000;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: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 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-input-wrap[data-tools-open=true] .hsk-cb-tools-toggle{position:relative;z-index:1002}.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:1002;display:inline-flex;flex-wrap:nowrap;white-space:nowrap;align-items:center;gap:8px;width:fit-content;max-width:calc(100% - 24px);margin-bottom:-11px;margin-inline-start:14px;padding:3px 4px 3px 12px;border-radius:999px;background:var(--hsk-chat-ai-bg, #eeeef0);color:var(--hsk-chat-text, #111827);box-shadow:0 0 0 3px var(--hsk-chat-bg, #ffffff);font:600 12px/24px 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:24px;padding:0 11px;border:none;border-radius:999px;background:#80808029;color:inherit;font:600 12px var(--hsk-font);cursor:pointer;transition:opacity .15s}.hsk-cb-leave-btn:hover{opacity:.88}.hsk-cb-leave-btn--end{background:var(--hsk-primary, #ff6a33);color:#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}}.hsk-cb-opening-spinner{animation:hsk-cb-opening-spin 1s linear infinite}@keyframes hsk-cb-opening-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.hsk-cb-opening-spinner{animation:none}}.hsk-opening-shell{position:fixed;inset:0;z-index:2147483647;height:100vh;height:100dvh;margin:0;box-sizing:border-box;background:var(--hsk-chat-bg, #f5f0e8);color:var(--hsk-chat-text, #342820);font:14px var(--hsk-font, system-ui, sans-serif)}.hsk-opening-panel{max-width:720px;height:100%;margin:0 auto;display:flex;flex-direction:column}.hsk-opening-header{display:flex;align-items:center;justify-content:space-between;padding:14px 24px 10px;min-height:48px;box-sizing:border-box;font-weight:600}.hsk-opening-logo{max-width:150px;height:24px;object-fit:contain}.hsk-opening-close{appearance:none;border:0;border-radius:50%;background:transparent;color:inherit;font:28px/1 system-ui,sans-serif;width:40px;height:40px;cursor:pointer}.hsk-opening-close:focus-visible,.hsk-opening-retry:focus-visible{outline:2px solid currentColor;outline-offset:3px}.hsk-opening-content{flex:1;display:grid;place-items:center;padding:24px}.hsk-opening-feedback{display:flex;flex-direction:column;align-items:center;gap:14px;color:inherit}.hsk-opening-feedback p{margin:0}.hsk-opening-retry{appearance:none;background:transparent;color:inherit;border:1px solid currentColor;border-radius:6px;padding:8px 16px;font:inherit;cursor:pointer}.hsk-gallery-cover{position:relative;display:block;width:100%;border:0;padding:0;cursor:pointer;background:transparent}.hsk-gallery-cover img{width:100%;height:100%;object-fit:cover}.hsk-gallery-count{position:absolute;bottom:6px;right:6px;padding:3px 7px;border-radius:10px;background:#000000b8;color:#fff;font-size:11px}.hsk-gallery-cover:focus-visible{outline:2px solid var(--hsk-primary,#ff6a33);outline-offset:3px}@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;user-select:none}@keyframes hsk-lightbox-in{0%{opacity:0}to{opacity:1}}.hsk-lightbox-top{position:absolute;top:18px;left:20px;right:68px;display:flex;align-items:center;z-index:2;pointer-events:none}.hsk-lightbox-title{font-size:14px;font-weight:600;letter-spacing:-.01em;color:var(--hsk-chat-text, #111);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:6px 14px;border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 80%,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 2px 10px #0000000f}.hsk-lightbox-stage{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:100%;max-width:100%;max-height:100%;cursor:default}.hsk-lightbox-content{display:flex;flex-direction:column;align-items:center;justify-content:center;max-width:min(92vw,1000px);max-height:calc(100vh - 120px);position:relative}.hsk-lightbox-img{max-width:100%;max-height:min(78vh,760px);width:auto;height:auto;object-fit:contain;border-radius:12px;box-shadow:0 24px 64px -16px #0000005c;cursor:default;transition:transform .18s ease-out}.hsk-lightbox-caption{margin-top:12px;font-size:13px;font-weight:500;line-height:1.4;color:var(--hsk-chat-text, #111);text-align:center;padding:5px 14px;border-radius:999px;background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 75%,transparent);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 8%,transparent);box-shadow:0 2px 8px #0000000d}.hsk-lightbox-close{position:absolute;top:16px;right:16px;width:38px;height:38px;border-radius:50%;border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 10%,transparent);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%);color:var(--hsk-chat-text, #111);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .15s ease;z-index:3;box-shadow:0 2px 8px #00000014}.hsk-lightbox-close:hover{background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 95%,transparent);transform:scale(1.05)}.hsk-lightbox-nav{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:44px;border-radius:50%;border:1px solid color-mix(in srgb,var(--hsk-chat-text, #111) 12%,transparent);background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 78%,transparent);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);color:var(--hsk-chat-text, #111);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .16s ease;z-index:3;box-shadow:0 4px 16px #0000001f}.hsk-lightbox-nav:hover{background:color-mix(in srgb,var(--hsk-chat-bg, #fff) 95%,transparent);transform:translateY(-50%) scale(1.08);box-shadow:0 6px 20px #0000002e}.hsk-lightbox-nav:active{transform:translateY(-50%) scale(.96)}.hsk-lightbox-nav--prev{left:20px}.hsk-lightbox-nav--next{right:20px}.hsk-lightbox-bottom{position:absolute;bottom:22px;left:50%;transform:translate(-50%);display:flex;align-items:center;z-index:2;pointer-events:none}.hsk-lightbox-counter{padding:6px 16px;border-radius:999px;font-size:13px;font-weight:600;letter-spacing:.03em;color:var(--hsk-chat-text, #111);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 4px 14px #00000014}@media(max-width:600px){.hsk-lightbox-nav--prev{left:8px}.hsk-lightbox-nav--next{right:8px}.hsk-lightbox-content{max-width:100%}}.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)!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-opening-shell[data-hsk-theme=light],.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-opening-shell[data-hsk-theme=dark],.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-opening-shell[data-hsk-theme=mahogany],.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-opening-shell[data-hsk-theme=blush],.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-opening-shell[data-hsk-theme=coffee],.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-opening-shell[data-hsk-theme=midnight],.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-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","themeDef","id","t","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","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","d","poisson","w","r","cell","gw","gh","grid","pts","active","place","fits","cx","cy","gy","gx","j","dx","dy","ai","px","py","placed","k","ang","rad","wob","motifs","ctx","cap","q","eave","belly","n","dir","l","drupes","ox","oy","side","ax","ay","off","lift","scribbles","nx","ny","turns","rr","lean","len","step","specks","o","accents","rgb","p","mix","A","B","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","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_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","openedLangRef","React","prevShopperLanguage","setPrevShopperLanguage","knownNow","cached","sourceStrings","preloadScriptFont","fontsLoadedFor","f","effectiveChromeReady","useEffect","meta","isLangEn","cancelled","holdForFonts","font","strings","families","loadFontsFor","cachedFull","cachedOnboarding","tryLoad","got","resFast","prev","resFull","attempt","gap","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","VoiceRecovery","code","recoveredTurns","turns","heard","said","result","turn","role","text","index","i","lastUser","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","recoveryRef","VoiceRecovery","recoverRef","retryTimerRef","connectTimerRef","hasConnectedRef","lastCaptureRef","captureResumeAtRef","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","closing","t","stop","sendOpen","history","x","attachWsHandlers","abandoned","ev","prev","next","decodeAdpcm","f","chime","last","text","hotReconnect","newVoice","oldWs","recoveredTurns","image","recover","delay","checkCapture","timer","currentVoiceRef","start","ctxReady","primeChimes","inAnalyser","outGain","outAnalyser","node","srcNode","attach","lastLoud","on","quietSince","id","prewarm","attachPhoto","file","store","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","w","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","theme","canvasRef","React","labelRef","run","cv","text","primary","st","paintedPrimary","refreshPalette","color","paint","frame","alpha","thump","thumpDoodles","repaint","seq","fade","id","tick","jsx","jsxs","CheckMark","OnboardingView","theme","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","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","_","shown","r","useState","normalizeEntityImages","jsx","jsxs","EntityGallery","source","onImageClick","images","normalizeEntityImages","failed","setFailed","useState","cover","SparkleIcon","handleClick","e","initialIndex","i","img","useState","useRef","useEffect","useCallback","normalizeEntityImages","useCardFields","Fragment","jsx","jsxs","SourcesCarousel","sources","onSelectSource","onImageClick","referencedIds","compact","targetLabel","cardFields","useCardFields","railRef","useRef","showPrev","setShowPrev","useState","showNext","setShowNext","activeIndex","setActiveIndex","referenced","s","swatches","entities","isSingleEntity","display","source","images","normalizeEntityImages","image","idx","measure","useCallback","el","travelled","maxScroll","useEffect","ro","railStep","dir","rtl","scrollNext","scrollPrev","swatchGrid","jsx","src","si","jsxs","cn","Fragment","ChevronLeftIcon","photoIndex","totalPhotos","isReferenced","EntityGallery","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","isLiveStreaming","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","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","toolsheetRef","onKey","e","handleOutside","path","isInsideToggle","el","isInsideSheet","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","hex","value","c","m","mix","a","b","rgba","alpha","BANDS","SPECTRUM_FRACTION","VoiceCanvas","phase","theme","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","useState","useEffect","useRef","jsx","jsxs","LightboxModal","src","images","initialIndex","title","onClose","list","index","setIndex","useState","touchX","useRef","useEffect","handleKeyDown","e","i","current","step","dir","CloseIcon","end","ChevronLeftIcon","ChevronRightIcon","Fragment","jsx","jsxs","ImageRow","images","siteId","themeAttr","rowRef","useRef","open","setOpen","useState","useEffect","row","pendingAt","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","i","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","d","prevY","i","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","x","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","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","lightboxData","setLightboxData","handleOpenLightbox","src","gallery","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","hasLiveData","subscribeLiveStream","isNarrow","setIsNarrow","mq","apply","chooseLanguage","lang","v","DEFAULT_UI_STRINGS","animStart","MIN_ANIM_MS","cached","ONBOARDING_UI_STRINGS","preloadScriptFont","fetchP","res","resolve","elapsed","r","chooseEntityLang","mode","agreeTerms","activePlaceholder","getLoadingMeta","activeChips","onboardingMood","currentTheme","setCurrentTheme","initialTheme","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","lastAssistant","detailsText","detailsOf","handleSelectExtension","ext","handleKeyDown","composerHeight","singleRowFieldWidth","measureCanvasRef","getTextWidth","font","ctx","autoGrow","val","cs","textWidth","threshold","hasNewline","shouldExpand","targetHeight","handleInput","trimmed","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","warmLanguage","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"]}
|