@unctad-ai/voice-agent-ui 5.4.3 → 5.4.4
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/{VoiceSettingsView-5KC4U5MD.js → VoiceSettingsView-JSFEXCBI.js} +2 -2
- package/dist/{chunk-HCWPPDLW.js → chunk-5RSFLMYI.js} +2 -2
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- /package/dist/{VoiceSettingsView-5KC4U5MD.js.map → VoiceSettingsView-JSFEXCBI.js.map} +0 -0
- /package/dist/{chunk-HCWPPDLW.js.map → chunk-5RSFLMYI.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/VoiceAgentProvider.tsx","../src/components/GlassCopilotPanel.tsx","../src/components/AgentAvatar.tsx","../src/components/VoiceOrb.tsx","../src/components/agentFabStyles.ts","../src/components/VoiceTranscript.tsx","../src/utils.ts","../src/components/VoiceToolCard.tsx","../src/components/VoiceErrorBoundary.tsx","../src/components/VoiceErrorDisplay.tsx","../src/components/PipelineMetricsBar.tsx","../src/components/VoiceA11yAnnouncer.tsx","../src/components/VoiceCopilotFAB.tsx","../src/components/VoiceControls.tsx","../src/components/VoiceDotRing.tsx","../src/components/VoiceOnboarding.tsx","../src/components/VoiceOverlay.tsx","../src/components/VoiceWaveformCanvas.tsx"],"sourcesContent":["import { SiteConfigProvider } from '@unctad-ai/voice-agent-core';\nimport { CopilotProvider } from '@unctad-ai/voice-agent-registries';\nimport { VoiceSettingsProvider } from './contexts/VoiceSettingsContext';\nimport type { SiteConfig } from '@unctad-ai/voice-agent-core';\n\nexport function VoiceAgentProvider({\n config,\n children,\n}: {\n config: SiteConfig;\n children: React.ReactNode;\n}) {\n return (\n <SiteConfigProvider config={config}>\n <CopilotProvider>\n <VoiceSettingsProvider siteLanguage={config.language}>\n {children}\n </VoiceSettingsProvider>\n </CopilotProvider>\n </SiteConfigProvider>\n );\n}\n","import {\n useState,\n useEffect,\n useCallback,\n useRef,\n lazy,\n Suspense,\n Component,\n type ReactNode,\n type ErrorInfo,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { motion, AnimatePresence, useReducedMotion } from 'motion/react';\nimport { ChevronDown, X, Mic, MicOff, ArrowUp, Keyboard, RotateCw, Settings, VolumeX, Flag } from 'lucide-react';\nimport {\n useVoiceAgent,\n voiceStateToOrbState,\n checkBackendHealth,\n useSiteConfig,\n RECOVERY_POLL_MS,\n PANEL_WIDTH,\n PANEL_COLLAPSED_HEIGHT,\n PANEL_EXPANDED_HEIGHT,\n PANEL_BORDER_RADIUS,\n PANEL_BOTTOM,\n PANEL_RIGHT,\n PANEL_Z_INDEX,\n SPRING_PANEL,\n SPRING_MICRO,\n SPRING_PANEL_EXIT,\n DEFAULT_FONT_FAMILY,\n} from '@unctad-ai/voice-agent-core';\nimport type { OrbState, VoiceToolResult, VoiceState, VoiceMessage, PipelineTimings } from '@unctad-ai/voice-agent-core';\nimport { useVoiceSettings } from '../contexts/VoiceSettingsContext';\nimport AgentAvatar from './AgentAvatar';\nimport { injectAgentFabCSS } from './agentFabStyles';\nimport VoiceTranscript from './VoiceTranscript';\nimport VoiceToolCard from './VoiceToolCard';\nimport VoiceErrorBoundary from './VoiceErrorBoundary';\nimport VoiceErrorDisplay from './VoiceErrorDisplay';\nimport type { VoiceErrorType } from './VoiceErrorDisplay';\nimport PipelineMetricsBar from './PipelineMetricsBar';\nconst VoiceSettingsView = lazy(() => import('./VoiceSettingsView'));\n\n// ---------------------------------------------------------------------------\n// Retry backoff constants\n// ---------------------------------------------------------------------------\nconst RETRY_INITIAL_MS = 3000;\nconst RETRY_MAX_MS = 30000;\n\n// ---------------------------------------------------------------------------\n// State labels for composer bar\n// ---------------------------------------------------------------------------\nconst STATE_LABELS: Record<VoiceState, string> = {\n IDLE: 'Tap mic to speak',\n LISTENING: \"I'm listening...\",\n USER_SPEAKING: \"I'm listening...\",\n PROCESSING: 'Thinking...',\n AI_SPEAKING: 'Responding...',\n};\n\n// ---------------------------------------------------------------------------\n// Aria-live announcements for screen readers\n// ---------------------------------------------------------------------------\nconst ARIA_LIVE_LABELS: Record<OrbState, string> = {\n idle: '',\n listening: 'Listening for your question',\n processing: 'Processing your request',\n speaking: 'Playing response',\n error: 'An error occurred',\n};\n\n// ---------------------------------------------------------------------------\n// Panel states\n// ---------------------------------------------------------------------------\ntype PanelState = 'hidden' | 'collapsed' | 'expanded';\n\n// ---------------------------------------------------------------------------\n// Scrollbar-hiding CSS for suggestion chips\n// ---------------------------------------------------------------------------\nlet chipScrollStylesInjected = false;\nfunction ensureChipScrollStyles() {\n if (chipScrollStylesInjected || typeof document === 'undefined') return;\n chipScrollStylesInjected = true;\n const style = document.createElement('style');\n style.textContent = `.suggestion-chips::-webkit-scrollbar { display: none }`;\n document.head.appendChild(style);\n}\n\ninterface GlassCopilotPanelProps {\n /** Controlled open state. When omitted, the panel manages its own open/close state. */\n isOpen?: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n onStateChange?: (orbState: OrbState) => void;\n /** URL for the avatar portrait image */\n portraitSrc?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Route exclusion helper\n// ---------------------------------------------------------------------------\nfunction isRouteExcluded(patterns?: string[]): boolean {\n if (!patterns?.length || typeof window === 'undefined') return false;\n const path = window.location.pathname;\n return patterns.some((p) => {\n if (p.endsWith('/*')) return path.startsWith(p.slice(0, -1));\n return path === p;\n });\n}\n\n// ---------------------------------------------------------------------------\n// FAB — shown when panel is hidden\n// ---------------------------------------------------------------------------\nfunction CopilotFAB({ onClick, portraitSrc, isOffline = false }: { onClick: () => void; portraitSrc?: string; isOffline?: boolean }) {\n const { colors } = useSiteConfig();\n return (\n <motion.button\n onClick={onClick}\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.95 }}\n className=\"shadow-lg cursor-pointer\"\n style={{\n background: 'transparent',\n border: 'none',\n padding: 0,\n borderRadius: '50%',\n width: 80,\n height: 80,\n }}\n aria-label=\"Open voice assistant\"\n data-testid=\"voice-agent-fab\"\n >\n <div className=\"agent-fab-border\" style={{ width: 80, height: 80, '--agent-primary': isOffline ? '#9ca3af' : colors.primary, animation: isOffline ? 'none' : undefined } as React.CSSProperties}>\n <div className=\"agent-fab-border-inner\">\n {portraitSrc ? (\n <img\n src={portraitSrc}\n alt=\"Assistant\"\n style={{ width: '100%', height: '100%', objectFit: 'cover', borderRadius: '50%' }}\n draggable={false}\n />\n ) : (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: '#6b7280',\n color: 'white',\n fontSize: 24,\n fontWeight: 700,\n }}\n >\n AI\n </div>\n )}\n </div>\n </div>\n </motion.button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FAB Tooltip — animated greeting to the left of the FAB\n// ---------------------------------------------------------------------------\nconst FAB_GREETED_KEY = (name: string) => `voice-fab-greeted:${name}`;\nconst FAB_LAST_SHOWN_KEY = (name: string) => `voice-fab-last-shown:${name}`;\nconst FAB_COOLDOWN_MS = 30 * 60 * 1000; // 30 minutes\nconst FAB_TOOLTIP_NARROW_QUERY = '(max-width: 479px)';\n\nfunction safeStorage(op: () => string | null): string | null;\nfunction safeStorage(op: () => void): void;\nfunction safeStorage(op: () => unknown): unknown {\n try { return op(); } catch { return null; }\n}\n\nfunction CopilotFABTooltip({ onClick }: { onClick: () => void }) {\n const { copilotName, colors, fabTooltip } = useSiteConfig();\n const prefersReduced = useReducedMotion();\n const [visible, setVisible] = useState(false);\n const [dismissed, setDismissed] = useState(false);\n\n // Compute first-visit synchronously so render reads a stable value (not a ref set inside a timer)\n const [isFirstVisit] = useState(() => !safeStorage(() => localStorage.getItem(FAB_GREETED_KEY(copilotName))));\n\n // Responsive narrow viewport check via matchMedia\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mql = window.matchMedia(FAB_TOOLTIP_NARROW_QUERY);\n if (mql.matches) { setDismissed(true); return; }\n const handler = (e: MediaQueryListEvent) => { if (e.matches) setDismissed(true); };\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, []);\n\n useEffect(() => {\n if (isFirstVisit) {\n const timer = setTimeout(() => {\n setVisible(true);\n safeStorage(() => localStorage.setItem(FAB_GREETED_KEY(copilotName), 'true'));\n safeStorage(() => localStorage.setItem(FAB_LAST_SHOWN_KEY(copilotName), new Date().toISOString()));\n }, 2000);\n return () => clearTimeout(timer);\n }\n\n // Return visit: check cooldown\n const lastShown = safeStorage(() => localStorage.getItem(FAB_LAST_SHOWN_KEY(copilotName)));\n if (lastShown && Date.now() - new Date(lastShown).getTime() < FAB_COOLDOWN_MS) return;\n\n const timer = setTimeout(() => {\n setVisible(true);\n safeStorage(() => localStorage.setItem(FAB_LAST_SHOWN_KEY(copilotName), new Date().toISOString()));\n }, 5000);\n return () => clearTimeout(timer);\n }, [copilotName, isFirstVisit]);\n\n // Auto-hide timer (return visits only — first visit stays until user interacts)\n useEffect(() => {\n if (!visible || isFirstVisit) return;\n const timer = setTimeout(() => setDismissed(true), 5000);\n return () => clearTimeout(timer);\n }, [visible, isFirstVisit]);\n\n // Scroll dismissal (return visits only)\n useEffect(() => {\n if (!visible || dismissed || isFirstVisit) return;\n const handleScroll = () => setDismissed(true);\n window.addEventListener('scroll', handleScroll, { passive: true, once: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, [visible, dismissed, isFirstVisit]);\n\n const handleTryNow = () => {\n setDismissed(true);\n onClick();\n };\n\n const handleDismiss = (e: React.MouseEvent) => {\n e.stopPropagation();\n setDismissed(true);\n };\n\n const firstVisitText = fabTooltip?.firstVisit\n ? fabTooltip.firstVisit.replaceAll('{name}', copilotName)\n : `I'm ${copilotName}, your virtual civil servant.\\nHow may I help you?`;\n const returnVisitText = fabTooltip?.returnVisit ?? 'How may I help you?';\n\n const show = visible && !dismissed;\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"voice-agent-fab-tooltip\"\n initial={prefersReduced ? { opacity: 0 } : { opacity: 0, x: 20 }}\n animate={prefersReduced ? { opacity: 1 } : { opacity: 1, x: 0 }}\n exit={prefersReduced ? { opacity: 0 } : { opacity: 0, x: 10 }}\n transition={\n prefersReduced\n ? { duration: 0.2 }\n : { type: 'spring', stiffness: 300, damping: 25 }\n }\n onClick={isFirstVisit ? undefined : handleTryNow}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 0,\n cursor: isFirstVisit ? 'default' : 'pointer',\n }}\n >\n <div\n style={{\n background: 'white',\n borderRadius: 20,\n padding: isFirstVisit ? '12px 20px' : '10px 18px',\n boxShadow: '0 2px 12px rgba(0,0,0,0.10), 0 0 0 1px rgba(0,0,0,0.04)',\n maxWidth: 340,\n }}\n >\n <div\n style={{\n fontSize: isFirstVisit ? 14 : 13,\n color: '#1a1a1a',\n fontWeight: 500,\n lineHeight: 1.4,\n whiteSpace: 'pre-line',\n }}\n >\n {isFirstVisit ? firstVisitText : returnVisitText}\n </div>\n {isFirstVisit && (\n <div style={{ display: 'flex', gap: 8, marginTop: 8 }}>\n <button\n data-testid=\"voice-agent-fab-tooltip-cta\"\n aria-label={`Open ${copilotName} voice assistant`}\n onClick={handleTryNow}\n style={{\n padding: '6px 16px',\n background: colors.primary,\n color: 'white',\n border: 'none',\n borderRadius: 12,\n fontSize: 12,\n fontWeight: 600,\n cursor: 'pointer',\n }}\n >\n Try it now\n </button>\n <button\n onClick={handleDismiss}\n style={{\n padding: '6px 12px',\n background: 'transparent',\n color: '#6b7280',\n border: 'none',\n borderRadius: 12,\n fontSize: 12,\n cursor: 'pointer',\n }}\n >\n Maybe later\n </button>\n </div>\n )}\n </div>\n {/* Arrow pointing right toward FAB */}\n <div\n style={{\n width: 0,\n height: 0,\n borderTop: '8px solid transparent',\n borderBottom: '8px solid transparent',\n borderLeft: '8px solid white',\n flexShrink: 0,\n filter: 'drop-shadow(2px 0 1px rgba(0,0,0,0.06))',\n }}\n />\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Collapsed header bar\n// ---------------------------------------------------------------------------\nfunction CollapsedBar({\n orbState,\n getAmplitude,\n analyser: _analyser,\n voiceState,\n onExpand,\n onClose,\n onRetry,\n isRetrying = false,\n retryCountdown,\n voiceError,\n micPaused = false,\n onMicToggle,\n ttsEnabled = true,\n copilotName,\n portraitSrc,\n lastMessage,\n}: {\n orbState: OrbState;\n getAmplitude: () => number;\n analyser: AnalyserNode | null;\n voiceState: VoiceState;\n onExpand: () => void;\n onClose: () => void;\n onRetry?: () => void;\n isRetrying?: boolean;\n retryCountdown?: number | null;\n voiceError?: VoiceErrorType;\n micPaused?: boolean;\n onMicToggle?: () => void;\n ttsEnabled?: boolean;\n copilotName: string;\n portraitSrc?: string;\n lastMessage?: string;\n}) {\n const { colors } = useSiteConfig();\n const isOffline = voiceError === 'network_error';\n\n return (\n <div\n className=\"flex items-center gap-3 h-full cursor-pointer select-none\"\n style={{ padding: '0 16px' }}\n role=\"button\"\n tabIndex={0}\n data-testid=\"voice-agent-bar\"\n onClick={onExpand}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onExpand();\n }\n }}\n >\n {/* Mini avatar */}\n <div\n className=\"relative shrink-0\"\n style={{ width: 56, height: 56, opacity: isOffline ? 0.4 : 1 }}\n >\n <AgentAvatar state={orbState} getAmplitude={getAmplitude} size={56} portraitSrc={portraitSrc} />\n {!ttsEnabled && (\n <div\n className=\"absolute flex items-center justify-center\"\n style={{\n bottom: -2,\n right: -2,\n width: 18,\n height: 18,\n borderRadius: 9,\n backgroundColor: 'rgba(0,0,0,0.65)',\n border: '1.5px solid rgba(255,255,255,0.8)',\n }}\n >\n <VolumeX style={{ width: 10, height: 10, color: '#fff' }} />\n </div>\n )}\n </div>\n\n {/* Title */}\n <div className=\"flex-1 min-w-0\">\n <p\n className=\"truncate\"\n style={{ fontSize: '14px', fontWeight: 600, color: '#1a1a1a' }}\n >\n {copilotName}\n </p>\n <p\n className=\"truncate\"\n style={{\n fontSize: '12px',\n fontWeight: 400,\n color: isOffline ? 'rgba(220, 38, 38, 0.7)' : 'rgba(0,0,0,0.42)',\n letterSpacing: '0.01em',\n }}\n >\n {isOffline ? (\n <span className=\"inline-flex items-center gap-1\">\n {retryCountdown ? `Retrying in ${retryCountdown}s` : 'Offline'}\n {onRetry && !retryCountdown && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n onRetry();\n }}\n className=\"inline-flex items-center justify-center rounded-full transition-colors cursor-pointer\"\n style={{\n width: 18,\n height: 18,\n color: 'rgba(220, 38, 38, 0.5)',\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLElement).style.color = 'rgba(220, 38, 38, 0.8)';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLElement).style.color = 'rgba(220, 38, 38, 0.5)';\n }}\n aria-label=\"Retry connection\"\n >\n <motion.span\n animate={isRetrying ? { rotate: 360 } : { rotate: 0 }}\n transition={\n isRetrying\n ? { duration: 0.8, repeat: Infinity, ease: 'linear' }\n : { duration: 0.3 }\n }\n style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}\n >\n <RotateCw style={{ width: 12, height: 12 }} />\n </motion.span>\n </button>\n )}\n </span>\n ) : (micPaused || voiceState === 'IDLE') && lastMessage ? (\n lastMessage.length > 40 ? lastMessage.slice(0, 40).trimEnd() + '...' : lastMessage\n ) : micPaused ? (\n 'Tap mic to resume'\n ) : (\n STATE_LABELS[voiceState]\n )}\n </p>\n </div>\n\n {/* Mic toggle button */}\n {!isOffline && onMicToggle && (() => {\n const barListening = voiceState === 'LISTENING' || voiceState === 'USER_SPEAKING';\n return (\n <motion.button\n onClick={(e) => {\n e.stopPropagation();\n onMicToggle();\n }}\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.93 }}\n animate={barListening\n ? { backgroundColor: [colors.primary, `${colors.primary}BB`, colors.primary] }\n : { backgroundColor: 'rgba(0,0,0,0.06)' }\n }\n transition={barListening\n ? { backgroundColor: { duration: 1.8, repeat: Infinity, ease: 'easeInOut' } }\n : { duration: 0.3 }\n }\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer relative\"\n style={{\n width: 44,\n height: 44,\n color: barListening ? 'white' : 'rgba(0,0,0,0.45)',\n border: 'none',\n padding: 0,\n boxShadow: barListening\n ? `0 2px 8px ${colors.primary}40, 0 1px 3px rgba(0,0,0,0.12)`\n : '0 1px 4px rgba(0,0,0,0.10)',\n }}\n aria-label={barListening ? 'Stop listening' : 'Start listening'}\n >\n {barListening\n ? <Mic style={{ width: 16, height: 16, position: 'relative', zIndex: 1 }} />\n : <MicOff style={{ width: 16, height: 16, position: 'relative', zIndex: 1 }} />\n }\n </motion.button>\n );\n })()}\n\n {/* Offline status dot */}\n {isOffline && (\n <span\n className=\"shrink-0 rounded-full\"\n style={{\n width: 8,\n height: 8,\n backgroundColor: 'rgba(220, 38, 38, 0.5)',\n }}\n />\n )}\n\n {/* Close */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n onClose();\n }}\n className=\"shrink-0 rounded-full flex items-center justify-center transition-colors cursor-pointer\"\n style={{\n width: 32,\n height: 32,\n color: 'rgba(0,0,0,0.4)',\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLElement).style.color = 'rgba(0,0,0,0.7)';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLElement).style.color = 'rgba(0,0,0,0.4)';\n }}\n aria-label=\"Close voice assistant\"\n >\n <X style={{ width: 14, height: 14 }} />\n </button>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Composer bar\n// ---------------------------------------------------------------------------\nfunction ComposerBar({\n voiceState,\n isListening,\n micPaused = false,\n onTextSubmit,\n onMicToggle,\n onCancel,\n disabled = false,\n switchToTextRef,\n feedbackTarget,\n onFeedbackSubmit,\n onFeedbackCancel,\n}: {\n voiceState: VoiceState;\n isListening: boolean;\n micPaused?: boolean;\n onTextSubmit: (text: string) => void;\n onMicToggle: () => void;\n onCancel?: () => void;\n disabled?: boolean;\n switchToTextRef?: React.RefObject<(() => void) | null>;\n feedbackTarget?: { assistantMessage: string; userMessage?: string; turnNumber: number } | null;\n onFeedbackSubmit?: (text: string, target: { assistantMessage: string; userMessage?: string; turnNumber: number }) => void;\n onFeedbackCancel?: () => void;\n}) {\n const { colors } = useSiteConfig();\n const [mode, setMode] = useState<'voice' | 'text' | 'feedback'>(disabled ? 'text' : 'voice');\n const [text, setText] = useState('');\n const [showCancelHint, setShowCancelHint] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n // After 2s in PROCESSING, show \"Tap mic to cancel\" hint\n useEffect(() => {\n if (voiceState !== 'PROCESSING') { setShowCancelHint(false); return; }\n const timer = setTimeout(() => setShowCancelHint(true), 2000);\n return () => clearTimeout(timer);\n }, [voiceState]);\n\n // Expose switch-to-text for external triggers (empty state CTA)\n useEffect(() => {\n if (switchToTextRef) (switchToTextRef as React.MutableRefObject<(() => void) | null>).current = () => setMode('text');\n }, [switchToTextRef]);\n\n // When mic is disabled (e.g. STT down), force text mode\n useEffect(() => {\n if (disabled) setMode('text');\n }, [disabled]);\n\n // Enter feedback mode when triggered externally\n useEffect(() => {\n if (feedbackTarget) {\n setMode('feedback');\n const timer = setTimeout(() => inputRef.current?.focus(), 200);\n return () => clearTimeout(timer);\n }\n }, [feedbackTarget]);\n\n useEffect(() => {\n if (mode === 'text') {\n // Delay focus to after AnimatePresence mount animation\n const timer = setTimeout(() => inputRef.current?.focus(), 200);\n return () => clearTimeout(timer);\n }\n }, [mode]);\n\n const handleSubmit = () => {\n if (disabled) return;\n const trimmed = text.trim();\n if (!trimmed) return;\n onTextSubmit(trimmed);\n setText('');\n // Stay in text mode — user switches back to voice via mic button\n requestAnimationFrame(() => inputRef.current?.focus());\n };\n\n const handleCancel = () => {\n setText('');\n if (disabled) return; // Can't switch back to voice when mic is disabled\n setMode('voice');\n onMicToggle();\n };\n\n const handleFeedbackSubmit = () => {\n const trimmed = text.trim();\n if (!trimmed || !feedbackTarget) return;\n onFeedbackSubmit?.(trimmed, feedbackTarget);\n setText('');\n setMode('voice');\n };\n\n const handleFeedbackCancel = () => {\n setText('');\n setMode('voice');\n onFeedbackCancel?.();\n };\n\n return (\n <div\n className=\"shrink-0 overflow-hidden\"\n style={{\n height: 56,\n borderTop: '1px solid rgba(0,0,0,0.08)',\n }}\n >\n <AnimatePresence mode=\"wait\" initial={false}>\n {mode === 'voice' ? (\n <motion.div\n key=\"voice-mode\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.18, ease: [0.22, 1, 0.36, 1] }}\n className=\"flex items-center gap-3\"\n style={{ height: 56, padding: '10px 14px' }}\n >\n <motion.button\n onClick={onMicToggle}\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.93 }}\n animate={isListening\n ? { backgroundColor: [colors.primary, `${colors.primary}BB`, colors.primary] }\n : { backgroundColor: 'rgba(0,0,0,0.06)' }\n }\n transition={isListening\n ? { backgroundColor: { duration: 1.8, repeat: Infinity, ease: 'easeInOut' } }\n : { duration: 0.3 }\n }\n className=\"shrink-0 rounded-full flex items-center justify-center relative cursor-pointer\"\n style={{\n width: 44,\n height: 44,\n color: isListening ? 'white' : 'rgba(0,0,0,0.5)',\n border: 'none',\n padding: 0,\n boxShadow: isListening\n ? `0 2px 8px ${colors.primary}40, 0 1px 3px rgba(0,0,0,0.12)`\n : '0 1px 4px rgba(0,0,0,0.10)',\n }}\n aria-label={isListening ? 'Stop listening' : 'Start listening'}\n data-testid=\"voice-agent-mic\"\n >\n {isListening\n ? <Mic style={{ width: 18, height: 18, position: 'relative', zIndex: 1 }} />\n : <MicOff style={{ width: 18, height: 18, position: 'relative', zIndex: 1 }} />\n }\n </motion.button>\n\n <div className=\"flex-1 min-w-0\">\n <AnimatePresence mode=\"wait\">\n <motion.p\n key={micPaused ? 'paused' : showCancelHint ? 'cancel-hint' : voiceState}\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.15 }}\n className=\"truncate\"\n style={{\n fontSize: '14px',\n fontWeight: 400,\n color: micPaused\n ? 'rgba(0,0,0,0.35)'\n : showCancelHint\n ? 'rgba(0,0,0,0.35)'\n : voiceState === 'LISTENING' || voiceState === 'USER_SPEAKING'\n ? colors.primary\n : 'rgba(0,0,0,0.45)',\n }}\n >\n {micPaused ? 'Tap mic to resume' : showCancelHint ? 'Tap mic to cancel' : STATE_LABELS[voiceState]}\n </motion.p>\n </AnimatePresence>\n </div>\n\n <motion.button\n whileHover={{ scale: 1.04 }}\n whileTap={{ scale: 0.96 }}\n onClick={() => {\n if (voiceState === 'PROCESSING' || voiceState === 'AI_SPEAKING') onCancel?.();\n else if (isListening) onMicToggle();\n setMode('text');\n }}\n className=\"shrink-0 flex items-center gap-1.5 cursor-pointer\"\n style={{\n height: 36,\n padding: '0 12px',\n borderRadius: 18,\n backgroundColor: 'rgba(0,0,0,0.05)',\n color: 'rgba(0,0,0,0.4)',\n border: 'none',\n fontSize: 12,\n fontWeight: 500,\n }}\n aria-label=\"Type a message\"\n data-testid=\"voice-agent-keyboard\"\n >\n <Keyboard style={{ width: 14, height: 14 }} />\n <span>Type</span>\n </motion.button>\n </motion.div>\n ) : mode === 'text' ? (\n <motion.div\n key=\"text-mode\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.18, ease: [0.22, 1, 0.36, 1] }}\n className=\"flex items-center gap-2\"\n style={{ height: 56, padding: '10px 14px' }}\n >\n <div\n className=\"flex-1 min-w-0 flex items-center\"\n style={{\n height: 36,\n borderRadius: 18,\n padding: '0 14px',\n backgroundColor: 'rgba(0,0,0,0.03)',\n border: '1px solid rgba(0,0,0,0.08)',\n transition: 'border-color 0.15s, box-shadow 0.15s',\n }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n disabled={disabled}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleSubmit();\n if (e.key === 'Escape') handleCancel();\n }}\n onFocus={(e) => {\n const pill = e.currentTarget.parentElement;\n if (pill) {\n pill.style.borderColor = 'rgba(0,0,0,0.15)';\n pill.style.boxShadow = '0 0 0 2px rgba(0,0,0,0.04)';\n }\n }}\n onBlur={(e) => {\n const pill = e.currentTarget.parentElement;\n if (pill) {\n pill.style.borderColor = 'rgba(0,0,0,0.08)';\n pill.style.boxShadow = 'none';\n }\n }}\n placeholder={disabled ? 'Reconnecting...' : 'Message...'}\n aria-label=\"Type your question\"\n data-testid=\"voice-agent-input\"\n className=\"w-full\"\n style={{\n fontSize: '14px',\n color: '#1a1a1a',\n background: 'transparent',\n border: 'none',\n outline: 'none',\n padding: 0,\n opacity: disabled ? 0.5 : 1,\n cursor: disabled ? 'not-allowed' : undefined,\n }}\n />\n </div>\n\n <AnimatePresence>\n {text.trim().length > 0 && (\n <motion.button\n initial={{ scale: 0, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0, opacity: 0 }}\n transition={SPRING_MICRO}\n whileTap={{ scale: 0.9 }}\n onClick={handleSubmit}\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer\"\n style={{\n width: 44,\n height: 44,\n backgroundColor: colors.primary,\n color: 'white',\n }}\n aria-label=\"Send message\"\n data-testid=\"voice-agent-send\"\n >\n <ArrowUp style={{ width: 18, height: 18 }} />\n </motion.button>\n )}\n </AnimatePresence>\n\n {!disabled && (\n <motion.button\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.92 }}\n onClick={handleCancel}\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer\"\n style={{\n width: 44,\n height: 44,\n backgroundColor: 'rgba(0,0,0,0.05)',\n color: 'rgba(0,0,0,0.4)',\n }}\n aria-label=\"Back to voice mode\"\n data-testid=\"voice-agent-voice-mode\"\n >\n <Mic style={{ width: 18, height: 18 }} />\n </motion.button>\n )}\n </motion.div>\n ) : mode === 'feedback' ? (\n <motion.div\n key=\"feedback-mode\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.18, ease: [0.22, 1, 0.36, 1] }}\n className=\"flex items-center gap-2\"\n style={{ height: 56, padding: '10px 14px' }}\n >\n <div\n className=\"shrink-0 rounded-full flex items-center justify-center\"\n style={{ width: 44, height: 44, backgroundColor: '#d97706' }}\n >\n <Flag style={{ width: 18, height: 18, color: 'white' }} />\n </div>\n\n <div\n className=\"flex-1 min-w-0 flex items-center\"\n style={{\n height: 36, borderRadius: 18, padding: '0 14px',\n backgroundColor: 'rgba(217,119,6,0.05)',\n border: '2px solid #d97706',\n }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleFeedbackSubmit();\n if (e.key === 'Escape') handleFeedbackCancel();\n }}\n placeholder=\"How could this be better?\"\n className=\"w-full\"\n style={{\n fontSize: '14px', color: '#1a1a1a', background: 'transparent',\n border: 'none', outline: 'none', padding: 0,\n }}\n />\n </div>\n\n <AnimatePresence>\n {text.trim().length > 0 && (\n <motion.button\n initial={{ scale: 0, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0, opacity: 0 }}\n transition={SPRING_MICRO}\n whileTap={{ scale: 0.9 }}\n onClick={handleFeedbackSubmit}\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer\"\n style={{ width: 44, height: 44, backgroundColor: '#d97706', color: 'white' }}\n >\n <ArrowUp style={{ width: 18, height: 18 }} />\n </motion.button>\n )}\n </AnimatePresence>\n\n <motion.button\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.92 }}\n onClick={handleFeedbackCancel}\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer\"\n style={{ width: 44, height: 44, backgroundColor: 'rgba(0,0,0,0.05)', color: 'rgba(0,0,0,0.35)' }}\n >\n <X style={{ width: 18, height: 18 }} />\n </motion.button>\n </motion.div>\n ) : null}\n </AnimatePresence>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Expanded panel content\n// ---------------------------------------------------------------------------\nfunction ExpandedContent({\n orbState, getAmplitude, analyser, voiceState, messages, isTyping,\n toolResult, voiceError, dismissError, onCollapse, onClose, onTextSubmit,\n onMicToggle, onCancel, micPaused = false, onToolDismiss, onInteraction, onRetry,\n isRetrying = false, retryCountdown, lastTimings, showPipelineMetrics, pipelineMetricsAutoHideMs,\n showSettings, onSettingsToggle, ttsEnabled = true, copilotName, portraitSrc,\n onStartMic, onSwitchToKeyboard, switchToTextRef,\n onReport, feedbackSentTurns, feedbackTarget, onFeedbackSubmit, onFeedbackCancel,\n}: {\n orbState: OrbState; getAmplitude: () => number; analyser: AnalyserNode | null;\n voiceState: VoiceState; messages: VoiceMessage[]; isTyping: boolean;\n toolResult: VoiceToolResult | null; voiceError: VoiceErrorType; dismissError: () => void;\n onCollapse: () => void; onClose: () => void; onTextSubmit: (text: string) => void;\n onMicToggle: () => void; onCancel?: () => void; micPaused?: boolean; onToolDismiss: () => void;\n onInteraction: () => void; onRetry?: () => void; isRetrying?: boolean; retryCountdown?: number | null;\n lastTimings?: PipelineTimings | null; showPipelineMetrics?: boolean;\n pipelineMetricsAutoHideMs?: number; showSettings: boolean; onSettingsToggle: () => void;\n ttsEnabled?: boolean; copilotName: string; portraitSrc?: string;\n onStartMic?: () => void; onSwitchToKeyboard?: () => void;\n switchToTextRef?: React.RefObject<(() => void) | null>;\n onReport?: (turnNumber: number, assistantMessage: string, userMessage?: string) => void;\n feedbackSentTurns?: Record<number, string>;\n feedbackTarget?: { assistantMessage: string; userMessage?: string; turnNumber: number } | null;\n onFeedbackSubmit?: (text: string, target: { assistantMessage: string; userMessage?: string; turnNumber: number }) => void;\n onFeedbackCancel?: () => void;\n}) {\n const config = useSiteConfig();\n const { colors } = config;\n const isListening = voiceState === 'LISTENING' || voiceState === 'USER_SPEAKING';\n const isOffline = voiceError === 'network_error';\n\n return (\n <div\n style={{ display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}\n onClick={onInteraction}\n onKeyDown={onInteraction}\n >\n {/* Header (64px) */}\n <div\n className=\"flex items-center gap-3 shrink-0\"\n style={{ height: 64, padding: '12px 16px', borderBottom: '1px solid rgba(0,0,0,0.06)', backgroundColor: `${colors.primary}08` }}\n >\n <motion.div\n animate={{ opacity: isOffline ? 0.35 : 1 }}\n className=\"relative shrink-0\"\n style={{ width: 56, height: 56, filter: isOffline ? 'grayscale(0.8)' : 'none' }}\n >\n <AgentAvatar state={orbState} getAmplitude={getAmplitude} size={56} showRing portraitSrc={portraitSrc} />\n {!ttsEnabled && (\n <div\n className=\"absolute flex items-center justify-center\"\n style={{\n bottom: -2, right: -2, width: 18, height: 18, borderRadius: 9,\n backgroundColor: 'rgba(0,0,0,0.65)', border: '1.5px solid rgba(255,255,255,0.8)',\n }}\n >\n <VolumeX style={{ width: 10, height: 10, color: '#fff' }} />\n </div>\n )}\n </motion.div>\n\n <div className=\"flex-1 min-w-0\">\n <p className=\"truncate\" style={{ fontSize: '14px', fontWeight: 600, color: '#1a1a1a' }}>{copilotName}</p>\n <p className=\"truncate\" data-testid=\"voice-agent-status\" style={{ fontSize: '12px', fontWeight: 400, color: isOffline ? 'rgba(220,38,38,0.7)' : 'rgba(0,0,0,0.42)', letterSpacing: '0.01em' }}>\n {isOffline ? (\n <span className=\"inline-flex items-center gap-1\">\n Offline\n {onRetry && (\n <button onClick={(e) => { e.stopPropagation(); onRetry(); }} className=\"inline-flex items-center justify-center rounded-full transition-colors cursor-pointer\" style={{ width: 18, height: 18, color: 'rgba(220,38,38,0.5)' }} aria-label=\"Retry connection\">\n <motion.span animate={isRetrying ? { rotate: 360 } : { rotate: 0 }} transition={isRetrying ? { duration: 0.8, repeat: Infinity, ease: 'linear' } : { duration: 0.3 }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <RotateCw style={{ width: 12, height: 12 }} />\n </motion.span>\n </button>\n )}\n </span>\n ) : micPaused ? 'Tap mic to resume' : STATE_LABELS[voiceState]}\n </p>\n </div>\n\n <button\n onClick={onSettingsToggle}\n className=\"shrink-0 rounded-full transition-colors cursor-pointer\"\n style={{\n color: showSettings ? colors.primary : 'rgba(0,0,0,0.4)',\n width: 32, height: 32, display: 'flex', alignItems: 'center', justifyContent: 'center',\n backgroundColor: showSettings ? `${colors.primary}14` : 'transparent',\n }}\n aria-label={showSettings ? 'Close settings' : 'Open settings'}\n data-testid=\"voice-agent-settings\"\n >\n <Settings style={{ width: 14, height: 14 }} />\n </button>\n <button onClick={onCollapse} className=\"shrink-0 rounded-full transition-colors cursor-pointer\" style={{ color: 'rgba(0,0,0,0.4)', width: 32, height: 32, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'transparent' }} aria-label=\"Minimize panel\" data-testid=\"voice-agent-minimize\">\n <ChevronDown style={{ width: 14, height: 14 }} />\n </button>\n <button onClick={onClose} className=\"shrink-0 rounded-full transition-colors cursor-pointer\" style={{ color: 'rgba(0,0,0,0.4)', width: 32, height: 32, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'transparent' }} aria-label=\"Close voice assistant\" data-testid=\"voice-agent-close\">\n <X style={{ width: 14, height: 14 }} />\n </button>\n </div>\n\n <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>\n <div data-testid=\"voice-agent-transcript\" style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }}><VoiceTranscript messages={messages} isTyping={isTyping} variant=\"panel\" voiceError={voiceError} voiceState={voiceState} onStartMic={onStartMic} onSwitchToKeyboard={onSwitchToKeyboard} onReport={onReport} feedbackSentTurns={feedbackSentTurns} onTextSubmit={onTextSubmit} /></div>\n <div style={{ flexShrink: 0 }}>\n <PipelineMetricsBar timings={lastTimings ?? null} show={showPipelineMetrics} autoHideMs={pipelineMetricsAutoHideMs} />\n {isOffline && onRetry && (\n <div style={{ padding: '0 16px 8px', display: 'flex', justifyContent: 'center' }}>\n <motion.button whileHover={{ scale: 1.04 }} whileTap={{ scale: 0.96 }} onClick={onRetry} disabled={isRetrying} className=\"inline-flex items-center gap-2 rounded-full cursor-pointer transition-colors\" style={{ padding: '8px 18px', fontSize: '13px', fontWeight: 500, color: isRetrying ? 'rgba(0,0,0,0.35)' : 'rgba(220,38,38,0.8)', backgroundColor: isRetrying ? 'rgba(0,0,0,0.04)' : 'rgba(220,38,38,0.08)', border: '1px solid', borderColor: isRetrying ? 'rgba(0,0,0,0.06)' : 'rgba(220,38,38,0.15)' }} aria-label=\"Retry connection\">\n <motion.span animate={isRetrying ? { rotate: 360 } : { rotate: 0 }} transition={isRetrying ? { duration: 0.8, repeat: Infinity, ease: 'linear' } : { duration: 0.3 }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <RotateCw style={{ width: 14, height: 14 }} />\n </motion.span>\n {isRetrying ? 'Checking...' : retryCountdown ? `Retrying in ${retryCountdown}s...` : 'Retry connection'}\n </motion.button>\n </div>\n )}\n {voiceError !== 'network_error' && (\n <div style={{ padding: '0 16px 8px' }}><VoiceErrorDisplay error={voiceError} onDismiss={dismissError} /></div>\n )}\n <div style={{ padding: '0 16px 8px' }}><VoiceToolCard result={toolResult} onDismiss={onToolDismiss} variant=\"capsule\" /></div>\n </div>\n </div>\n\n {micPaused && messages.length === 0 && (() => {\n ensureChipScrollStyles();\n const prompts = config.suggestedPrompts ?? ['What services are available?', 'Help me with an application'];\n return (\n <div className=\"suggestion-chips\" style={{\n padding: '0 16px 4px',\n display: 'flex',\n gap: 8,\n overflowX: 'auto',\n flexShrink: 0,\n WebkitOverflowScrolling: 'touch',\n scrollbarWidth: 'none',\n }}>\n {prompts.map((prompt, i) => (\n <button\n key={i}\n onClick={() => onTextSubmit(prompt)}\n style={{\n flexShrink: 0,\n padding: '6px 14px',\n fontSize: 12,\n fontWeight: 500,\n color: colors.primary,\n backgroundColor: `${colors.primary}0a`,\n border: `1px solid ${colors.primary}20`,\n borderRadius: 20,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n transition: 'background-color 0.15s',\n }}\n onMouseEnter={(e) => { (e.target as HTMLElement).style.backgroundColor = `${colors.primary}18`; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.backgroundColor = `${colors.primary}0a`; }}\n >\n {prompt}\n </button>\n ))}\n </div>\n );\n })()}\n\n <div className=\"shrink-0\">\n <ComposerBar voiceState={voiceState} isListening={isListening} micPaused={micPaused} onTextSubmit={onTextSubmit} onMicToggle={onMicToggle} onCancel={onCancel} disabled={voiceError === 'network_error' || voiceError === 'stt_failed'} switchToTextRef={switchToTextRef} feedbackTarget={feedbackTarget} onFeedbackSubmit={onFeedbackSubmit} onFeedbackCancel={onFeedbackCancel} />\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Static panel shell\n// ---------------------------------------------------------------------------\nfunction StaticPanelShell({\n panelState, onCollapse, onExpand, onClose, onRetry, copilotName, portraitSrc,\n}: {\n panelState: PanelState; onCollapse: () => void; onExpand: () => void; onClose: () => void;\n onRetry?: () => Promise<boolean>; copilotName: string; portraitSrc?: string;\n}) {\n const noopAmplitude = useCallback(() => 0, []);\n const [isRetrying, setIsRetrying] = useState(false);\n const handleRetry = useCallback(() => { if (isRetrying || !onRetry) return; setIsRetrying(true); onRetry().finally(() => setIsRetrying(false)); }, [onRetry, isRetrying]);\n\n if (panelState === 'collapsed') {\n return <CollapsedBar orbState=\"idle\" getAmplitude={noopAmplitude} analyser={null} voiceState=\"IDLE\" onExpand={onExpand} onClose={onClose} onRetry={handleRetry} isRetrying={isRetrying} voiceError=\"network_error\" copilotName={copilotName} portraitSrc={portraitSrc} />;\n }\n return <ExpandedContent orbState=\"idle\" getAmplitude={noopAmplitude} analyser={null} voiceState=\"IDLE\" messages={[]} isTyping={false} toolResult={null} voiceError=\"network_error\" dismissError={() => {}} onCollapse={onCollapse} onClose={onClose} onTextSubmit={() => {}} onMicToggle={() => {}} onToolDismiss={() => {}} onInteraction={() => {}} onRetry={handleRetry} isRetrying={isRetrying} showSettings={false} onSettingsToggle={() => {}} copilotName={copilotName} portraitSrc={portraitSrc} />;\n}\n\n// ---------------------------------------------------------------------------\n// Error boundary\n// ---------------------------------------------------------------------------\nclass WiredPanelErrorBoundary extends Component<\n { children: ReactNode; panelState: PanelState; onCollapse: () => void; onExpand: () => void; onClose: () => void; copilotName: string; portraitSrc?: string },\n { hasError: boolean }\n> {\n state = { hasError: false };\n static getDerivedStateFromError() { return { hasError: true }; }\n componentDidCatch(error: Error, _info: ErrorInfo) { console.warn('[GlassCopilotPanel] Voice agent unavailable:', error.message); }\n handleRetry = (): Promise<boolean> => {\n return checkBackendHealth().then(({ available }) => {\n if (available) this.setState({ hasError: false });\n return available;\n });\n };\n render() {\n if (this.state.hasError) {\n return <StaticPanelShell panelState={this.props.panelState} onCollapse={this.props.onCollapse} onExpand={this.props.onExpand} onClose={this.props.onClose} onRetry={this.handleRetry} copilotName={this.props.copilotName} portraitSrc={this.props.portraitSrc} />;\n }\n return this.props.children;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wired panel\n// ---------------------------------------------------------------------------\nfunction WiredPanel({\n panelState, onCollapse, onExpand, onClose, onStateChange, portraitSrc,\n}: {\n panelState: PanelState; onCollapse: () => void; onExpand: () => void; onClose: () => void;\n onStateChange?: (orbState: OrbState) => void; portraitSrc?: string;\n}) {\n const config = useSiteConfig();\n return (\n <WiredPanelErrorBoundary panelState={panelState} onCollapse={onCollapse} onExpand={onExpand} onClose={onClose} copilotName={config.copilotName} portraitSrc={portraitSrc}>\n <WiredPanelInner panelState={panelState} onCollapse={onCollapse} onExpand={onExpand} onClose={onClose} onStateChange={onStateChange} portraitSrc={portraitSrc} />\n </WiredPanelErrorBoundary>\n );\n}\n\nfunction WiredPanelInner({\n panelState, onCollapse, onExpand, onClose, onStateChange, portraitSrc,\n}: {\n panelState: PanelState; onCollapse: () => void; onExpand: () => void; onClose: () => void;\n onStateChange?: (orbState: OrbState) => void; portraitSrc?: string;\n}) {\n const config = useSiteConfig();\n const resolvedPortrait = portraitSrc ?? config.avatarUrl;\n const { settings: voiceSettings, volumeRef, speedRef } = useVoiceSettings();\n const { state, start, stop, messages, getAmplitude, analyser, sendTextMessage, voiceError, dismissError, lastTimings, sessionId, applyVolume, settings } = useVoiceAgent({ settings: voiceSettings, volumeRef, speedRef });\n\n const [toolResult, setToolResult] = useState<VoiceToolResult | null>(null);\n const [feedbackTarget, setFeedbackTarget] = useState<{ assistantMessage: string; userMessage?: string; turnNumber: number } | null>(null);\n const [feedbackSentTurns, setFeedbackSentTurns] = useState<Record<number, string>>({});\n const orbState = voiceStateToOrbState(state);\n const [backendDown, setBackendDown] = useState(false);\n const autoStartedRef = useRef(false);\n const pollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const cancelledRef = useRef(false);\n const [retryCountdown, setRetryCountdown] = useState<number | null>(null);\n const backoffDelayRef = useRef(RETRY_INITIAL_MS);\n const countdownTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const dismissErrorRef = useRef(dismissError);\n useEffect(() => { dismissErrorRef.current = dismissError; }, [dismissError]);\n const autoListenRef = useRef(settings.autoListen);\n useEffect(() => { autoListenRef.current = settings.autoListen; }, [settings.autoListen]);\n\n const clearCountdown = useCallback(() => {\n if (countdownTimerRef.current) { clearInterval(countdownTimerRef.current); countdownTimerRef.current = null; }\n setRetryCountdown(null);\n }, []);\n\n const runHealthCheckRef = useRef<() => void>(() => {});\n\n const scheduleRetry = useCallback((delayMs: number) => {\n if (pollTimerRef.current) clearTimeout(pollTimerRef.current);\n clearCountdown();\n const seconds = Math.ceil(delayMs / 1000);\n setRetryCountdown(seconds);\n let remaining = seconds;\n countdownTimerRef.current = setInterval(() => {\n remaining -= 1;\n if (remaining <= 0) { clearCountdown(); return; }\n setRetryCountdown(remaining);\n }, 1000);\n pollTimerRef.current = setTimeout(() => runHealthCheckRef.current(), delayMs);\n backoffDelayRef.current = Math.min(delayMs * 2, RETRY_MAX_MS);\n }, [clearCountdown]);\n\n const runHealthCheck = useCallback(() => {\n clearCountdown();\n checkBackendHealth().then(({ available }) => {\n if (cancelledRef.current) return;\n setBackendDown(!available);\n if (available) {\n backoffDelayRef.current = RETRY_INITIAL_MS;\n dismissErrorRef.current();\n if (!autoStartedRef.current && autoListenRef.current) { autoStartedRef.current = true; startRef.current(); }\n } else {\n scheduleRetry(backoffDelayRef.current);\n }\n });\n }, [scheduleRetry, clearCountdown]);\n\n useEffect(() => { runHealthCheckRef.current = runHealthCheck; }, [runHealthCheck]);\n\n useEffect(() => {\n cancelledRef.current = false; runHealthCheck();\n return () => {\n cancelledRef.current = true;\n if (pollTimerRef.current) clearTimeout(pollTimerRef.current);\n if (countdownTimerRef.current) clearInterval(countdownTimerRef.current);\n };\n }, [runHealthCheck]);\n\n const onStateChangeRef = useRef(onStateChange);\n useEffect(() => { onStateChangeRef.current = onStateChange; });\n useEffect(() => { onStateChangeRef.current?.(orbState); }, [orbState]);\n\n const startRef = useRef(start);\n const stopRef = useRef(stop);\n useEffect(() => { startRef.current = start; }, [start]);\n useEffect(() => { stopRef.current = stop; }, [stop]);\n useEffect(() => { return () => { stopRef.current(true); }; }, []);\n\n const [micPaused, setMicPaused] = useState(false);\n const [activity, setActivity] = useState(0);\n const [showSettings, setShowSettings] = useState(false);\n const hasConversationRef = useRef(false);\n hasConversationRef.current = messages.length > 0;\n const onCollapseRef = useRef(onCollapse);\n useEffect(() => { onCollapseRef.current = onCollapse; });\n\n const bumpActivity = useCallback(() => { setActivity((c) => c + 1); }, []);\n\n const handleCancel = useCallback(() => {\n if (state === 'PROCESSING' || state === 'AI_SPEAKING') { stop(); return true; }\n return false;\n }, [state, stop]);\n\n const handleMicToggle = useCallback(() => {\n setMicPaused(false); bumpActivity();\n if (state === 'LISTENING' || state === 'USER_SPEAKING') { stop(); }\n else if (state === 'IDLE') { start(); }\n else if (handleCancel()) { start(); }\n }, [state, start, stop, bumpActivity, handleCancel]);\n\n useEffect(() => { if (panelState === 'hidden') stopRef.current(true); }, [panelState]);\n\n // micOpen: true when mic is live (LISTENING or USER_SPEAKING).\n // Used as the effect dep so the idle timer starts when the mic opens and\n // clears when the pipeline takes over (PROCESSING/AI_SPEAKING).\n // VAD bouncing between LISTENING↔USER_SPEAKING keeps micOpen=true,\n // so background noise doesn't reset the timer.\n // Full pipeline turns DO reset it (micOpen false→true), which is correct —\n // after a real answer the user needs a fresh window to respond.\n const micOpen = state === 'LISTENING' || state === 'USER_SPEAKING';\n const stateRef = useRef(state);\n stateRef.current = state;\n\n useEffect(() => {\n if (panelState === 'hidden' || micPaused || showSettings) return;\n if (!micOpen) return;\n // Reschedule loop: if the timer fires while the user is mid-speech,\n // reschedule instead of closing — prevents cutting off long utterances.\n let timer: ReturnType<typeof setTimeout>;\n const schedule = () => {\n timer = setTimeout(() => {\n if (stateRef.current === 'USER_SPEAKING') { schedule(); return; }\n stopRef.current();\n if (hasConversationRef.current) { setMicPaused(true); } else { onCollapseRef.current(); }\n }, settings.idleTimeoutMs);\n };\n schedule();\n return () => clearTimeout(timer);\n }, [micOpen, panelState, micPaused, showSettings, activity, settings.idleTimeoutMs]);\n\n useEffect(() => {\n if (!micPaused || panelState !== 'expanded' || showSettings) return;\n if (settings.panelCollapseTimeoutMs === 0) return;\n const timer = setTimeout(() => { onCollapseRef.current(); }, settings.panelCollapseTimeoutMs);\n return () => clearTimeout(timer);\n }, [micPaused, panelState, showSettings, activity, settings.panelCollapseTimeoutMs]);\n\n const handleTextSubmit = useCallback((text: string) => { setMicPaused(false); bumpActivity(); sendTextMessage(text); }, [sendTextMessage, bumpActivity]);\n\n const handleReport = useCallback((turnNumber: number, assistantMessage: string, userMessage?: string) => {\n setFeedbackTarget({ assistantMessage, userMessage, turnNumber });\n }, []);\n\n const handleFeedbackCancel = useCallback(() => {\n setFeedbackTarget(null);\n }, []);\n\n const handleFeedbackSubmit = useCallback(async (text: string, target: { assistantMessage: string; userMessage?: string; turnNumber: number }) => {\n const backendUrl = (typeof import.meta !== 'undefined' && import.meta.env?.VITE_BACKEND_URL) || '';\n const url = backendUrl ? `${backendUrl}/api/feedback` : '/api/feedback';\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n sessionId,\n turnNumber: target.turnNumber,\n text,\n assistantMessage: target.assistantMessage,\n userMessage: target.userMessage,\n timings: lastTimings ?? undefined,\n route: window.location.pathname,\n copilotName: config.copilotName,\n kitVersion: __KIT_VERSION__,\n }),\n });\n const body = await res.json().catch(() => ({ ticketId: undefined }));\n setFeedbackSentTurns(prev => ({ ...prev, [target.turnNumber]: body.ticketId || '\\u2713' }));\n } catch { /* silent — feedback is best-effort */ }\n setFeedbackTarget(null);\n }, [sessionId, config.copilotName, lastTimings]);\n\n const isTyping = state === 'AI_SPEAKING';\n const effectiveError = backendDown ? ('network_error' as const) : voiceError;\n\n const [isRetrying, setIsRetrying] = useState(false);\n const handleRetryClick = useCallback(() => {\n if (isRetrying) return;\n setIsRetrying(true);\n backoffDelayRef.current = RETRY_INITIAL_MS;\n clearCountdown();\n checkBackendHealth().then(({ available }) => {\n if (cancelledRef.current) return;\n setIsRetrying(false);\n setBackendDown(!available);\n if (available) {\n dismissErrorRef.current();\n if (!autoStartedRef.current && autoListenRef.current) { autoStartedRef.current = true; startRef.current(); }\n } else {\n scheduleRetry(backoffDelayRef.current);\n }\n }).catch(() => setIsRetrying(false));\n }, [isRetrying, clearCountdown, scheduleRetry]);\n\n // Auto-expand panel when first message arrives (voice-first: skip empty state)\n const onExpandRef = useRef(onExpand);\n useEffect(() => { onExpandRef.current = onExpand; });\n useEffect(() => {\n if (panelState === 'collapsed' && messages.length > 0) {\n onExpandRef.current();\n }\n }, [panelState, messages.length]);\n\n const switchToTextRef = useRef<(() => void) | null>(null);\n const handleSwitchToKeyboard = useCallback(() => { switchToTextRef.current?.(); }, []);\n\n const toggleSettings = useCallback(() => setShowSettings((p) => !p), []);\n\n // Pause listening when settings panel is open, resume when closed\n const wasListeningBeforeSettingsRef = useRef(false);\n useEffect(() => {\n if (showSettings) {\n if (state === 'LISTENING' || state === 'USER_SPEAKING') {\n wasListeningBeforeSettingsRef.current = true;\n stopRef.current();\n } else {\n wasListeningBeforeSettingsRef.current = false;\n }\n } else if (wasListeningBeforeSettingsRef.current) {\n wasListeningBeforeSettingsRef.current = false;\n startRef.current();\n }\n }, [showSettings]);\n\n if (panelState === 'collapsed') {\n const lastAssistantMsg = messages.slice().reverse().find(m => m.role === 'assistant')?.text;\n return <CollapsedBar orbState={orbState} getAmplitude={getAmplitude} analyser={analyser} voiceState={state} onExpand={onExpand} onClose={onClose} onRetry={handleRetryClick} isRetrying={isRetrying} retryCountdown={retryCountdown} voiceError={effectiveError} micPaused={micPaused} onMicToggle={handleMicToggle} ttsEnabled={settings.ttsEnabled} copilotName={config.copilotName} portraitSrc={resolvedPortrait} lastMessage={lastAssistantMsg} />;\n }\n\n return (\n <div className=\"relative h-full\">\n <ExpandedContent orbState={orbState} getAmplitude={getAmplitude} analyser={analyser} voiceState={state} messages={messages} isTyping={isTyping} toolResult={toolResult} voiceError={effectiveError} dismissError={dismissError} onCollapse={onCollapse} onClose={onClose} onTextSubmit={handleTextSubmit} onMicToggle={handleMicToggle} onCancel={handleCancel} micPaused={micPaused} onToolDismiss={() => setToolResult(null)} onInteraction={bumpActivity} onRetry={handleRetryClick} isRetrying={isRetrying} retryCountdown={retryCountdown} lastTimings={lastTimings} showPipelineMetrics={settings.showPipelineMetrics} pipelineMetricsAutoHideMs={settings.pipelineMetricsAutoHideMs} showSettings={showSettings} onSettingsToggle={toggleSettings} ttsEnabled={settings.ttsEnabled} copilotName={config.copilotName} portraitSrc={resolvedPortrait} onStartMic={handleMicToggle} onSwitchToKeyboard={handleSwitchToKeyboard} switchToTextRef={switchToTextRef} onReport={handleReport} feedbackSentTurns={feedbackSentTurns} feedbackTarget={feedbackTarget} onFeedbackSubmit={handleFeedbackSubmit} onFeedbackCancel={handleFeedbackCancel} />\n <AnimatePresence>\n {showSettings && (<Suspense fallback={null}><VoiceSettingsView onBack={toggleSettings} onVolumeChange={applyVolume} /></Suspense>)}\n </AnimatePresence>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main exported component\n// ---------------------------------------------------------------------------\nexport default function GlassCopilotPanel({ isOpen: isOpenProp, onOpen: onOpenProp, onClose: onCloseProp, onStateChange, portraitSrc }: GlassCopilotPanelProps) {\n injectAgentFabCSS();\n const config = useSiteConfig();\n const resolvedPortrait = portraitSrc ?? config.avatarUrl;\n\n // Hide on excluded routes\n const [routeHidden, setRouteHidden] = useState(() => isRouteExcluded(config.excludeRoutes));\n useEffect(() => {\n if (!config.excludeRoutes?.length) return;\n // Re-check on SPA navigation (popstate) and periodically for pushState\n const check = () => setRouteHidden(isRouteExcluded(config.excludeRoutes));\n window.addEventListener('popstate', check);\n const timer = setInterval(check, 500);\n return () => { window.removeEventListener('popstate', check); clearInterval(timer); };\n }, [config.excludeRoutes]);\n\n // Uncontrolled mode: manage open state internally when isOpen prop is not provided\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = isOpenProp !== undefined;\n const isOpen = isControlled ? isOpenProp : internalOpen;\n\n const handleOpen = useCallback(() => {\n onOpenProp?.();\n if (!isControlled) setInternalOpen(true);\n }, [onOpenProp, isControlled]);\n\n const [internalState, setInternalState] = useState<'collapsed' | 'expanded'>('collapsed');\n const panelState: PanelState = isOpen ? internalState : 'hidden';\n const handleClose = useCallback(() => {\n onCloseProp?.();\n if (!isControlled) setInternalOpen(false);\n }, [onCloseProp, isControlled]);\n const handleCollapse = useCallback(() => { setInternalState('collapsed'); }, []);\n const handleExpand = useCallback(() => { setInternalState('expanded'); }, []);\n\n const [fabOffline, setFabOffline] = useState(false);\n useEffect(() => {\n if (isOpen || routeHidden) return; // Skip polling when panel visible or route excluded\n let cancelled = false;\n const check = () => {\n checkBackendHealth().then(({ available }) => {\n if (!cancelled) setFabOffline(!available);\n });\n };\n check();\n const timer = setInterval(check, RECOVERY_POLL_MS);\n return () => { cancelled = true; clearInterval(timer); };\n }, [isOpen, routeHidden]);\n\n const isVisible = panelState !== 'hidden';\n const isExpanded = panelState === 'expanded';\n const targetHeight = isExpanded ? PANEL_EXPANDED_HEIGHT : PANEL_COLLAPSED_HEIGHT;\n\n const panelRef = useRef<HTMLDivElement>(null);\n const fabRef = useRef<HTMLDivElement>(null);\n const prevVisibleRef = useRef(isVisible);\n\n useEffect(() => {\n if (isVisible && !prevVisibleRef.current) { requestAnimationFrame(() => panelRef.current?.focus()); }\n else if (!isVisible && prevVisibleRef.current) { requestAnimationFrame(() => { const fabButton = fabRef.current?.querySelector('button'); fabButton?.focus(); }); }\n prevVisibleRef.current = isVisible;\n }, [isVisible]);\n\n const [ariaAnnouncement, setAriaAnnouncement] = useState('');\n const handleStateChange = useCallback((orbState: OrbState) => { setAriaAnnouncement(ARIA_LIVE_LABELS[orbState]); onStateChange?.(orbState); }, [onStateChange]);\n\n if (routeHidden) return null;\n\n return createPortal(\n <VoiceErrorBoundary onReset={handleClose}>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"0\" height=\"0\" style={{ position: 'absolute', overflow: 'hidden' }} aria-hidden=\"true\">\n <defs>\n <filter id=\"liquid-glass-panel\" x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n <feTurbulence type=\"fractalNoise\" baseFrequency=\"0.008 0.008\" numOctaves=\"2\" seed=\"42\" result=\"noise\" />\n <feGaussianBlur in=\"noise\" stdDeviation=\"2\" result=\"blurred_noise\" />\n <feDisplacementMap in=\"SourceGraphic\" in2=\"blurred_noise\" scale=\"50\" xChannelSelector=\"R\" yChannelSelector=\"G\" />\n </filter>\n </defs>\n </svg>\n\n <span aria-live=\"polite\" aria-atomic=\"true\" style={{ position: 'absolute', width: 1, height: 1, padding: 0, margin: -1, overflow: 'hidden', clip: 'rect(0,0,0,0)', whiteSpace: 'nowrap', borderWidth: 0 }}>\n {ariaAnnouncement}\n </span>\n\n <AnimatePresence>\n {!isVisible && (\n <motion.div ref={fabRef} key=\"copilot-fab\" initial={{ scale: 0, opacity: 0 }} animate={{ scale: 1, opacity: 1 }} exit={{ scale: 0, opacity: 0 }} transition={{ duration: 0.25, ease: 'easeOut' }} className=\"fixed\" style={{ bottom: PANEL_BOTTOM, right: PANEL_RIGHT, zIndex: PANEL_Z_INDEX, display: 'flex', alignItems: 'flex-end', gap: 12 }}>\n <CopilotFABTooltip onClick={handleOpen} />\n <CopilotFAB onClick={handleOpen} portraitSrc={resolvedPortrait} isOffline={fabOffline} />\n </motion.div>\n )}\n\n {isVisible && (\n <motion.div ref={panelRef} tabIndex={-1} key=\"copilot-panel\" role=\"dialog\" aria-label=\"Voice Assistant\" aria-modal=\"false\" data-testid=\"voice-agent-panel\"\n initial={{ width: 80, height: 80, borderRadius: 40, opacity: 0, scale: 0.9 }}\n animate={{ width: PANEL_WIDTH, height: Math.min(targetHeight, window.innerHeight - 48), borderRadius: PANEL_BORDER_RADIUS, opacity: 1, scale: 1, transition: SPRING_PANEL }}\n exit={{ width: 80, height: 80, borderRadius: 40, opacity: 0, scale: 0.95, transition: SPRING_PANEL_EXIT }}\n className=\"fixed\"\n style={{ bottom: PANEL_BOTTOM, right: PANEL_RIGHT, zIndex: PANEL_Z_INDEX, transformOrigin: 'bottom right', maxWidth: 'calc(100vw - 32px)', outline: 'none', fontFamily: config.fontFamily ?? DEFAULT_FONT_FAMILY }}\n >\n <div className=\"absolute inset-0 pointer-events-none\" style={{ borderRadius: PANEL_BORDER_RADIUS, overflow: 'hidden', backdropFilter: 'blur(2px)', WebkitBackdropFilter: 'blur(2px)', filter: 'url(#liquid-glass-panel)', isolation: 'isolate' }} />\n <div className=\"absolute inset-0 pointer-events-none\" style={{ borderRadius: PANEL_BORDER_RADIUS, overflow: 'hidden', backdropFilter: 'blur(14px) saturate(1.4)', WebkitBackdropFilter: 'blur(14px) saturate(1.4)', backgroundColor: 'rgba(230,232,245,0.32)', border: '1px solid rgba(255,255,255,0.4)', boxShadow: 'inset 0 0 20px -5px rgba(255,255,255,0.3), inset 0 1px 0 0 rgba(255,255,255,0.8), 0 0 0 1px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.08), 0 8px 24px rgba(0,0,0,0.14), 0 24px 48px rgba(0,0,0,0.10)' }} />\n <div className=\"absolute inset-0 pointer-events-none\" style={{ borderRadius: PANEL_BORDER_RADIUS, background: 'linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0) 20%)' }} />\n <div style={{ position: 'relative', zIndex: 1, height: '100%', overflow: 'hidden', borderRadius: PANEL_BORDER_RADIUS, backgroundColor: 'rgba(255,255,255,0.78)' }}>\n <WiredPanel panelState={panelState} onCollapse={handleCollapse} onExpand={handleExpand} onClose={handleClose} onStateChange={handleStateChange} portraitSrc={resolvedPortrait} />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </VoiceErrorBoundary>,\n document.body\n );\n}\n","import { useRef, useEffect, useState, useCallback } from 'react';\nimport VoiceOrb from './VoiceOrb';\nimport {\n AVATAR_PORTRAIT_RATIO,\n AVATAR_STATE_FILTERS,\n buildGlowColors,\n useSiteConfig,\n} from '@unctad-ai/voice-agent-core';\nimport type { OrbState } from '@unctad-ai/voice-agent-core';\n\n/** Conic gradient colors per state — [color1, color2] */\nconst RING_COLORS: Record<OrbState, [string, string]> = {\n idle: ['#93a3c8', '#b0bfdb'],\n listening: ['#DB2129', '#34d399'],\n processing: ['#F59E0B', '#FBBF24'],\n speaking: ['#14B8A6', '#34d399'],\n error: ['#DC2626', '#991B1B'],\n};\n\ninterface AgentAvatarProps {\n state: OrbState;\n getAmplitude: () => number;\n size?: number;\n showAura?: boolean;\n /** Show audio-reactive conic-gradient ring around portrait */\n showRing?: boolean;\n /** URL for the avatar portrait image */\n portraitSrc?: string;\n /** Monogram letter shown when image fails to load */\n monogram?: string;\n}\n\nfunction lerp(a: number, b: number, t: number) {\n return a + (b - a) * t;\n}\n\nexport default function AgentAvatar({\n state,\n getAmplitude,\n size = 36,\n showAura = true,\n showRing = false,\n portraitSrc,\n monogram,\n}: AgentAvatarProps) {\n const config = useSiteConfig();\n const initial = monogram ?? config.copilotName?.charAt(0)?.toUpperCase() ?? 'A';\n const { colors } = useSiteConfig();\n const AVATAR_GLOW_COLORS = buildGlowColors(colors);\n const portraitSize = Math.round(size * AVATAR_PORTRAIT_RATIO);\n const offset = Math.round((size - portraitSize) / 2);\n\n // Ring sits between aura and portrait — 3px border around portrait\n const ringWidth = 3;\n const ringSize = portraitSize + ringWidth * 2;\n const ringOffset = Math.round((size - ringSize) / 2);\n\n const imgRef = useRef<HTMLImageElement>(null);\n const glowRef = useRef<HTMLDivElement>(null);\n const ringRef = useRef<HTMLDivElement>(null);\n const rafRef = useRef<number>(0);\n const stateRef = useRef<OrbState>(state);\n useEffect(() => {\n stateRef.current = state;\n });\n const getAmpRef = useRef(getAmplitude);\n useEffect(() => {\n getAmpRef.current = getAmplitude;\n });\n\n const [loaded, setLoaded] = useState(false);\n const [errored, setErrored] = useState(false);\n\n // Detect prefers-reduced-motion\n const reducedRef = useRef(false);\n useEffect(() => {\n const mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n reducedRef.current = mql.matches;\n const handler = (e: MediaQueryListEvent) => {\n reducedRef.current = e.matches;\n };\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, []);\n\n // Animated filter values — lerped each frame, no React re-renders\n const animRef = useRef({\n brightness: AVATAR_STATE_FILTERS.idle.brightness,\n saturate: AVATAR_STATE_FILTERS.idle.saturate,\n opacity: AVATAR_STATE_FILTERS.idle.opacity,\n scale: AVATAR_STATE_FILTERS.idle.scale,\n glowIntensity: AVATAR_STATE_FILTERS.idle.glowIntensity,\n ringAngle: 0,\n });\n\n useEffect(() => {\n let startTime: number | null = null;\n let prevTimestamp = 0;\n\n const tick = (timestamp: number) => {\n if (startTime === null) startTime = timestamp;\n const elapsed = (timestamp - startTime) / 1000;\n const dt = prevTimestamp ? (timestamp - prevTimestamp) / 1000 : 0.016;\n prevTimestamp = timestamp;\n\n const target = AVATAR_STATE_FILTERS[stateRef.current];\n const a = animRef.current;\n const speed = 0.08;\n\n a.brightness = lerp(a.brightness, target.brightness, speed);\n a.saturate = lerp(a.saturate, target.saturate, speed);\n a.scale = lerp(a.scale, target.scale, speed);\n a.glowIntensity = lerp(a.glowIntensity, target.glowIntensity, speed);\n\n // Processing opacity pulses\n let targetOpacity = target.opacity;\n if (stateRef.current === 'processing') {\n targetOpacity = 0.92 + Math.sin(elapsed * 4) * 0.06;\n }\n a.opacity = lerp(a.opacity, targetOpacity, speed);\n\n // Speaking state: portrait scale reacts to amplitude\n const amp = getAmpRef.current();\n const ampFactor = reducedRef.current ? 0.2 : 1;\n let scaleBoost = 0;\n if (stateRef.current === 'speaking') {\n scaleBoost = amp * 0.03 * ampFactor;\n }\n\n // Apply to portrait image via direct DOM mutation\n const img = imgRef.current;\n if (img) {\n img.style.filter = `brightness(${a.brightness}) saturate(${a.saturate})`;\n img.style.opacity = String(a.opacity);\n img.style.transform = `scale(${a.scale + scaleBoost})`;\n }\n\n // Apply glow overlay\n const glow = glowRef.current;\n if (glow) {\n glow.style.backgroundColor = AVATAR_GLOW_COLORS[stateRef.current];\n glow.style.opacity = String(a.glowIntensity);\n }\n\n // Audio-reactive ring\n const ring = ringRef.current;\n if (ring) {\n const ringColors = RING_COLORS[stateRef.current];\n // Rotation: base 120 deg/s, amplitude boosts up to 3x\n const rotSpeed = reducedRef.current ? 0 : 120 * (1 + amp * 2);\n a.ringAngle = (a.ringAngle + rotSpeed * dt) % 360;\n // Ring opacity: idle = subtle, active states = brighter with amplitude boost\n const isActive = stateRef.current !== 'idle';\n const ringOpacity = isActive ? 0.7 + amp * 0.3 : 0.35;\n // Scale pulse with amplitude\n const ringScale = 1 + amp * 0.04 * ampFactor;\n\n ring.style.background = `conic-gradient(from ${a.ringAngle}deg, ${ringColors[0]}, ${ringColors[1]}, ${ringColors[0]})`;\n ring.style.opacity = String(ringOpacity);\n ring.style.transform = `scale(${ringScale})`;\n }\n\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafRef.current);\n }, []);\n\n const handleLoad = useCallback(() => setLoaded(true), []);\n const handleError = useCallback(() => setErrored(true), []);\n\n return (\n <div\n style={{\n position: 'relative',\n width: size,\n height: size,\n flexShrink: 0,\n }}\n >\n {/* Layer 1: Aura — VoiceOrb as reactive background */}\n {showAura && (\n <div style={{ position: 'absolute', inset: 0 }}>\n <VoiceOrb state={state} getAmplitude={getAmplitude} size={size} />\n </div>\n )}\n\n {/* Layer 1.5: Audio-reactive conic-gradient ring */}\n {showRing && (\n <div\n ref={ringRef}\n style={{\n position: 'absolute',\n top: ringOffset,\n left: ringOffset,\n width: ringSize,\n height: ringSize,\n borderRadius: '50%',\n background: `conic-gradient(from 0deg, ${RING_COLORS.idle[0]}, ${RING_COLORS.idle[1]}, ${RING_COLORS.idle[0]})`,\n opacity: 0.35,\n WebkitMask: `radial-gradient(circle, transparent ${Math.round((portraitSize / ringSize) * 50)}%, black ${Math.round((portraitSize / ringSize) * 50)}%)`,\n mask: `radial-gradient(circle, transparent ${Math.round((portraitSize / ringSize) * 50)}%, black ${Math.round((portraitSize / ringSize) * 50)}%)`,\n pointerEvents: 'none',\n willChange: 'transform, background, opacity',\n }}\n />\n )}\n\n {/* Layer 2: Glow overlay — color wash per state */}\n <div\n ref={glowRef}\n style={{\n position: 'absolute',\n top: offset,\n left: offset,\n width: portraitSize,\n height: portraitSize,\n borderRadius: '50%',\n mixBlendMode: 'soft-light',\n opacity: 0,\n pointerEvents: 'none',\n transition: 'background-color 0.3s',\n }}\n />\n\n {/* Layer 3: Portrait */}\n <div\n style={{\n position: 'absolute',\n top: offset,\n left: offset,\n width: portraitSize,\n height: portraitSize,\n borderRadius: '50%',\n overflow: 'hidden',\n }}\n >\n {errored || !portraitSrc ? (\n // Monogram fallback\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: colors.primary,\n color: 'white',\n fontFamily: 'inherit',\n fontWeight: 700,\n fontSize: Math.round(portraitSize * 0.45),\n }}\n >\n {initial}\n </div>\n ) : (\n <img\n ref={imgRef}\n src={portraitSrc}\n alt=\"Avatar\"\n onLoad={handleLoad}\n onError={handleError}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n borderRadius: '50%',\n opacity: loaded ? 0.95 : 0,\n transition: loaded ? 'none' : 'opacity 0.3s ease-in',\n willChange: 'filter, transform, opacity',\n }}\n draggable={false}\n />\n )}\n </div>\n </div>\n );\n}\n","import { useRef, useEffect, useCallback, useState, useMemo } from 'react';\nimport { createNoise3D } from 'simplex-noise';\nimport { ORB_NUM_POINTS, ORB_LERP_SPEED, useSiteConfig } from '@unctad-ai/voice-agent-core';\nimport type { OrbState, SiteColors } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceOrbProps {\n state: OrbState;\n /** Getter function called each animation frame — avoids 60fps React re-renders */\n getAmplitude: () => number;\n size?: number;\n}\n\n// ---------- state config ----------\n\ninterface StateConfig {\n colors: [string, string];\n noiseSpeed: number;\n noiseMag: number;\n baseScale: number;\n breathAmp: number;\n breathSpeed: number;\n rotation: number;\n shimmer: boolean;\n}\n\n/** Normalize any hex shorthand (#RGB) to full form (#RRGGBB), strip alpha */\nfunction normalizeHex(hex: string): string {\n if (!hex || hex[0] !== '#') return '#808080';\n const h = hex.slice(1);\n if (h.length === 3) return '#' + h[0]+h[0] + h[1]+h[1] + h[2]+h[2];\n if (h.length >= 6) return '#' + h.slice(0, 6);\n return '#808080';\n}\n\n/** Darken a hex color by lerping toward black */\nfunction darkenHex(hex: string, amount: number): string {\n hex = normalizeHex(hex);\n const r = Math.max(0, Math.round(parseInt(hex.slice(1, 3), 16) * (1 - amount)));\n const g = Math.max(0, Math.round(parseInt(hex.slice(3, 5), 16) * (1 - amount)));\n const b = Math.max(0, Math.round(parseInt(hex.slice(5, 7), 16) * (1 - amount)));\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}`;\n}\n\n/** Lighten a hex color by lerping toward white */\nfunction lightenHex(hex: string, amount: number): string {\n hex = normalizeHex(hex);\n const r = Math.min(255, Math.round(parseInt(hex.slice(1, 3), 16) + (255 - parseInt(hex.slice(1, 3), 16)) * amount));\n const g = Math.min(255, Math.round(parseInt(hex.slice(3, 5), 16) + (255 - parseInt(hex.slice(3, 5), 16)) * amount));\n const b = Math.min(255, Math.round(parseInt(hex.slice(5, 7), 16) + (255 - parseInt(hex.slice(5, 7), 16)) * amount));\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}`;\n}\n\n/** Convert hex to rgba string */\nfunction hexToRGBA(hex: string, opacity: number): string {\n hex = normalizeHex(hex);\n return `rgba(${parseInt(hex.slice(1, 3), 16)}, ${parseInt(hex.slice(3, 5), 16)}, ${parseInt(hex.slice(5, 7), 16)}, ${opacity})`;\n}\n\n/** Glow color that pulses around the orb per state — derived from SiteColors */\nfunction buildStateGlow(colors: SiteColors): Record<OrbState, string> {\n return {\n idle: 'rgba(59, 130, 246, 0.25)',\n listening: hexToRGBA(colors.primary, 0.45),\n processing: hexToRGBA(colors.processing, 0.4),\n speaking: hexToRGBA(colors.speaking, 0.4),\n error: hexToRGBA(colors.error ?? '#DC2626', 0.4),\n };\n}\n\nfunction buildStateConfig(colors: SiteColors): Record<OrbState, StateConfig> {\n const errorColor = colors.error ?? '#DC2626';\n return {\n idle: {\n colors: ['#1E3A5F', '#3B82F6'],\n noiseSpeed: 0.3,\n noiseMag: 8,\n baseScale: 0.975,\n breathAmp: 0.025,\n breathSpeed: 0.25,\n rotation: 0,\n shimmer: false,\n },\n listening: {\n colors: [colors.primary, colors.processing],\n noiseSpeed: 0.6,\n noiseMag: 18,\n baseScale: 1.0,\n breathAmp: 0.04,\n breathSpeed: 0.5,\n rotation: 0,\n shimmer: false,\n },\n processing: {\n colors: [darkenHex(colors.processing, 0.3), lightenHex(colors.processing, 0.4)],\n noiseSpeed: 1.0,\n noiseMag: 14,\n baseScale: 1.0,\n breathAmp: 0.02,\n breathSpeed: 0.8,\n rotation: 0.4,\n shimmer: true,\n },\n speaking: {\n colors: [darkenHex(colors.speaking, 0.35), lightenHex(colors.speaking, 0.4)],\n noiseSpeed: 0.5,\n noiseMag: 16,\n baseScale: 1.0,\n breathAmp: 0.05,\n breathSpeed: 0.4,\n rotation: 0,\n shimmer: false,\n },\n error: {\n colors: [errorColor, darkenHex(errorColor, 0.35)],\n noiseSpeed: 1.4,\n noiseMag: 22,\n baseScale: 0.95,\n breathAmp: 0.01,\n breathSpeed: 1.2,\n rotation: 0,\n shimmer: false,\n },\n };\n}\n\nconst NUM_POINTS = ORB_NUM_POINTS;\nconst LERP_SPEED = ORB_LERP_SPEED;\n\nfunction useReducedMotion() {\n const [reduced, setReduced] = useState(\n () => window.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n useEffect(() => {\n const mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n const handler = (e: MediaQueryListEvent) => setReduced(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, []);\n return reduced;\n}\n\nfunction lerp(a: number, b: number, t: number) {\n return a + (b - a) * t;\n}\n\nfunction lerpColor(a: string, b: string, t: number): string {\n const parseHex = (h: string) => [\n parseInt(h.slice(1, 3), 16),\n parseInt(h.slice(3, 5), 16),\n parseInt(h.slice(5, 7), 16),\n ];\n const ca = parseHex(a);\n const cb = parseHex(b);\n const r = Math.round(lerp(ca[0], cb[0], t));\n const g = Math.round(lerp(ca[1], cb[1], t));\n const bl = Math.round(lerp(ca[2], cb[2], t));\n return `#${((1 << 24) | (r << 16) | (g << 8) | bl).toString(16).slice(1)}`;\n}\n\nexport default function VoiceOrb({ state, getAmplitude, size = 200 }: VoiceOrbProps) {\n const config = useSiteConfig();\n const STATE_CONFIG = useMemo(() => buildStateConfig(config.colors), [config.colors]);\n const STATE_GLOW = useMemo(() => buildStateGlow(config.colors), [config.colors]);\n\n const svgRef = useRef<SVGSVGElement>(null);\n const rafRef = useRef<number>(0);\n const noise3D = useRef(createNoise3D());\n const prefersReduced = useReducedMotion();\n const reducedRef = useRef(prefersReduced);\n reducedRef.current = prefersReduced;\n\n // Animated (lerped) config values that transition smoothly between states\n const animRef = useRef({\n noiseSpeed: STATE_CONFIG.idle.noiseSpeed,\n noiseMag: STATE_CONFIG.idle.noiseMag,\n baseScale: STATE_CONFIG.idle.baseScale,\n breathAmp: STATE_CONFIG.idle.breathAmp,\n breathSpeed: STATE_CONFIG.idle.breathSpeed,\n rotation: STATE_CONFIG.idle.rotation,\n color0: STATE_CONFIG.idle.colors[0],\n color1: STATE_CONFIG.idle.colors[1],\n shimmer: 0,\n errorShake: 0,\n });\n\n const stateRef = useRef<OrbState>(state);\n stateRef.current = state;\n\n const stateGlowRef = useRef(STATE_GLOW);\n stateGlowRef.current = STATE_GLOW;\n\n const getAmplitudeRef = useRef(getAmplitude);\n getAmplitudeRef.current = getAmplitude;\n\n const stateConfigRef = useRef(STATE_CONFIG);\n stateConfigRef.current = STATE_CONFIG;\n\n const buildPath = useCallback(\n (time: number, a: typeof animRef.current): string => {\n const cx = size / 2;\n const cy = size / 2;\n const baseR = size * 0.35;\n const amp = getAmplitudeRef.current();\n\n // amplitude influences noise magnitude\n const mag = a.noiseMag + amp * 20;\n\n const points: [number, number][] = [];\n for (let i = 0; i < NUM_POINTS; i++) {\n const angle = (i / NUM_POINTS) * Math.PI * 2;\n const nx = Math.cos(angle);\n const ny = Math.sin(angle);\n const noiseVal = noise3D.current(nx * 1.5, ny * 1.5, time * a.noiseSpeed);\n const r = baseR + noiseVal * mag;\n points.push([cx + Math.cos(angle) * r, cy + Math.sin(angle) * r]);\n }\n\n // Build smooth closed path with cubic beziers\n let d = `M ${points[0][0]},${points[0][1]} `;\n for (let i = 0; i < NUM_POINTS; i++) {\n const curr = points[i];\n const next = points[(i + 1) % NUM_POINTS];\n const prev = points[(i - 1 + NUM_POINTS) % NUM_POINTS];\n const next2 = points[(i + 2) % NUM_POINTS];\n\n const cp1x = curr[0] + (next[0] - prev[0]) / 6;\n const cp1y = curr[1] + (next[1] - prev[1]) / 6;\n const cp2x = next[0] - (next2[0] - curr[0]) / 6;\n const cp2y = next[1] - (next2[1] - curr[1]) / 6;\n\n d += `C ${cp1x},${cp1y} ${cp2x},${cp2y} ${next[0]},${next[1]} `;\n }\n d += 'Z';\n return d;\n },\n [size]\n );\n\n useEffect(() => {\n let startTime: number | null = null;\n\n const tick = (timestamp: number) => {\n if (startTime === null) startTime = timestamp;\n const elapsed = (timestamp - startTime) / 1000;\n\n const target = stateConfigRef.current[stateRef.current];\n const a = animRef.current;\n\n // When prefers-reduced-motion is active, dampen animations significantly\n const rd = reducedRef.current ? 0.15 : 1;\n\n // Lerp all animated values toward target\n a.noiseSpeed = lerp(a.noiseSpeed, target.noiseSpeed * rd, LERP_SPEED);\n a.noiseMag = lerp(a.noiseMag, target.noiseMag * rd, LERP_SPEED);\n a.baseScale = lerp(a.baseScale, target.baseScale, LERP_SPEED);\n a.breathAmp = lerp(a.breathAmp, target.breathAmp * rd, LERP_SPEED);\n a.breathSpeed = lerp(a.breathSpeed, target.breathSpeed * rd, LERP_SPEED);\n a.rotation = lerp(a.rotation, target.rotation * rd, LERP_SPEED);\n a.shimmer = lerp(a.shimmer, target.shimmer ? (reducedRef.current ? 0 : 1) : 0, LERP_SPEED);\n a.color0 = lerpColor(a.color0, target.colors[0], LERP_SPEED);\n a.color1 = lerpColor(a.color1, target.colors[1], LERP_SPEED);\n\n // Error shake decays\n if (stateRef.current === 'error') {\n a.errorShake = lerp(a.errorShake, 1, 0.1);\n } else {\n a.errorShake = lerp(a.errorShake, 0, 0.08);\n }\n\n const svg = svgRef.current;\n if (!svg) {\n rafRef.current = requestAnimationFrame(tick);\n return;\n }\n\n // Breathing scale\n const breath = a.baseScale + Math.sin(elapsed * Math.PI * 2 * a.breathSpeed) * a.breathAmp;\n\n // Error shake offset\n const shakeX = a.errorShake * Math.sin(elapsed * 30) * 3 * (1 - Math.min(elapsed * 0.3, 1));\n\n // Rotation\n const rot = elapsed * a.rotation * 360;\n\n // Update transform\n const group = svg.querySelector<SVGGElement>('[data-orb-group]');\n if (group) {\n group.setAttribute(\n 'transform',\n `translate(${size / 2 + shakeX}, ${size / 2}) scale(${breath}) rotate(${rot}) translate(${-size / 2}, ${-size / 2})`\n );\n }\n\n // Update blob path\n const path = svg.querySelector<SVGPathElement>('[data-orb-path]');\n if (path) {\n path.setAttribute('d', buildPath(elapsed, a));\n }\n\n // Update gradient colors\n const stop0 = svg.querySelector<SVGStopElement>('[data-stop-0]');\n const stop1 = svg.querySelector<SVGStopElement>('[data-stop-1]');\n if (stop0) stop0.setAttribute('stop-color', a.color0);\n if (stop1) stop1.setAttribute('stop-color', a.color1);\n\n // Shimmer opacity\n const shimmerEl = svg.querySelector<SVGCircleElement>('[data-shimmer]');\n if (shimmerEl) {\n const shimmerOpacity = a.shimmer * (0.15 + Math.sin(elapsed * 6) * 0.1);\n shimmerEl.setAttribute('opacity', String(shimmerOpacity));\n }\n\n // Ambient glow — color follows state, opacity pulses with breath\n const glowEl = svg.querySelector<SVGCircleElement>('[data-orb-glow]');\n if (glowEl) {\n const amp = getAmplitudeRef.current();\n const glowPulse = 0.35 + Math.sin(elapsed * Math.PI * 2 * a.breathSpeed) * 0.15 + amp * 0.3;\n glowEl.setAttribute('opacity', String(Math.min(glowPulse, 1)));\n glowEl.setAttribute('fill', stateGlowRef.current[stateRef.current]);\n }\n\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafRef.current);\n }, [size, buildPath]);\n\n const idRef = useRef<string>(null);\n idRef.current ??= Math.random().toString(36).slice(2, 8);\n const gradientId = `orb-gradient-${idRef.current}`;\n const shimmerId = `orb-shimmer-${idRef.current}`;\n const glowFilterId = `orb-glow-${idRef.current}`;\n\n return (\n <svg\n ref={svgRef}\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n className=\"select-none\"\n style={{ overflow: 'visible' }}\n aria-hidden=\"true\"\n >\n <defs>\n <radialGradient id={gradientId} cx=\"40%\" cy=\"35%\" r=\"60%\">\n <stop data-stop-0 offset=\"0%\" stopColor={STATE_CONFIG.idle.colors[0]} />\n <stop data-stop-1 offset=\"100%\" stopColor={STATE_CONFIG.idle.colors[1]} />\n </radialGradient>\n <radialGradient id={shimmerId} cx=\"30%\" cy=\"30%\" r=\"50%\">\n <stop offset=\"0%\" stopColor=\"white\" stopOpacity=\"0.6\" />\n <stop offset=\"100%\" stopColor=\"white\" stopOpacity=\"0\" />\n </radialGradient>\n <filter id={glowFilterId} x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"18\" />\n </filter>\n </defs>\n {/* Ambient glow halo behind the orb */}\n <circle\n data-orb-glow\n cx={size / 2}\n cy={size / 2}\n r={size * 0.38}\n fill={STATE_GLOW['idle']}\n opacity=\"0.5\"\n filter={`url(#${glowFilterId})`}\n />\n <g data-orb-group>\n <path data-orb-path fill={`url(#${gradientId})`} />\n <circle\n data-shimmer\n cx={size / 2}\n cy={size / 2}\n r={size * 0.3}\n fill={`url(#${shimmerId})`}\n opacity=\"0\"\n />\n </g>\n </svg>\n );\n}\n","const AGENT_FAB_CSS = `\n@keyframes agent-fab-rotate {\n from { --agent-angle: 0deg; }\n to { --agent-angle: 360deg; }\n}\n@property --agent-angle {\n syntax: '<angle>';\n initial-value: 0deg;\n inherits: false;\n}\n.agent-fab-border {\n position: relative;\n border-radius: 50%;\n padding: 3px;\n background: conic-gradient(from var(--agent-angle), var(--agent-primary, #db2129) 0%, #34d399 50%, var(--agent-primary, #db2129) 100%);\n animation: agent-fab-rotate 3s linear infinite;\n}\n.agent-fab-border-inner {\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n overflow: hidden;\n width: 100%;\n height: 100%;\n background: #fff;\n}\n.agent-fab-border-inner img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: 50%;\n}\n@media (prefers-reduced-motion: reduce) {\n .agent-fab-border { animation: none; }\n}\n.voice-msg-group:hover .voice-feedback-pill { opacity: 1 !important; }\n.voice-feedback-pill:hover { color: rgba(0,0,0,0.5) !important; border-color: rgba(0,0,0,0.2) !important; }`;\n\nlet injected = false;\nexport function injectAgentFabCSS() {\n if (injected || typeof document === 'undefined') return;\n const style = document.createElement('style');\n style.textContent = AGENT_FAB_CSS;\n document.head.appendChild(style);\n injected = true;\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { cn } from '../utils';\nimport {\n MAX_VISIBLE_MESSAGES,\n MAX_TEXT_LENGTH,\n TYPEWRITER_DELAY_MS,\n MIN_DISPLAY_LENGTH,\n PANEL_MAX_VISIBLE_MESSAGES,\n PANEL_MAX_TEXT_LENGTH,\n DEFAULT_FONT_FAMILY,\n useSiteConfig,\n} from '@unctad-ai/voice-agent-core';\nimport type { VoiceMessage, ActionCategory } from '@unctad-ai/voice-agent-core';\nimport type { VoiceErrorType } from './VoiceErrorDisplay';\nimport { ArrowRight, PenLine, MousePointerClick, Search, Info, ChevronDown, Mic, Keyboard, Flag, Copy, Check } from 'lucide-react';\n\n/** Strip markdown/HTML artifacts, TTS paralinguistic tags, and emojis — preserves line breaks */\nfunction cleanForDisplay(text: string): string {\n return text\n .replace(/\\[(laugh|chuckle|sigh|gasp|cough|clear throat|sniff|groan|shush)\\]/gi, '') // TTS paralinguistic tags\n .replace(/\\*\\*(.*?)\\*\\*/g, '$1') // **bold** → bold\n .replace(/^\\s*\\*\\s+/gm, '- ') // * list items → dash lists\n .replace(/\\*(.*?)\\*/g, '$1') // *italic* → italic\n .replace(/`([^`]+)`/g, '$1') // `code` → code\n .replace(/^#{1,6}\\s+/gm, '') // # headings → plain text\n .replace(/<br\\s*\\/?>/gi, '\\n') // <br> → newline\n .replace(/<[^>]+>/g, '') // strip remaining HTML tags\n .replace(/\\|[-:\\s|]+\\|/g, '') // table separator rows\n .replace(/\\|/g, '\\n') // | cell dividers → newlines\n .replace(/\\p{Emoji_Presentation}|\\p{Extended_Pictographic}/gu, '') // strip emojis\n .replace(/[ \\t]{3,}/g, ' ') // collapse horizontal whitespace (preserve \\n)\n .replace(/\\n{3,}/g, '\\n\\n') // collapse 3+ newlines to double\n .replace(/^[\\s-]{3,}$/gm, '') // --- horizontal rules\n .trim();\n}\n\n/** Render cleaned text with line breaks and styled list items */\nfunction FormattedText({\n text,\n className,\n style,\n}: {\n text: string;\n className?: string;\n style?: React.CSSProperties;\n}) {\n const lines = text.split('\\n').filter((l) => l.trim().length > 0);\n\n if (lines.length <= 1) {\n return (\n <p className={className} style={style}>\n {text}\n </p>\n );\n }\n\n return (\n <div className={className} style={style}>\n {lines.map((line, i) => {\n const trimmed = line.trim();\n const isListItem = /^\\d+[.)]\\s/.test(trimmed) || /^[-]\\s/.test(trimmed);\n return (\n <p\n key={i}\n style={{\n marginTop: i === 0 ? 0 : isListItem ? 4 : 8,\n paddingLeft: isListItem ? 8 : 0,\n }}\n >\n {trimmed}\n </p>\n );\n })}\n </div>\n );\n}\n\ninterface VoiceTranscriptProps {\n messages: VoiceMessage[];\n isTyping: boolean;\n /** When true, uses minimal text layout (no glass background) for the panel */\n variant?: 'overlay' | 'panel';\n /** When set, replaces the empty-state placeholder with a prominent error message */\n voiceError?: VoiceErrorType;\n /** Current voice state — used for contextual empty state */\n voiceState?: string;\n /** Callback to start mic from empty state */\n onStartMic?: () => void;\n /** Callback to switch to keyboard mode from empty state */\n onSwitchToKeyboard?: () => void;\n /** Callback when user reports a bad assistant response */\n onReport?: (turnNumber: number, assistantMessage: string, userMessage?: string) => void;\n /** Map of turn numbers to ticket IDs for sent feedback */\n feedbackSentTurns?: Record<number, string>;\n /** Callback to submit a text message (for suggested prompt chips) */\n onTextSubmit?: (text: string) => void;\n}\n\n/** Progressively reveals words while preserving FormattedText structure */\nfunction TypewriterFormattedText({\n text,\n className,\n style,\n}: {\n text: string;\n className?: string;\n style?: React.CSSProperties;\n}) {\n const [visibleWords, setVisibleWords] = useState(0);\n const words = text.split(' ');\n\n useEffect(() => {\n setVisibleWords(0);\n if (words.length === 0) return;\n\n let i = 0;\n const interval = setInterval(() => {\n i++;\n setVisibleWords(i);\n if (i >= words.length) clearInterval(interval);\n }, TYPEWRITER_DELAY_MS);\n\n return () => clearInterval(interval);\n }, [text, words.length]);\n\n const partialText = words.slice(0, visibleWords).join(' ');\n return <FormattedText text={partialText} className={className} style={style} />;\n}\n\n// ---------------------------------------------------------------------------\n// Action Badge — colors aligned to design system\n// ---------------------------------------------------------------------------\n\n// Subtle tints from project palette — same low-opacity family, gentle differentiation\nconst ACTION_CATEGORY_STYLES: Record<\n ActionCategory,\n { bg: string; border: string; text: string; Icon: typeof ArrowRight }\n> = {\n navigation: {\n bg: 'rgba(45,134,89,0.07)',\n border: 'rgba(45,134,89,0.14)',\n text: 'rgba(31,110,71,0.75)',\n Icon: ArrowRight,\n },\n form: {\n bg: 'rgba(110,114,138,0.07)',\n border: 'rgba(110,114,138,0.14)',\n text: 'rgba(85,88,102,0.75)',\n Icon: PenLine,\n },\n ui: {\n bg: 'rgba(141,145,168,0.07)',\n border: 'rgba(141,145,168,0.14)',\n text: 'rgba(85,88,102,0.75)',\n Icon: MousePointerClick,\n },\n search: {\n bg: 'rgba(219,33,41,0.05)',\n border: 'rgba(219,33,41,0.11)',\n text: 'rgba(168,26,31,0.7)',\n Icon: Search,\n },\n info: {\n bg: 'rgba(172,176,195,0.08)',\n border: 'rgba(172,176,195,0.14)',\n text: 'rgba(110,114,138,0.7)',\n Icon: Info,\n },\n};\n\nconst BADGE_CONTAINER_STYLE: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'flex-start',\n};\nconst BADGE_TRANSITION = { duration: 0.2, ease: 'easeOut' as const };\n\nfunction ActionBadge({ msg, count = 1 }: { msg: VoiceMessage; count?: number }) {\n const category = msg.action?.category ?? 'info';\n const styles = ACTION_CATEGORY_STYLES[category];\n const { Icon } = styles;\n\n return (\n <motion.div\n initial={{ opacity: 0, scale: 0.92 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.92 }}\n transition={BADGE_TRANSITION}\n style={BADGE_CONTAINER_STYLE}\n role=\"status\"\n aria-label={count > 1 ? `${msg.text} (${count} times)` : msg.text}\n >\n <span\n className=\"inline-flex items-center gap-1.5 rounded-full\"\n style={{\n padding: '3px 10px',\n fontSize: '11px',\n fontWeight: 500,\n lineHeight: '1.3',\n color: styles.text,\n backgroundColor: styles.bg,\n border: `1px solid ${styles.border}`,\n }}\n >\n <Icon size={11} strokeWidth={2.2} aria-hidden=\"true\" />\n {msg.text}\n {count > 1 && (\n <span\n className=\"inline-flex items-center justify-center rounded-full\"\n style={{\n minWidth: 16,\n height: 16,\n padding: '0 4px',\n fontSize: '10px',\n fontWeight: 600,\n lineHeight: 1,\n color: styles.text,\n backgroundColor: styles.text.replace(/[\\d.]+\\)$/, '0.10)'),\n }}\n >\n {count}x\n </span>\n )}\n </span>\n </motion.div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Group consecutive action badges by action name\n// ---------------------------------------------------------------------------\n\ntype DisplayItem =\n | { type: 'message'; msg: VoiceMessage }\n | { type: 'action'; msg: VoiceMessage; count: number };\n\nfunction groupDisplayItems(messages: VoiceMessage[]): DisplayItem[] {\n const items: DisplayItem[] = [];\n for (const msg of messages) {\n if (msg.role !== 'action') {\n items.push({ type: 'message', msg });\n continue;\n }\n const prev = items[items.length - 1];\n if (prev?.type === 'action' && prev.msg.action?.name === msg.action?.name) {\n prev.count++;\n prev.msg = msg; // keep latest text/timestamp for display\n } else {\n items.push({ type: 'action', msg, count: 1 });\n }\n }\n return items;\n}\n\n/** Filter out noise, protocol leaks, and very short fragments */\nfunction isDisplayWorthy(msg: VoiceMessage): boolean {\n if (msg.role === 'action') return msg.text.trim().length > 0;\n const t = msg.text.trim();\n if (t.length < MIN_DISPLAY_LENGTH) return false;\n const alphaOnly = t.replace(/[\\s\\p{P}\\p{S}]+/gu, '');\n if (alphaOnly.length === 0) return false;\n return true;\n}\n\nfunction FeedbackPill({ isSent, ticketId, onReport }: {\n isSent: boolean;\n ticketId: string | null;\n onReport: () => void;\n}) {\n const [copied, setCopied] = useState(false);\n const [showTicket, setShowTicket] = useState(false);\n\n // Two-phase: show \"✓ Sent\" first, then fade to ticket ID after 2s\n useEffect(() => {\n if (!isSent) { setShowTicket(false); return; }\n const timer = setTimeout(() => setShowTicket(true), 2000);\n return () => clearTimeout(timer);\n }, [isSent]);\n\n const phase = !isSent ? 'idle' : showTicket ? 'ticket' : 'sent';\n\n return (\n <span\n role={phase === 'idle' ? 'button' : undefined}\n onClick={phase === 'idle' ? onReport : undefined}\n className=\"voice-feedback-pill\"\n style={{\n marginTop: 2,\n fontSize: 11,\n padding: '2px 8px',\n borderRadius: 8,\n border: phase === 'sent' ? '1px solid rgba(22,163,74,0.3)'\n : phase === 'ticket' ? '1px solid rgba(217,119,6,0.3)'\n : '1px solid rgba(0,0,0,0.12)',\n background: 'transparent',\n color: phase === 'sent' ? '#16a34a'\n : phase === 'ticket' ? '#92400e'\n : 'rgba(0,0,0,0.30)',\n cursor: phase === 'idle' ? 'pointer' : 'default',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 3,\n opacity: isSent ? 1 : 0,\n transition: 'opacity 0.15s, color 0.4s, border-color 0.4s',\n fontFamily: phase === 'ticket' ? 'monospace' : 'inherit',\n }}\n >\n {phase === 'sent' ? (\n <>\n <Check size={10} strokeWidth={2} />\n Sent\n </>\n ) : phase === 'ticket' && ticketId ? (\n <>\n Ticket {ticketId}\n <span\n role=\"button\"\n aria-label=\"Copy ticket ID\"\n onClick={() => {\n navigator.clipboard.writeText(ticketId).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n }).catch(() => {});\n }}\n style={{\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n marginLeft: 3,\n gap: 2,\n color: copied ? '#16a34a' : '#92400e',\n transition: 'color 0.15s',\n }}\n >\n {copied ? <><Check size={10} strokeWidth={2} /> Copied</> : <Copy size={10} strokeWidth={2} />}\n </span>\n </>\n ) : (\n <>\n <Flag size={10} strokeWidth={2} />\n Feedback\n </>\n )}\n </span>\n );\n}\n\nexport default function VoiceTranscript({\n messages,\n isTyping,\n variant = 'overlay',\n voiceError,\n voiceState,\n onStartMic,\n onSwitchToKeyboard,\n onReport,\n feedbackSentTurns,\n onTextSubmit,\n}: VoiceTranscriptProps) {\n const config = useSiteConfig();\n const fontFamily = config.fontFamily ?? DEFAULT_FONT_FAMILY;\n const assistantLabel = config.copilotName || 'Assistant';\n const { colors } = config;\n const containerRef = useRef<HTMLDivElement>(null);\n const isPanel = variant === 'panel';\n const maxVisible = isPanel ? PANEL_MAX_VISIBLE_MESSAGES : MAX_VISIBLE_MESSAGES;\n const maxTextLen = isPanel ? PANEL_MAX_TEXT_LENGTH : MAX_TEXT_LENGTH;\n const visible = messages.filter(isDisplayWorthy).slice(-maxVisible);\n\n // Track whether user has manually scrolled away from bottom\n const userScrolledRef = useRef(false);\n const lastMessageCountRef = useRef(0);\n const contentRef = useRef<HTMLDivElement>(null);\n const [showNewMessagePill, setShowNewMessagePill] = useState(false);\n\n // Detect manual scroll: if user scrolls up, stop auto-scrolling; clear pill when at bottom\n useEffect(() => {\n if (!isPanel) return;\n const el = containerRef.current;\n if (!el) return;\n const handleScroll = () => {\n const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 40;\n userScrolledRef.current = !atBottom;\n if (atBottom) setShowNewMessagePill(false);\n };\n el.addEventListener('scroll', handleScroll, { passive: true });\n return () => el.removeEventListener('scroll', handleScroll);\n }, [isPanel]);\n\n // Scroll to bottom on new messages, or show pill if user has scrolled away\n useEffect(() => {\n if (!isPanel) return;\n if (visible.length > lastMessageCountRef.current) {\n if (userScrolledRef.current) {\n setShowNewMessagePill(true);\n } else {\n requestAnimationFrame(() => {\n const el = containerRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n });\n }\n }\n lastMessageCountRef.current = visible.length;\n }, [visible.length, isPanel]);\n\n // Auto-scroll whenever content height changes (typewriter words, streaming, new messages)\n useEffect(() => {\n if (!isPanel) return;\n const contentEl = contentRef.current;\n const scrollEl = containerRef.current;\n if (!contentEl || !scrollEl) return;\n const observer = new ResizeObserver(() => {\n if (!userScrolledRef.current) {\n scrollEl.scrollTop = scrollEl.scrollHeight;\n }\n });\n observer.observe(contentEl);\n return () => observer.disconnect();\n }, [isPanel]);\n\n const scrollToBottom = () => {\n const el = containerRef.current;\n if (el) {\n el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' });\n userScrolledRef.current = false;\n setShowNewMessagePill(false);\n }\n };\n\n if (isPanel) {\n return (\n <div style={{ flex: 1, minHeight: 0, position: 'relative', fontFamily }}>\n <div\n ref={containerRef}\n style={{\n position: 'absolute',\n inset: 0,\n overflowY: 'auto',\n overscrollBehavior: 'contain',\n padding: '16px 16px 12px',\n maskImage:\n 'linear-gradient(to bottom, transparent 0%, black 8px, black calc(100% - 8px), transparent 100%)',\n WebkitMaskImage:\n 'linear-gradient(to bottom, transparent 0%, black 8px, black calc(100% - 8px), transparent 100%)',\n }}\n >\n <div ref={contentRef} style={{ display: 'flex', flexDirection: 'column', paddingBottom: 24 }}>\n <AnimatePresence mode=\"popLayout\">\n {groupDisplayItems(visible).map((item, idx, arr) => {\n if (item.type === 'action') {\n // Show assistant name label before first action in a group\n const prevIsAction = idx > 0 && arr[idx - 1].type === 'action';\n const showLabel = !prevIsAction;\n return (\n <motion.div\n key={item.msg.timestamp}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n marginTop: idx === 0 ? 0 : prevIsAction ? 4 : 12,\n }}\n >\n {showLabel && (\n <p\n className=\"uppercase tracking-wider\"\n style={{\n fontSize: '10px',\n fontWeight: 500,\n letterSpacing: '0.06em',\n color: 'rgba(0,0,0,0.35)',\n marginBottom: '4px',\n }}\n >\n {assistantLabel}\n </p>\n )}\n <ActionBadge msg={item.msg} count={item.count} />\n </motion.div>\n );\n }\n\n const { msg } = item;\n const isLast = idx === arr.length - 1;\n const isAI = msg.role === 'assistant';\n // Skip label when previous item was also from the same role (assistant or action)\n const prevItem = idx > 0 ? arr[idx - 1] : null;\n const prevIsAI = prevItem?.type === 'action' || (prevItem?.type === 'message' && prevItem.msg.role === 'assistant');\n const prevIsUser = prevItem?.type === 'message' && prevItem.msg.role === 'user';\n const showLabel = isAI ? !prevIsAI : !prevIsUser;\n\n const cleaned = cleanForDisplay(msg.text);\n const displayText =\n cleaned.length > maxTextLen\n ? cleaned.slice(0, maxTextLen).trimEnd() + '...'\n : cleaned;\n\n return (\n <motion.div\n key={msg.timestamp}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n className={isAI ? 'voice-msg-group' : undefined}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: isAI ? 'flex-start' : 'flex-end',\n marginTop: idx === 0 ? 0 : 12,\n }}\n >\n {showLabel && (\n <p\n className=\"uppercase tracking-wider\"\n style={{\n fontSize: '10px',\n fontWeight: 500,\n letterSpacing: '0.06em',\n color: isAI ? 'rgba(0,0,0,0.35)' : 'rgba(219,33,41,0.5)',\n marginBottom: '4px',\n }}\n >\n {isAI ? assistantLabel : 'You'}\n </p>\n )}\n <div\n style={{\n ...(isAI\n ? {\n backgroundColor: `${colors.primary}0D`,\n borderRadius: '14px 14px 14px 4px',\n padding: '10px 14px',\n maxWidth: '85%',\n }\n : {\n backgroundColor: 'rgba(0,0,0,0.04)',\n borderRadius: '14px 14px 4px 14px',\n padding: '10px 14px',\n maxWidth: '85%',\n }),\n }}\n >\n {isAI && isLast && isTyping ? (\n <TypewriterFormattedText\n text={displayText}\n \n style={{\n fontSize: '14px',\n fontWeight: 400,\n lineHeight: '1.45',\n color: '#1a1a1a',\n }}\n />\n ) : (\n <FormattedText\n text={displayText}\n \n style={{\n fontSize: '14px',\n fontWeight: isAI ? 400 : 450,\n lineHeight: '1.45',\n color: isAI ? '#1a1a1a' : '#3d0a0b',\n }}\n />\n )}\n </div>\n {isAI && (!isLast || !isTyping) && onReport && (() => {\n const turnNumber = visible.slice(0, idx + 1).filter(m => m.role === 'assistant').length;\n const ticketId = feedbackSentTurns?.[turnNumber] ?? null;\n const isSent = ticketId !== null;\n return (\n <FeedbackPill\n isSent={isSent}\n ticketId={ticketId}\n onReport={() => {\n const userMsg = visible.slice(0, idx).reverse().find(m => m.role === 'user');\n onReport(turnNumber, msg.text, userMsg?.text);\n }}\n />\n );\n })()}\n </motion.div>\n );\n })}\n </AnimatePresence>\n\n {visible.length === 0 &&\n !isTyping &&\n (voiceError === 'llm_failed' || voiceError === 'network_error' ? (\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.4, delay: 0.15 }}\n className=\"text-center\"\n style={{ paddingTop: '48px', paddingBottom: '16px' }}\n >\n <div\n className=\"mx-auto rounded-full flex items-center justify-center\"\n style={{\n width: 48,\n height: 48,\n backgroundColor: 'rgba(220, 38, 38, 0.08)',\n marginBottom: '14px',\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"rgba(220,38,38,0.6)\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" />\n <path d=\"M16.72 11.06A10.94 10.94 0 0 1 19 12.55\" />\n <path d=\"M5 12.55a10.94 10.94 0 0 1 5.17-2.39\" />\n <path d=\"M10.71 5.05A16 16 0 0 1 22.56 9\" />\n <path d=\"M1.42 9a15.91 15.91 0 0 1 4.7-2.88\" />\n <path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\" />\n <line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\" />\n </svg>\n </div>\n <p\n style={{\n fontSize: '15px',\n fontWeight: 600,\n color: 'rgba(0,0,0,0.7)',\n marginBottom: '6px',\n }}\n >\n Service offline\n </p>\n <p\n style={{\n fontSize: '13px',\n color: 'rgba(0,0,0,0.4)',\n lineHeight: '1.4',\n maxWidth: '240px',\n margin: '0 auto',\n }}\n >\n The AI assistant is currently unavailable. Please try again shortly.\n </p>\n </motion.div>\n ) : (\n <div style={{ paddingTop: 40 }}>\n <EmptyStateGraphic primaryColor={config.colors.primary} onTextSubmit={onTextSubmit} />\n </div>\n ))}\n\n {isTyping && visible.length === 0 && (\n <motion.p\n initial={{ opacity: 0 }}\n animate={{ opacity: 0.5 }}\n style={{ color: 'rgba(0,0,0,0.4)', fontSize: '14px' }}\n >\n ...\n </motion.p>\n )}\n </div>\n </div>\n <AnimatePresence>\n {showNewMessagePill && (\n <motion.button\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.18 }}\n onClick={scrollToBottom}\n style={{\n position: 'absolute',\n bottom: 8,\n left: '50%',\n transform: 'translateX(-50%)',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n padding: '5px 12px 5px 10px',\n fontSize: 11,\n fontWeight: 500,\n color: 'rgba(0,0,0,0.6)',\n backgroundColor: 'rgba(255,255,255,0.92)',\n border: '1px solid rgba(0,0,0,0.08)',\n borderRadius: 9999,\n boxShadow: '0 2px 8px rgba(0,0,0,0.1)',\n cursor: 'pointer',\n backdropFilter: 'blur(8px)',\n WebkitBackdropFilter: 'blur(8px)',\n zIndex: 1,\n }}\n >\n <ChevronDown size={12} strokeWidth={2.5} />\n New message\n </motion.button>\n )}\n </AnimatePresence>\n </div>\n );\n }\n\n // Original overlay variant (unchanged)\n return (\n <div\n ref={containerRef}\n className=\"relative w-full max-w-md text-center rounded-2xl overflow-hidden\"\n style={{ fontFamily }}\n >\n {/* Glass refraction layer */}\n <div\n className=\"absolute inset-0 rounded-2xl\"\n style={{\n backdropFilter: 'blur(2px)',\n WebkitBackdropFilter: 'blur(2px)',\n filter: 'url(#liquid-glass-orb)',\n isolation: 'isolate',\n }}\n />\n {/* Glass surface */}\n <div\n className=\"absolute inset-0 rounded-2xl\"\n style={{\n backgroundColor: 'rgba(255, 255, 255, 0.6)',\n border: '1px solid rgba(255, 255, 255, 0.4)',\n boxShadow: '0 6px 24px rgba(0, 0, 0, 0.05), inset 0 0 20px -5px rgba(255, 255, 255, 0.5)',\n }}\n />\n {/* Specular highlight */}\n <div\n className=\"absolute inset-0 rounded-2xl pointer-events-none\"\n style={{\n background:\n 'linear-gradient(to bottom, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 40%)',\n }}\n />\n {/* Content */}\n <div className=\"relative flex flex-col gap-2 px-6 py-4\">\n <AnimatePresence mode=\"popLayout\">\n {groupDisplayItems(visible).map((item, idx, arr) => {\n if (item.type === 'action') {\n const prevIsAction = idx > 0 && arr[idx - 1].type === 'action';\n return (\n <div key={item.msg.timestamp} style={{ marginTop: prevIsAction ? -4 : 0 }}>\n <ActionBadge msg={item.msg} count={item.count} />\n </div>\n );\n }\n\n const { msg } = item;\n const isLatest = idx === arr.length - 1;\n const isAI = msg.role === 'assistant';\n const isFading = idx < arr.length - 1;\n\n const displayText =\n msg.text.length > maxTextLen\n ? msg.text.slice(0, maxTextLen).trimEnd() + '...'\n : msg.text;\n\n return (\n <motion.p\n key={msg.timestamp}\n initial={{ opacity: 0, y: 12 }}\n animate={{ opacity: isFading ? 0.5 : 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.3, ease: 'easeOut' }}\n className={cn('text-lg leading-relaxed', isAI ? '' : 'italic')}\n style={{\n color: isAI ? '#1a1a1a' : 'rgba(0,0,0,0.7)',\n }}\n >\n {isAI && isLatest && isTyping ? (\n <TypewriterFormattedText text={displayText} />\n ) : (\n displayText\n )}\n </motion.p>\n );\n })}\n </AnimatePresence>\n\n {visible.length === 0 && !isTyping && (\n <EmptyStateGraphic\n primaryColor={config.colors.primary}\n voiceState={voiceState}\n onStartMic={onStartMic}\n onSwitchToKeyboard={onSwitchToKeyboard}\n onTextSubmit={onTextSubmit}\n />\n )}\n\n {isTyping && visible.length === 0 && (\n <motion.p\n initial={{ opacity: 0 }}\n animate={{ opacity: 0.5 }}\n className=\"text-black/50 text-lg\"\n >\n ...\n </motion.p>\n )}\n </div>\n </div>\n );\n}\n\nfunction EmptyStateGraphic({ primaryColor, voiceState, onStartMic, onSwitchToKeyboard, onTextSubmit }: {\n primaryColor: string;\n voiceState?: string;\n onStartMic?: () => void;\n onSwitchToKeyboard?: () => void;\n onTextSubmit?: (text: string) => void;\n}) {\n const config = useSiteConfig();\n const isListening = voiceState === 'LISTENING' || voiceState === 'USER_SPEAKING';\n const greeting = config.greetingMessage || 'How can I help you today?';\n const prompts = config.suggestedPrompts ?? ['What services are available?', 'Help me with an application'];\n\n if (isListening) {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.3 }}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 6,\n paddingTop: 60,\n }}\n >\n <p style={{ fontSize: 16, fontWeight: 500, color: primaryColor, margin: 0, opacity: 0.7 }}>\n I'm listening...\n </p>\n <p style={{ fontSize: 12, color: 'rgba(0,0,0,0.3)', margin: 0 }}>\n Go ahead, I can hear you\n </p>\n </motion.div>\n );\n }\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, delay: 0.15 }}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 20,\n paddingTop: 48,\n }}\n >\n <p style={{ fontSize: 17, fontWeight: 500, color: primaryColor, margin: 0, opacity: 0.6, textAlign: 'center', lineHeight: 1.4 }}>\n {greeting}\n </p>\n\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center', maxWidth: 320 }}>\n {prompts.map((prompt) => (\n <button\n key={prompt}\n onClick={() => onTextSubmit?.(prompt)}\n style={{\n padding: '8px 16px',\n borderRadius: 18,\n border: '1px solid rgba(0,0,0,0.1)',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n fontFamily: 'inherit',\n fontSize: 13,\n color: 'rgba(0,0,0,0.55)',\n transition: 'background-color 0.15s, border-color 0.15s',\n lineHeight: 1.3,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = `${primaryColor}0A`;\n e.currentTarget.style.borderColor = `${primaryColor}33`;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent';\n e.currentTarget.style.borderColor = 'rgba(0,0,0,0.1)';\n }}\n >\n {prompt}\n </button>\n ))}\n </div>\n\n <div style={{ display: 'flex', gap: 12, marginTop: 4 }}>\n {onStartMic && (\n <button\n onClick={onStartMic}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 14px',\n borderRadius: 16,\n border: 'none',\n backgroundColor: `${primaryColor}0A`,\n cursor: 'pointer',\n fontFamily: 'inherit',\n fontSize: 12,\n color: 'rgba(0,0,0,0.4)',\n }}\n >\n <Mic style={{ width: 12, height: 12, opacity: 0.5 }} />\n or speak\n </button>\n )}\n </div>\n </motion.div>\n );\n}\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { ArrowUpRight } from 'lucide-react';\nimport { cn } from '../utils';\nimport type { VoiceToolResult } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceToolCardProps {\n result: VoiceToolResult | null;\n onAction?: (result: VoiceToolResult) => void;\n onDismiss?: () => void;\n /** When 'capsule', uses inline panel capsule style */\n variant?: 'overlay' | 'capsule';\n}\n\nconst AUTO_DISMISS_MS = 8000;\n\nexport default function VoiceToolCard({\n result,\n onAction,\n onDismiss,\n variant = 'overlay',\n}: VoiceToolCardProps) {\n useEffect(() => {\n if (!result) return;\n const timer = setTimeout(() => onDismiss?.(), AUTO_DISMISS_MS);\n return () => clearTimeout(timer);\n }, [result, onDismiss]);\n\n const isCapsule = variant === 'capsule';\n\n return (\n <AnimatePresence>\n {result && (\n <motion.div\n initial={{ opacity: 0, y: isCapsule ? 8 : 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: isCapsule ? 4 : 10 }}\n transition={{ duration: 0.3, ease: 'easeOut' }}\n className={cn(\n 'cursor-pointer transition-colors duration-200',\n isCapsule\n ? 'w-full rounded-xl px-4 py-2.5 flex items-center gap-3'\n : 'bg-white/10 backdrop-blur-md rounded-xl border border-white/20 px-5 py-4 max-w-sm w-full hover:bg-white/15'\n )}\n style={\n isCapsule\n ? {\n backgroundColor: 'rgba(0,0,0,0.04)',\n border: '1px solid rgba(0,0,0,0.08)',\n }\n : undefined\n }\n onClick={() => onAction?.(result)}\n onMouseEnter={\n isCapsule\n ? (e) => {\n (e.currentTarget as HTMLElement).style.backgroundColor = 'rgba(0,0,0,0.06)';\n }\n : undefined\n }\n onMouseLeave={\n isCapsule\n ? (e) => {\n (e.currentTarget as HTMLElement).style.backgroundColor = 'rgba(0,0,0,0.04)';\n }\n : undefined\n }\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onAction?.(result);\n }\n }}\n >\n {isCapsule ? (\n <>\n <ArrowUpRight\n className=\"shrink-0\"\n style={{ width: 14, height: 14, color: 'rgba(0,0,0,0.5)' }}\n />\n <span\n className=\"truncate\"\n style={{ fontSize: '13px', fontWeight: 500, color: 'rgba(0,0,0,0.7)' }}\n >\n {result.displayText}\n </span>\n </>\n ) : (\n <>\n <p className=\"text-white/50 text-xs uppercase tracking-wider mb-1\">{result.name}</p>\n <p className=\"text-white text-sm leading-relaxed\">{result.displayText}</p>\n </>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { Component } from 'react';\nimport type { ReactNode, ErrorInfo } from 'react';\nimport { cn } from '../utils';\nimport { AlertTriangle, RefreshCw } from 'lucide-react';\n\ninterface Props {\n children: ReactNode;\n onReset?: () => void;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\nexport default class VoiceErrorBoundary extends Component<Props, State> {\n state: State = { hasError: false, error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error('Voice component error:', error, info.componentStack);\n }\n\n handleReset = () => {\n this.setState({ hasError: false, error: null });\n this.props.onReset?.();\n };\n\n render() {\n if (this.state.hasError) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-4 p-8 text-center\">\n <AlertTriangle className=\"h-10 w-10 text-red-400\" />\n <p className=\"text-white text-lg\">Something went wrong with the voice assistant.</p>\n <p className=\"text-white/50 text-sm max-w-sm\">\n {this.state.error?.message || 'An unexpected error occurred.'}\n </p>\n <button\n onClick={this.handleReset}\n className={cn(\n 'flex items-center gap-2 px-4 py-2',\n 'bg-white/10 backdrop-blur-md rounded-full',\n 'text-white text-sm hover:bg-white/20 transition-colors cursor-pointer'\n )}\n >\n <RefreshCw className=\"h-4 w-4\" />\n Try again\n </button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n","import { motion, AnimatePresence } from 'motion/react';\nimport { AlertTriangle, Hourglass, Mic, MicOff, VolumeX, Wifi, WifiOff } from 'lucide-react';\nimport { cn } from '../utils';\n\nexport type VoiceErrorType =\n | 'mic_denied'\n | 'mic_unavailable'\n | 'vad_load_failed'\n | 'stt_failed'\n | 'tts_failed'\n | 'network_error'\n | 'llm_failed'\n | 'speech_too_short'\n | 'not_addressed'\n | 'processing'\n | null;\n\ninterface VoiceErrorDisplayProps {\n error: VoiceErrorType;\n onDismiss: () => void;\n}\n\ntype Severity = 'error' | 'warning' | 'info';\n\nconst SEVERITY_STYLES: Record<\n Severity,\n { bg: string; border: string; icon: string; text: string; dismiss: string }\n> = {\n error: {\n bg: 'rgba(220, 38, 38, 0.08)',\n border: 'rgba(220, 38, 38, 0.15)',\n icon: 'text-red-500',\n text: 'text-red-700',\n dismiss: 'text-red-400 hover:text-red-600',\n },\n warning: {\n bg: 'rgba(217, 119, 6, 0.08)',\n border: 'rgba(217, 119, 6, 0.15)',\n icon: 'text-amber-500',\n text: 'text-amber-700',\n dismiss: 'text-amber-400 hover:text-amber-600',\n },\n info: {\n bg: 'rgba(0, 0, 0, 0.04)',\n border: 'rgba(0, 0, 0, 0.08)',\n icon: 'text-neutral-500',\n text: 'text-neutral-600',\n dismiss: 'text-neutral-400 hover:text-neutral-600',\n },\n};\n\nconst ERROR_CONFIG: Record<\n NonNullable<VoiceErrorType>,\n { icon: typeof AlertTriangle; title: string; severity: Severity }\n> = {\n mic_denied: {\n icon: MicOff,\n title: 'Microphone access denied',\n severity: 'error',\n },\n mic_unavailable: {\n icon: MicOff,\n title: 'No microphone found',\n severity: 'error',\n },\n vad_load_failed: {\n icon: AlertTriangle,\n title: 'Voice detection unavailable',\n severity: 'warning',\n },\n stt_failed: {\n icon: Mic,\n title: 'Voice input unavailable — use text',\n severity: 'warning',\n },\n tts_failed: {\n icon: AlertTriangle,\n title: 'Voice response unavailable',\n severity: 'warning',\n },\n network_error: {\n icon: WifiOff,\n title: 'Connection lost',\n severity: 'error',\n },\n llm_failed: {\n icon: Wifi,\n title: 'AI service unavailable',\n severity: 'error',\n },\n speech_too_short: {\n icon: Mic,\n title: \"Didn't catch that\",\n severity: 'info',\n },\n not_addressed: {\n icon: VolumeX,\n title: 'Not addressed to me',\n severity: 'info',\n },\n processing: {\n icon: Hourglass,\n title: 'Still processing...',\n severity: 'info',\n },\n};\n\nexport default function VoiceErrorDisplay({ error, onDismiss }: VoiceErrorDisplayProps) {\n return (\n <AnimatePresence>\n {error && (\n <motion.div\n initial={{ opacity: 0, y: 16, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: -8, scale: 0.95 }}\n transition={{ duration: 0.25 }}\n className={cn('max-w-xs mx-auto', 'rounded-xl', 'px-4 py-2')}\n style={{\n backgroundColor: SEVERITY_STYLES[ERROR_CONFIG[error].severity].bg,\n border: `1px solid ${SEVERITY_STYLES[ERROR_CONFIG[error].severity].border}`,\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n pointerEvents: 'auto',\n }}\n >\n {(() => {\n const config = ERROR_CONFIG[error];\n const styles = SEVERITY_STYLES[config.severity];\n const Icon = config.icon;\n return (\n <div className=\"flex items-center gap-2\">\n <Icon className={cn('h-4 w-4 shrink-0', styles.icon)} />\n <span className={cn('text-xs flex-1', styles.text)}>{config.title}</span>\n <button\n onClick={onDismiss}\n className={cn('text-xs transition-colors cursor-pointer', styles.dismiss)}\n >\n ×\n </button>\n </div>\n );\n })()}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport type { PipelineTimings } from '@unctad-ai/voice-agent-core';\nimport {\n DEFAULT_SHOW_PIPELINE_METRICS,\n DEFAULT_PIPELINE_METRICS_AUTO_HIDE_MS,\n} from '@unctad-ai/voice-agent-core';\n\nfunction fmt(ms: number): string {\n return ms >= 1000 ? `${(ms / 1000).toFixed(1)}s` : `${Math.round(ms)}ms`;\n}\n\nexport default function PipelineMetricsBar({\n timings,\n show = DEFAULT_SHOW_PIPELINE_METRICS,\n autoHideMs = DEFAULT_PIPELINE_METRICS_AUTO_HIDE_MS,\n}: {\n timings: PipelineTimings | null;\n show?: boolean;\n autoHideMs?: number;\n}) {\n const [visible, setVisible] = useState(false);\n const [display, setDisplay] = useState<PipelineTimings | null>(null);\n\n // React-recommended pattern: adjust state during render based on prop change.\n // https://react.dev/reference/react/useState#storing-information-from-previous-renders\n const [prevTimings, setPrevTimings] = useState(timings);\n if (timings !== prevTimings) {\n setPrevTimings(timings);\n if (timings) {\n setDisplay(timings);\n setVisible(true);\n }\n }\n\n // Auto-hide timer: only the setTimeout callback calls setState (async, not synchronous)\n useEffect(() => {\n if (!visible || autoHideMs <= 0) return;\n const timer = setTimeout(() => setVisible(false), autoHideMs);\n return () => clearTimeout(timer);\n }, [visible, display, autoHideMs]);\n\n if (!display || !show) return null;\n\n const pills: { label: string; value: string }[] = [];\n\n pills.push({ label: display.pipeline, value: '' });\n\n if (display.sttMs != null) pills.push({ label: 'STT', value: fmt(display.sttMs) });\n if (display.llmTotalMs != null) pills.push({ label: 'LLM', value: fmt(display.llmTotalMs) });\n if (display.ttsFirstChunkMs != null && display.ttsTotalMs != null) {\n pills.push({\n label: 'TTS',\n value: `${fmt(display.ttsFirstChunkMs)} / ${fmt(display.ttsTotalMs)}`,\n });\n } else if (display.ttsMs != null) {\n pills.push({ label: 'TTS', value: fmt(display.ttsMs) });\n }\n pills.push({ label: 'Total', value: fmt(display.totalMs) });\n\n return (\n <AnimatePresence>\n {visible && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 28 }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.2, ease: [0.25, 0.1, 0.25, 1] }}\n className=\"flex items-center gap-2 overflow-hidden select-none\"\n style={{\n height: 28,\n padding: '0 16px',\n fontSize: 11,\n fontFamily: 'inherit',\n fontVariantNumeric: 'tabular-nums',\n borderTop: '1px solid rgba(0,0,0,0.06)',\n background: 'rgba(0,0,0,0.03)',\n }}\n >\n {pills.map((p, i) =>\n i === 0 ? (\n <span\n key=\"type\"\n style={{\n color: 'rgba(0,0,0,0.35)',\n fontWeight: 500,\n textTransform: 'uppercase',\n fontSize: 10,\n letterSpacing: '0.04em',\n }}\n >\n {p.label}\n </span>\n ) : (\n <span key={p.label} className=\"inline-flex items-center gap-1\">\n <span style={{ color: 'rgba(0,0,0,0.4)' }}>{p.label}</span>\n <span style={{ color: 'rgba(0,0,0,0.65)', fontWeight: 500 }}>{p.value}</span>\n </span>\n )\n )}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { useEffect, useRef } from 'react';\nimport type { OrbState } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceA11yAnnouncerProps {\n isOpen: boolean;\n orbState: OrbState;\n}\n\nconst STATE_ANNOUNCEMENTS: Record<OrbState, string> = {\n idle: 'Voice assistant ready',\n listening: 'Listening for your question',\n processing: 'Processing your request',\n speaking: 'Assistant is responding',\n error: 'An error occurred',\n};\n\nexport default function VoiceA11yAnnouncer({ isOpen, orbState }: VoiceA11yAnnouncerProps) {\n const prevOpen = useRef(isOpen);\n const prevState = useRef(orbState);\n const announceRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!announceRef.current) return;\n\n if (isOpen && !prevOpen.current) {\n announceRef.current.textContent =\n 'Voice assistant opened. Press Escape to close. Use Ctrl+Shift+V to toggle.';\n } else if (!isOpen && prevOpen.current) {\n announceRef.current.textContent = 'Voice assistant closed';\n } else if (isOpen && orbState !== prevState.current) {\n announceRef.current.textContent = STATE_ANNOUNCEMENTS[orbState];\n }\n\n prevOpen.current = isOpen;\n prevState.current = orbState;\n }, [isOpen, orbState]);\n\n return (\n <div\n ref={announceRef}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"sr-only\"\n role=\"status\"\n />\n );\n}\n","import { motion, AnimatePresence, useReducedMotion } from 'motion/react';\nimport { Mic } from 'lucide-react';\nimport { useSiteConfig } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceCopilotFABProps {\n onClick: () => void;\n isActive?: boolean;\n isOverlayOpen?: boolean;\n onMouseEnter?: () => void;\n}\n\nexport default function VoiceCopilotFAB({\n onClick,\n isActive,\n isOverlayOpen,\n onMouseEnter,\n}: VoiceCopilotFABProps) {\n const prefersReduced = useReducedMotion();\n const { colors } = useSiteConfig();\n\n return (\n <AnimatePresence>\n {!isOverlayOpen && (\n <motion.div\n key=\"voice-fab-wrapper\"\n initial={{ scale: 0, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0, opacity: 0 }}\n transition={{ duration: 0.25, ease: 'easeOut' }}\n className=\"fixed bottom-6 right-6 z-50\"\n >\n <motion.button\n onClick={onClick}\n onMouseEnter={onMouseEnter}\n animate={prefersReduced ? {} : { scale: [1, 1.15, 1] }}\n transition={\n prefersReduced\n ? {}\n : { scale: { duration: 1.5, repeat: Infinity, ease: 'easeInOut' } }\n }\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.95 }}\n className=\"relative rounded-full p-3 shadow-lg text-white transition-all cursor-pointer\"\n style={{ backgroundColor: colors.primary }}\n aria-label=\"Open voice assistant\"\n >\n {isActive ? (\n <span className=\"h-3 w-3 rounded-full bg-white animate-pulse\" />\n ) : (\n <Mic className=\"w-6 h-6\" />\n )}\n </motion.button>\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { Keyboard, Send, X } from 'lucide-react';\nimport { cn } from '../utils';\nimport { useSiteConfig } from '@unctad-ai/voice-agent-core';\nimport type { VoiceState } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceControlsProps {\n state: VoiceState;\n onTextSubmit: (text: string) => void;\n isListening: boolean;\n}\n\nconst STATE_LABELS: Record<VoiceState, string> = {\n IDLE: 'How can I help you?',\n LISTENING: \"I'm listening...\",\n USER_SPEAKING: 'Go ahead...',\n PROCESSING: 'Let me look into that...',\n AI_SPEAKING: \"Here's what I found...\",\n};\n\n/** Shared glass-pill style for control buttons */\nconst GLASS_PILL_BASE = cn(\n 'backdrop-blur-xl rounded-full',\n 'flex items-center justify-center',\n 'border border-white/15',\n 'transition-all duration-200 cursor-pointer',\n 'hover:border-white/30 hover:shadow-[0_0_16px_rgba(255,255,255,0.08)]'\n);\n\nexport default function VoiceControls({ state, onTextSubmit, isListening }: VoiceControlsProps) {\n const { colors } = useSiteConfig();\n const [showTextInput, setShowTextInput] = useState(false);\n const [text, setText] = useState('');\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (showTextInput) inputRef.current?.focus();\n }, [showTextInput]);\n\n const handleSubmit = () => {\n const trimmed = text.trim();\n if (!trimmed) return;\n onTextSubmit(trimmed);\n setText('');\n setShowTextInput(false);\n };\n\n return (\n <div className=\"w-full max-w-2xl mx-auto mt-auto pb-8 px-4\">\n <AnimatePresence mode=\"wait\">\n {showTextInput ? (\n <motion.div\n key=\"text-input\"\n initial={{ opacity: 0, y: 16, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 16, scale: 0.95 }}\n transition={{ duration: 0.25, ease: [0.22, 1, 0.36, 1] }}\n className={cn(\n 'rounded-full',\n 'flex items-center gap-4',\n 'border border-white/20',\n 'px-8 py-3'\n )}\n style={{\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(16px) saturate(1.2)',\n WebkitBackdropFilter: 'blur(16px) saturate(1.2)',\n }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && handleSubmit()}\n placeholder=\"Ask a question...\"\n className=\"flex-1 text-sm placeholder:text-white/40 min-w-0\"\n style={{\n color: 'white',\n background: 'none',\n border: 'none',\n outline: 'none',\n boxShadow: 'none',\n WebkitAppearance: 'none',\n padding: 0,\n }}\n />\n <motion.button\n onClick={handleSubmit}\n whileTap={{ scale: 0.9 }}\n className=\"rounded-full p-2 text-white transition-colors cursor-pointer\"\n style={{ backgroundColor: colors.primary }}\n aria-label=\"Send message\"\n >\n <Send className=\"h-4 w-4\" />\n </motion.button>\n <button\n onClick={() => {\n setShowTextInput(false);\n setText('');\n }}\n className=\"rounded-full p-2 text-white/60 hover:text-white hover:bg-white/10 transition-all cursor-pointer\"\n aria-label=\"Cancel text input\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </motion.div>\n ) : (\n <motion.div\n key=\"controls\"\n initial={{ opacity: 0, y: 16, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 16, scale: 0.95 }}\n transition={{ duration: 0.25, ease: [0.22, 1, 0.36, 1] }}\n className=\"flex items-center justify-center gap-3\"\n >\n {/* Mic status + keyboard — unified control bar */}\n <div\n className={cn(\n 'rounded-full',\n 'text-white text-sm font-medium',\n 'flex items-center gap-6',\n 'border border-white/20',\n 'pl-8 pr-4 py-1.5'\n )}\n style={{\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(16px) saturate(1.2)',\n WebkitBackdropFilter: 'blur(16px) saturate(1.2)',\n color: 'white',\n }}\n >\n {/* Pulse dot */}\n <span className=\"relative flex items-center justify-center w-3 h-3 ml-0.5\">\n {isListening && (\n <span\n className=\"absolute inset-0 rounded-full animate-ping\"\n style={{ backgroundColor: `${colors.primary}80` }}\n />\n )}\n <span\n className={cn(\n 'relative h-2.5 w-2.5 rounded-full transition-colors duration-300',\n )}\n style={isListening ? {\n backgroundColor: colors.primary,\n boxShadow: `0 0 8px ${colors.primary}99`,\n } : {\n backgroundColor: 'rgba(255,255,255,0.3)',\n }}\n />\n </span>\n {/* Animated label */}\n <AnimatePresence mode=\"wait\">\n <motion.span\n key={state}\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.2 }}\n className=\"pr-1\"\n >\n {STATE_LABELS[state]}\n </motion.span>\n </AnimatePresence>\n\n {/* Type button — integrated into the bar */}\n <button\n onClick={() => setShowTextInput(true)}\n className={cn(\n 'rounded-full p-2',\n 'text-white/60 hover:text-white',\n 'hover:bg-white/10',\n 'transition-all duration-200 cursor-pointer'\n )}\n aria-label=\"Type a message\"\n >\n <Keyboard className=\"h-4 w-4\" />\n </button>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n","import { useRef, useEffect, useState } from 'react';\nimport {\n DOT_RING_COUNT,\n DOT_RING_GAP,\n DOT_RING_BASE_RADIUS,\n DOT_RING_PEAK_RADIUS,\n DOT_RING_SMOOTHING,\n} from '@unctad-ai/voice-agent-core';\nimport type { OrbState } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceDotRingProps {\n analyserNode: AnalyserNode | null;\n state: OrbState;\n orbRadius: number;\n}\n\nconst STATE_COLORS: Record<OrbState, string> = {\n idle: 'rgba(59,130,246,0.6)',\n listening: 'rgba(219,33,41,0.8)',\n processing: 'rgba(245,158,11,0.7)',\n speaking: 'rgba(34,197,94,0.7)',\n error: 'rgba(220,38,38,0.6)',\n};\n\nexport default function VoiceDotRing({ analyserNode, state, orbRadius }: VoiceDotRingProps) {\n const dotsRef = useRef<(SVGCircleElement | null)[]>([]);\n const barsRef = useRef<Float32Array>(new Float32Array(DOT_RING_COUNT));\n const rafRef = useRef<number>(0);\n const colorRef = useRef(STATE_COLORS.idle);\n\n const [reducedMotion] = useState(\n () => window.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n\n const ringRadius = orbRadius + DOT_RING_GAP;\n const svgSize = (ringRadius + DOT_RING_PEAK_RADIUS + 2) * 2;\n const cx = svgSize / 2;\n const cy = svgSize / 2;\n\n useEffect(() => {\n const freqData = analyserNode ? new Uint8Array(analyserNode.frequencyBinCount) : null;\n\n const tick = () => {\n // Lerp color toward target\n colorRef.current = STATE_COLORS[state];\n\n if (analyserNode && freqData) {\n analyserNode.getByteFrequencyData(freqData);\n }\n\n for (let i = 0; i < DOT_RING_COUNT; i++) {\n const dot = dotsRef.current[i];\n if (!dot) continue;\n\n let targetVal = 0;\n if (freqData && freqData.length > 0) {\n const binIndex = Math.floor((i / DOT_RING_COUNT) * freqData.length);\n targetVal = freqData[binIndex] / 255;\n }\n\n barsRef.current[i] += (targetVal - barsRef.current[i]) * DOT_RING_SMOOTHING;\n\n const val = reducedMotion ? 0 : barsRef.current[i];\n const r = DOT_RING_BASE_RADIUS + val * (DOT_RING_PEAK_RADIUS - DOT_RING_BASE_RADIUS);\n const opacity = 0.3 + val * 0.5;\n\n dot.setAttribute('r', String(r));\n dot.setAttribute('opacity', String(opacity));\n dot.setAttribute('fill', colorRef.current);\n }\n\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafRef.current);\n }, [analyserNode, state, reducedMotion, ringRadius]);\n\n return (\n <svg\n width={svgSize}\n height={svgSize}\n viewBox={`0 0 ${svgSize} ${svgSize}`}\n className=\"absolute pointer-events-none\"\n style={{\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n }}\n aria-hidden=\"true\"\n >\n {Array.from({ length: DOT_RING_COUNT }, (_, i) => {\n const angle = (i / DOT_RING_COUNT) * Math.PI * 2 - Math.PI / 2;\n const x = cx + Math.cos(angle) * ringRadius;\n const y = cy + Math.sin(angle) * ringRadius;\n return (\n <circle\n key={i}\n ref={(el) => {\n dotsRef.current[i] = el;\n }}\n cx={x}\n cy={y}\n r={DOT_RING_BASE_RADIUS}\n fill={STATE_COLORS.idle}\n opacity={0.3}\n />\n );\n })}\n </svg>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { cn } from '../utils';\nimport { useSiteConfig } from '@unctad-ai/voice-agent-core';\n\nconst STORAGE_KEY = 'voice-onboarding-dismissed';\n\ninterface VoiceOnboardingProps {\n onTryNow: () => void;\n /** Custom description text shown in the onboarding tooltip */\n description?: string;\n}\n\nexport default function VoiceOnboarding({ onTryNow, description }: VoiceOnboardingProps) {\n const { colors } = useSiteConfig();\n const [show, setShow] = useState(false);\n\n useEffect(() => {\n const dismissed = localStorage.getItem(STORAGE_KEY);\n if (!dismissed) {\n // Small delay so FAB renders first\n const timer = setTimeout(() => setShow(true), 1500);\n return () => clearTimeout(timer);\n }\n }, []);\n\n const dismiss = () => {\n setShow(false);\n localStorage.setItem(STORAGE_KEY, 'true');\n };\n\n const handleTryNow = () => {\n dismiss();\n onTryNow();\n };\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n initial={{ opacity: 0, y: 8, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 8, scale: 0.95 }}\n transition={{ duration: 0.25, ease: 'easeOut' }}\n className={cn(\n 'fixed bottom-24 right-6 z-50',\n 'md:bottom-[104px] md:right-6',\n 'bg-white rounded-xl shadow-xl',\n 'border border-neutral-200',\n 'p-4 max-w-[280px]'\n )}\n role=\"tooltip\"\n >\n {/* Arrow pointing down to FAB */}\n <div className=\"absolute -bottom-2 right-6 w-4 h-4 bg-white border-b border-r border-neutral-200 rotate-45\" />\n\n <p className=\"text-sm text-neutral-700 leading-relaxed mb-3\">\n {description ?? 'Meet your AI assistant. Ask about services, permits, or opportunities.'}\n </p>\n <div className=\"flex gap-2\">\n <button\n onClick={handleTryNow}\n className={cn(\n 'text-white text-sm font-medium',\n 'rounded-lg px-3 py-1.5',\n 'transition-colors cursor-pointer'\n )}\n style={{ backgroundColor: colors.primary }}\n >\n Try it now\n </button>\n <button\n onClick={dismiss}\n className={cn(\n 'text-neutral-500 text-sm',\n 'rounded-lg px-3 py-1.5',\n 'hover:text-neutral-700 hover:bg-neutral-100',\n 'transition-colors cursor-pointer'\n )}\n >\n Maybe later\n </button>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { motion } from 'motion/react';\nimport { X } from 'lucide-react';\nimport { useVoiceAgent, voiceStateToOrbState } from '@unctad-ai/voice-agent-core';\nimport { IDLE_TIMEOUT_MS, WIND_DOWN_MS, EXIT_ANIMATION_MS } from '@unctad-ai/voice-agent-core';\nimport type { OrbState, VoiceToolResult } from '@unctad-ai/voice-agent-core';\nimport { useVoiceSettings } from '../contexts/VoiceSettingsContext';\nimport VoiceOrb from './VoiceOrb';\nimport VoiceWaveformCanvas from './VoiceWaveformCanvas';\nimport VoiceTranscript from './VoiceTranscript';\nimport VoiceToolCard from './VoiceToolCard';\nimport VoiceControls from './VoiceControls';\nimport VoiceErrorBoundary from './VoiceErrorBoundary';\nimport VoiceErrorDisplay from './VoiceErrorDisplay';\n\n/** Inline z-index guarantees stacking above all page elements */\nconst OVERLAY_Z = 2147483647;\n\n/** Liquid spring configs for entrance choreography */\nconst SPRING_BOUNCY = { type: 'spring' as const, damping: 20, stiffness: 180 };\nconst SPRING_SMOOTH = { type: 'spring' as const, damping: 28, stiffness: 160 };\n\n/** Exit easing — smooth start, accelerating pull */\nconst EXIT_EASE: [number, number, number, number] = [0.4, 0, 0.7, 0.2];\n\ninterface VoiceOverlayProps {\n isOpen: boolean;\n onClose: () => void;\n onStateChange?: (orbState: OrbState) => void;\n}\n\nfunction WiredOverlayContent({\n isMobile,\n onClose,\n onStateChange,\n isClosing,\n}: {\n isMobile: boolean;\n onClose: () => void;\n onStateChange?: (orbState: OrbState) => void;\n isClosing: boolean;\n}) {\n const orbSize = isMobile ? 120 : 200;\n const { settings, volumeRef, speedRef } = useVoiceSettings();\n\n const {\n state,\n start,\n stop,\n messages,\n isLLMLoading,\n getAmplitude,\n analyser,\n sendTextMessage,\n voiceError,\n dismissError,\n } = useVoiceAgent({ settings, volumeRef, speedRef });\n\n const [toolResult, setToolResult] = useState<VoiceToolResult | null>(null);\n\n const orbState = voiceStateToOrbState(state);\n\n // Notify parent of state changes for a11y announcer\n const onStateChangeRef = useRef(onStateChange);\n useEffect(() => {\n onStateChangeRef.current = onStateChange;\n });\n useEffect(() => {\n onStateChangeRef.current?.(orbState);\n }, [orbState]);\n\n // Start VAD when overlay mounts, force-stop on unmount (bypass debounce)\n const startRef = useRef(start);\n const stopRef = useRef(stop);\n useEffect(() => {\n startRef.current = start;\n }, [start]);\n useEffect(() => {\n stopRef.current = stop;\n }, [stop]);\n useEffect(() => {\n startRef.current();\n return () => stopRef.current(true);\n }, []);\n\n // Stop VAD immediately when exit starts\n useEffect(() => {\n if (isClosing) stop();\n }, [isClosing, stop]);\n\n // --- Idle timeout: auto-close after 30s of no user activity ---\n const [isWindingDown, setIsWindingDown] = useState(false);\n const idleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const windDownTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const onCloseRef = useRef(onClose);\n useEffect(() => {\n onCloseRef.current = onClose;\n });\n\n useEffect(() => {\n const clear = () => {\n if (idleTimerRef.current) clearTimeout(idleTimerRef.current);\n if (windDownTimerRef.current) clearTimeout(windDownTimerRef.current);\n idleTimerRef.current = null;\n windDownTimerRef.current = null;\n };\n\n if (isClosing || state === 'PROCESSING' || state === 'AI_SPEAKING') {\n clear();\n setIsWindingDown(false);\n return;\n }\n clear();\n setIsWindingDown(false);\n windDownTimerRef.current = setTimeout(() => {\n setIsWindingDown(true);\n }, IDLE_TIMEOUT_MS - WIND_DOWN_MS);\n idleTimerRef.current = setTimeout(() => {\n onCloseRef.current();\n }, IDLE_TIMEOUT_MS);\n return clear;\n }, [state, isClosing]);\n\n const handleTextSubmit = useCallback(\n (text: string) => {\n sendTextMessage(text);\n },\n [sendTextMessage]\n );\n\n const isListening = state === 'LISTENING' || state === 'USER_SPEAKING';\n\n return (\n <div\n className=\"flex flex-col items-center justify-center gap-6 h-full px-6\"\n style={{ pointerEvents: 'none' }}\n >\n {/* Orb + Waveform */}\n <motion.div\n initial={{ opacity: 0, scale: 0.15 }}\n animate={\n isClosing\n ? { opacity: 0, scale: 0 }\n : { opacity: isWindingDown ? 0.3 : 1, scale: isWindingDown ? 0.92 : 1 }\n }\n transition={\n isClosing\n ? { duration: 0.3, ease: EXIT_EASE, delay: 0.15 }\n : isWindingDown\n ? { duration: WIND_DOWN_MS / 1000, ease: 'easeOut' }\n : { ...SPRING_BOUNCY, delay: 0.1 }\n }\n className=\"relative flex items-center justify-center\"\n style={{ width: orbSize + 100, height: orbSize + 100, pointerEvents: 'auto' }}\n >\n <div\n className=\"absolute rounded-full\"\n style={{\n width: orbSize + 100,\n height: orbSize + 100,\n backdropFilter: 'blur(2px)',\n WebkitBackdropFilter: 'blur(2px)',\n filter: 'url(#liquid-glass-orb)',\n isolation: 'isolate',\n }}\n />\n <div\n className=\"absolute rounded-full pointer-events-none\"\n style={{\n width: orbSize + 100,\n height: orbSize + 100,\n backgroundColor: 'rgba(255, 255, 255, 0.02)',\n border: '1px solid rgba(255, 255, 255, 0.15)',\n boxShadow:\n '0 6px 24px rgba(0, 0, 0, 0.08), inset 0 0 20px -5px rgba(255, 255, 255, 0.3)',\n }}\n />\n <div\n className=\"absolute rounded-full pointer-events-none\"\n style={{\n width: orbSize + 100,\n height: orbSize + 100,\n background:\n 'radial-gradient(ellipse 70% 40% at 50% 12%, rgba(255,255,255,0.2) 0%, transparent 55%)',\n }}\n />\n <VoiceWaveformCanvas analyserNode={analyser} state={orbState} size={orbSize + 100} />\n <div className=\"absolute rounded-full\" style={{ width: orbSize, height: orbSize }}>\n <VoiceOrb state={orbState} getAmplitude={getAmplitude} size={orbSize} />\n </div>\n </motion.div>\n\n {/* Transcript */}\n <motion.div\n initial={{ opacity: 0, y: 24 }}\n animate={isClosing ? { opacity: 0, y: 16 } : { opacity: 1, y: 0 }}\n transition={\n isClosing\n ? { duration: 0.25, ease: EXIT_EASE, delay: 0.08 }\n : { ...SPRING_SMOOTH, delay: 0.3 }\n }\n >\n <VoiceTranscript messages={messages} isTyping={state === 'AI_SPEAKING' || isLLMLoading} />\n </motion.div>\n\n {/* Error display */}\n <div style={{ pointerEvents: 'auto' }}>\n <VoiceErrorDisplay error={voiceError} onDismiss={dismissError} />\n </div>\n\n {/* Tool result card */}\n <div style={{ pointerEvents: 'auto' }}>\n <VoiceToolCard result={toolResult} onDismiss={() => setToolResult(null)} />\n </div>\n\n {/* Controls */}\n <motion.div\n initial={{ opacity: 0, y: 48 }}\n animate={isClosing ? { opacity: 0, y: 30 } : { opacity: 1, y: 0 }}\n transition={\n isClosing\n ? { duration: 0.25, ease: EXIT_EASE, delay: 0 }\n : { ...SPRING_SMOOTH, delay: 0.4 }\n }\n className=\"w-full\"\n style={{ pointerEvents: 'auto' }}\n >\n <VoiceControls state={state} onTextSubmit={handleTextSubmit} isListening={isListening} />\n </motion.div>\n </div>\n );\n}\n\nfunction OverlayPortal({\n isOpen,\n isClosing,\n onClose,\n onStateChange,\n isMobile,\n}: VoiceOverlayProps & { isMobile: boolean; isClosing: boolean }) {\n if (!isOpen) return null;\n\n return createPortal(\n <>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"0\"\n height=\"0\"\n style={{ position: 'absolute', overflow: 'hidden' }}\n aria-hidden=\"true\"\n >\n <defs>\n <filter id=\"liquid-glass-orb\" x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n <feTurbulence\n type=\"fractalNoise\"\n baseFrequency=\"0.008 0.008\"\n numOctaves=\"2\"\n seed=\"92\"\n result=\"noise\"\n />\n <feGaussianBlur in=\"noise\" stdDeviation=\"2\" result=\"blurred_noise\" />\n <feDisplacementMap\n in=\"SourceGraphic\"\n in2=\"blurred_noise\"\n scale=\"50\"\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n />\n </filter>\n </defs>\n </svg>\n\n <motion.div\n key=\"voice-overlay-bg\"\n initial={{ opacity: 0 }}\n animate={isClosing ? { opacity: 0 } : { opacity: 1 }}\n transition={{\n duration: isClosing ? 0.35 : 0.4,\n ease: 'easeOut',\n delay: isClosing ? 0.2 : 0,\n }}\n aria-hidden=\"true\"\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: OVERLAY_Z,\n pointerEvents: 'none',\n backgroundColor: 'rgba(0, 0, 0, 0.15)',\n }}\n />\n\n <motion.div\n key=\"voice-overlay-gradient\"\n initial={{ opacity: 0, y: 80 }}\n animate={isClosing ? { opacity: 0, y: 60 } : { opacity: 1, y: 0 }}\n transition={\n isClosing\n ? { duration: 0.3, ease: EXIT_EASE, delay: 0.2 }\n : { duration: 0.6, ease: [0.22, 1, 0.36, 1], delay: 0.05 }\n }\n aria-hidden=\"true\"\n style={{\n position: 'fixed',\n bottom: 0,\n left: 0,\n right: 0,\n height: '28rem',\n zIndex: OVERLAY_Z,\n pointerEvents: 'none',\n background:\n 'linear-gradient(to top, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.15) 40%, transparent 100%)',\n }}\n />\n\n <div\n role=\"dialog\"\n aria-label=\"Voice Assistant\"\n aria-modal=\"false\"\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: OVERLAY_Z,\n pointerEvents: 'none',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <motion.button\n initial={{ opacity: 0, scale: 0.7 }}\n animate={isClosing ? { opacity: 0, scale: 0.7 } : { opacity: 1, scale: 1 }}\n transition={\n isClosing\n ? { duration: 0.2, ease: EXIT_EASE, delay: 0.06 }\n : { ...SPRING_SMOOTH, delay: 0.35 }\n }\n onClick={onClose}\n className=\"absolute top-6 right-6 flex items-center justify-center rounded-full transition-all duration-200 cursor-pointer hover:scale-110\"\n style={{\n pointerEvents: 'auto',\n zIndex: OVERLAY_Z,\n width: 44,\n height: 44,\n backgroundColor: 'rgba(255, 255, 255, 0.12)',\n border: '1px solid rgba(255, 255, 255, 0.25)',\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n color: 'rgba(255, 255, 255, 0.85)',\n }}\n aria-label=\"Close voice assistant\"\n >\n <X className=\"h-5 w-5\" />\n </motion.button>\n\n <div className=\"w-full h-full\" style={{ pointerEvents: 'none' }}>\n <WiredOverlayContent\n isMobile={isMobile}\n onClose={onClose}\n onStateChange={onStateChange}\n isClosing={isClosing}\n />\n </div>\n </div>\n </>,\n document.body\n );\n}\n\nfunction useIsMobile(breakpoint = 768) {\n const [isMobile, setIsMobile] = useState(\n () => window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches\n );\n useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [breakpoint]);\n return isMobile;\n}\n\nexport default function VoiceOverlay({ isOpen, onClose, onStateChange }: VoiceOverlayProps) {\n const isMobile = useIsMobile();\n const [isClosing, setIsClosing] = useState(false);\n const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleClose = useCallback(() => {\n if (isClosing) return;\n setIsClosing(true);\n closeTimerRef.current = setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, EXIT_ANIMATION_MS);\n }, [isClosing, onClose]);\n\n useEffect(() => {\n return () => {\n if (closeTimerRef.current != null) clearTimeout(closeTimerRef.current);\n };\n }, []);\n\n if (!isOpen) return null;\n\n return (\n <VoiceErrorBoundary onReset={onClose}>\n <OverlayPortal\n isOpen={isOpen}\n isClosing={isClosing}\n onClose={handleClose}\n onStateChange={onStateChange}\n isMobile={isMobile}\n />\n </VoiceErrorBoundary>\n );\n}\n","import { useRef, useEffect, useState } from 'react';\nimport {\n WAVEFORM_NUM_BARS,\n WAVEFORM_MIN_BAR_HEIGHT,\n WAVEFORM_MAX_BAR_HEIGHT,\n WAVEFORM_GAP,\n WAVEFORM_SMOOTHING,\n} from '@unctad-ai/voice-agent-core';\nimport type { OrbState } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceWaveformCanvasProps {\n analyserNode: AnalyserNode | null;\n state: OrbState;\n size: number;\n}\n\nconst STATE_COLORS: Record<OrbState, [string, string]> = {\n idle: ['rgba(59,130,246,0.35)', 'rgba(96,165,250,0.12)'],\n listening: ['rgba(239,68,68,0.75)', 'rgba(251,191,36,0.3)'],\n processing: ['rgba(245,158,11,0.7)', 'rgba(251,191,36,0.3)'],\n speaking: ['rgba(34,197,94,0.7)', 'rgba(45,212,191,0.3)'],\n error: ['rgba(220,38,38,0.6)', 'rgba(153,27,27,0.25)'],\n};\n\nfunction lerpColor(a: string, b: string, t: number): string {\n // Parse rgba strings\n const parse = (s: string) => {\n const m = s.match(/[\\d.]+/g);\n return m ? m.map(Number) : [0, 0, 0, 0];\n };\n const ca = parse(a);\n const cb = parse(b);\n const r = ca.map((v, i) => v + (cb[i] - v) * t);\n return `rgba(${Math.round(r[0])},${Math.round(r[1])},${Math.round(r[2])},${r[3].toFixed(3)})`;\n}\n\nexport default function VoiceWaveformCanvas({\n analyserNode,\n state,\n size,\n}: VoiceWaveformCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const rafRef = useRef<number>(0);\n const barsRef = useRef<Float32Array>(new Float32Array(WAVEFORM_NUM_BARS));\n const colorRef = useRef({ inner: STATE_COLORS.idle[0], outer: STATE_COLORS.idle[1] });\n\n const [reducedMotion] = useState(\n () => window.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const dpr = window.devicePixelRatio || 1;\n canvas.width = size * dpr;\n canvas.height = size * dpr;\n ctx.scale(dpr, dpr);\n\n const freqData = analyserNode ? new Uint8Array(analyserNode.frequencyBinCount) : null;\n\n const tick = () => {\n ctx.clearRect(0, 0, size, size);\n\n // Lerp colors toward target state\n const target = STATE_COLORS[state];\n colorRef.current.inner = lerpColor(colorRef.current.inner, target[0], WAVEFORM_SMOOTHING);\n colorRef.current.outer = lerpColor(colorRef.current.outer, target[1], WAVEFORM_SMOOTHING);\n\n // Get frequency data\n if (analyserNode && freqData) {\n analyserNode.getByteFrequencyData(freqData);\n }\n\n const cx = size / 2;\n const cy = size / 2;\n const baseRadius = size * 0.35 + WAVEFORM_GAP;\n const baseBarWidth = Math.max(1.5, ((2 * Math.PI * baseRadius) / WAVEFORM_NUM_BARS) * 0.55);\n\n for (let i = 0; i < WAVEFORM_NUM_BARS; i++) {\n // Map frequency bin to target height\n let targetVal = 0;\n if (freqData && freqData.length > 0) {\n const binIndex = Math.floor((i / WAVEFORM_NUM_BARS) * freqData.length);\n targetVal = freqData[binIndex] / 255;\n }\n\n // Smooth interpolation\n barsRef.current[i] += (targetVal - barsRef.current[i]) * WAVEFORM_SMOOTHING;\n\n const effectiveMax = reducedMotion ? WAVEFORM_MIN_BAR_HEIGHT + 5 : WAVEFORM_MAX_BAR_HEIGHT;\n const barHeight =\n WAVEFORM_MIN_BAR_HEIGHT + barsRef.current[i] * (effectiveMax - WAVEFORM_MIN_BAR_HEIGHT);\n\n const angle = (i / WAVEFORM_NUM_BARS) * Math.PI * 2 - Math.PI / 2;\n const x1 = cx + Math.cos(angle) * baseRadius;\n const y1 = cy + Math.sin(angle) * baseRadius;\n const x2 = cx + Math.cos(angle) * (baseRadius + barHeight);\n const y2 = cy + Math.sin(angle) * (baseRadius + barHeight);\n\n // Draw bar with gradient\n const gradient = ctx.createLinearGradient(x1, y1, x2, y2);\n gradient.addColorStop(0, colorRef.current.inner);\n gradient.addColorStop(1, colorRef.current.outer);\n\n // Bars thicken with amplitude for a more alive feel\n const barWidth = baseBarWidth + barsRef.current[i] * baseBarWidth * 0.6;\n\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.strokeStyle = gradient;\n ctx.lineWidth = barWidth;\n ctx.lineCap = 'round';\n ctx.stroke();\n }\n\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafRef.current);\n }, [analyserNode, state, size, reducedMotion]);\n\n return (\n <canvas\n ref={canvasRef}\n style={{ width: size, height: size }}\n className=\"absolute inset-0 pointer-events-none\"\n aria-hidden=\"true\"\n />\n );\n}\n"],"mappings":"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","names":["useState","useEffect","useCallback","useRef","Component","motion","AnimatePresence","useReducedMotion","ChevronDown","Mic","MicOff","Keyboard","VolumeX","Flag","useSiteConfig","DEFAULT_FONT_FAMILY","useRef","useEffect","useState","useCallback","jsx","useSiteConfig","jsx","jsxs","lerp","useRef","useEffect","useState","useCallback","useState","useEffect","useRef","useSiteConfig","jsx","jsxs","useState","useEffect","useRef","showLabel","useEffect","motion","AnimatePresence","Fragment","jsx","jsxs","useEffect","AnimatePresence","motion","jsx","jsxs","motion","AnimatePresence","AlertTriangle","Mic","jsx","jsxs","AlertTriangle","Mic","AnimatePresence","motion","useState","useEffect","motion","AnimatePresence","jsx","jsxs","jsx","jsxs","VoiceSettingsView","useSiteConfig","motion","useReducedMotion","useState","useEffect","timer","AnimatePresence","VolumeX","Mic","MicOff","useRef","Keyboard","Flag","ChevronDown","useCallback","Component","DEFAULT_FONT_FAMILY","useEffect","useRef","jsx","motion","AnimatePresence","useReducedMotion","Mic","useSiteConfig","jsx","useState","useRef","useEffect","motion","AnimatePresence","Keyboard","X","useSiteConfig","jsx","jsxs","STATE_LABELS","useState","useRef","useEffect","AnimatePresence","motion","X","Keyboard","useRef","useEffect","useState","jsx","useState","useEffect","motion","AnimatePresence","useSiteConfig","jsx","jsxs","useState","useEffect","AnimatePresence","motion","useState","useEffect","useCallback","useRef","createPortal","motion","X","useVoiceAgent","voiceStateToOrbState","useRef","useEffect","useState","jsx","STATE_COLORS","lerpColor","Fragment","jsx","jsxs","useVoiceAgent","useState","voiceStateToOrbState","useRef","useEffect","useCallback","motion","createPortal","X"]}
|
|
1
|
+
{"version":3,"sources":["../src/VoiceAgentProvider.tsx","../src/components/GlassCopilotPanel.tsx","../src/components/AgentAvatar.tsx","../src/components/VoiceOrb.tsx","../src/components/agentFabStyles.ts","../src/components/VoiceTranscript.tsx","../src/utils.ts","../src/components/VoiceToolCard.tsx","../src/components/VoiceErrorBoundary.tsx","../src/components/VoiceErrorDisplay.tsx","../src/components/PipelineMetricsBar.tsx","../src/components/VoiceA11yAnnouncer.tsx","../src/components/VoiceCopilotFAB.tsx","../src/components/VoiceControls.tsx","../src/components/VoiceDotRing.tsx","../src/components/VoiceOnboarding.tsx","../src/components/VoiceOverlay.tsx","../src/components/VoiceWaveformCanvas.tsx"],"sourcesContent":["import { SiteConfigProvider } from '@unctad-ai/voice-agent-core';\nimport { CopilotProvider } from '@unctad-ai/voice-agent-registries';\nimport { VoiceSettingsProvider } from './contexts/VoiceSettingsContext';\nimport type { SiteConfig } from '@unctad-ai/voice-agent-core';\n\nexport function VoiceAgentProvider({\n config,\n children,\n}: {\n config: SiteConfig;\n children: React.ReactNode;\n}) {\n return (\n <SiteConfigProvider config={config}>\n <CopilotProvider>\n <VoiceSettingsProvider siteLanguage={config.language}>\n {children}\n </VoiceSettingsProvider>\n </CopilotProvider>\n </SiteConfigProvider>\n );\n}\n","import {\n useState,\n useEffect,\n useCallback,\n useRef,\n lazy,\n Suspense,\n Component,\n type ReactNode,\n type ErrorInfo,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { motion, AnimatePresence, useReducedMotion } from 'motion/react';\nimport { ChevronDown, X, Mic, MicOff, ArrowUp, Keyboard, RotateCw, Settings, VolumeX, Flag } from 'lucide-react';\nimport {\n useVoiceAgent,\n voiceStateToOrbState,\n checkBackendHealth,\n useSiteConfig,\n RECOVERY_POLL_MS,\n PANEL_WIDTH,\n PANEL_COLLAPSED_HEIGHT,\n PANEL_EXPANDED_HEIGHT,\n PANEL_BORDER_RADIUS,\n PANEL_BOTTOM,\n PANEL_RIGHT,\n PANEL_Z_INDEX,\n SPRING_PANEL,\n SPRING_MICRO,\n SPRING_PANEL_EXIT,\n DEFAULT_FONT_FAMILY,\n} from '@unctad-ai/voice-agent-core';\nimport type { OrbState, VoiceToolResult, VoiceState, VoiceMessage, PipelineTimings } from '@unctad-ai/voice-agent-core';\nimport { useVoiceSettings } from '../contexts/VoiceSettingsContext';\nimport AgentAvatar from './AgentAvatar';\nimport { injectAgentFabCSS } from './agentFabStyles';\nimport VoiceTranscript from './VoiceTranscript';\nimport VoiceToolCard from './VoiceToolCard';\nimport VoiceErrorBoundary from './VoiceErrorBoundary';\nimport VoiceErrorDisplay from './VoiceErrorDisplay';\nimport type { VoiceErrorType } from './VoiceErrorDisplay';\nimport PipelineMetricsBar from './PipelineMetricsBar';\nconst VoiceSettingsView = lazy(() => import('./VoiceSettingsView'));\n\n// ---------------------------------------------------------------------------\n// Retry backoff constants\n// ---------------------------------------------------------------------------\nconst RETRY_INITIAL_MS = 3000;\nconst RETRY_MAX_MS = 30000;\n\n// ---------------------------------------------------------------------------\n// State labels for composer bar\n// ---------------------------------------------------------------------------\nconst STATE_LABELS: Record<VoiceState, string> = {\n IDLE: 'Tap mic to speak',\n LISTENING: \"I'm listening...\",\n USER_SPEAKING: \"I'm listening...\",\n PROCESSING: 'Thinking...',\n AI_SPEAKING: 'Responding...',\n};\n\n// ---------------------------------------------------------------------------\n// Aria-live announcements for screen readers\n// ---------------------------------------------------------------------------\nconst ARIA_LIVE_LABELS: Record<OrbState, string> = {\n idle: '',\n listening: 'Listening for your question',\n processing: 'Processing your request',\n speaking: 'Playing response',\n error: 'An error occurred',\n};\n\n// ---------------------------------------------------------------------------\n// Panel states\n// ---------------------------------------------------------------------------\ntype PanelState = 'hidden' | 'collapsed' | 'expanded';\n\n// ---------------------------------------------------------------------------\n// Scrollbar-hiding CSS for suggestion chips\n// ---------------------------------------------------------------------------\nlet chipScrollStylesInjected = false;\nfunction ensureChipScrollStyles() {\n if (chipScrollStylesInjected || typeof document === 'undefined') return;\n chipScrollStylesInjected = true;\n const style = document.createElement('style');\n style.textContent = `.suggestion-chips::-webkit-scrollbar { display: none }`;\n document.head.appendChild(style);\n}\n\ninterface GlassCopilotPanelProps {\n /** Controlled open state. When omitted, the panel manages its own open/close state. */\n isOpen?: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n onStateChange?: (orbState: OrbState) => void;\n /** URL for the avatar portrait image */\n portraitSrc?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Route exclusion helper\n// ---------------------------------------------------------------------------\nfunction isRouteExcluded(patterns?: string[]): boolean {\n if (!patterns?.length || typeof window === 'undefined') return false;\n const path = window.location.pathname;\n return patterns.some((p) => {\n if (p.endsWith('/*')) return path.startsWith(p.slice(0, -1));\n return path === p;\n });\n}\n\n// ---------------------------------------------------------------------------\n// FAB — shown when panel is hidden\n// ---------------------------------------------------------------------------\nfunction CopilotFAB({ onClick, portraitSrc, isOffline = false }: { onClick: () => void; portraitSrc?: string; isOffline?: boolean }) {\n const { colors } = useSiteConfig();\n return (\n <motion.button\n onClick={onClick}\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.95 }}\n className=\"shadow-lg cursor-pointer\"\n style={{\n background: 'transparent',\n border: 'none',\n padding: 0,\n borderRadius: '50%',\n width: 80,\n height: 80,\n }}\n aria-label=\"Open voice assistant\"\n data-testid=\"voice-agent-fab\"\n >\n <div className=\"agent-fab-border\" style={{ width: 80, height: 80, '--agent-primary': isOffline ? '#9ca3af' : colors.primary, animation: isOffline ? 'none' : undefined } as React.CSSProperties}>\n <div className=\"agent-fab-border-inner\">\n {portraitSrc ? (\n <img\n src={portraitSrc}\n alt=\"Assistant\"\n style={{ width: '100%', height: '100%', objectFit: 'cover', borderRadius: '50%' }}\n draggable={false}\n />\n ) : (\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: '#6b7280',\n color: 'white',\n fontSize: 24,\n fontWeight: 700,\n }}\n >\n AI\n </div>\n )}\n </div>\n </div>\n </motion.button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FAB Tooltip — animated greeting to the left of the FAB\n// ---------------------------------------------------------------------------\nconst FAB_GREETED_KEY = (name: string) => `voice-fab-greeted:${name}`;\nconst FAB_LAST_SHOWN_KEY = (name: string) => `voice-fab-last-shown:${name}`;\nconst FAB_COOLDOWN_MS = 30 * 60 * 1000; // 30 minutes\nconst FAB_TOOLTIP_NARROW_QUERY = '(max-width: 479px)';\n\nfunction safeStorage(op: () => string | null): string | null;\nfunction safeStorage(op: () => void): void;\nfunction safeStorage(op: () => unknown): unknown {\n try { return op(); } catch { return null; }\n}\n\nfunction CopilotFABTooltip({ onClick }: { onClick: () => void }) {\n const { copilotName, colors, fabTooltip } = useSiteConfig();\n const prefersReduced = useReducedMotion();\n const [visible, setVisible] = useState(false);\n const [dismissed, setDismissed] = useState(false);\n\n // Compute first-visit synchronously so render reads a stable value (not a ref set inside a timer)\n const [isFirstVisit] = useState(() => !safeStorage(() => localStorage.getItem(FAB_GREETED_KEY(copilotName))));\n\n // Responsive narrow viewport check via matchMedia\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mql = window.matchMedia(FAB_TOOLTIP_NARROW_QUERY);\n if (mql.matches) { setDismissed(true); return; }\n const handler = (e: MediaQueryListEvent) => { if (e.matches) setDismissed(true); };\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, []);\n\n useEffect(() => {\n if (isFirstVisit) {\n const timer = setTimeout(() => {\n setVisible(true);\n safeStorage(() => localStorage.setItem(FAB_GREETED_KEY(copilotName), 'true'));\n safeStorage(() => localStorage.setItem(FAB_LAST_SHOWN_KEY(copilotName), new Date().toISOString()));\n }, 2000);\n return () => clearTimeout(timer);\n }\n\n // Return visit: check cooldown\n const lastShown = safeStorage(() => localStorage.getItem(FAB_LAST_SHOWN_KEY(copilotName)));\n if (lastShown && Date.now() - new Date(lastShown).getTime() < FAB_COOLDOWN_MS) return;\n\n const timer = setTimeout(() => {\n setVisible(true);\n safeStorage(() => localStorage.setItem(FAB_LAST_SHOWN_KEY(copilotName), new Date().toISOString()));\n }, 5000);\n return () => clearTimeout(timer);\n }, [copilotName, isFirstVisit]);\n\n // Auto-hide timer (return visits only — first visit stays until user interacts)\n useEffect(() => {\n if (!visible || isFirstVisit) return;\n const timer = setTimeout(() => setDismissed(true), 5000);\n return () => clearTimeout(timer);\n }, [visible, isFirstVisit]);\n\n // Scroll dismissal (return visits only)\n useEffect(() => {\n if (!visible || dismissed || isFirstVisit) return;\n const handleScroll = () => setDismissed(true);\n window.addEventListener('scroll', handleScroll, { passive: true, once: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, [visible, dismissed, isFirstVisit]);\n\n const handleTryNow = () => {\n setDismissed(true);\n onClick();\n };\n\n const handleDismiss = (e: React.MouseEvent) => {\n e.stopPropagation();\n setDismissed(true);\n };\n\n const firstVisitText = fabTooltip?.firstVisit\n ? fabTooltip.firstVisit.replaceAll('{name}', copilotName)\n : `I'm ${copilotName}, your virtual civil servant.\\nHow may I help you?`;\n const returnVisitText = fabTooltip?.returnVisit ?? 'How may I help you?';\n\n const show = visible && !dismissed;\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"voice-agent-fab-tooltip\"\n initial={prefersReduced ? { opacity: 0 } : { opacity: 0, x: 20 }}\n animate={prefersReduced ? { opacity: 1 } : { opacity: 1, x: 0 }}\n exit={prefersReduced ? { opacity: 0 } : { opacity: 0, x: 10 }}\n transition={\n prefersReduced\n ? { duration: 0.2 }\n : { type: 'spring', stiffness: 300, damping: 25 }\n }\n onClick={isFirstVisit ? undefined : handleTryNow}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 0,\n cursor: isFirstVisit ? 'default' : 'pointer',\n }}\n >\n <div\n style={{\n background: 'white',\n borderRadius: 20,\n padding: isFirstVisit ? '12px 20px' : '10px 18px',\n boxShadow: '0 2px 12px rgba(0,0,0,0.10), 0 0 0 1px rgba(0,0,0,0.04)',\n maxWidth: 340,\n }}\n >\n <div\n style={{\n fontSize: isFirstVisit ? 14 : 13,\n color: '#1a1a1a',\n fontWeight: 500,\n lineHeight: 1.4,\n whiteSpace: 'pre-line',\n }}\n >\n {isFirstVisit ? firstVisitText : returnVisitText}\n </div>\n {isFirstVisit && (\n <div style={{ display: 'flex', gap: 8, marginTop: 8 }}>\n <button\n data-testid=\"voice-agent-fab-tooltip-cta\"\n aria-label={`Open ${copilotName} voice assistant`}\n onClick={handleTryNow}\n style={{\n padding: '6px 16px',\n background: colors.primary,\n color: 'white',\n border: 'none',\n borderRadius: 12,\n fontSize: 12,\n fontWeight: 600,\n cursor: 'pointer',\n }}\n >\n Try it now\n </button>\n <button\n onClick={handleDismiss}\n style={{\n padding: '6px 12px',\n background: 'transparent',\n color: '#6b7280',\n border: 'none',\n borderRadius: 12,\n fontSize: 12,\n cursor: 'pointer',\n }}\n >\n Maybe later\n </button>\n </div>\n )}\n </div>\n {/* Arrow pointing right toward FAB */}\n <div\n style={{\n width: 0,\n height: 0,\n borderTop: '8px solid transparent',\n borderBottom: '8px solid transparent',\n borderLeft: '8px solid white',\n flexShrink: 0,\n filter: 'drop-shadow(2px 0 1px rgba(0,0,0,0.06))',\n }}\n />\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Collapsed header bar\n// ---------------------------------------------------------------------------\nfunction CollapsedBar({\n orbState,\n getAmplitude,\n analyser: _analyser,\n voiceState,\n onExpand,\n onClose,\n onRetry,\n isRetrying = false,\n retryCountdown,\n voiceError,\n micPaused = false,\n onMicToggle,\n ttsEnabled = true,\n copilotName,\n portraitSrc,\n lastMessage,\n}: {\n orbState: OrbState;\n getAmplitude: () => number;\n analyser: AnalyserNode | null;\n voiceState: VoiceState;\n onExpand: () => void;\n onClose: () => void;\n onRetry?: () => void;\n isRetrying?: boolean;\n retryCountdown?: number | null;\n voiceError?: VoiceErrorType;\n micPaused?: boolean;\n onMicToggle?: () => void;\n ttsEnabled?: boolean;\n copilotName: string;\n portraitSrc?: string;\n lastMessage?: string;\n}) {\n const { colors } = useSiteConfig();\n const isOffline = voiceError === 'network_error';\n\n return (\n <div\n className=\"flex items-center gap-3 h-full cursor-pointer select-none\"\n style={{ padding: '0 16px' }}\n role=\"button\"\n tabIndex={0}\n data-testid=\"voice-agent-bar\"\n onClick={onExpand}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onExpand();\n }\n }}\n >\n {/* Mini avatar */}\n <div\n className=\"relative shrink-0\"\n style={{ width: 56, height: 56, opacity: isOffline ? 0.4 : 1 }}\n >\n <AgentAvatar state={orbState} getAmplitude={getAmplitude} size={56} portraitSrc={portraitSrc} />\n {!ttsEnabled && (\n <div\n className=\"absolute flex items-center justify-center\"\n style={{\n bottom: -2,\n right: -2,\n width: 18,\n height: 18,\n borderRadius: 9,\n backgroundColor: 'rgba(0,0,0,0.65)',\n border: '1.5px solid rgba(255,255,255,0.8)',\n }}\n >\n <VolumeX style={{ width: 10, height: 10, color: '#fff' }} />\n </div>\n )}\n </div>\n\n {/* Title */}\n <div className=\"flex-1 min-w-0\">\n <p\n className=\"truncate\"\n style={{ fontSize: '14px', fontWeight: 600, color: '#1a1a1a' }}\n >\n {copilotName}\n </p>\n <p\n className=\"truncate\"\n style={{\n fontSize: '12px',\n fontWeight: 400,\n color: isOffline ? 'rgba(220, 38, 38, 0.7)' : 'rgba(0,0,0,0.42)',\n letterSpacing: '0.01em',\n }}\n >\n {isOffline ? (\n <span className=\"inline-flex items-center gap-1\">\n {retryCountdown ? `Retrying in ${retryCountdown}s` : 'Offline'}\n {onRetry && !retryCountdown && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n onRetry();\n }}\n className=\"inline-flex items-center justify-center rounded-full transition-colors cursor-pointer\"\n style={{\n width: 18,\n height: 18,\n color: 'rgba(220, 38, 38, 0.5)',\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLElement).style.color = 'rgba(220, 38, 38, 0.8)';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLElement).style.color = 'rgba(220, 38, 38, 0.5)';\n }}\n aria-label=\"Retry connection\"\n >\n <motion.span\n animate={isRetrying ? { rotate: 360 } : { rotate: 0 }}\n transition={\n isRetrying\n ? { duration: 0.8, repeat: Infinity, ease: 'linear' }\n : { duration: 0.3 }\n }\n style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}\n >\n <RotateCw style={{ width: 12, height: 12 }} />\n </motion.span>\n </button>\n )}\n </span>\n ) : (micPaused || voiceState === 'IDLE') && lastMessage ? (\n lastMessage.length > 40 ? lastMessage.slice(0, 40).trimEnd() + '...' : lastMessage\n ) : micPaused ? (\n 'Tap mic to resume'\n ) : (\n STATE_LABELS[voiceState]\n )}\n </p>\n </div>\n\n {/* Mic toggle button */}\n {!isOffline && onMicToggle && (() => {\n const barListening = voiceState === 'LISTENING' || voiceState === 'USER_SPEAKING';\n return (\n <motion.button\n onClick={(e) => {\n e.stopPropagation();\n onMicToggle();\n }}\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.93 }}\n animate={barListening\n ? { backgroundColor: [colors.primary, `${colors.primary}BB`, colors.primary] }\n : { backgroundColor: 'rgba(0,0,0,0.06)' }\n }\n transition={barListening\n ? { backgroundColor: { duration: 1.8, repeat: Infinity, ease: 'easeInOut' } }\n : { duration: 0.3 }\n }\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer relative\"\n style={{\n width: 44,\n height: 44,\n color: barListening ? 'white' : 'rgba(0,0,0,0.45)',\n border: 'none',\n padding: 0,\n boxShadow: barListening\n ? `0 2px 8px ${colors.primary}40, 0 1px 3px rgba(0,0,0,0.12)`\n : '0 1px 4px rgba(0,0,0,0.10)',\n }}\n aria-label={barListening ? 'Stop listening' : 'Start listening'}\n >\n {barListening\n ? <Mic style={{ width: 16, height: 16, position: 'relative', zIndex: 1 }} />\n : <MicOff style={{ width: 16, height: 16, position: 'relative', zIndex: 1 }} />\n }\n </motion.button>\n );\n })()}\n\n {/* Offline status dot */}\n {isOffline && (\n <span\n className=\"shrink-0 rounded-full\"\n style={{\n width: 8,\n height: 8,\n backgroundColor: 'rgba(220, 38, 38, 0.5)',\n }}\n />\n )}\n\n {/* Close */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n onClose();\n }}\n className=\"shrink-0 rounded-full flex items-center justify-center transition-colors cursor-pointer\"\n style={{\n width: 32,\n height: 32,\n color: 'rgba(0,0,0,0.4)',\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLElement).style.color = 'rgba(0,0,0,0.7)';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLElement).style.color = 'rgba(0,0,0,0.4)';\n }}\n aria-label=\"Close voice assistant\"\n >\n <X style={{ width: 14, height: 14 }} />\n </button>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Composer bar\n// ---------------------------------------------------------------------------\nfunction ComposerBar({\n voiceState,\n isListening,\n micPaused = false,\n onTextSubmit,\n onMicToggle,\n onCancel,\n disabled = false,\n switchToTextRef,\n feedbackTarget,\n onFeedbackSubmit,\n onFeedbackCancel,\n}: {\n voiceState: VoiceState;\n isListening: boolean;\n micPaused?: boolean;\n onTextSubmit: (text: string) => void;\n onMicToggle: () => void;\n onCancel?: () => void;\n disabled?: boolean;\n switchToTextRef?: React.RefObject<(() => void) | null>;\n feedbackTarget?: { assistantMessage: string; userMessage?: string; turnNumber: number } | null;\n onFeedbackSubmit?: (text: string, target: { assistantMessage: string; userMessage?: string; turnNumber: number }) => void;\n onFeedbackCancel?: () => void;\n}) {\n const { colors } = useSiteConfig();\n const [mode, setMode] = useState<'voice' | 'text' | 'feedback'>(disabled ? 'text' : 'voice');\n const [text, setText] = useState('');\n const [showCancelHint, setShowCancelHint] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n // After 2s in PROCESSING, show \"Tap mic to cancel\" hint\n useEffect(() => {\n if (voiceState !== 'PROCESSING') { setShowCancelHint(false); return; }\n const timer = setTimeout(() => setShowCancelHint(true), 2000);\n return () => clearTimeout(timer);\n }, [voiceState]);\n\n // Expose switch-to-text for external triggers (empty state CTA)\n useEffect(() => {\n if (switchToTextRef) (switchToTextRef as React.MutableRefObject<(() => void) | null>).current = () => setMode('text');\n }, [switchToTextRef]);\n\n // When mic is disabled (e.g. STT down), force text mode\n useEffect(() => {\n if (disabled) setMode('text');\n }, [disabled]);\n\n // Enter feedback mode when triggered externally\n useEffect(() => {\n if (feedbackTarget) {\n setMode('feedback');\n const timer = setTimeout(() => inputRef.current?.focus(), 200);\n return () => clearTimeout(timer);\n }\n }, [feedbackTarget]);\n\n useEffect(() => {\n if (mode === 'text') {\n // Delay focus to after AnimatePresence mount animation\n const timer = setTimeout(() => inputRef.current?.focus(), 200);\n return () => clearTimeout(timer);\n }\n }, [mode]);\n\n const handleSubmit = () => {\n if (disabled) return;\n const trimmed = text.trim();\n if (!trimmed) return;\n onTextSubmit(trimmed);\n setText('');\n // Stay in text mode — user switches back to voice via mic button\n requestAnimationFrame(() => inputRef.current?.focus());\n };\n\n const handleCancel = () => {\n setText('');\n if (disabled) return; // Can't switch back to voice when mic is disabled\n setMode('voice');\n onMicToggle();\n };\n\n const handleFeedbackSubmit = () => {\n const trimmed = text.trim();\n if (!trimmed || !feedbackTarget) return;\n onFeedbackSubmit?.(trimmed, feedbackTarget);\n setText('');\n setMode('voice');\n };\n\n const handleFeedbackCancel = () => {\n setText('');\n setMode('voice');\n onFeedbackCancel?.();\n };\n\n return (\n <div\n className=\"shrink-0 overflow-hidden\"\n style={{\n height: 56,\n borderTop: '1px solid rgba(0,0,0,0.08)',\n }}\n >\n <AnimatePresence mode=\"wait\" initial={false}>\n {mode === 'voice' ? (\n <motion.div\n key=\"voice-mode\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.18, ease: [0.22, 1, 0.36, 1] }}\n className=\"flex items-center gap-3\"\n style={{ height: 56, padding: '10px 14px' }}\n >\n <motion.button\n onClick={onMicToggle}\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.93 }}\n animate={isListening\n ? { backgroundColor: [colors.primary, `${colors.primary}BB`, colors.primary] }\n : { backgroundColor: 'rgba(0,0,0,0.06)' }\n }\n transition={isListening\n ? { backgroundColor: { duration: 1.8, repeat: Infinity, ease: 'easeInOut' } }\n : { duration: 0.3 }\n }\n className=\"shrink-0 rounded-full flex items-center justify-center relative cursor-pointer\"\n style={{\n width: 44,\n height: 44,\n color: isListening ? 'white' : 'rgba(0,0,0,0.5)',\n border: 'none',\n padding: 0,\n boxShadow: isListening\n ? `0 2px 8px ${colors.primary}40, 0 1px 3px rgba(0,0,0,0.12)`\n : '0 1px 4px rgba(0,0,0,0.10)',\n }}\n aria-label={isListening ? 'Stop listening' : 'Start listening'}\n data-testid=\"voice-agent-mic\"\n >\n {isListening\n ? <Mic style={{ width: 18, height: 18, position: 'relative', zIndex: 1 }} />\n : <MicOff style={{ width: 18, height: 18, position: 'relative', zIndex: 1 }} />\n }\n </motion.button>\n\n <div className=\"flex-1 min-w-0\">\n <AnimatePresence mode=\"wait\">\n <motion.p\n key={micPaused ? 'paused' : showCancelHint ? 'cancel-hint' : voiceState}\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.15 }}\n className=\"truncate\"\n style={{\n fontSize: '14px',\n fontWeight: 400,\n color: micPaused\n ? 'rgba(0,0,0,0.35)'\n : showCancelHint\n ? 'rgba(0,0,0,0.35)'\n : voiceState === 'LISTENING' || voiceState === 'USER_SPEAKING'\n ? colors.primary\n : 'rgba(0,0,0,0.45)',\n }}\n >\n {micPaused ? 'Tap mic to resume' : showCancelHint ? 'Tap mic to cancel' : STATE_LABELS[voiceState]}\n </motion.p>\n </AnimatePresence>\n </div>\n\n <motion.button\n whileHover={{ scale: 1.04 }}\n whileTap={{ scale: 0.96 }}\n onClick={() => {\n if (voiceState === 'PROCESSING' || voiceState === 'AI_SPEAKING') onCancel?.();\n else if (isListening) onMicToggle();\n setMode('text');\n }}\n className=\"shrink-0 flex items-center gap-1.5 cursor-pointer\"\n style={{\n height: 36,\n padding: '0 12px',\n borderRadius: 18,\n backgroundColor: 'rgba(0,0,0,0.05)',\n color: 'rgba(0,0,0,0.4)',\n border: 'none',\n fontSize: 12,\n fontWeight: 500,\n }}\n aria-label=\"Type a message\"\n data-testid=\"voice-agent-keyboard\"\n >\n <Keyboard style={{ width: 14, height: 14 }} />\n <span>Type</span>\n </motion.button>\n </motion.div>\n ) : mode === 'text' ? (\n <motion.div\n key=\"text-mode\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.18, ease: [0.22, 1, 0.36, 1] }}\n className=\"flex items-center gap-2\"\n style={{ height: 56, padding: '10px 14px' }}\n >\n <div\n className=\"flex-1 min-w-0 flex items-center\"\n style={{\n height: 36,\n borderRadius: 18,\n padding: '0 14px',\n backgroundColor: 'rgba(0,0,0,0.03)',\n border: '1px solid rgba(0,0,0,0.08)',\n transition: 'border-color 0.15s, box-shadow 0.15s',\n }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n disabled={disabled}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleSubmit();\n if (e.key === 'Escape') handleCancel();\n }}\n onFocus={(e) => {\n const pill = e.currentTarget.parentElement;\n if (pill) {\n pill.style.borderColor = 'rgba(0,0,0,0.15)';\n pill.style.boxShadow = '0 0 0 2px rgba(0,0,0,0.04)';\n }\n }}\n onBlur={(e) => {\n const pill = e.currentTarget.parentElement;\n if (pill) {\n pill.style.borderColor = 'rgba(0,0,0,0.08)';\n pill.style.boxShadow = 'none';\n }\n }}\n placeholder={disabled ? 'Reconnecting...' : 'Message...'}\n aria-label=\"Type your question\"\n data-testid=\"voice-agent-input\"\n className=\"w-full\"\n style={{\n fontSize: '14px',\n color: '#1a1a1a',\n background: 'transparent',\n border: 'none',\n outline: 'none',\n padding: 0,\n opacity: disabled ? 0.5 : 1,\n cursor: disabled ? 'not-allowed' : undefined,\n }}\n />\n </div>\n\n <AnimatePresence>\n {text.trim().length > 0 && (\n <motion.button\n initial={{ scale: 0, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0, opacity: 0 }}\n transition={SPRING_MICRO}\n whileTap={{ scale: 0.9 }}\n onClick={handleSubmit}\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer\"\n style={{\n width: 44,\n height: 44,\n backgroundColor: colors.primary,\n color: 'white',\n }}\n aria-label=\"Send message\"\n data-testid=\"voice-agent-send\"\n >\n <ArrowUp style={{ width: 18, height: 18 }} />\n </motion.button>\n )}\n </AnimatePresence>\n\n {!disabled && (\n <motion.button\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.92 }}\n onClick={handleCancel}\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer\"\n style={{\n width: 44,\n height: 44,\n backgroundColor: 'rgba(0,0,0,0.05)',\n color: 'rgba(0,0,0,0.4)',\n }}\n aria-label=\"Back to voice mode\"\n data-testid=\"voice-agent-voice-mode\"\n >\n <Mic style={{ width: 18, height: 18 }} />\n </motion.button>\n )}\n </motion.div>\n ) : mode === 'feedback' ? (\n <motion.div\n key=\"feedback-mode\"\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.18, ease: [0.22, 1, 0.36, 1] }}\n className=\"flex items-center gap-2\"\n style={{ height: 56, padding: '10px 14px' }}\n >\n <div\n className=\"shrink-0 rounded-full flex items-center justify-center\"\n style={{ width: 44, height: 44, backgroundColor: '#d97706' }}\n >\n <Flag style={{ width: 18, height: 18, color: 'white' }} />\n </div>\n\n <div\n className=\"flex-1 min-w-0 flex items-center\"\n style={{\n height: 36, borderRadius: 18, padding: '0 14px',\n backgroundColor: 'rgba(217,119,6,0.05)',\n border: '2px solid #d97706',\n }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleFeedbackSubmit();\n if (e.key === 'Escape') handleFeedbackCancel();\n }}\n placeholder=\"How could this be better?\"\n className=\"w-full\"\n style={{\n fontSize: '14px', color: '#1a1a1a', background: 'transparent',\n border: 'none', outline: 'none', padding: 0,\n }}\n />\n </div>\n\n <AnimatePresence>\n {text.trim().length > 0 && (\n <motion.button\n initial={{ scale: 0, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0, opacity: 0 }}\n transition={SPRING_MICRO}\n whileTap={{ scale: 0.9 }}\n onClick={handleFeedbackSubmit}\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer\"\n style={{ width: 44, height: 44, backgroundColor: '#d97706', color: 'white' }}\n >\n <ArrowUp style={{ width: 18, height: 18 }} />\n </motion.button>\n )}\n </AnimatePresence>\n\n <motion.button\n whileHover={{ scale: 1.08 }}\n whileTap={{ scale: 0.92 }}\n onClick={handleFeedbackCancel}\n className=\"shrink-0 rounded-full flex items-center justify-center cursor-pointer\"\n style={{ width: 44, height: 44, backgroundColor: 'rgba(0,0,0,0.05)', color: 'rgba(0,0,0,0.35)' }}\n >\n <X style={{ width: 18, height: 18 }} />\n </motion.button>\n </motion.div>\n ) : null}\n </AnimatePresence>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Expanded panel content\n// ---------------------------------------------------------------------------\nfunction ExpandedContent({\n orbState, getAmplitude, analyser, voiceState, messages, isTyping,\n toolResult, voiceError, dismissError, onCollapse, onClose, onTextSubmit,\n onMicToggle, onCancel, micPaused = false, onToolDismiss, onInteraction, onRetry,\n isRetrying = false, retryCountdown, lastTimings, showPipelineMetrics, pipelineMetricsAutoHideMs,\n showSettings, onSettingsToggle, ttsEnabled = true, copilotName, portraitSrc,\n onStartMic, onSwitchToKeyboard, switchToTextRef,\n onReport, feedbackSentTurns, feedbackTarget, onFeedbackSubmit, onFeedbackCancel,\n}: {\n orbState: OrbState; getAmplitude: () => number; analyser: AnalyserNode | null;\n voiceState: VoiceState; messages: VoiceMessage[]; isTyping: boolean;\n toolResult: VoiceToolResult | null; voiceError: VoiceErrorType; dismissError: () => void;\n onCollapse: () => void; onClose: () => void; onTextSubmit: (text: string) => void;\n onMicToggle: () => void; onCancel?: () => void; micPaused?: boolean; onToolDismiss: () => void;\n onInteraction: () => void; onRetry?: () => void; isRetrying?: boolean; retryCountdown?: number | null;\n lastTimings?: PipelineTimings | null; showPipelineMetrics?: boolean;\n pipelineMetricsAutoHideMs?: number; showSettings: boolean; onSettingsToggle: () => void;\n ttsEnabled?: boolean; copilotName: string; portraitSrc?: string;\n onStartMic?: () => void; onSwitchToKeyboard?: () => void;\n switchToTextRef?: React.RefObject<(() => void) | null>;\n onReport?: (turnNumber: number, assistantMessage: string, userMessage?: string) => void;\n feedbackSentTurns?: Record<number, string>;\n feedbackTarget?: { assistantMessage: string; userMessage?: string; turnNumber: number } | null;\n onFeedbackSubmit?: (text: string, target: { assistantMessage: string; userMessage?: string; turnNumber: number }) => void;\n onFeedbackCancel?: () => void;\n}) {\n const config = useSiteConfig();\n const { colors } = config;\n const isListening = voiceState === 'LISTENING' || voiceState === 'USER_SPEAKING';\n const isOffline = voiceError === 'network_error';\n\n return (\n <div\n style={{ display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}\n onClick={onInteraction}\n onKeyDown={onInteraction}\n >\n {/* Header (64px) */}\n <div\n className=\"flex items-center gap-3 shrink-0\"\n style={{ height: 64, padding: '12px 16px', borderBottom: '1px solid rgba(0,0,0,0.06)', backgroundColor: `${colors.primary}08` }}\n >\n <motion.div\n animate={{ opacity: isOffline ? 0.35 : 1 }}\n className=\"relative shrink-0\"\n style={{ width: 56, height: 56, filter: isOffline ? 'grayscale(0.8)' : 'none' }}\n >\n <AgentAvatar state={orbState} getAmplitude={getAmplitude} size={56} showRing portraitSrc={portraitSrc} />\n {!ttsEnabled && (\n <div\n className=\"absolute flex items-center justify-center\"\n style={{\n bottom: -2, right: -2, width: 18, height: 18, borderRadius: 9,\n backgroundColor: 'rgba(0,0,0,0.65)', border: '1.5px solid rgba(255,255,255,0.8)',\n }}\n >\n <VolumeX style={{ width: 10, height: 10, color: '#fff' }} />\n </div>\n )}\n </motion.div>\n\n <div className=\"flex-1 min-w-0\">\n <p className=\"truncate\" style={{ fontSize: '14px', fontWeight: 600, color: '#1a1a1a' }}>{copilotName}</p>\n <p className=\"truncate\" data-testid=\"voice-agent-status\" style={{ fontSize: '12px', fontWeight: 400, color: isOffline ? 'rgba(220,38,38,0.7)' : 'rgba(0,0,0,0.42)', letterSpacing: '0.01em' }}>\n {isOffline ? (\n <span className=\"inline-flex items-center gap-1\">\n Offline\n {onRetry && (\n <button onClick={(e) => { e.stopPropagation(); onRetry(); }} className=\"inline-flex items-center justify-center rounded-full transition-colors cursor-pointer\" style={{ width: 18, height: 18, color: 'rgba(220,38,38,0.5)' }} aria-label=\"Retry connection\">\n <motion.span animate={isRetrying ? { rotate: 360 } : { rotate: 0 }} transition={isRetrying ? { duration: 0.8, repeat: Infinity, ease: 'linear' } : { duration: 0.3 }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <RotateCw style={{ width: 12, height: 12 }} />\n </motion.span>\n </button>\n )}\n </span>\n ) : micPaused ? 'Tap mic to resume' : STATE_LABELS[voiceState]}\n </p>\n </div>\n\n <button\n onClick={onSettingsToggle}\n className=\"shrink-0 rounded-full transition-colors cursor-pointer\"\n style={{\n color: showSettings ? colors.primary : 'rgba(0,0,0,0.4)',\n width: 32, height: 32, display: 'flex', alignItems: 'center', justifyContent: 'center',\n backgroundColor: showSettings ? `${colors.primary}14` : 'transparent',\n }}\n aria-label={showSettings ? 'Close settings' : 'Open settings'}\n data-testid=\"voice-agent-settings\"\n >\n <Settings style={{ width: 14, height: 14 }} />\n </button>\n <button onClick={onCollapse} className=\"shrink-0 rounded-full transition-colors cursor-pointer\" style={{ color: 'rgba(0,0,0,0.4)', width: 32, height: 32, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'transparent' }} aria-label=\"Minimize panel\" data-testid=\"voice-agent-minimize\">\n <ChevronDown style={{ width: 14, height: 14 }} />\n </button>\n <button onClick={onClose} className=\"shrink-0 rounded-full transition-colors cursor-pointer\" style={{ color: 'rgba(0,0,0,0.4)', width: 32, height: 32, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'transparent' }} aria-label=\"Close voice assistant\" data-testid=\"voice-agent-close\">\n <X style={{ width: 14, height: 14 }} />\n </button>\n </div>\n\n <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>\n <div data-testid=\"voice-agent-transcript\" style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }}><VoiceTranscript messages={messages} isTyping={isTyping} variant=\"panel\" voiceError={voiceError} voiceState={voiceState} onStartMic={onStartMic} onSwitchToKeyboard={onSwitchToKeyboard} onReport={onReport} feedbackSentTurns={feedbackSentTurns} onTextSubmit={onTextSubmit} /></div>\n <div style={{ flexShrink: 0 }}>\n <PipelineMetricsBar timings={lastTimings ?? null} show={showPipelineMetrics} autoHideMs={pipelineMetricsAutoHideMs} />\n {isOffline && onRetry && (\n <div style={{ padding: '0 16px 8px', display: 'flex', justifyContent: 'center' }}>\n <motion.button whileHover={{ scale: 1.04 }} whileTap={{ scale: 0.96 }} onClick={onRetry} disabled={isRetrying} className=\"inline-flex items-center gap-2 rounded-full cursor-pointer transition-colors\" style={{ padding: '8px 18px', fontSize: '13px', fontWeight: 500, color: isRetrying ? 'rgba(0,0,0,0.35)' : 'rgba(220,38,38,0.8)', backgroundColor: isRetrying ? 'rgba(0,0,0,0.04)' : 'rgba(220,38,38,0.08)', border: '1px solid', borderColor: isRetrying ? 'rgba(0,0,0,0.06)' : 'rgba(220,38,38,0.15)' }} aria-label=\"Retry connection\">\n <motion.span animate={isRetrying ? { rotate: 360 } : { rotate: 0 }} transition={isRetrying ? { duration: 0.8, repeat: Infinity, ease: 'linear' } : { duration: 0.3 }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <RotateCw style={{ width: 14, height: 14 }} />\n </motion.span>\n {isRetrying ? 'Checking...' : retryCountdown ? `Retrying in ${retryCountdown}s...` : 'Retry connection'}\n </motion.button>\n </div>\n )}\n {voiceError !== 'network_error' && (\n <div style={{ padding: '0 16px 8px' }}><VoiceErrorDisplay error={voiceError} onDismiss={dismissError} /></div>\n )}\n <div style={{ padding: '0 16px 8px' }}><VoiceToolCard result={toolResult} onDismiss={onToolDismiss} variant=\"capsule\" /></div>\n </div>\n </div>\n\n {micPaused && messages.length === 0 && (() => {\n ensureChipScrollStyles();\n const prompts = config.suggestedPrompts ?? ['What services are available?', 'Help me with an application'];\n return (\n <div className=\"suggestion-chips\" style={{\n padding: '0 16px 4px',\n display: 'flex',\n gap: 8,\n overflowX: 'auto',\n flexShrink: 0,\n WebkitOverflowScrolling: 'touch',\n scrollbarWidth: 'none',\n }}>\n {prompts.map((prompt, i) => (\n <button\n key={i}\n onClick={() => onTextSubmit(prompt)}\n style={{\n flexShrink: 0,\n padding: '6px 14px',\n fontSize: 12,\n fontWeight: 500,\n color: colors.primary,\n backgroundColor: `${colors.primary}0a`,\n border: `1px solid ${colors.primary}20`,\n borderRadius: 20,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n transition: 'background-color 0.15s',\n }}\n onMouseEnter={(e) => { (e.target as HTMLElement).style.backgroundColor = `${colors.primary}18`; }}\n onMouseLeave={(e) => { (e.target as HTMLElement).style.backgroundColor = `${colors.primary}0a`; }}\n >\n {prompt}\n </button>\n ))}\n </div>\n );\n })()}\n\n <div className=\"shrink-0\">\n <ComposerBar voiceState={voiceState} isListening={isListening} micPaused={micPaused} onTextSubmit={onTextSubmit} onMicToggle={onMicToggle} onCancel={onCancel} disabled={voiceError === 'network_error' || voiceError === 'stt_failed'} switchToTextRef={switchToTextRef} feedbackTarget={feedbackTarget} onFeedbackSubmit={onFeedbackSubmit} onFeedbackCancel={onFeedbackCancel} />\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Static panel shell\n// ---------------------------------------------------------------------------\nfunction StaticPanelShell({\n panelState, onCollapse, onExpand, onClose, onRetry, copilotName, portraitSrc,\n}: {\n panelState: PanelState; onCollapse: () => void; onExpand: () => void; onClose: () => void;\n onRetry?: () => Promise<boolean>; copilotName: string; portraitSrc?: string;\n}) {\n const noopAmplitude = useCallback(() => 0, []);\n const [isRetrying, setIsRetrying] = useState(false);\n const handleRetry = useCallback(() => { if (isRetrying || !onRetry) return; setIsRetrying(true); onRetry().finally(() => setIsRetrying(false)); }, [onRetry, isRetrying]);\n\n if (panelState === 'collapsed') {\n return <CollapsedBar orbState=\"idle\" getAmplitude={noopAmplitude} analyser={null} voiceState=\"IDLE\" onExpand={onExpand} onClose={onClose} onRetry={handleRetry} isRetrying={isRetrying} voiceError=\"network_error\" copilotName={copilotName} portraitSrc={portraitSrc} />;\n }\n return <ExpandedContent orbState=\"idle\" getAmplitude={noopAmplitude} analyser={null} voiceState=\"IDLE\" messages={[]} isTyping={false} toolResult={null} voiceError=\"network_error\" dismissError={() => {}} onCollapse={onCollapse} onClose={onClose} onTextSubmit={() => {}} onMicToggle={() => {}} onToolDismiss={() => {}} onInteraction={() => {}} onRetry={handleRetry} isRetrying={isRetrying} showSettings={false} onSettingsToggle={() => {}} copilotName={copilotName} portraitSrc={portraitSrc} />;\n}\n\n// ---------------------------------------------------------------------------\n// Error boundary\n// ---------------------------------------------------------------------------\nclass WiredPanelErrorBoundary extends Component<\n { children: ReactNode; panelState: PanelState; onCollapse: () => void; onExpand: () => void; onClose: () => void; copilotName: string; portraitSrc?: string },\n { hasError: boolean }\n> {\n state = { hasError: false };\n static getDerivedStateFromError() { return { hasError: true }; }\n componentDidCatch(error: Error, _info: ErrorInfo) { console.warn('[GlassCopilotPanel] Voice agent unavailable:', error.message); }\n handleRetry = (): Promise<boolean> => {\n return checkBackendHealth().then(({ available }) => {\n if (available) this.setState({ hasError: false });\n return available;\n });\n };\n render() {\n if (this.state.hasError) {\n return <StaticPanelShell panelState={this.props.panelState} onCollapse={this.props.onCollapse} onExpand={this.props.onExpand} onClose={this.props.onClose} onRetry={this.handleRetry} copilotName={this.props.copilotName} portraitSrc={this.props.portraitSrc} />;\n }\n return this.props.children;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wired panel\n// ---------------------------------------------------------------------------\nfunction WiredPanel({\n panelState, onCollapse, onExpand, onClose, onStateChange, portraitSrc,\n}: {\n panelState: PanelState; onCollapse: () => void; onExpand: () => void; onClose: () => void;\n onStateChange?: (orbState: OrbState) => void; portraitSrc?: string;\n}) {\n const config = useSiteConfig();\n return (\n <WiredPanelErrorBoundary panelState={panelState} onCollapse={onCollapse} onExpand={onExpand} onClose={onClose} copilotName={config.copilotName} portraitSrc={portraitSrc}>\n <WiredPanelInner panelState={panelState} onCollapse={onCollapse} onExpand={onExpand} onClose={onClose} onStateChange={onStateChange} portraitSrc={portraitSrc} />\n </WiredPanelErrorBoundary>\n );\n}\n\nfunction WiredPanelInner({\n panelState, onCollapse, onExpand, onClose, onStateChange, portraitSrc,\n}: {\n panelState: PanelState; onCollapse: () => void; onExpand: () => void; onClose: () => void;\n onStateChange?: (orbState: OrbState) => void; portraitSrc?: string;\n}) {\n const config = useSiteConfig();\n const resolvedPortrait = portraitSrc ?? config.avatarUrl;\n const { settings: voiceSettings, volumeRef, speedRef } = useVoiceSettings();\n const { state, start, stop, messages, getAmplitude, analyser, sendTextMessage, voiceError, dismissError, lastTimings, sessionId, applyVolume, settings } = useVoiceAgent({ settings: voiceSettings, volumeRef, speedRef });\n\n const [toolResult, setToolResult] = useState<VoiceToolResult | null>(null);\n const [feedbackTarget, setFeedbackTarget] = useState<{ assistantMessage: string; userMessage?: string; turnNumber: number } | null>(null);\n const [feedbackSentTurns, setFeedbackSentTurns] = useState<Record<number, string>>({});\n const orbState = voiceStateToOrbState(state);\n const [backendDown, setBackendDown] = useState(false);\n const autoStartedRef = useRef(false);\n const pollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const cancelledRef = useRef(false);\n const [retryCountdown, setRetryCountdown] = useState<number | null>(null);\n const backoffDelayRef = useRef(RETRY_INITIAL_MS);\n const countdownTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const dismissErrorRef = useRef(dismissError);\n useEffect(() => { dismissErrorRef.current = dismissError; }, [dismissError]);\n const autoListenRef = useRef(settings.autoListen);\n useEffect(() => { autoListenRef.current = settings.autoListen; }, [settings.autoListen]);\n\n const clearCountdown = useCallback(() => {\n if (countdownTimerRef.current) { clearInterval(countdownTimerRef.current); countdownTimerRef.current = null; }\n setRetryCountdown(null);\n }, []);\n\n const runHealthCheckRef = useRef<() => void>(() => {});\n\n const scheduleRetry = useCallback((delayMs: number) => {\n if (pollTimerRef.current) clearTimeout(pollTimerRef.current);\n clearCountdown();\n const seconds = Math.ceil(delayMs / 1000);\n setRetryCountdown(seconds);\n let remaining = seconds;\n countdownTimerRef.current = setInterval(() => {\n remaining -= 1;\n if (remaining <= 0) { clearCountdown(); return; }\n setRetryCountdown(remaining);\n }, 1000);\n pollTimerRef.current = setTimeout(() => runHealthCheckRef.current(), delayMs);\n backoffDelayRef.current = Math.min(delayMs * 2, RETRY_MAX_MS);\n }, [clearCountdown]);\n\n const runHealthCheck = useCallback(() => {\n clearCountdown();\n checkBackendHealth().then(({ available }) => {\n if (cancelledRef.current) return;\n setBackendDown(!available);\n if (available) {\n backoffDelayRef.current = RETRY_INITIAL_MS;\n dismissErrorRef.current();\n if (!autoStartedRef.current && autoListenRef.current) { autoStartedRef.current = true; startRef.current(); }\n } else {\n scheduleRetry(backoffDelayRef.current);\n }\n });\n }, [scheduleRetry, clearCountdown]);\n\n useEffect(() => { runHealthCheckRef.current = runHealthCheck; }, [runHealthCheck]);\n\n useEffect(() => {\n cancelledRef.current = false; runHealthCheck();\n return () => {\n cancelledRef.current = true;\n if (pollTimerRef.current) clearTimeout(pollTimerRef.current);\n if (countdownTimerRef.current) clearInterval(countdownTimerRef.current);\n };\n }, [runHealthCheck]);\n\n const onStateChangeRef = useRef(onStateChange);\n useEffect(() => { onStateChangeRef.current = onStateChange; });\n useEffect(() => { onStateChangeRef.current?.(orbState); }, [orbState]);\n\n const startRef = useRef(start);\n const stopRef = useRef(stop);\n useEffect(() => { startRef.current = start; }, [start]);\n useEffect(() => { stopRef.current = stop; }, [stop]);\n useEffect(() => { return () => { stopRef.current(true); }; }, []);\n\n const [micPaused, setMicPaused] = useState(false);\n const [activity, setActivity] = useState(0);\n const [showSettings, setShowSettings] = useState(false);\n const hasConversationRef = useRef(false);\n hasConversationRef.current = messages.length > 0;\n const onCollapseRef = useRef(onCollapse);\n useEffect(() => { onCollapseRef.current = onCollapse; });\n\n const bumpActivity = useCallback(() => { setActivity((c) => c + 1); }, []);\n\n const handleCancel = useCallback(() => {\n if (state === 'PROCESSING' || state === 'AI_SPEAKING') { stop(); return true; }\n return false;\n }, [state, stop]);\n\n const handleMicToggle = useCallback(() => {\n setMicPaused(false); bumpActivity();\n if (state === 'LISTENING' || state === 'USER_SPEAKING') { stop(); }\n else if (state === 'IDLE') { start(); }\n else if (handleCancel()) { start(); }\n }, [state, start, stop, bumpActivity, handleCancel]);\n\n useEffect(() => { if (panelState === 'hidden') stopRef.current(true); }, [panelState]);\n\n // micOpen: true when mic is live (LISTENING or USER_SPEAKING).\n // Used as the effect dep so the idle timer starts when the mic opens and\n // clears when the pipeline takes over (PROCESSING/AI_SPEAKING).\n // VAD bouncing between LISTENING↔USER_SPEAKING keeps micOpen=true,\n // so background noise doesn't reset the timer.\n // Full pipeline turns DO reset it (micOpen false→true), which is correct —\n // after a real answer the user needs a fresh window to respond.\n const micOpen = state === 'LISTENING' || state === 'USER_SPEAKING';\n const stateRef = useRef(state);\n stateRef.current = state;\n\n useEffect(() => {\n if (panelState === 'hidden' || micPaused || showSettings) return;\n if (!micOpen) return;\n // Reschedule loop: if the timer fires while the user is mid-speech,\n // reschedule instead of closing — prevents cutting off long utterances.\n let timer: ReturnType<typeof setTimeout>;\n const schedule = () => {\n timer = setTimeout(() => {\n if (stateRef.current === 'USER_SPEAKING') { schedule(); return; }\n stopRef.current();\n if (hasConversationRef.current) { setMicPaused(true); } else { onCollapseRef.current(); }\n }, settings.idleTimeoutMs);\n };\n schedule();\n return () => clearTimeout(timer);\n }, [micOpen, panelState, micPaused, showSettings, activity, settings.idleTimeoutMs]);\n\n useEffect(() => {\n if (!micPaused || panelState !== 'expanded' || showSettings) return;\n if (settings.panelCollapseTimeoutMs === 0) return;\n const timer = setTimeout(() => { onCollapseRef.current(); }, settings.panelCollapseTimeoutMs);\n return () => clearTimeout(timer);\n }, [micPaused, panelState, showSettings, activity, settings.panelCollapseTimeoutMs]);\n\n const handleTextSubmit = useCallback((text: string) => { setMicPaused(false); bumpActivity(); sendTextMessage(text); }, [sendTextMessage, bumpActivity]);\n\n const handleReport = useCallback((turnNumber: number, assistantMessage: string, userMessage?: string) => {\n setFeedbackTarget({ assistantMessage, userMessage, turnNumber });\n }, []);\n\n const handleFeedbackCancel = useCallback(() => {\n setFeedbackTarget(null);\n }, []);\n\n const handleFeedbackSubmit = useCallback(async (text: string, target: { assistantMessage: string; userMessage?: string; turnNumber: number }) => {\n const backendUrl = (typeof import.meta !== 'undefined' && import.meta.env?.VITE_BACKEND_URL) || '';\n const url = backendUrl ? `${backendUrl}/api/feedback` : '/api/feedback';\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n sessionId,\n turnNumber: target.turnNumber,\n text,\n assistantMessage: target.assistantMessage,\n userMessage: target.userMessage,\n timings: lastTimings ?? undefined,\n route: window.location.pathname,\n copilotName: config.copilotName,\n kitVersion: __KIT_VERSION__,\n }),\n });\n const body = await res.json().catch(() => ({ ticketId: undefined }));\n setFeedbackSentTurns(prev => ({ ...prev, [target.turnNumber]: body.ticketId || '\\u2713' }));\n } catch { /* silent — feedback is best-effort */ }\n setFeedbackTarget(null);\n }, [sessionId, config.copilotName, lastTimings]);\n\n const isTyping = state === 'AI_SPEAKING';\n const effectiveError = backendDown ? ('network_error' as const) : voiceError;\n\n const [isRetrying, setIsRetrying] = useState(false);\n const handleRetryClick = useCallback(() => {\n if (isRetrying) return;\n setIsRetrying(true);\n backoffDelayRef.current = RETRY_INITIAL_MS;\n clearCountdown();\n checkBackendHealth().then(({ available }) => {\n if (cancelledRef.current) return;\n setIsRetrying(false);\n setBackendDown(!available);\n if (available) {\n dismissErrorRef.current();\n if (!autoStartedRef.current && autoListenRef.current) { autoStartedRef.current = true; startRef.current(); }\n } else {\n scheduleRetry(backoffDelayRef.current);\n }\n }).catch(() => setIsRetrying(false));\n }, [isRetrying, clearCountdown, scheduleRetry]);\n\n // Auto-expand panel when first message arrives (voice-first: skip empty state)\n const onExpandRef = useRef(onExpand);\n useEffect(() => { onExpandRef.current = onExpand; });\n useEffect(() => {\n if (panelState === 'collapsed' && messages.length > 0) {\n onExpandRef.current();\n }\n }, [panelState, messages.length]);\n\n const switchToTextRef = useRef<(() => void) | null>(null);\n const handleSwitchToKeyboard = useCallback(() => { switchToTextRef.current?.(); }, []);\n\n const toggleSettings = useCallback(() => setShowSettings((p) => !p), []);\n\n // Pause listening when settings panel is open, resume when closed\n const wasListeningBeforeSettingsRef = useRef(false);\n useEffect(() => {\n if (showSettings) {\n if (state === 'LISTENING' || state === 'USER_SPEAKING') {\n wasListeningBeforeSettingsRef.current = true;\n stopRef.current();\n } else {\n wasListeningBeforeSettingsRef.current = false;\n }\n } else if (wasListeningBeforeSettingsRef.current) {\n wasListeningBeforeSettingsRef.current = false;\n startRef.current();\n }\n }, [showSettings]);\n\n if (panelState === 'collapsed') {\n const lastAssistantMsg = messages.slice().reverse().find(m => m.role === 'assistant')?.text;\n return <CollapsedBar orbState={orbState} getAmplitude={getAmplitude} analyser={analyser} voiceState={state} onExpand={onExpand} onClose={onClose} onRetry={handleRetryClick} isRetrying={isRetrying} retryCountdown={retryCountdown} voiceError={effectiveError} micPaused={micPaused} onMicToggle={handleMicToggle} ttsEnabled={settings.ttsEnabled} copilotName={config.copilotName} portraitSrc={resolvedPortrait} lastMessage={lastAssistantMsg} />;\n }\n\n return (\n <div className=\"relative h-full\">\n <ExpandedContent orbState={orbState} getAmplitude={getAmplitude} analyser={analyser} voiceState={state} messages={messages} isTyping={isTyping} toolResult={toolResult} voiceError={effectiveError} dismissError={dismissError} onCollapse={onCollapse} onClose={onClose} onTextSubmit={handleTextSubmit} onMicToggle={handleMicToggle} onCancel={handleCancel} micPaused={micPaused} onToolDismiss={() => setToolResult(null)} onInteraction={bumpActivity} onRetry={handleRetryClick} isRetrying={isRetrying} retryCountdown={retryCountdown} lastTimings={lastTimings} showPipelineMetrics={settings.showPipelineMetrics} pipelineMetricsAutoHideMs={settings.pipelineMetricsAutoHideMs} showSettings={showSettings} onSettingsToggle={toggleSettings} ttsEnabled={settings.ttsEnabled} copilotName={config.copilotName} portraitSrc={resolvedPortrait} onStartMic={handleMicToggle} onSwitchToKeyboard={handleSwitchToKeyboard} switchToTextRef={switchToTextRef} onReport={handleReport} feedbackSentTurns={feedbackSentTurns} feedbackTarget={feedbackTarget} onFeedbackSubmit={handleFeedbackSubmit} onFeedbackCancel={handleFeedbackCancel} />\n <AnimatePresence>\n {showSettings && (<Suspense fallback={null}><VoiceSettingsView onBack={toggleSettings} onVolumeChange={applyVolume} /></Suspense>)}\n </AnimatePresence>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main exported component\n// ---------------------------------------------------------------------------\nexport default function GlassCopilotPanel({ isOpen: isOpenProp, onOpen: onOpenProp, onClose: onCloseProp, onStateChange, portraitSrc }: GlassCopilotPanelProps) {\n injectAgentFabCSS();\n const config = useSiteConfig();\n const resolvedPortrait = portraitSrc ?? config.avatarUrl;\n\n // Hide on excluded routes\n const [routeHidden, setRouteHidden] = useState(() => isRouteExcluded(config.excludeRoutes));\n useEffect(() => {\n if (!config.excludeRoutes?.length) return;\n // Re-check on SPA navigation (popstate) and periodically for pushState\n const check = () => setRouteHidden(isRouteExcluded(config.excludeRoutes));\n window.addEventListener('popstate', check);\n const timer = setInterval(check, 500);\n return () => { window.removeEventListener('popstate', check); clearInterval(timer); };\n }, [config.excludeRoutes]);\n\n // Uncontrolled mode: manage open state internally when isOpen prop is not provided\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = isOpenProp !== undefined;\n const isOpen = isControlled ? isOpenProp : internalOpen;\n\n const handleOpen = useCallback(() => {\n onOpenProp?.();\n if (!isControlled) setInternalOpen(true);\n }, [onOpenProp, isControlled]);\n\n const [internalState, setInternalState] = useState<'collapsed' | 'expanded'>('collapsed');\n const panelState: PanelState = isOpen ? internalState : 'hidden';\n const handleClose = useCallback(() => {\n onCloseProp?.();\n if (!isControlled) setInternalOpen(false);\n }, [onCloseProp, isControlled]);\n const handleCollapse = useCallback(() => { setInternalState('collapsed'); }, []);\n const handleExpand = useCallback(() => { setInternalState('expanded'); }, []);\n\n const [fabOffline, setFabOffline] = useState(false);\n useEffect(() => {\n if (isOpen || routeHidden) return; // Skip polling when panel visible or route excluded\n let cancelled = false;\n const check = () => {\n checkBackendHealth().then(({ available }) => {\n if (!cancelled) setFabOffline(!available);\n });\n };\n check();\n const timer = setInterval(check, RECOVERY_POLL_MS);\n return () => { cancelled = true; clearInterval(timer); };\n }, [isOpen, routeHidden]);\n\n const isVisible = panelState !== 'hidden';\n const isExpanded = panelState === 'expanded';\n const targetHeight = isExpanded ? PANEL_EXPANDED_HEIGHT : PANEL_COLLAPSED_HEIGHT;\n\n const panelRef = useRef<HTMLDivElement>(null);\n const fabRef = useRef<HTMLDivElement>(null);\n const prevVisibleRef = useRef(isVisible);\n\n useEffect(() => {\n if (isVisible && !prevVisibleRef.current) { requestAnimationFrame(() => panelRef.current?.focus()); }\n else if (!isVisible && prevVisibleRef.current) { requestAnimationFrame(() => { const fabButton = fabRef.current?.querySelector('button'); fabButton?.focus(); }); }\n prevVisibleRef.current = isVisible;\n }, [isVisible]);\n\n const [ariaAnnouncement, setAriaAnnouncement] = useState('');\n const handleStateChange = useCallback((orbState: OrbState) => { setAriaAnnouncement(ARIA_LIVE_LABELS[orbState]); onStateChange?.(orbState); }, [onStateChange]);\n\n if (routeHidden) return null;\n\n return createPortal(\n <VoiceErrorBoundary onReset={handleClose}>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"0\" height=\"0\" style={{ position: 'absolute', overflow: 'hidden' }} aria-hidden=\"true\">\n <defs>\n <filter id=\"liquid-glass-panel\" x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n <feTurbulence type=\"fractalNoise\" baseFrequency=\"0.008 0.008\" numOctaves=\"2\" seed=\"42\" result=\"noise\" />\n <feGaussianBlur in=\"noise\" stdDeviation=\"2\" result=\"blurred_noise\" />\n <feDisplacementMap in=\"SourceGraphic\" in2=\"blurred_noise\" scale=\"50\" xChannelSelector=\"R\" yChannelSelector=\"G\" />\n </filter>\n </defs>\n </svg>\n\n <span aria-live=\"polite\" aria-atomic=\"true\" style={{ position: 'absolute', width: 1, height: 1, padding: 0, margin: -1, overflow: 'hidden', clip: 'rect(0,0,0,0)', whiteSpace: 'nowrap', borderWidth: 0 }}>\n {ariaAnnouncement}\n </span>\n\n <AnimatePresence>\n {!isVisible && (\n <motion.div ref={fabRef} key=\"copilot-fab\" initial={{ scale: 0, opacity: 0 }} animate={{ scale: 1, opacity: 1 }} exit={{ scale: 0, opacity: 0 }} transition={{ duration: 0.25, ease: 'easeOut' }} className=\"fixed\" style={{ bottom: PANEL_BOTTOM, right: PANEL_RIGHT, zIndex: PANEL_Z_INDEX, display: 'flex', alignItems: 'flex-end', gap: 12 }}>\n <CopilotFABTooltip onClick={handleOpen} />\n <CopilotFAB onClick={handleOpen} portraitSrc={resolvedPortrait} isOffline={fabOffline} />\n </motion.div>\n )}\n\n {isVisible && (\n <motion.div ref={panelRef} tabIndex={-1} key=\"copilot-panel\" role=\"dialog\" aria-label=\"Voice Assistant\" aria-modal=\"false\" data-testid=\"voice-agent-panel\"\n initial={{ width: 80, height: 80, borderRadius: 40, opacity: 0, scale: 0.9 }}\n animate={{ width: PANEL_WIDTH, height: Math.min(targetHeight, window.innerHeight - 48), borderRadius: PANEL_BORDER_RADIUS, opacity: 1, scale: 1, transition: SPRING_PANEL }}\n exit={{ width: 80, height: 80, borderRadius: 40, opacity: 0, scale: 0.95, transition: SPRING_PANEL_EXIT }}\n className=\"fixed\"\n style={{ bottom: PANEL_BOTTOM, right: PANEL_RIGHT, zIndex: PANEL_Z_INDEX, transformOrigin: 'bottom right', maxWidth: 'calc(100vw - 32px)', outline: 'none', fontFamily: config.fontFamily ?? DEFAULT_FONT_FAMILY }}\n >\n <div className=\"absolute inset-0 pointer-events-none\" style={{ borderRadius: PANEL_BORDER_RADIUS, overflow: 'hidden', backdropFilter: 'blur(2px)', WebkitBackdropFilter: 'blur(2px)', filter: 'url(#liquid-glass-panel)', isolation: 'isolate' }} />\n <div className=\"absolute inset-0 pointer-events-none\" style={{ borderRadius: PANEL_BORDER_RADIUS, overflow: 'hidden', backdropFilter: 'blur(14px) saturate(1.4)', WebkitBackdropFilter: 'blur(14px) saturate(1.4)', backgroundColor: 'rgba(230,232,245,0.32)', border: '1px solid rgba(255,255,255,0.4)', boxShadow: 'inset 0 0 20px -5px rgba(255,255,255,0.3), inset 0 1px 0 0 rgba(255,255,255,0.8), 0 0 0 1px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.08), 0 8px 24px rgba(0,0,0,0.14), 0 24px 48px rgba(0,0,0,0.10)' }} />\n <div className=\"absolute inset-0 pointer-events-none\" style={{ borderRadius: PANEL_BORDER_RADIUS, background: 'linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0) 20%)' }} />\n <div style={{ position: 'relative', zIndex: 1, height: '100%', overflow: 'hidden', borderRadius: PANEL_BORDER_RADIUS, backgroundColor: 'rgba(255,255,255,0.78)' }}>\n <WiredPanel panelState={panelState} onCollapse={handleCollapse} onExpand={handleExpand} onClose={handleClose} onStateChange={handleStateChange} portraitSrc={resolvedPortrait} />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </VoiceErrorBoundary>,\n document.body\n );\n}\n","import { useRef, useEffect, useState, useCallback } from 'react';\nimport VoiceOrb from './VoiceOrb';\nimport {\n AVATAR_PORTRAIT_RATIO,\n AVATAR_STATE_FILTERS,\n buildGlowColors,\n useSiteConfig,\n} from '@unctad-ai/voice-agent-core';\nimport type { OrbState } from '@unctad-ai/voice-agent-core';\n\n/** Conic gradient colors per state — [color1, color2] */\nconst RING_COLORS: Record<OrbState, [string, string]> = {\n idle: ['#93a3c8', '#b0bfdb'],\n listening: ['#DB2129', '#34d399'],\n processing: ['#F59E0B', '#FBBF24'],\n speaking: ['#14B8A6', '#34d399'],\n error: ['#DC2626', '#991B1B'],\n};\n\ninterface AgentAvatarProps {\n state: OrbState;\n getAmplitude: () => number;\n size?: number;\n showAura?: boolean;\n /** Show audio-reactive conic-gradient ring around portrait */\n showRing?: boolean;\n /** URL for the avatar portrait image */\n portraitSrc?: string;\n /** Monogram letter shown when image fails to load */\n monogram?: string;\n}\n\nfunction lerp(a: number, b: number, t: number) {\n return a + (b - a) * t;\n}\n\nexport default function AgentAvatar({\n state,\n getAmplitude,\n size = 36,\n showAura = true,\n showRing = false,\n portraitSrc,\n monogram,\n}: AgentAvatarProps) {\n const config = useSiteConfig();\n const initial = monogram ?? config.copilotName?.charAt(0)?.toUpperCase() ?? 'A';\n const { colors } = useSiteConfig();\n const AVATAR_GLOW_COLORS = buildGlowColors(colors);\n const portraitSize = Math.round(size * AVATAR_PORTRAIT_RATIO);\n const offset = Math.round((size - portraitSize) / 2);\n\n // Ring sits between aura and portrait — 3px border around portrait\n const ringWidth = 3;\n const ringSize = portraitSize + ringWidth * 2;\n const ringOffset = Math.round((size - ringSize) / 2);\n\n const imgRef = useRef<HTMLImageElement>(null);\n const glowRef = useRef<HTMLDivElement>(null);\n const ringRef = useRef<HTMLDivElement>(null);\n const rafRef = useRef<number>(0);\n const stateRef = useRef<OrbState>(state);\n useEffect(() => {\n stateRef.current = state;\n });\n const getAmpRef = useRef(getAmplitude);\n useEffect(() => {\n getAmpRef.current = getAmplitude;\n });\n\n const [loaded, setLoaded] = useState(false);\n const [errored, setErrored] = useState(false);\n\n // Detect prefers-reduced-motion\n const reducedRef = useRef(false);\n useEffect(() => {\n const mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n reducedRef.current = mql.matches;\n const handler = (e: MediaQueryListEvent) => {\n reducedRef.current = e.matches;\n };\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, []);\n\n // Animated filter values — lerped each frame, no React re-renders\n const animRef = useRef({\n brightness: AVATAR_STATE_FILTERS.idle.brightness,\n saturate: AVATAR_STATE_FILTERS.idle.saturate,\n opacity: AVATAR_STATE_FILTERS.idle.opacity,\n scale: AVATAR_STATE_FILTERS.idle.scale,\n glowIntensity: AVATAR_STATE_FILTERS.idle.glowIntensity,\n ringAngle: 0,\n });\n\n useEffect(() => {\n let startTime: number | null = null;\n let prevTimestamp = 0;\n\n const tick = (timestamp: number) => {\n if (startTime === null) startTime = timestamp;\n const elapsed = (timestamp - startTime) / 1000;\n const dt = prevTimestamp ? (timestamp - prevTimestamp) / 1000 : 0.016;\n prevTimestamp = timestamp;\n\n const target = AVATAR_STATE_FILTERS[stateRef.current];\n const a = animRef.current;\n const speed = 0.08;\n\n a.brightness = lerp(a.brightness, target.brightness, speed);\n a.saturate = lerp(a.saturate, target.saturate, speed);\n a.scale = lerp(a.scale, target.scale, speed);\n a.glowIntensity = lerp(a.glowIntensity, target.glowIntensity, speed);\n\n // Processing opacity pulses\n let targetOpacity = target.opacity;\n if (stateRef.current === 'processing') {\n targetOpacity = 0.92 + Math.sin(elapsed * 4) * 0.06;\n }\n a.opacity = lerp(a.opacity, targetOpacity, speed);\n\n // Speaking state: portrait scale reacts to amplitude\n const amp = getAmpRef.current();\n const ampFactor = reducedRef.current ? 0.2 : 1;\n let scaleBoost = 0;\n if (stateRef.current === 'speaking') {\n scaleBoost = amp * 0.03 * ampFactor;\n }\n\n // Apply to portrait image via direct DOM mutation\n const img = imgRef.current;\n if (img) {\n img.style.filter = `brightness(${a.brightness}) saturate(${a.saturate})`;\n img.style.opacity = String(a.opacity);\n img.style.transform = `scale(${a.scale + scaleBoost})`;\n }\n\n // Apply glow overlay\n const glow = glowRef.current;\n if (glow) {\n glow.style.backgroundColor = AVATAR_GLOW_COLORS[stateRef.current];\n glow.style.opacity = String(a.glowIntensity);\n }\n\n // Audio-reactive ring\n const ring = ringRef.current;\n if (ring) {\n const ringColors = RING_COLORS[stateRef.current];\n // Rotation: base 120 deg/s, amplitude boosts up to 3x\n const rotSpeed = reducedRef.current ? 0 : 120 * (1 + amp * 2);\n a.ringAngle = (a.ringAngle + rotSpeed * dt) % 360;\n // Ring opacity: idle = subtle, active states = brighter with amplitude boost\n const isActive = stateRef.current !== 'idle';\n const ringOpacity = isActive ? 0.7 + amp * 0.3 : 0.35;\n // Scale pulse with amplitude\n const ringScale = 1 + amp * 0.04 * ampFactor;\n\n ring.style.background = `conic-gradient(from ${a.ringAngle}deg, ${ringColors[0]}, ${ringColors[1]}, ${ringColors[0]})`;\n ring.style.opacity = String(ringOpacity);\n ring.style.transform = `scale(${ringScale})`;\n }\n\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafRef.current);\n }, []);\n\n const handleLoad = useCallback(() => setLoaded(true), []);\n const handleError = useCallback(() => setErrored(true), []);\n\n return (\n <div\n style={{\n position: 'relative',\n width: size,\n height: size,\n flexShrink: 0,\n }}\n >\n {/* Layer 1: Aura — VoiceOrb as reactive background */}\n {showAura && (\n <div style={{ position: 'absolute', inset: 0 }}>\n <VoiceOrb state={state} getAmplitude={getAmplitude} size={size} />\n </div>\n )}\n\n {/* Layer 1.5: Audio-reactive conic-gradient ring */}\n {showRing && (\n <div\n ref={ringRef}\n style={{\n position: 'absolute',\n top: ringOffset,\n left: ringOffset,\n width: ringSize,\n height: ringSize,\n borderRadius: '50%',\n background: `conic-gradient(from 0deg, ${RING_COLORS.idle[0]}, ${RING_COLORS.idle[1]}, ${RING_COLORS.idle[0]})`,\n opacity: 0.35,\n WebkitMask: `radial-gradient(circle, transparent ${Math.round((portraitSize / ringSize) * 50)}%, black ${Math.round((portraitSize / ringSize) * 50)}%)`,\n mask: `radial-gradient(circle, transparent ${Math.round((portraitSize / ringSize) * 50)}%, black ${Math.round((portraitSize / ringSize) * 50)}%)`,\n pointerEvents: 'none',\n willChange: 'transform, background, opacity',\n }}\n />\n )}\n\n {/* Layer 2: Glow overlay — color wash per state */}\n <div\n ref={glowRef}\n style={{\n position: 'absolute',\n top: offset,\n left: offset,\n width: portraitSize,\n height: portraitSize,\n borderRadius: '50%',\n mixBlendMode: 'soft-light',\n opacity: 0,\n pointerEvents: 'none',\n transition: 'background-color 0.3s',\n }}\n />\n\n {/* Layer 3: Portrait */}\n <div\n style={{\n position: 'absolute',\n top: offset,\n left: offset,\n width: portraitSize,\n height: portraitSize,\n borderRadius: '50%',\n overflow: 'hidden',\n }}\n >\n {errored || !portraitSrc ? (\n // Monogram fallback\n <div\n style={{\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: colors.primary,\n color: 'white',\n fontFamily: 'inherit',\n fontWeight: 700,\n fontSize: Math.round(portraitSize * 0.45),\n }}\n >\n {initial}\n </div>\n ) : (\n <img\n ref={imgRef}\n src={portraitSrc}\n alt=\"Avatar\"\n onLoad={handleLoad}\n onError={handleError}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n borderRadius: '50%',\n opacity: loaded ? 0.95 : 0,\n transition: loaded ? 'none' : 'opacity 0.3s ease-in',\n willChange: 'filter, transform, opacity',\n }}\n draggable={false}\n />\n )}\n </div>\n </div>\n );\n}\n","import { useRef, useEffect, useCallback, useState, useMemo } from 'react';\nimport { createNoise3D } from 'simplex-noise';\nimport { ORB_NUM_POINTS, ORB_LERP_SPEED, useSiteConfig } from '@unctad-ai/voice-agent-core';\nimport type { OrbState, SiteColors } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceOrbProps {\n state: OrbState;\n /** Getter function called each animation frame — avoids 60fps React re-renders */\n getAmplitude: () => number;\n size?: number;\n}\n\n// ---------- state config ----------\n\ninterface StateConfig {\n colors: [string, string];\n noiseSpeed: number;\n noiseMag: number;\n baseScale: number;\n breathAmp: number;\n breathSpeed: number;\n rotation: number;\n shimmer: boolean;\n}\n\n/** Normalize any hex shorthand (#RGB) to full form (#RRGGBB), strip alpha */\nfunction normalizeHex(hex: string): string {\n if (!hex || hex[0] !== '#') return '#808080';\n const h = hex.slice(1);\n if (h.length === 3) return '#' + h[0]+h[0] + h[1]+h[1] + h[2]+h[2];\n if (h.length >= 6) return '#' + h.slice(0, 6);\n return '#808080';\n}\n\n/** Darken a hex color by lerping toward black */\nfunction darkenHex(hex: string, amount: number): string {\n hex = normalizeHex(hex);\n const r = Math.max(0, Math.round(parseInt(hex.slice(1, 3), 16) * (1 - amount)));\n const g = Math.max(0, Math.round(parseInt(hex.slice(3, 5), 16) * (1 - amount)));\n const b = Math.max(0, Math.round(parseInt(hex.slice(5, 7), 16) * (1 - amount)));\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}`;\n}\n\n/** Lighten a hex color by lerping toward white */\nfunction lightenHex(hex: string, amount: number): string {\n hex = normalizeHex(hex);\n const r = Math.min(255, Math.round(parseInt(hex.slice(1, 3), 16) + (255 - parseInt(hex.slice(1, 3), 16)) * amount));\n const g = Math.min(255, Math.round(parseInt(hex.slice(3, 5), 16) + (255 - parseInt(hex.slice(3, 5), 16)) * amount));\n const b = Math.min(255, Math.round(parseInt(hex.slice(5, 7), 16) + (255 - parseInt(hex.slice(5, 7), 16)) * amount));\n return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}`;\n}\n\n/** Convert hex to rgba string */\nfunction hexToRGBA(hex: string, opacity: number): string {\n hex = normalizeHex(hex);\n return `rgba(${parseInt(hex.slice(1, 3), 16)}, ${parseInt(hex.slice(3, 5), 16)}, ${parseInt(hex.slice(5, 7), 16)}, ${opacity})`;\n}\n\n/** Glow color that pulses around the orb per state — derived from SiteColors */\nfunction buildStateGlow(colors: SiteColors): Record<OrbState, string> {\n return {\n idle: 'rgba(59, 130, 246, 0.25)',\n listening: hexToRGBA(colors.primary, 0.45),\n processing: hexToRGBA(colors.processing, 0.4),\n speaking: hexToRGBA(colors.speaking, 0.4),\n error: hexToRGBA(colors.error ?? '#DC2626', 0.4),\n };\n}\n\nfunction buildStateConfig(colors: SiteColors): Record<OrbState, StateConfig> {\n const errorColor = colors.error ?? '#DC2626';\n return {\n idle: {\n colors: ['#1E3A5F', '#3B82F6'],\n noiseSpeed: 0.3,\n noiseMag: 8,\n baseScale: 0.975,\n breathAmp: 0.025,\n breathSpeed: 0.25,\n rotation: 0,\n shimmer: false,\n },\n listening: {\n colors: [colors.primary, colors.processing],\n noiseSpeed: 0.6,\n noiseMag: 18,\n baseScale: 1.0,\n breathAmp: 0.04,\n breathSpeed: 0.5,\n rotation: 0,\n shimmer: false,\n },\n processing: {\n colors: [darkenHex(colors.processing, 0.3), lightenHex(colors.processing, 0.4)],\n noiseSpeed: 1.0,\n noiseMag: 14,\n baseScale: 1.0,\n breathAmp: 0.02,\n breathSpeed: 0.8,\n rotation: 0.4,\n shimmer: true,\n },\n speaking: {\n colors: [darkenHex(colors.speaking, 0.35), lightenHex(colors.speaking, 0.4)],\n noiseSpeed: 0.5,\n noiseMag: 16,\n baseScale: 1.0,\n breathAmp: 0.05,\n breathSpeed: 0.4,\n rotation: 0,\n shimmer: false,\n },\n error: {\n colors: [errorColor, darkenHex(errorColor, 0.35)],\n noiseSpeed: 1.4,\n noiseMag: 22,\n baseScale: 0.95,\n breathAmp: 0.01,\n breathSpeed: 1.2,\n rotation: 0,\n shimmer: false,\n },\n };\n}\n\nconst NUM_POINTS = ORB_NUM_POINTS;\nconst LERP_SPEED = ORB_LERP_SPEED;\n\nfunction useReducedMotion() {\n const [reduced, setReduced] = useState(\n () => window.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n useEffect(() => {\n const mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n const handler = (e: MediaQueryListEvent) => setReduced(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, []);\n return reduced;\n}\n\nfunction lerp(a: number, b: number, t: number) {\n return a + (b - a) * t;\n}\n\nfunction lerpColor(a: string, b: string, t: number): string {\n const parseHex = (h: string) => [\n parseInt(h.slice(1, 3), 16),\n parseInt(h.slice(3, 5), 16),\n parseInt(h.slice(5, 7), 16),\n ];\n const ca = parseHex(a);\n const cb = parseHex(b);\n const r = Math.round(lerp(ca[0], cb[0], t));\n const g = Math.round(lerp(ca[1], cb[1], t));\n const bl = Math.round(lerp(ca[2], cb[2], t));\n return `#${((1 << 24) | (r << 16) | (g << 8) | bl).toString(16).slice(1)}`;\n}\n\nexport default function VoiceOrb({ state, getAmplitude, size = 200 }: VoiceOrbProps) {\n const config = useSiteConfig();\n const STATE_CONFIG = useMemo(() => buildStateConfig(config.colors), [config.colors]);\n const STATE_GLOW = useMemo(() => buildStateGlow(config.colors), [config.colors]);\n\n const svgRef = useRef<SVGSVGElement>(null);\n const rafRef = useRef<number>(0);\n const noise3D = useRef(createNoise3D());\n const prefersReduced = useReducedMotion();\n const reducedRef = useRef(prefersReduced);\n reducedRef.current = prefersReduced;\n\n // Animated (lerped) config values that transition smoothly between states\n const animRef = useRef({\n noiseSpeed: STATE_CONFIG.idle.noiseSpeed,\n noiseMag: STATE_CONFIG.idle.noiseMag,\n baseScale: STATE_CONFIG.idle.baseScale,\n breathAmp: STATE_CONFIG.idle.breathAmp,\n breathSpeed: STATE_CONFIG.idle.breathSpeed,\n rotation: STATE_CONFIG.idle.rotation,\n color0: STATE_CONFIG.idle.colors[0],\n color1: STATE_CONFIG.idle.colors[1],\n shimmer: 0,\n errorShake: 0,\n });\n\n const stateRef = useRef<OrbState>(state);\n stateRef.current = state;\n\n const stateGlowRef = useRef(STATE_GLOW);\n stateGlowRef.current = STATE_GLOW;\n\n const getAmplitudeRef = useRef(getAmplitude);\n getAmplitudeRef.current = getAmplitude;\n\n const stateConfigRef = useRef(STATE_CONFIG);\n stateConfigRef.current = STATE_CONFIG;\n\n const buildPath = useCallback(\n (time: number, a: typeof animRef.current): string => {\n const cx = size / 2;\n const cy = size / 2;\n const baseR = size * 0.35;\n const amp = getAmplitudeRef.current();\n\n // amplitude influences noise magnitude\n const mag = a.noiseMag + amp * 20;\n\n const points: [number, number][] = [];\n for (let i = 0; i < NUM_POINTS; i++) {\n const angle = (i / NUM_POINTS) * Math.PI * 2;\n const nx = Math.cos(angle);\n const ny = Math.sin(angle);\n const noiseVal = noise3D.current(nx * 1.5, ny * 1.5, time * a.noiseSpeed);\n const r = baseR + noiseVal * mag;\n points.push([cx + Math.cos(angle) * r, cy + Math.sin(angle) * r]);\n }\n\n // Build smooth closed path with cubic beziers\n let d = `M ${points[0][0]},${points[0][1]} `;\n for (let i = 0; i < NUM_POINTS; i++) {\n const curr = points[i];\n const next = points[(i + 1) % NUM_POINTS];\n const prev = points[(i - 1 + NUM_POINTS) % NUM_POINTS];\n const next2 = points[(i + 2) % NUM_POINTS];\n\n const cp1x = curr[0] + (next[0] - prev[0]) / 6;\n const cp1y = curr[1] + (next[1] - prev[1]) / 6;\n const cp2x = next[0] - (next2[0] - curr[0]) / 6;\n const cp2y = next[1] - (next2[1] - curr[1]) / 6;\n\n d += `C ${cp1x},${cp1y} ${cp2x},${cp2y} ${next[0]},${next[1]} `;\n }\n d += 'Z';\n return d;\n },\n [size]\n );\n\n useEffect(() => {\n let startTime: number | null = null;\n\n const tick = (timestamp: number) => {\n if (startTime === null) startTime = timestamp;\n const elapsed = (timestamp - startTime) / 1000;\n\n const target = stateConfigRef.current[stateRef.current];\n const a = animRef.current;\n\n // When prefers-reduced-motion is active, dampen animations significantly\n const rd = reducedRef.current ? 0.15 : 1;\n\n // Lerp all animated values toward target\n a.noiseSpeed = lerp(a.noiseSpeed, target.noiseSpeed * rd, LERP_SPEED);\n a.noiseMag = lerp(a.noiseMag, target.noiseMag * rd, LERP_SPEED);\n a.baseScale = lerp(a.baseScale, target.baseScale, LERP_SPEED);\n a.breathAmp = lerp(a.breathAmp, target.breathAmp * rd, LERP_SPEED);\n a.breathSpeed = lerp(a.breathSpeed, target.breathSpeed * rd, LERP_SPEED);\n a.rotation = lerp(a.rotation, target.rotation * rd, LERP_SPEED);\n a.shimmer = lerp(a.shimmer, target.shimmer ? (reducedRef.current ? 0 : 1) : 0, LERP_SPEED);\n a.color0 = lerpColor(a.color0, target.colors[0], LERP_SPEED);\n a.color1 = lerpColor(a.color1, target.colors[1], LERP_SPEED);\n\n // Error shake decays\n if (stateRef.current === 'error') {\n a.errorShake = lerp(a.errorShake, 1, 0.1);\n } else {\n a.errorShake = lerp(a.errorShake, 0, 0.08);\n }\n\n const svg = svgRef.current;\n if (!svg) {\n rafRef.current = requestAnimationFrame(tick);\n return;\n }\n\n // Breathing scale\n const breath = a.baseScale + Math.sin(elapsed * Math.PI * 2 * a.breathSpeed) * a.breathAmp;\n\n // Error shake offset\n const shakeX = a.errorShake * Math.sin(elapsed * 30) * 3 * (1 - Math.min(elapsed * 0.3, 1));\n\n // Rotation\n const rot = elapsed * a.rotation * 360;\n\n // Update transform\n const group = svg.querySelector<SVGGElement>('[data-orb-group]');\n if (group) {\n group.setAttribute(\n 'transform',\n `translate(${size / 2 + shakeX}, ${size / 2}) scale(${breath}) rotate(${rot}) translate(${-size / 2}, ${-size / 2})`\n );\n }\n\n // Update blob path\n const path = svg.querySelector<SVGPathElement>('[data-orb-path]');\n if (path) {\n path.setAttribute('d', buildPath(elapsed, a));\n }\n\n // Update gradient colors\n const stop0 = svg.querySelector<SVGStopElement>('[data-stop-0]');\n const stop1 = svg.querySelector<SVGStopElement>('[data-stop-1]');\n if (stop0) stop0.setAttribute('stop-color', a.color0);\n if (stop1) stop1.setAttribute('stop-color', a.color1);\n\n // Shimmer opacity\n const shimmerEl = svg.querySelector<SVGCircleElement>('[data-shimmer]');\n if (shimmerEl) {\n const shimmerOpacity = a.shimmer * (0.15 + Math.sin(elapsed * 6) * 0.1);\n shimmerEl.setAttribute('opacity', String(shimmerOpacity));\n }\n\n // Ambient glow — color follows state, opacity pulses with breath\n const glowEl = svg.querySelector<SVGCircleElement>('[data-orb-glow]');\n if (glowEl) {\n const amp = getAmplitudeRef.current();\n const glowPulse = 0.35 + Math.sin(elapsed * Math.PI * 2 * a.breathSpeed) * 0.15 + amp * 0.3;\n glowEl.setAttribute('opacity', String(Math.min(glowPulse, 1)));\n glowEl.setAttribute('fill', stateGlowRef.current[stateRef.current]);\n }\n\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafRef.current);\n }, [size, buildPath]);\n\n const idRef = useRef<string>(null);\n idRef.current ??= Math.random().toString(36).slice(2, 8);\n const gradientId = `orb-gradient-${idRef.current}`;\n const shimmerId = `orb-shimmer-${idRef.current}`;\n const glowFilterId = `orb-glow-${idRef.current}`;\n\n return (\n <svg\n ref={svgRef}\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n className=\"select-none\"\n style={{ overflow: 'visible' }}\n aria-hidden=\"true\"\n >\n <defs>\n <radialGradient id={gradientId} cx=\"40%\" cy=\"35%\" r=\"60%\">\n <stop data-stop-0 offset=\"0%\" stopColor={STATE_CONFIG.idle.colors[0]} />\n <stop data-stop-1 offset=\"100%\" stopColor={STATE_CONFIG.idle.colors[1]} />\n </radialGradient>\n <radialGradient id={shimmerId} cx=\"30%\" cy=\"30%\" r=\"50%\">\n <stop offset=\"0%\" stopColor=\"white\" stopOpacity=\"0.6\" />\n <stop offset=\"100%\" stopColor=\"white\" stopOpacity=\"0\" />\n </radialGradient>\n <filter id={glowFilterId} x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"18\" />\n </filter>\n </defs>\n {/* Ambient glow halo behind the orb */}\n <circle\n data-orb-glow\n cx={size / 2}\n cy={size / 2}\n r={size * 0.38}\n fill={STATE_GLOW['idle']}\n opacity=\"0.5\"\n filter={`url(#${glowFilterId})`}\n />\n <g data-orb-group>\n <path data-orb-path fill={`url(#${gradientId})`} />\n <circle\n data-shimmer\n cx={size / 2}\n cy={size / 2}\n r={size * 0.3}\n fill={`url(#${shimmerId})`}\n opacity=\"0\"\n />\n </g>\n </svg>\n );\n}\n","const AGENT_FAB_CSS = `\n@keyframes agent-fab-rotate {\n from { --agent-angle: 0deg; }\n to { --agent-angle: 360deg; }\n}\n@property --agent-angle {\n syntax: '<angle>';\n initial-value: 0deg;\n inherits: false;\n}\n.agent-fab-border {\n position: relative;\n border-radius: 50%;\n padding: 3px;\n background: conic-gradient(from var(--agent-angle), var(--agent-primary, #db2129) 0%, #34d399 50%, var(--agent-primary, #db2129) 100%);\n animation: agent-fab-rotate 3s linear infinite;\n}\n.agent-fab-border-inner {\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n overflow: hidden;\n width: 100%;\n height: 100%;\n background: #fff;\n}\n.agent-fab-border-inner img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: 50%;\n}\n@media (prefers-reduced-motion: reduce) {\n .agent-fab-border { animation: none; }\n}\n.voice-msg-group:hover .voice-feedback-pill { opacity: 1 !important; }\n.voice-feedback-pill:hover { color: rgba(0,0,0,0.5) !important; border-color: rgba(0,0,0,0.2) !important; }`;\n\nlet injected = false;\nexport function injectAgentFabCSS() {\n if (injected || typeof document === 'undefined') return;\n const style = document.createElement('style');\n style.textContent = AGENT_FAB_CSS;\n document.head.appendChild(style);\n injected = true;\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { cn } from '../utils';\nimport {\n MAX_VISIBLE_MESSAGES,\n MAX_TEXT_LENGTH,\n TYPEWRITER_DELAY_MS,\n MIN_DISPLAY_LENGTH,\n PANEL_MAX_VISIBLE_MESSAGES,\n PANEL_MAX_TEXT_LENGTH,\n DEFAULT_FONT_FAMILY,\n useSiteConfig,\n} from '@unctad-ai/voice-agent-core';\nimport type { VoiceMessage, ActionCategory } from '@unctad-ai/voice-agent-core';\nimport type { VoiceErrorType } from './VoiceErrorDisplay';\nimport { ArrowRight, PenLine, MousePointerClick, Search, Info, ChevronDown, Mic, Keyboard, Flag, Copy, Check } from 'lucide-react';\n\n/** Strip markdown/HTML artifacts, TTS paralinguistic tags, and emojis — preserves line breaks */\nfunction cleanForDisplay(text: string): string {\n return text\n .replace(/\\[(laugh|chuckle|sigh|gasp|cough|clear throat|sniff|groan|shush)\\]/gi, '') // TTS paralinguistic tags\n .replace(/\\*\\*(.*?)\\*\\*/g, '$1') // **bold** → bold\n .replace(/^\\s*\\*\\s+/gm, '- ') // * list items → dash lists\n .replace(/\\*(.*?)\\*/g, '$1') // *italic* → italic\n .replace(/`([^`]+)`/g, '$1') // `code` → code\n .replace(/^#{1,6}\\s+/gm, '') // # headings → plain text\n .replace(/<br\\s*\\/?>/gi, '\\n') // <br> → newline\n .replace(/<[^>]+>/g, '') // strip remaining HTML tags\n .replace(/\\|[-:\\s|]+\\|/g, '') // table separator rows\n .replace(/\\|/g, '\\n') // | cell dividers → newlines\n .replace(/\\p{Emoji_Presentation}|\\p{Extended_Pictographic}/gu, '') // strip emojis\n .replace(/[ \\t]{3,}/g, ' ') // collapse horizontal whitespace (preserve \\n)\n .replace(/\\n{3,}/g, '\\n\\n') // collapse 3+ newlines to double\n .replace(/^[\\s-]{3,}$/gm, '') // --- horizontal rules\n .trim();\n}\n\n/** Render cleaned text with line breaks and styled list items */\nfunction FormattedText({\n text,\n className,\n style,\n}: {\n text: string;\n className?: string;\n style?: React.CSSProperties;\n}) {\n const lines = text.split('\\n').filter((l) => l.trim().length > 0);\n\n if (lines.length <= 1) {\n return (\n <p className={className} style={style}>\n {text}\n </p>\n );\n }\n\n return (\n <div className={className} style={style}>\n {lines.map((line, i) => {\n const trimmed = line.trim();\n const isListItem = /^\\d+[.)]\\s/.test(trimmed) || /^[-]\\s/.test(trimmed);\n return (\n <p\n key={i}\n style={{\n marginTop: i === 0 ? 0 : isListItem ? 4 : 8,\n paddingLeft: isListItem ? 8 : 0,\n }}\n >\n {trimmed}\n </p>\n );\n })}\n </div>\n );\n}\n\ninterface VoiceTranscriptProps {\n messages: VoiceMessage[];\n isTyping: boolean;\n /** When true, uses minimal text layout (no glass background) for the panel */\n variant?: 'overlay' | 'panel';\n /** When set, replaces the empty-state placeholder with a prominent error message */\n voiceError?: VoiceErrorType;\n /** Current voice state — used for contextual empty state */\n voiceState?: string;\n /** Callback to start mic from empty state */\n onStartMic?: () => void;\n /** Callback to switch to keyboard mode from empty state */\n onSwitchToKeyboard?: () => void;\n /** Callback when user reports a bad assistant response */\n onReport?: (turnNumber: number, assistantMessage: string, userMessage?: string) => void;\n /** Map of turn numbers to ticket IDs for sent feedback */\n feedbackSentTurns?: Record<number, string>;\n /** Callback to submit a text message (for suggested prompt chips) */\n onTextSubmit?: (text: string) => void;\n}\n\n/** Progressively reveals words while preserving FormattedText structure */\nfunction TypewriterFormattedText({\n text,\n className,\n style,\n}: {\n text: string;\n className?: string;\n style?: React.CSSProperties;\n}) {\n const [visibleWords, setVisibleWords] = useState(0);\n const words = text.split(' ');\n\n useEffect(() => {\n setVisibleWords(0);\n if (words.length === 0) return;\n\n let i = 0;\n const interval = setInterval(() => {\n i++;\n setVisibleWords(i);\n if (i >= words.length) clearInterval(interval);\n }, TYPEWRITER_DELAY_MS);\n\n return () => clearInterval(interval);\n }, [text, words.length]);\n\n const partialText = words.slice(0, visibleWords).join(' ');\n return <FormattedText text={partialText} className={className} style={style} />;\n}\n\n// ---------------------------------------------------------------------------\n// Action Badge — colors aligned to design system\n// ---------------------------------------------------------------------------\n\n// Subtle tints from project palette — same low-opacity family, gentle differentiation\nconst ACTION_CATEGORY_STYLES: Record<\n ActionCategory,\n { bg: string; border: string; text: string; Icon: typeof ArrowRight }\n> = {\n navigation: {\n bg: 'rgba(45,134,89,0.07)',\n border: 'rgba(45,134,89,0.14)',\n text: 'rgba(31,110,71,0.75)',\n Icon: ArrowRight,\n },\n form: {\n bg: 'rgba(110,114,138,0.07)',\n border: 'rgba(110,114,138,0.14)',\n text: 'rgba(85,88,102,0.75)',\n Icon: PenLine,\n },\n ui: {\n bg: 'rgba(141,145,168,0.07)',\n border: 'rgba(141,145,168,0.14)',\n text: 'rgba(85,88,102,0.75)',\n Icon: MousePointerClick,\n },\n search: {\n bg: 'rgba(219,33,41,0.05)',\n border: 'rgba(219,33,41,0.11)',\n text: 'rgba(168,26,31,0.7)',\n Icon: Search,\n },\n info: {\n bg: 'rgba(172,176,195,0.08)',\n border: 'rgba(172,176,195,0.14)',\n text: 'rgba(110,114,138,0.7)',\n Icon: Info,\n },\n};\n\nconst BADGE_CONTAINER_STYLE: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'flex-start',\n};\nconst BADGE_TRANSITION = { duration: 0.2, ease: 'easeOut' as const };\n\nfunction ActionBadge({ msg, count = 1 }: { msg: VoiceMessage; count?: number }) {\n const category = msg.action?.category ?? 'info';\n const styles = ACTION_CATEGORY_STYLES[category];\n const { Icon } = styles;\n\n return (\n <motion.div\n initial={{ opacity: 0, scale: 0.92 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.92 }}\n transition={BADGE_TRANSITION}\n style={BADGE_CONTAINER_STYLE}\n role=\"status\"\n aria-label={count > 1 ? `${msg.text} (${count} times)` : msg.text}\n >\n <span\n className=\"inline-flex items-center gap-1.5 rounded-full\"\n style={{\n padding: '3px 10px',\n fontSize: '11px',\n fontWeight: 500,\n lineHeight: '1.3',\n color: styles.text,\n backgroundColor: styles.bg,\n border: `1px solid ${styles.border}`,\n }}\n >\n <Icon size={11} strokeWidth={2.2} aria-hidden=\"true\" />\n {msg.text}\n {count > 1 && (\n <span\n className=\"inline-flex items-center justify-center rounded-full\"\n style={{\n minWidth: 16,\n height: 16,\n padding: '0 4px',\n fontSize: '10px',\n fontWeight: 600,\n lineHeight: 1,\n color: styles.text,\n backgroundColor: styles.text.replace(/[\\d.]+\\)$/, '0.10)'),\n }}\n >\n {count}x\n </span>\n )}\n </span>\n </motion.div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Group consecutive action badges by action name\n// ---------------------------------------------------------------------------\n\ntype DisplayItem =\n | { type: 'message'; msg: VoiceMessage }\n | { type: 'action'; msg: VoiceMessage; count: number };\n\nfunction groupDisplayItems(messages: VoiceMessage[]): DisplayItem[] {\n const items: DisplayItem[] = [];\n for (const msg of messages) {\n if (msg.role !== 'action') {\n items.push({ type: 'message', msg });\n continue;\n }\n const prev = items[items.length - 1];\n if (prev?.type === 'action' && prev.msg.action?.name === msg.action?.name) {\n prev.count++;\n prev.msg = msg; // keep latest text/timestamp for display\n } else {\n items.push({ type: 'action', msg, count: 1 });\n }\n }\n return items;\n}\n\n/** Filter out noise, protocol leaks, and very short fragments */\nfunction isDisplayWorthy(msg: VoiceMessage): boolean {\n if (msg.role === 'action') return msg.text.trim().length > 0;\n const t = msg.text.trim();\n if (t.length < MIN_DISPLAY_LENGTH) return false;\n const alphaOnly = t.replace(/[\\s\\p{P}\\p{S}]+/gu, '');\n if (alphaOnly.length === 0) return false;\n return true;\n}\n\nfunction FeedbackPill({ isSent, ticketId, onReport }: {\n isSent: boolean;\n ticketId: string | null;\n onReport: () => void;\n}) {\n const [copied, setCopied] = useState(false);\n const [showTicket, setShowTicket] = useState(false);\n\n // Two-phase: show \"✓ Sent\" first, then fade to ticket ID after 2s\n useEffect(() => {\n if (!isSent) { setShowTicket(false); return; }\n const timer = setTimeout(() => setShowTicket(true), 2000);\n return () => clearTimeout(timer);\n }, [isSent]);\n\n const phase = !isSent ? 'idle' : showTicket ? 'ticket' : 'sent';\n\n return (\n <span\n role={phase === 'idle' ? 'button' : undefined}\n onClick={phase === 'idle' ? onReport : undefined}\n className=\"voice-feedback-pill\"\n style={{\n marginTop: 2,\n fontSize: 11,\n padding: '2px 8px',\n borderRadius: 8,\n border: phase === 'sent' ? '1px solid rgba(22,163,74,0.3)'\n : phase === 'ticket' ? '1px solid rgba(217,119,6,0.3)'\n : '1px solid rgba(0,0,0,0.12)',\n background: 'transparent',\n color: phase === 'sent' ? '#16a34a'\n : phase === 'ticket' ? '#92400e'\n : 'rgba(0,0,0,0.30)',\n cursor: phase === 'idle' ? 'pointer' : 'default',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 3,\n opacity: isSent ? 1 : 0,\n transition: 'opacity 0.15s, color 0.4s, border-color 0.4s',\n fontFamily: phase === 'ticket' ? 'monospace' : 'inherit',\n }}\n >\n {phase === 'sent' ? (\n <>\n <Check size={10} strokeWidth={2} />\n Sent\n </>\n ) : phase === 'ticket' && ticketId ? (\n <>\n Ticket {ticketId}\n <span\n role=\"button\"\n aria-label=\"Copy ticket ID\"\n onClick={() => {\n navigator.clipboard.writeText(ticketId).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n }).catch(() => {});\n }}\n style={{\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n marginLeft: 3,\n gap: 2,\n color: copied ? '#16a34a' : '#92400e',\n transition: 'color 0.15s',\n }}\n >\n {copied ? <><Check size={10} strokeWidth={2} /> Copied</> : <Copy size={10} strokeWidth={2} />}\n </span>\n </>\n ) : (\n <>\n <Flag size={10} strokeWidth={2} />\n Feedback\n </>\n )}\n </span>\n );\n}\n\nexport default function VoiceTranscript({\n messages,\n isTyping,\n variant = 'overlay',\n voiceError,\n voiceState,\n onStartMic,\n onSwitchToKeyboard,\n onReport,\n feedbackSentTurns,\n onTextSubmit,\n}: VoiceTranscriptProps) {\n const config = useSiteConfig();\n const fontFamily = config.fontFamily ?? DEFAULT_FONT_FAMILY;\n const assistantLabel = config.copilotName || 'Assistant';\n const { colors } = config;\n const containerRef = useRef<HTMLDivElement>(null);\n const isPanel = variant === 'panel';\n const maxVisible = isPanel ? PANEL_MAX_VISIBLE_MESSAGES : MAX_VISIBLE_MESSAGES;\n const maxTextLen = isPanel ? PANEL_MAX_TEXT_LENGTH : MAX_TEXT_LENGTH;\n const visible = messages.filter(isDisplayWorthy).slice(-maxVisible);\n\n // Track whether user has manually scrolled away from bottom\n const userScrolledRef = useRef(false);\n const lastMessageCountRef = useRef(0);\n const contentRef = useRef<HTMLDivElement>(null);\n const [showNewMessagePill, setShowNewMessagePill] = useState(false);\n\n // Detect manual scroll: if user scrolls up, stop auto-scrolling; clear pill when at bottom\n useEffect(() => {\n if (!isPanel) return;\n const el = containerRef.current;\n if (!el) return;\n const handleScroll = () => {\n const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 40;\n userScrolledRef.current = !atBottom;\n if (atBottom) setShowNewMessagePill(false);\n };\n el.addEventListener('scroll', handleScroll, { passive: true });\n return () => el.removeEventListener('scroll', handleScroll);\n }, [isPanel]);\n\n // Scroll to bottom on new messages, or show pill if user has scrolled away\n useEffect(() => {\n if (!isPanel) return;\n if (visible.length > lastMessageCountRef.current) {\n if (userScrolledRef.current) {\n setShowNewMessagePill(true);\n } else {\n requestAnimationFrame(() => {\n const el = containerRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n });\n }\n }\n lastMessageCountRef.current = visible.length;\n }, [visible.length, isPanel]);\n\n // Auto-scroll whenever content height changes (typewriter words, streaming, new messages)\n useEffect(() => {\n if (!isPanel) return;\n const contentEl = contentRef.current;\n const scrollEl = containerRef.current;\n if (!contentEl || !scrollEl) return;\n const observer = new ResizeObserver(() => {\n if (!userScrolledRef.current) {\n scrollEl.scrollTop = scrollEl.scrollHeight;\n }\n });\n observer.observe(contentEl);\n return () => observer.disconnect();\n }, [isPanel]);\n\n const scrollToBottom = () => {\n const el = containerRef.current;\n if (el) {\n el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' });\n userScrolledRef.current = false;\n setShowNewMessagePill(false);\n }\n };\n\n if (isPanel) {\n return (\n <div style={{ flex: 1, minHeight: 0, position: 'relative', fontFamily }}>\n <div\n ref={containerRef}\n style={{\n position: 'absolute',\n inset: 0,\n overflowY: 'auto',\n overscrollBehavior: 'contain',\n padding: '16px 16px 12px',\n maskImage:\n 'linear-gradient(to bottom, transparent 0%, black 8px, black calc(100% - 8px), transparent 100%)',\n WebkitMaskImage:\n 'linear-gradient(to bottom, transparent 0%, black 8px, black calc(100% - 8px), transparent 100%)',\n }}\n >\n <div ref={contentRef} style={{ display: 'flex', flexDirection: 'column', paddingBottom: 24 }}>\n <AnimatePresence mode=\"popLayout\">\n {groupDisplayItems(visible).map((item, idx, arr) => {\n if (item.type === 'action') {\n // Show assistant name label before first action in a group\n const prevIsAction = idx > 0 && arr[idx - 1].type === 'action';\n const showLabel = !prevIsAction;\n return (\n <motion.div\n key={item.msg.timestamp}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n marginTop: idx === 0 ? 0 : prevIsAction ? 4 : 12,\n }}\n >\n {showLabel && (\n <p\n className=\"uppercase tracking-wider\"\n style={{\n fontSize: '10px',\n fontWeight: 500,\n letterSpacing: '0.06em',\n color: 'rgba(0,0,0,0.35)',\n marginBottom: '4px',\n }}\n >\n {assistantLabel}\n </p>\n )}\n <ActionBadge msg={item.msg} count={item.count} />\n </motion.div>\n );\n }\n\n const { msg } = item;\n const isLast = idx === arr.length - 1;\n const isAI = msg.role === 'assistant';\n // Skip label when previous item was also from the same role (assistant or action)\n const prevItem = idx > 0 ? arr[idx - 1] : null;\n const prevIsAI = prevItem?.type === 'action' || (prevItem?.type === 'message' && prevItem.msg.role === 'assistant');\n const prevIsUser = prevItem?.type === 'message' && prevItem.msg.role === 'user';\n const showLabel = isAI ? !prevIsAI : !prevIsUser;\n\n const cleaned = cleanForDisplay(msg.text);\n const displayText =\n cleaned.length > maxTextLen\n ? cleaned.slice(0, maxTextLen).trimEnd() + '...'\n : cleaned;\n\n return (\n <motion.div\n key={msg.timestamp}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n className={isAI ? 'voice-msg-group' : undefined}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: isAI ? 'flex-start' : 'flex-end',\n marginTop: idx === 0 ? 0 : 12,\n }}\n >\n {showLabel && (\n <p\n className=\"uppercase tracking-wider\"\n style={{\n fontSize: '10px',\n fontWeight: 500,\n letterSpacing: '0.06em',\n color: isAI ? 'rgba(0,0,0,0.35)' : 'rgba(219,33,41,0.5)',\n marginBottom: '4px',\n }}\n >\n {isAI ? assistantLabel : 'You'}\n </p>\n )}\n <div\n style={{\n ...(isAI\n ? {\n backgroundColor: `${colors.primary}0D`,\n borderRadius: '14px 14px 14px 4px',\n padding: '10px 14px',\n maxWidth: '85%',\n }\n : {\n backgroundColor: 'rgba(0,0,0,0.04)',\n borderRadius: '14px 14px 4px 14px',\n padding: '10px 14px',\n maxWidth: '85%',\n }),\n }}\n >\n {isAI && isLast && isTyping ? (\n <TypewriterFormattedText\n text={displayText}\n\n style={{\n fontSize: '14px',\n fontWeight: 400,\n lineHeight: '1.45',\n color: '#1a1a1a',\n }}\n />\n ) : isAI && isLast && voiceState === 'PROCESSING' ? (\n null /* hide until typewriter starts to prevent flash */\n ) : (\n <FormattedText\n text={displayText}\n\n style={{\n fontSize: '14px',\n fontWeight: isAI ? 400 : 450,\n lineHeight: '1.45',\n color: isAI ? '#1a1a1a' : '#3d0a0b',\n }}\n />\n )}\n </div>\n {isAI && (!isLast || !isTyping) && onReport && (() => {\n const turnNumber = visible.slice(0, idx + 1).filter(m => m.role === 'assistant').length;\n const ticketId = feedbackSentTurns?.[turnNumber] ?? null;\n const isSent = ticketId !== null;\n return (\n <FeedbackPill\n isSent={isSent}\n ticketId={ticketId}\n onReport={() => {\n const userMsg = visible.slice(0, idx).reverse().find(m => m.role === 'user');\n onReport(turnNumber, msg.text, userMsg?.text);\n }}\n />\n );\n })()}\n </motion.div>\n );\n })}\n </AnimatePresence>\n\n {visible.length === 0 &&\n !isTyping &&\n (voiceError === 'llm_failed' || voiceError === 'network_error' ? (\n <motion.div\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.4, delay: 0.15 }}\n className=\"text-center\"\n style={{ paddingTop: '48px', paddingBottom: '16px' }}\n >\n <div\n className=\"mx-auto rounded-full flex items-center justify-center\"\n style={{\n width: 48,\n height: 48,\n backgroundColor: 'rgba(220, 38, 38, 0.08)',\n marginBottom: '14px',\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"rgba(220,38,38,0.6)\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" />\n <path d=\"M16.72 11.06A10.94 10.94 0 0 1 19 12.55\" />\n <path d=\"M5 12.55a10.94 10.94 0 0 1 5.17-2.39\" />\n <path d=\"M10.71 5.05A16 16 0 0 1 22.56 9\" />\n <path d=\"M1.42 9a15.91 15.91 0 0 1 4.7-2.88\" />\n <path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\" />\n <line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\" />\n </svg>\n </div>\n <p\n style={{\n fontSize: '15px',\n fontWeight: 600,\n color: 'rgba(0,0,0,0.7)',\n marginBottom: '6px',\n }}\n >\n Service offline\n </p>\n <p\n style={{\n fontSize: '13px',\n color: 'rgba(0,0,0,0.4)',\n lineHeight: '1.4',\n maxWidth: '240px',\n margin: '0 auto',\n }}\n >\n The AI assistant is currently unavailable. Please try again shortly.\n </p>\n </motion.div>\n ) : (\n <div style={{ paddingTop: 40 }}>\n <EmptyStateGraphic primaryColor={config.colors.primary} onTextSubmit={onTextSubmit} />\n </div>\n ))}\n\n {isTyping && visible.length === 0 && (\n <motion.p\n initial={{ opacity: 0 }}\n animate={{ opacity: 0.5 }}\n style={{ color: 'rgba(0,0,0,0.4)', fontSize: '14px' }}\n >\n ...\n </motion.p>\n )}\n </div>\n </div>\n <AnimatePresence>\n {showNewMessagePill && (\n <motion.button\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.18 }}\n onClick={scrollToBottom}\n style={{\n position: 'absolute',\n bottom: 8,\n left: '50%',\n transform: 'translateX(-50%)',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n padding: '5px 12px 5px 10px',\n fontSize: 11,\n fontWeight: 500,\n color: 'rgba(0,0,0,0.6)',\n backgroundColor: 'rgba(255,255,255,0.92)',\n border: '1px solid rgba(0,0,0,0.08)',\n borderRadius: 9999,\n boxShadow: '0 2px 8px rgba(0,0,0,0.1)',\n cursor: 'pointer',\n backdropFilter: 'blur(8px)',\n WebkitBackdropFilter: 'blur(8px)',\n zIndex: 1,\n }}\n >\n <ChevronDown size={12} strokeWidth={2.5} />\n New message\n </motion.button>\n )}\n </AnimatePresence>\n </div>\n );\n }\n\n // Original overlay variant (unchanged)\n return (\n <div\n ref={containerRef}\n className=\"relative w-full max-w-md text-center rounded-2xl overflow-hidden\"\n style={{ fontFamily }}\n >\n {/* Glass refraction layer */}\n <div\n className=\"absolute inset-0 rounded-2xl\"\n style={{\n backdropFilter: 'blur(2px)',\n WebkitBackdropFilter: 'blur(2px)',\n filter: 'url(#liquid-glass-orb)',\n isolation: 'isolate',\n }}\n />\n {/* Glass surface */}\n <div\n className=\"absolute inset-0 rounded-2xl\"\n style={{\n backgroundColor: 'rgba(255, 255, 255, 0.6)',\n border: '1px solid rgba(255, 255, 255, 0.4)',\n boxShadow: '0 6px 24px rgba(0, 0, 0, 0.05), inset 0 0 20px -5px rgba(255, 255, 255, 0.5)',\n }}\n />\n {/* Specular highlight */}\n <div\n className=\"absolute inset-0 rounded-2xl pointer-events-none\"\n style={{\n background:\n 'linear-gradient(to bottom, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 40%)',\n }}\n />\n {/* Content */}\n <div className=\"relative flex flex-col gap-2 px-6 py-4\">\n <AnimatePresence mode=\"popLayout\">\n {groupDisplayItems(visible).map((item, idx, arr) => {\n if (item.type === 'action') {\n const prevIsAction = idx > 0 && arr[idx - 1].type === 'action';\n return (\n <div key={item.msg.timestamp} style={{ marginTop: prevIsAction ? -4 : 0 }}>\n <ActionBadge msg={item.msg} count={item.count} />\n </div>\n );\n }\n\n const { msg } = item;\n const isLatest = idx === arr.length - 1;\n const isAI = msg.role === 'assistant';\n const isFading = idx < arr.length - 1;\n\n const displayText =\n msg.text.length > maxTextLen\n ? msg.text.slice(0, maxTextLen).trimEnd() + '...'\n : msg.text;\n\n return (\n <motion.p\n key={msg.timestamp}\n initial={{ opacity: 0, y: 12 }}\n animate={{ opacity: isFading ? 0.5 : 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n transition={{ duration: 0.3, ease: 'easeOut' }}\n className={cn('text-lg leading-relaxed', isAI ? '' : 'italic')}\n style={{\n color: isAI ? '#1a1a1a' : 'rgba(0,0,0,0.7)',\n }}\n >\n {isAI && isLatest && isTyping ? (\n <TypewriterFormattedText text={displayText} />\n ) : (\n displayText\n )}\n </motion.p>\n );\n })}\n </AnimatePresence>\n\n {visible.length === 0 && !isTyping && (\n <EmptyStateGraphic\n primaryColor={config.colors.primary}\n voiceState={voiceState}\n onStartMic={onStartMic}\n onSwitchToKeyboard={onSwitchToKeyboard}\n onTextSubmit={onTextSubmit}\n />\n )}\n\n {isTyping && visible.length === 0 && (\n <motion.p\n initial={{ opacity: 0 }}\n animate={{ opacity: 0.5 }}\n className=\"text-black/50 text-lg\"\n >\n ...\n </motion.p>\n )}\n </div>\n </div>\n );\n}\n\nfunction EmptyStateGraphic({ primaryColor, voiceState, onStartMic, onSwitchToKeyboard, onTextSubmit }: {\n primaryColor: string;\n voiceState?: string;\n onStartMic?: () => void;\n onSwitchToKeyboard?: () => void;\n onTextSubmit?: (text: string) => void;\n}) {\n const config = useSiteConfig();\n const isListening = voiceState === 'LISTENING' || voiceState === 'USER_SPEAKING';\n const greeting = config.greetingMessage || 'How can I help you today?';\n const prompts = config.suggestedPrompts ?? ['What services are available?', 'Help me with an application'];\n\n if (isListening) {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.3 }}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 6,\n paddingTop: 60,\n }}\n >\n <p style={{ fontSize: 16, fontWeight: 500, color: primaryColor, margin: 0, opacity: 0.7 }}>\n I'm listening...\n </p>\n <p style={{ fontSize: 12, color: 'rgba(0,0,0,0.3)', margin: 0 }}>\n Go ahead, I can hear you\n </p>\n </motion.div>\n );\n }\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, delay: 0.15 }}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 20,\n paddingTop: 48,\n }}\n >\n <p style={{ fontSize: 17, fontWeight: 500, color: primaryColor, margin: 0, opacity: 0.6, textAlign: 'center', lineHeight: 1.4 }}>\n {greeting}\n </p>\n\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center', maxWidth: 320 }}>\n {prompts.map((prompt) => (\n <button\n key={prompt}\n onClick={() => onTextSubmit?.(prompt)}\n style={{\n padding: '8px 16px',\n borderRadius: 18,\n border: '1px solid rgba(0,0,0,0.1)',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n fontFamily: 'inherit',\n fontSize: 13,\n color: 'rgba(0,0,0,0.55)',\n transition: 'background-color 0.15s, border-color 0.15s',\n lineHeight: 1.3,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = `${primaryColor}0A`;\n e.currentTarget.style.borderColor = `${primaryColor}33`;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent';\n e.currentTarget.style.borderColor = 'rgba(0,0,0,0.1)';\n }}\n >\n {prompt}\n </button>\n ))}\n </div>\n\n <div style={{ display: 'flex', gap: 12, marginTop: 4 }}>\n {onStartMic && (\n <button\n onClick={onStartMic}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 14px',\n borderRadius: 16,\n border: 'none',\n backgroundColor: `${primaryColor}0A`,\n cursor: 'pointer',\n fontFamily: 'inherit',\n fontSize: 12,\n color: 'rgba(0,0,0,0.4)',\n }}\n >\n <Mic style={{ width: 12, height: 12, opacity: 0.5 }} />\n or speak\n </button>\n )}\n </div>\n </motion.div>\n );\n}\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { ArrowUpRight } from 'lucide-react';\nimport { cn } from '../utils';\nimport type { VoiceToolResult } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceToolCardProps {\n result: VoiceToolResult | null;\n onAction?: (result: VoiceToolResult) => void;\n onDismiss?: () => void;\n /** When 'capsule', uses inline panel capsule style */\n variant?: 'overlay' | 'capsule';\n}\n\nconst AUTO_DISMISS_MS = 8000;\n\nexport default function VoiceToolCard({\n result,\n onAction,\n onDismiss,\n variant = 'overlay',\n}: VoiceToolCardProps) {\n useEffect(() => {\n if (!result) return;\n const timer = setTimeout(() => onDismiss?.(), AUTO_DISMISS_MS);\n return () => clearTimeout(timer);\n }, [result, onDismiss]);\n\n const isCapsule = variant === 'capsule';\n\n return (\n <AnimatePresence>\n {result && (\n <motion.div\n initial={{ opacity: 0, y: isCapsule ? 8 : 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: isCapsule ? 4 : 10 }}\n transition={{ duration: 0.3, ease: 'easeOut' }}\n className={cn(\n 'cursor-pointer transition-colors duration-200',\n isCapsule\n ? 'w-full rounded-xl px-4 py-2.5 flex items-center gap-3'\n : 'bg-white/10 backdrop-blur-md rounded-xl border border-white/20 px-5 py-4 max-w-sm w-full hover:bg-white/15'\n )}\n style={\n isCapsule\n ? {\n backgroundColor: 'rgba(0,0,0,0.04)',\n border: '1px solid rgba(0,0,0,0.08)',\n }\n : undefined\n }\n onClick={() => onAction?.(result)}\n onMouseEnter={\n isCapsule\n ? (e) => {\n (e.currentTarget as HTMLElement).style.backgroundColor = 'rgba(0,0,0,0.06)';\n }\n : undefined\n }\n onMouseLeave={\n isCapsule\n ? (e) => {\n (e.currentTarget as HTMLElement).style.backgroundColor = 'rgba(0,0,0,0.04)';\n }\n : undefined\n }\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onAction?.(result);\n }\n }}\n >\n {isCapsule ? (\n <>\n <ArrowUpRight\n className=\"shrink-0\"\n style={{ width: 14, height: 14, color: 'rgba(0,0,0,0.5)' }}\n />\n <span\n className=\"truncate\"\n style={{ fontSize: '13px', fontWeight: 500, color: 'rgba(0,0,0,0.7)' }}\n >\n {result.displayText}\n </span>\n </>\n ) : (\n <>\n <p className=\"text-white/50 text-xs uppercase tracking-wider mb-1\">{result.name}</p>\n <p className=\"text-white text-sm leading-relaxed\">{result.displayText}</p>\n </>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { Component } from 'react';\nimport type { ReactNode, ErrorInfo } from 'react';\nimport { cn } from '../utils';\nimport { AlertTriangle, RefreshCw } from 'lucide-react';\n\ninterface Props {\n children: ReactNode;\n onReset?: () => void;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\nexport default class VoiceErrorBoundary extends Component<Props, State> {\n state: State = { hasError: false, error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error('Voice component error:', error, info.componentStack);\n }\n\n handleReset = () => {\n this.setState({ hasError: false, error: null });\n this.props.onReset?.();\n };\n\n render() {\n if (this.state.hasError) {\n return (\n <div className=\"flex flex-col items-center justify-center gap-4 p-8 text-center\">\n <AlertTriangle className=\"h-10 w-10 text-red-400\" />\n <p className=\"text-white text-lg\">Something went wrong with the voice assistant.</p>\n <p className=\"text-white/50 text-sm max-w-sm\">\n {this.state.error?.message || 'An unexpected error occurred.'}\n </p>\n <button\n onClick={this.handleReset}\n className={cn(\n 'flex items-center gap-2 px-4 py-2',\n 'bg-white/10 backdrop-blur-md rounded-full',\n 'text-white text-sm hover:bg-white/20 transition-colors cursor-pointer'\n )}\n >\n <RefreshCw className=\"h-4 w-4\" />\n Try again\n </button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n","import { motion, AnimatePresence } from 'motion/react';\nimport { AlertTriangle, Hourglass, Mic, MicOff, VolumeX, Wifi, WifiOff } from 'lucide-react';\nimport { cn } from '../utils';\n\nexport type VoiceErrorType =\n | 'mic_denied'\n | 'mic_unavailable'\n | 'vad_load_failed'\n | 'stt_failed'\n | 'tts_failed'\n | 'network_error'\n | 'llm_failed'\n | 'speech_too_short'\n | 'not_addressed'\n | 'processing'\n | null;\n\ninterface VoiceErrorDisplayProps {\n error: VoiceErrorType;\n onDismiss: () => void;\n}\n\ntype Severity = 'error' | 'warning' | 'info';\n\nconst SEVERITY_STYLES: Record<\n Severity,\n { bg: string; border: string; icon: string; text: string; dismiss: string }\n> = {\n error: {\n bg: 'rgba(220, 38, 38, 0.08)',\n border: 'rgba(220, 38, 38, 0.15)',\n icon: 'text-red-500',\n text: 'text-red-700',\n dismiss: 'text-red-400 hover:text-red-600',\n },\n warning: {\n bg: 'rgba(217, 119, 6, 0.08)',\n border: 'rgba(217, 119, 6, 0.15)',\n icon: 'text-amber-500',\n text: 'text-amber-700',\n dismiss: 'text-amber-400 hover:text-amber-600',\n },\n info: {\n bg: 'rgba(0, 0, 0, 0.04)',\n border: 'rgba(0, 0, 0, 0.08)',\n icon: 'text-neutral-500',\n text: 'text-neutral-600',\n dismiss: 'text-neutral-400 hover:text-neutral-600',\n },\n};\n\nconst ERROR_CONFIG: Record<\n NonNullable<VoiceErrorType>,\n { icon: typeof AlertTriangle; title: string; severity: Severity }\n> = {\n mic_denied: {\n icon: MicOff,\n title: 'Microphone access denied',\n severity: 'error',\n },\n mic_unavailable: {\n icon: MicOff,\n title: 'No microphone found',\n severity: 'error',\n },\n vad_load_failed: {\n icon: AlertTriangle,\n title: 'Voice detection unavailable',\n severity: 'warning',\n },\n stt_failed: {\n icon: Mic,\n title: 'Voice input unavailable — use text',\n severity: 'warning',\n },\n tts_failed: {\n icon: AlertTriangle,\n title: 'Voice response unavailable',\n severity: 'warning',\n },\n network_error: {\n icon: WifiOff,\n title: 'Connection lost',\n severity: 'error',\n },\n llm_failed: {\n icon: Wifi,\n title: 'AI service unavailable',\n severity: 'error',\n },\n speech_too_short: {\n icon: Mic,\n title: \"Didn't catch that\",\n severity: 'info',\n },\n not_addressed: {\n icon: VolumeX,\n title: 'Not addressed to me',\n severity: 'info',\n },\n processing: {\n icon: Hourglass,\n title: 'Still processing...',\n severity: 'info',\n },\n};\n\nexport default function VoiceErrorDisplay({ error, onDismiss }: VoiceErrorDisplayProps) {\n return (\n <AnimatePresence>\n {error && (\n <motion.div\n initial={{ opacity: 0, y: 16, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: -8, scale: 0.95 }}\n transition={{ duration: 0.25 }}\n className={cn('max-w-xs mx-auto', 'rounded-xl', 'px-4 py-2')}\n style={{\n backgroundColor: SEVERITY_STYLES[ERROR_CONFIG[error].severity].bg,\n border: `1px solid ${SEVERITY_STYLES[ERROR_CONFIG[error].severity].border}`,\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n pointerEvents: 'auto',\n }}\n >\n {(() => {\n const config = ERROR_CONFIG[error];\n const styles = SEVERITY_STYLES[config.severity];\n const Icon = config.icon;\n return (\n <div className=\"flex items-center gap-2\">\n <Icon className={cn('h-4 w-4 shrink-0', styles.icon)} />\n <span className={cn('text-xs flex-1', styles.text)}>{config.title}</span>\n <button\n onClick={onDismiss}\n className={cn('text-xs transition-colors cursor-pointer', styles.dismiss)}\n >\n ×\n </button>\n </div>\n );\n })()}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport type { PipelineTimings } from '@unctad-ai/voice-agent-core';\nimport {\n DEFAULT_SHOW_PIPELINE_METRICS,\n DEFAULT_PIPELINE_METRICS_AUTO_HIDE_MS,\n} from '@unctad-ai/voice-agent-core';\n\nfunction fmt(ms: number): string {\n return ms >= 1000 ? `${(ms / 1000).toFixed(1)}s` : `${Math.round(ms)}ms`;\n}\n\nexport default function PipelineMetricsBar({\n timings,\n show = DEFAULT_SHOW_PIPELINE_METRICS,\n autoHideMs = DEFAULT_PIPELINE_METRICS_AUTO_HIDE_MS,\n}: {\n timings: PipelineTimings | null;\n show?: boolean;\n autoHideMs?: number;\n}) {\n const [visible, setVisible] = useState(false);\n const [display, setDisplay] = useState<PipelineTimings | null>(null);\n\n // React-recommended pattern: adjust state during render based on prop change.\n // https://react.dev/reference/react/useState#storing-information-from-previous-renders\n const [prevTimings, setPrevTimings] = useState(timings);\n if (timings !== prevTimings) {\n setPrevTimings(timings);\n if (timings) {\n setDisplay(timings);\n setVisible(true);\n }\n }\n\n // Auto-hide timer: only the setTimeout callback calls setState (async, not synchronous)\n useEffect(() => {\n if (!visible || autoHideMs <= 0) return;\n const timer = setTimeout(() => setVisible(false), autoHideMs);\n return () => clearTimeout(timer);\n }, [visible, display, autoHideMs]);\n\n if (!display || !show) return null;\n\n const pills: { label: string; value: string }[] = [];\n\n pills.push({ label: display.pipeline, value: '' });\n\n if (display.sttMs != null) pills.push({ label: 'STT', value: fmt(display.sttMs) });\n if (display.llmTotalMs != null) pills.push({ label: 'LLM', value: fmt(display.llmTotalMs) });\n if (display.ttsFirstChunkMs != null && display.ttsTotalMs != null) {\n pills.push({\n label: 'TTS',\n value: `${fmt(display.ttsFirstChunkMs)} / ${fmt(display.ttsTotalMs)}`,\n });\n } else if (display.ttsMs != null) {\n pills.push({ label: 'TTS', value: fmt(display.ttsMs) });\n }\n pills.push({ label: 'Total', value: fmt(display.totalMs) });\n\n return (\n <AnimatePresence>\n {visible && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 28 }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.2, ease: [0.25, 0.1, 0.25, 1] }}\n className=\"flex items-center gap-2 overflow-hidden select-none\"\n style={{\n height: 28,\n padding: '0 16px',\n fontSize: 11,\n fontFamily: 'inherit',\n fontVariantNumeric: 'tabular-nums',\n borderTop: '1px solid rgba(0,0,0,0.06)',\n background: 'rgba(0,0,0,0.03)',\n }}\n >\n {pills.map((p, i) =>\n i === 0 ? (\n <span\n key=\"type\"\n style={{\n color: 'rgba(0,0,0,0.35)',\n fontWeight: 500,\n textTransform: 'uppercase',\n fontSize: 10,\n letterSpacing: '0.04em',\n }}\n >\n {p.label}\n </span>\n ) : (\n <span key={p.label} className=\"inline-flex items-center gap-1\">\n <span style={{ color: 'rgba(0,0,0,0.4)' }}>{p.label}</span>\n <span style={{ color: 'rgba(0,0,0,0.65)', fontWeight: 500 }}>{p.value}</span>\n </span>\n )\n )}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { useEffect, useRef } from 'react';\nimport type { OrbState } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceA11yAnnouncerProps {\n isOpen: boolean;\n orbState: OrbState;\n}\n\nconst STATE_ANNOUNCEMENTS: Record<OrbState, string> = {\n idle: 'Voice assistant ready',\n listening: 'Listening for your question',\n processing: 'Processing your request',\n speaking: 'Assistant is responding',\n error: 'An error occurred',\n};\n\nexport default function VoiceA11yAnnouncer({ isOpen, orbState }: VoiceA11yAnnouncerProps) {\n const prevOpen = useRef(isOpen);\n const prevState = useRef(orbState);\n const announceRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!announceRef.current) return;\n\n if (isOpen && !prevOpen.current) {\n announceRef.current.textContent =\n 'Voice assistant opened. Press Escape to close. Use Ctrl+Shift+V to toggle.';\n } else if (!isOpen && prevOpen.current) {\n announceRef.current.textContent = 'Voice assistant closed';\n } else if (isOpen && orbState !== prevState.current) {\n announceRef.current.textContent = STATE_ANNOUNCEMENTS[orbState];\n }\n\n prevOpen.current = isOpen;\n prevState.current = orbState;\n }, [isOpen, orbState]);\n\n return (\n <div\n ref={announceRef}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"sr-only\"\n role=\"status\"\n />\n );\n}\n","import { motion, AnimatePresence, useReducedMotion } from 'motion/react';\nimport { Mic } from 'lucide-react';\nimport { useSiteConfig } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceCopilotFABProps {\n onClick: () => void;\n isActive?: boolean;\n isOverlayOpen?: boolean;\n onMouseEnter?: () => void;\n}\n\nexport default function VoiceCopilotFAB({\n onClick,\n isActive,\n isOverlayOpen,\n onMouseEnter,\n}: VoiceCopilotFABProps) {\n const prefersReduced = useReducedMotion();\n const { colors } = useSiteConfig();\n\n return (\n <AnimatePresence>\n {!isOverlayOpen && (\n <motion.div\n key=\"voice-fab-wrapper\"\n initial={{ scale: 0, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0, opacity: 0 }}\n transition={{ duration: 0.25, ease: 'easeOut' }}\n className=\"fixed bottom-6 right-6 z-50\"\n >\n <motion.button\n onClick={onClick}\n onMouseEnter={onMouseEnter}\n animate={prefersReduced ? {} : { scale: [1, 1.15, 1] }}\n transition={\n prefersReduced\n ? {}\n : { scale: { duration: 1.5, repeat: Infinity, ease: 'easeInOut' } }\n }\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.95 }}\n className=\"relative rounded-full p-3 shadow-lg text-white transition-all cursor-pointer\"\n style={{ backgroundColor: colors.primary }}\n aria-label=\"Open voice assistant\"\n >\n {isActive ? (\n <span className=\"h-3 w-3 rounded-full bg-white animate-pulse\" />\n ) : (\n <Mic className=\"w-6 h-6\" />\n )}\n </motion.button>\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { Keyboard, Send, X } from 'lucide-react';\nimport { cn } from '../utils';\nimport { useSiteConfig } from '@unctad-ai/voice-agent-core';\nimport type { VoiceState } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceControlsProps {\n state: VoiceState;\n onTextSubmit: (text: string) => void;\n isListening: boolean;\n}\n\nconst STATE_LABELS: Record<VoiceState, string> = {\n IDLE: 'How can I help you?',\n LISTENING: \"I'm listening...\",\n USER_SPEAKING: 'Go ahead...',\n PROCESSING: 'Let me look into that...',\n AI_SPEAKING: \"Here's what I found...\",\n};\n\n/** Shared glass-pill style for control buttons */\nconst GLASS_PILL_BASE = cn(\n 'backdrop-blur-xl rounded-full',\n 'flex items-center justify-center',\n 'border border-white/15',\n 'transition-all duration-200 cursor-pointer',\n 'hover:border-white/30 hover:shadow-[0_0_16px_rgba(255,255,255,0.08)]'\n);\n\nexport default function VoiceControls({ state, onTextSubmit, isListening }: VoiceControlsProps) {\n const { colors } = useSiteConfig();\n const [showTextInput, setShowTextInput] = useState(false);\n const [text, setText] = useState('');\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (showTextInput) inputRef.current?.focus();\n }, [showTextInput]);\n\n const handleSubmit = () => {\n const trimmed = text.trim();\n if (!trimmed) return;\n onTextSubmit(trimmed);\n setText('');\n setShowTextInput(false);\n };\n\n return (\n <div className=\"w-full max-w-2xl mx-auto mt-auto pb-8 px-4\">\n <AnimatePresence mode=\"wait\">\n {showTextInput ? (\n <motion.div\n key=\"text-input\"\n initial={{ opacity: 0, y: 16, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 16, scale: 0.95 }}\n transition={{ duration: 0.25, ease: [0.22, 1, 0.36, 1] }}\n className={cn(\n 'rounded-full',\n 'flex items-center gap-4',\n 'border border-white/20',\n 'px-8 py-3'\n )}\n style={{\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(16px) saturate(1.2)',\n WebkitBackdropFilter: 'blur(16px) saturate(1.2)',\n }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && handleSubmit()}\n placeholder=\"Ask a question...\"\n className=\"flex-1 text-sm placeholder:text-white/40 min-w-0\"\n style={{\n color: 'white',\n background: 'none',\n border: 'none',\n outline: 'none',\n boxShadow: 'none',\n WebkitAppearance: 'none',\n padding: 0,\n }}\n />\n <motion.button\n onClick={handleSubmit}\n whileTap={{ scale: 0.9 }}\n className=\"rounded-full p-2 text-white transition-colors cursor-pointer\"\n style={{ backgroundColor: colors.primary }}\n aria-label=\"Send message\"\n >\n <Send className=\"h-4 w-4\" />\n </motion.button>\n <button\n onClick={() => {\n setShowTextInput(false);\n setText('');\n }}\n className=\"rounded-full p-2 text-white/60 hover:text-white hover:bg-white/10 transition-all cursor-pointer\"\n aria-label=\"Cancel text input\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </motion.div>\n ) : (\n <motion.div\n key=\"controls\"\n initial={{ opacity: 0, y: 16, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 16, scale: 0.95 }}\n transition={{ duration: 0.25, ease: [0.22, 1, 0.36, 1] }}\n className=\"flex items-center justify-center gap-3\"\n >\n {/* Mic status + keyboard — unified control bar */}\n <div\n className={cn(\n 'rounded-full',\n 'text-white text-sm font-medium',\n 'flex items-center gap-6',\n 'border border-white/20',\n 'pl-8 pr-4 py-1.5'\n )}\n style={{\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(16px) saturate(1.2)',\n WebkitBackdropFilter: 'blur(16px) saturate(1.2)',\n color: 'white',\n }}\n >\n {/* Pulse dot */}\n <span className=\"relative flex items-center justify-center w-3 h-3 ml-0.5\">\n {isListening && (\n <span\n className=\"absolute inset-0 rounded-full animate-ping\"\n style={{ backgroundColor: `${colors.primary}80` }}\n />\n )}\n <span\n className={cn(\n 'relative h-2.5 w-2.5 rounded-full transition-colors duration-300',\n )}\n style={isListening ? {\n backgroundColor: colors.primary,\n boxShadow: `0 0 8px ${colors.primary}99`,\n } : {\n backgroundColor: 'rgba(255,255,255,0.3)',\n }}\n />\n </span>\n {/* Animated label */}\n <AnimatePresence mode=\"wait\">\n <motion.span\n key={state}\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.2 }}\n className=\"pr-1\"\n >\n {STATE_LABELS[state]}\n </motion.span>\n </AnimatePresence>\n\n {/* Type button — integrated into the bar */}\n <button\n onClick={() => setShowTextInput(true)}\n className={cn(\n 'rounded-full p-2',\n 'text-white/60 hover:text-white',\n 'hover:bg-white/10',\n 'transition-all duration-200 cursor-pointer'\n )}\n aria-label=\"Type a message\"\n >\n <Keyboard className=\"h-4 w-4\" />\n </button>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n","import { useRef, useEffect, useState } from 'react';\nimport {\n DOT_RING_COUNT,\n DOT_RING_GAP,\n DOT_RING_BASE_RADIUS,\n DOT_RING_PEAK_RADIUS,\n DOT_RING_SMOOTHING,\n} from '@unctad-ai/voice-agent-core';\nimport type { OrbState } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceDotRingProps {\n analyserNode: AnalyserNode | null;\n state: OrbState;\n orbRadius: number;\n}\n\nconst STATE_COLORS: Record<OrbState, string> = {\n idle: 'rgba(59,130,246,0.6)',\n listening: 'rgba(219,33,41,0.8)',\n processing: 'rgba(245,158,11,0.7)',\n speaking: 'rgba(34,197,94,0.7)',\n error: 'rgba(220,38,38,0.6)',\n};\n\nexport default function VoiceDotRing({ analyserNode, state, orbRadius }: VoiceDotRingProps) {\n const dotsRef = useRef<(SVGCircleElement | null)[]>([]);\n const barsRef = useRef<Float32Array>(new Float32Array(DOT_RING_COUNT));\n const rafRef = useRef<number>(0);\n const colorRef = useRef(STATE_COLORS.idle);\n\n const [reducedMotion] = useState(\n () => window.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n\n const ringRadius = orbRadius + DOT_RING_GAP;\n const svgSize = (ringRadius + DOT_RING_PEAK_RADIUS + 2) * 2;\n const cx = svgSize / 2;\n const cy = svgSize / 2;\n\n useEffect(() => {\n const freqData = analyserNode ? new Uint8Array(analyserNode.frequencyBinCount) : null;\n\n const tick = () => {\n // Lerp color toward target\n colorRef.current = STATE_COLORS[state];\n\n if (analyserNode && freqData) {\n analyserNode.getByteFrequencyData(freqData);\n }\n\n for (let i = 0; i < DOT_RING_COUNT; i++) {\n const dot = dotsRef.current[i];\n if (!dot) continue;\n\n let targetVal = 0;\n if (freqData && freqData.length > 0) {\n const binIndex = Math.floor((i / DOT_RING_COUNT) * freqData.length);\n targetVal = freqData[binIndex] / 255;\n }\n\n barsRef.current[i] += (targetVal - barsRef.current[i]) * DOT_RING_SMOOTHING;\n\n const val = reducedMotion ? 0 : barsRef.current[i];\n const r = DOT_RING_BASE_RADIUS + val * (DOT_RING_PEAK_RADIUS - DOT_RING_BASE_RADIUS);\n const opacity = 0.3 + val * 0.5;\n\n dot.setAttribute('r', String(r));\n dot.setAttribute('opacity', String(opacity));\n dot.setAttribute('fill', colorRef.current);\n }\n\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafRef.current);\n }, [analyserNode, state, reducedMotion, ringRadius]);\n\n return (\n <svg\n width={svgSize}\n height={svgSize}\n viewBox={`0 0 ${svgSize} ${svgSize}`}\n className=\"absolute pointer-events-none\"\n style={{\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n }}\n aria-hidden=\"true\"\n >\n {Array.from({ length: DOT_RING_COUNT }, (_, i) => {\n const angle = (i / DOT_RING_COUNT) * Math.PI * 2 - Math.PI / 2;\n const x = cx + Math.cos(angle) * ringRadius;\n const y = cy + Math.sin(angle) * ringRadius;\n return (\n <circle\n key={i}\n ref={(el) => {\n dotsRef.current[i] = el;\n }}\n cx={x}\n cy={y}\n r={DOT_RING_BASE_RADIUS}\n fill={STATE_COLORS.idle}\n opacity={0.3}\n />\n );\n })}\n </svg>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { cn } from '../utils';\nimport { useSiteConfig } from '@unctad-ai/voice-agent-core';\n\nconst STORAGE_KEY = 'voice-onboarding-dismissed';\n\ninterface VoiceOnboardingProps {\n onTryNow: () => void;\n /** Custom description text shown in the onboarding tooltip */\n description?: string;\n}\n\nexport default function VoiceOnboarding({ onTryNow, description }: VoiceOnboardingProps) {\n const { colors } = useSiteConfig();\n const [show, setShow] = useState(false);\n\n useEffect(() => {\n const dismissed = localStorage.getItem(STORAGE_KEY);\n if (!dismissed) {\n // Small delay so FAB renders first\n const timer = setTimeout(() => setShow(true), 1500);\n return () => clearTimeout(timer);\n }\n }, []);\n\n const dismiss = () => {\n setShow(false);\n localStorage.setItem(STORAGE_KEY, 'true');\n };\n\n const handleTryNow = () => {\n dismiss();\n onTryNow();\n };\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n initial={{ opacity: 0, y: 8, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 8, scale: 0.95 }}\n transition={{ duration: 0.25, ease: 'easeOut' }}\n className={cn(\n 'fixed bottom-24 right-6 z-50',\n 'md:bottom-[104px] md:right-6',\n 'bg-white rounded-xl shadow-xl',\n 'border border-neutral-200',\n 'p-4 max-w-[280px]'\n )}\n role=\"tooltip\"\n >\n {/* Arrow pointing down to FAB */}\n <div className=\"absolute -bottom-2 right-6 w-4 h-4 bg-white border-b border-r border-neutral-200 rotate-45\" />\n\n <p className=\"text-sm text-neutral-700 leading-relaxed mb-3\">\n {description ?? 'Meet your AI assistant. Ask about services, permits, or opportunities.'}\n </p>\n <div className=\"flex gap-2\">\n <button\n onClick={handleTryNow}\n className={cn(\n 'text-white text-sm font-medium',\n 'rounded-lg px-3 py-1.5',\n 'transition-colors cursor-pointer'\n )}\n style={{ backgroundColor: colors.primary }}\n >\n Try it now\n </button>\n <button\n onClick={dismiss}\n className={cn(\n 'text-neutral-500 text-sm',\n 'rounded-lg px-3 py-1.5',\n 'hover:text-neutral-700 hover:bg-neutral-100',\n 'transition-colors cursor-pointer'\n )}\n >\n Maybe later\n </button>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { motion } from 'motion/react';\nimport { X } from 'lucide-react';\nimport { useVoiceAgent, voiceStateToOrbState } from '@unctad-ai/voice-agent-core';\nimport { IDLE_TIMEOUT_MS, WIND_DOWN_MS, EXIT_ANIMATION_MS } from '@unctad-ai/voice-agent-core';\nimport type { OrbState, VoiceToolResult } from '@unctad-ai/voice-agent-core';\nimport { useVoiceSettings } from '../contexts/VoiceSettingsContext';\nimport VoiceOrb from './VoiceOrb';\nimport VoiceWaveformCanvas from './VoiceWaveformCanvas';\nimport VoiceTranscript from './VoiceTranscript';\nimport VoiceToolCard from './VoiceToolCard';\nimport VoiceControls from './VoiceControls';\nimport VoiceErrorBoundary from './VoiceErrorBoundary';\nimport VoiceErrorDisplay from './VoiceErrorDisplay';\n\n/** Inline z-index guarantees stacking above all page elements */\nconst OVERLAY_Z = 2147483647;\n\n/** Liquid spring configs for entrance choreography */\nconst SPRING_BOUNCY = { type: 'spring' as const, damping: 20, stiffness: 180 };\nconst SPRING_SMOOTH = { type: 'spring' as const, damping: 28, stiffness: 160 };\n\n/** Exit easing — smooth start, accelerating pull */\nconst EXIT_EASE: [number, number, number, number] = [0.4, 0, 0.7, 0.2];\n\ninterface VoiceOverlayProps {\n isOpen: boolean;\n onClose: () => void;\n onStateChange?: (orbState: OrbState) => void;\n}\n\nfunction WiredOverlayContent({\n isMobile,\n onClose,\n onStateChange,\n isClosing,\n}: {\n isMobile: boolean;\n onClose: () => void;\n onStateChange?: (orbState: OrbState) => void;\n isClosing: boolean;\n}) {\n const orbSize = isMobile ? 120 : 200;\n const { settings, volumeRef, speedRef } = useVoiceSettings();\n\n const {\n state,\n start,\n stop,\n messages,\n isLLMLoading,\n getAmplitude,\n analyser,\n sendTextMessage,\n voiceError,\n dismissError,\n } = useVoiceAgent({ settings, volumeRef, speedRef });\n\n const [toolResult, setToolResult] = useState<VoiceToolResult | null>(null);\n\n const orbState = voiceStateToOrbState(state);\n\n // Notify parent of state changes for a11y announcer\n const onStateChangeRef = useRef(onStateChange);\n useEffect(() => {\n onStateChangeRef.current = onStateChange;\n });\n useEffect(() => {\n onStateChangeRef.current?.(orbState);\n }, [orbState]);\n\n // Start VAD when overlay mounts, force-stop on unmount (bypass debounce)\n const startRef = useRef(start);\n const stopRef = useRef(stop);\n useEffect(() => {\n startRef.current = start;\n }, [start]);\n useEffect(() => {\n stopRef.current = stop;\n }, [stop]);\n useEffect(() => {\n startRef.current();\n return () => stopRef.current(true);\n }, []);\n\n // Stop VAD immediately when exit starts\n useEffect(() => {\n if (isClosing) stop();\n }, [isClosing, stop]);\n\n // --- Idle timeout: auto-close after 30s of no user activity ---\n const [isWindingDown, setIsWindingDown] = useState(false);\n const idleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const windDownTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const onCloseRef = useRef(onClose);\n useEffect(() => {\n onCloseRef.current = onClose;\n });\n\n useEffect(() => {\n const clear = () => {\n if (idleTimerRef.current) clearTimeout(idleTimerRef.current);\n if (windDownTimerRef.current) clearTimeout(windDownTimerRef.current);\n idleTimerRef.current = null;\n windDownTimerRef.current = null;\n };\n\n if (isClosing || state === 'PROCESSING' || state === 'AI_SPEAKING') {\n clear();\n setIsWindingDown(false);\n return;\n }\n clear();\n setIsWindingDown(false);\n windDownTimerRef.current = setTimeout(() => {\n setIsWindingDown(true);\n }, IDLE_TIMEOUT_MS - WIND_DOWN_MS);\n idleTimerRef.current = setTimeout(() => {\n onCloseRef.current();\n }, IDLE_TIMEOUT_MS);\n return clear;\n }, [state, isClosing]);\n\n const handleTextSubmit = useCallback(\n (text: string) => {\n sendTextMessage(text);\n },\n [sendTextMessage]\n );\n\n const isListening = state === 'LISTENING' || state === 'USER_SPEAKING';\n\n return (\n <div\n className=\"flex flex-col items-center justify-center gap-6 h-full px-6\"\n style={{ pointerEvents: 'none' }}\n >\n {/* Orb + Waveform */}\n <motion.div\n initial={{ opacity: 0, scale: 0.15 }}\n animate={\n isClosing\n ? { opacity: 0, scale: 0 }\n : { opacity: isWindingDown ? 0.3 : 1, scale: isWindingDown ? 0.92 : 1 }\n }\n transition={\n isClosing\n ? { duration: 0.3, ease: EXIT_EASE, delay: 0.15 }\n : isWindingDown\n ? { duration: WIND_DOWN_MS / 1000, ease: 'easeOut' }\n : { ...SPRING_BOUNCY, delay: 0.1 }\n }\n className=\"relative flex items-center justify-center\"\n style={{ width: orbSize + 100, height: orbSize + 100, pointerEvents: 'auto' }}\n >\n <div\n className=\"absolute rounded-full\"\n style={{\n width: orbSize + 100,\n height: orbSize + 100,\n backdropFilter: 'blur(2px)',\n WebkitBackdropFilter: 'blur(2px)',\n filter: 'url(#liquid-glass-orb)',\n isolation: 'isolate',\n }}\n />\n <div\n className=\"absolute rounded-full pointer-events-none\"\n style={{\n width: orbSize + 100,\n height: orbSize + 100,\n backgroundColor: 'rgba(255, 255, 255, 0.02)',\n border: '1px solid rgba(255, 255, 255, 0.15)',\n boxShadow:\n '0 6px 24px rgba(0, 0, 0, 0.08), inset 0 0 20px -5px rgba(255, 255, 255, 0.3)',\n }}\n />\n <div\n className=\"absolute rounded-full pointer-events-none\"\n style={{\n width: orbSize + 100,\n height: orbSize + 100,\n background:\n 'radial-gradient(ellipse 70% 40% at 50% 12%, rgba(255,255,255,0.2) 0%, transparent 55%)',\n }}\n />\n <VoiceWaveformCanvas analyserNode={analyser} state={orbState} size={orbSize + 100} />\n <div className=\"absolute rounded-full\" style={{ width: orbSize, height: orbSize }}>\n <VoiceOrb state={orbState} getAmplitude={getAmplitude} size={orbSize} />\n </div>\n </motion.div>\n\n {/* Transcript */}\n <motion.div\n initial={{ opacity: 0, y: 24 }}\n animate={isClosing ? { opacity: 0, y: 16 } : { opacity: 1, y: 0 }}\n transition={\n isClosing\n ? { duration: 0.25, ease: EXIT_EASE, delay: 0.08 }\n : { ...SPRING_SMOOTH, delay: 0.3 }\n }\n >\n <VoiceTranscript messages={messages} isTyping={state === 'AI_SPEAKING' || isLLMLoading} />\n </motion.div>\n\n {/* Error display */}\n <div style={{ pointerEvents: 'auto' }}>\n <VoiceErrorDisplay error={voiceError} onDismiss={dismissError} />\n </div>\n\n {/* Tool result card */}\n <div style={{ pointerEvents: 'auto' }}>\n <VoiceToolCard result={toolResult} onDismiss={() => setToolResult(null)} />\n </div>\n\n {/* Controls */}\n <motion.div\n initial={{ opacity: 0, y: 48 }}\n animate={isClosing ? { opacity: 0, y: 30 } : { opacity: 1, y: 0 }}\n transition={\n isClosing\n ? { duration: 0.25, ease: EXIT_EASE, delay: 0 }\n : { ...SPRING_SMOOTH, delay: 0.4 }\n }\n className=\"w-full\"\n style={{ pointerEvents: 'auto' }}\n >\n <VoiceControls state={state} onTextSubmit={handleTextSubmit} isListening={isListening} />\n </motion.div>\n </div>\n );\n}\n\nfunction OverlayPortal({\n isOpen,\n isClosing,\n onClose,\n onStateChange,\n isMobile,\n}: VoiceOverlayProps & { isMobile: boolean; isClosing: boolean }) {\n if (!isOpen) return null;\n\n return createPortal(\n <>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"0\"\n height=\"0\"\n style={{ position: 'absolute', overflow: 'hidden' }}\n aria-hidden=\"true\"\n >\n <defs>\n <filter id=\"liquid-glass-orb\" x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n <feTurbulence\n type=\"fractalNoise\"\n baseFrequency=\"0.008 0.008\"\n numOctaves=\"2\"\n seed=\"92\"\n result=\"noise\"\n />\n <feGaussianBlur in=\"noise\" stdDeviation=\"2\" result=\"blurred_noise\" />\n <feDisplacementMap\n in=\"SourceGraphic\"\n in2=\"blurred_noise\"\n scale=\"50\"\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n />\n </filter>\n </defs>\n </svg>\n\n <motion.div\n key=\"voice-overlay-bg\"\n initial={{ opacity: 0 }}\n animate={isClosing ? { opacity: 0 } : { opacity: 1 }}\n transition={{\n duration: isClosing ? 0.35 : 0.4,\n ease: 'easeOut',\n delay: isClosing ? 0.2 : 0,\n }}\n aria-hidden=\"true\"\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: OVERLAY_Z,\n pointerEvents: 'none',\n backgroundColor: 'rgba(0, 0, 0, 0.15)',\n }}\n />\n\n <motion.div\n key=\"voice-overlay-gradient\"\n initial={{ opacity: 0, y: 80 }}\n animate={isClosing ? { opacity: 0, y: 60 } : { opacity: 1, y: 0 }}\n transition={\n isClosing\n ? { duration: 0.3, ease: EXIT_EASE, delay: 0.2 }\n : { duration: 0.6, ease: [0.22, 1, 0.36, 1], delay: 0.05 }\n }\n aria-hidden=\"true\"\n style={{\n position: 'fixed',\n bottom: 0,\n left: 0,\n right: 0,\n height: '28rem',\n zIndex: OVERLAY_Z,\n pointerEvents: 'none',\n background:\n 'linear-gradient(to top, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.15) 40%, transparent 100%)',\n }}\n />\n\n <div\n role=\"dialog\"\n aria-label=\"Voice Assistant\"\n aria-modal=\"false\"\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: OVERLAY_Z,\n pointerEvents: 'none',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <motion.button\n initial={{ opacity: 0, scale: 0.7 }}\n animate={isClosing ? { opacity: 0, scale: 0.7 } : { opacity: 1, scale: 1 }}\n transition={\n isClosing\n ? { duration: 0.2, ease: EXIT_EASE, delay: 0.06 }\n : { ...SPRING_SMOOTH, delay: 0.35 }\n }\n onClick={onClose}\n className=\"absolute top-6 right-6 flex items-center justify-center rounded-full transition-all duration-200 cursor-pointer hover:scale-110\"\n style={{\n pointerEvents: 'auto',\n zIndex: OVERLAY_Z,\n width: 44,\n height: 44,\n backgroundColor: 'rgba(255, 255, 255, 0.12)',\n border: '1px solid rgba(255, 255, 255, 0.25)',\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n color: 'rgba(255, 255, 255, 0.85)',\n }}\n aria-label=\"Close voice assistant\"\n >\n <X className=\"h-5 w-5\" />\n </motion.button>\n\n <div className=\"w-full h-full\" style={{ pointerEvents: 'none' }}>\n <WiredOverlayContent\n isMobile={isMobile}\n onClose={onClose}\n onStateChange={onStateChange}\n isClosing={isClosing}\n />\n </div>\n </div>\n </>,\n document.body\n );\n}\n\nfunction useIsMobile(breakpoint = 768) {\n const [isMobile, setIsMobile] = useState(\n () => window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches\n );\n useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mql.addEventListener('change', handler);\n return () => mql.removeEventListener('change', handler);\n }, [breakpoint]);\n return isMobile;\n}\n\nexport default function VoiceOverlay({ isOpen, onClose, onStateChange }: VoiceOverlayProps) {\n const isMobile = useIsMobile();\n const [isClosing, setIsClosing] = useState(false);\n const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleClose = useCallback(() => {\n if (isClosing) return;\n setIsClosing(true);\n closeTimerRef.current = setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, EXIT_ANIMATION_MS);\n }, [isClosing, onClose]);\n\n useEffect(() => {\n return () => {\n if (closeTimerRef.current != null) clearTimeout(closeTimerRef.current);\n };\n }, []);\n\n if (!isOpen) return null;\n\n return (\n <VoiceErrorBoundary onReset={onClose}>\n <OverlayPortal\n isOpen={isOpen}\n isClosing={isClosing}\n onClose={handleClose}\n onStateChange={onStateChange}\n isMobile={isMobile}\n />\n </VoiceErrorBoundary>\n );\n}\n","import { useRef, useEffect, useState } from 'react';\nimport {\n WAVEFORM_NUM_BARS,\n WAVEFORM_MIN_BAR_HEIGHT,\n WAVEFORM_MAX_BAR_HEIGHT,\n WAVEFORM_GAP,\n WAVEFORM_SMOOTHING,\n} from '@unctad-ai/voice-agent-core';\nimport type { OrbState } from '@unctad-ai/voice-agent-core';\n\ninterface VoiceWaveformCanvasProps {\n analyserNode: AnalyserNode | null;\n state: OrbState;\n size: number;\n}\n\nconst STATE_COLORS: Record<OrbState, [string, string]> = {\n idle: ['rgba(59,130,246,0.35)', 'rgba(96,165,250,0.12)'],\n listening: ['rgba(239,68,68,0.75)', 'rgba(251,191,36,0.3)'],\n processing: ['rgba(245,158,11,0.7)', 'rgba(251,191,36,0.3)'],\n speaking: ['rgba(34,197,94,0.7)', 'rgba(45,212,191,0.3)'],\n error: ['rgba(220,38,38,0.6)', 'rgba(153,27,27,0.25)'],\n};\n\nfunction lerpColor(a: string, b: string, t: number): string {\n // Parse rgba strings\n const parse = (s: string) => {\n const m = s.match(/[\\d.]+/g);\n return m ? m.map(Number) : [0, 0, 0, 0];\n };\n const ca = parse(a);\n const cb = parse(b);\n const r = ca.map((v, i) => v + (cb[i] - v) * t);\n return `rgba(${Math.round(r[0])},${Math.round(r[1])},${Math.round(r[2])},${r[3].toFixed(3)})`;\n}\n\nexport default function VoiceWaveformCanvas({\n analyserNode,\n state,\n size,\n}: VoiceWaveformCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const rafRef = useRef<number>(0);\n const barsRef = useRef<Float32Array>(new Float32Array(WAVEFORM_NUM_BARS));\n const colorRef = useRef({ inner: STATE_COLORS.idle[0], outer: STATE_COLORS.idle[1] });\n\n const [reducedMotion] = useState(\n () => window.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const dpr = window.devicePixelRatio || 1;\n canvas.width = size * dpr;\n canvas.height = size * dpr;\n ctx.scale(dpr, dpr);\n\n const freqData = analyserNode ? new Uint8Array(analyserNode.frequencyBinCount) : null;\n\n const tick = () => {\n ctx.clearRect(0, 0, size, size);\n\n // Lerp colors toward target state\n const target = STATE_COLORS[state];\n colorRef.current.inner = lerpColor(colorRef.current.inner, target[0], WAVEFORM_SMOOTHING);\n colorRef.current.outer = lerpColor(colorRef.current.outer, target[1], WAVEFORM_SMOOTHING);\n\n // Get frequency data\n if (analyserNode && freqData) {\n analyserNode.getByteFrequencyData(freqData);\n }\n\n const cx = size / 2;\n const cy = size / 2;\n const baseRadius = size * 0.35 + WAVEFORM_GAP;\n const baseBarWidth = Math.max(1.5, ((2 * Math.PI * baseRadius) / WAVEFORM_NUM_BARS) * 0.55);\n\n for (let i = 0; i < WAVEFORM_NUM_BARS; i++) {\n // Map frequency bin to target height\n let targetVal = 0;\n if (freqData && freqData.length > 0) {\n const binIndex = Math.floor((i / WAVEFORM_NUM_BARS) * freqData.length);\n targetVal = freqData[binIndex] / 255;\n }\n\n // Smooth interpolation\n barsRef.current[i] += (targetVal - barsRef.current[i]) * WAVEFORM_SMOOTHING;\n\n const effectiveMax = reducedMotion ? WAVEFORM_MIN_BAR_HEIGHT + 5 : WAVEFORM_MAX_BAR_HEIGHT;\n const barHeight =\n WAVEFORM_MIN_BAR_HEIGHT + barsRef.current[i] * (effectiveMax - WAVEFORM_MIN_BAR_HEIGHT);\n\n const angle = (i / WAVEFORM_NUM_BARS) * Math.PI * 2 - Math.PI / 2;\n const x1 = cx + Math.cos(angle) * baseRadius;\n const y1 = cy + Math.sin(angle) * baseRadius;\n const x2 = cx + Math.cos(angle) * (baseRadius + barHeight);\n const y2 = cy + Math.sin(angle) * (baseRadius + barHeight);\n\n // Draw bar with gradient\n const gradient = ctx.createLinearGradient(x1, y1, x2, y2);\n gradient.addColorStop(0, colorRef.current.inner);\n gradient.addColorStop(1, colorRef.current.outer);\n\n // Bars thicken with amplitude for a more alive feel\n const barWidth = baseBarWidth + barsRef.current[i] * baseBarWidth * 0.6;\n\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.strokeStyle = gradient;\n ctx.lineWidth = barWidth;\n ctx.lineCap = 'round';\n ctx.stroke();\n }\n\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafRef.current);\n }, [analyserNode, state, size, reducedMotion]);\n\n return (\n <canvas\n ref={canvasRef}\n style={{ width: size, height: size }}\n className=\"absolute inset-0 pointer-events-none\"\n aria-hidden=\"true\"\n />\n );\n}\n"],"mappings":"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","names":["useState","useEffect","useCallback","useRef","Component","motion","AnimatePresence","useReducedMotion","ChevronDown","Mic","MicOff","Keyboard","VolumeX","Flag","useSiteConfig","DEFAULT_FONT_FAMILY","useRef","useEffect","useState","useCallback","jsx","useSiteConfig","jsx","jsxs","lerp","useRef","useEffect","useState","useCallback","useState","useEffect","useRef","useSiteConfig","jsx","jsxs","useState","useEffect","useRef","showLabel","useEffect","motion","AnimatePresence","Fragment","jsx","jsxs","useEffect","AnimatePresence","motion","jsx","jsxs","motion","AnimatePresence","AlertTriangle","Mic","jsx","jsxs","AlertTriangle","Mic","AnimatePresence","motion","useState","useEffect","motion","AnimatePresence","jsx","jsxs","jsx","jsxs","VoiceSettingsView","useSiteConfig","motion","useReducedMotion","useState","useEffect","timer","AnimatePresence","VolumeX","Mic","MicOff","useRef","Keyboard","Flag","ChevronDown","useCallback","Component","DEFAULT_FONT_FAMILY","useEffect","useRef","jsx","motion","AnimatePresence","useReducedMotion","Mic","useSiteConfig","jsx","useState","useRef","useEffect","motion","AnimatePresence","Keyboard","X","useSiteConfig","jsx","jsxs","STATE_LABELS","useState","useRef","useEffect","AnimatePresence","motion","X","Keyboard","useRef","useEffect","useState","jsx","useState","useEffect","motion","AnimatePresence","useSiteConfig","jsx","jsxs","useState","useEffect","AnimatePresence","motion","useState","useEffect","useCallback","useRef","createPortal","motion","X","useVoiceAgent","voiceStateToOrbState","useRef","useEffect","useState","jsx","STATE_COLORS","lerpColor","Fragment","jsx","jsxs","useVoiceAgent","useState","voiceStateToOrbState","useRef","useEffect","useCallback","motion","createPortal","X"]}
|