chordia-ui 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"UpdatedInteractionDetails.cjs.js","sources":["../../src/components/UpdatedInteractionDetails/UpdatedCoachingSynthesisCard.jsx","../../src/components/UpdatedInteractionDetails/UpdatedInteractionContext.jsx","../../src/components/UpdatedInteractionDetails/UpdatedInteractionSignals.jsx","../../src/components/UpdatedInteractionDetails/UpdatedCompassScore.jsx","../../src/components/UpdatedInteractionDetails/UpdatedThreads.jsx","../../src/components/UpdatedInteractionDetails/UpdatedGuidance.jsx","../../src/components/UpdatedInteractionDetails/UpdatedTalkPatterns.jsx","../../src/components/UpdatedInteractionDetails/UpdatedProductsServices.jsx","../../src/components/UpdatedInteractionDetails/UpdatedInteractionDetails.jsx","../../src/components/UpdatedInteractionDetails/UpdatedInteractionScores.jsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { useMediaQuery } from \"../../utils/useMediaQuery\";\nimport {\n ShieldCheck,\n ThumbsUp,\n TrendingUp,\n Lightbulb,\n ArrowUp,\n ArrowDown,\n ArrowLeftRight,\n} from \"lucide-react\";\n\n/**\n * UpdatedCoachingSynthesisCard — \"COACHING SUMMARY\" section matching Figma node 113-7216.\n *\n * Props:\n * - data object Coaching synthesis response\n * - loading boolean Show shimmer loading state\n * - error string Error message to display\n *\n * Data shape:\n * - one_liner string\n * - context string\n * - strengths Array<{ text: string, quote?: string }>\n * - improvements Array<{ text: string, quote?: string }>\n * - overall string \"effective\" | \"strong\" | \"needs_improvement\" | \"mixed\"\n */\n\nconst COLORS = {\n strong: \"var(--Grey-Strong, #2E3236)\",\n muted: \"var(--Grey-Muted, #808183)\",\n absent: \"var(--Grey-absent, #D9D9D9)\",\n accent: \"var(--rail-orange, #C98A5A)\",\n itemText: \"var(--text-item, #3F3F3F)\",\n quoteLine: \"var(--border-warm, #B2AEA8)\",\n quoteText: \"var(--text-subtle-warm, #767473)\",\n iconBg: \"var(--surface-hover, #F3F7F7)\",\n};\n\nconst OVERALL_MAP = {\n effective: \"Effective\",\n strong: \"Strong\",\n needs_improvement: \"Needs Improvement\",\n mixed: \"Mixed\",\n};\n\nconst STYLE_ID = \"updated-coaching-synthesis-keyframes\";\n\nfunction ensureKeyframes() {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n @keyframes updated-coaching-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n @keyframes updated-coaching-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n }\n `;\n document.head.appendChild(style);\n}\n\n// Maps an `overall` value to the icon next to the label. Per the Figma\n// (node 1160-4631):\n// strong / effective → ArrowUp (improving)\n// needs_improvement → ArrowDown (declining)\n// mixed → ArrowLeftRight (two horizontal arrows)\n// `ThumbsUp` stays imported as a defensive fallback for unknown values so\n// the badge keeps rendering even if the API ships a new state we haven't\n// mapped yet.\nfunction OverallIcon({ overall }) {\n const common = { size: 14, color: COLORS.strong, strokeWidth: 1.5 };\n switch (overall) {\n case \"strong\":\n case \"effective\":\n return <ArrowUp {...common} />;\n case \"needs_improvement\":\n return <ArrowDown {...common} />;\n case \"mixed\":\n return <ArrowLeftRight {...common} />;\n default:\n return <ThumbsUp {...common} />;\n }\n}\n\nfunction OverallBadge({ overall }) {\n const label = OVERALL_MAP[overall] || (overall ? overall.replace(/_/g, \" \") : \"\");\n\n return (\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flexShrink: 0,\n }}>\n <span style={{\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.2,\n }}>\n Overall:\n </span>\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n }}>\n <OverallIcon overall={overall} />\n <span style={{\n fontSize: 13,\n fontWeight:600,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.2,\n }}>\n {label}\n </span>\n </div>\n </div>\n );\n}\n\nfunction getDisplayQuote(quote) {\n if (quote == null) return null;\n const s = String(quote).trim();\n if (!s || s.toLowerCase() === \"null\" || s.toLowerCase() === \"undefined\") return null;\n return s;\n}\n\nfunction SectionItem({ item }) {\n const text = typeof item === \"string\" ? item : item?.text || \"\";\n const quote = getDisplayQuote(typeof item === \"object\" ? item?.quote : null);\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 14 }}>\n <div style={{\n fontSize: 14,\n fontWeight: 600,\n color: COLORS.itemText,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.5,\n }}>\n {text}\n </div>\n {quote && (\n <div style={{\n display: \"flex\",\n gap: 10,\n }}>\n <div style={{\n width: 1,\n flexShrink: 0,\n alignSelf: \"stretch\",\n background: COLORS.quoteLine,\n }} />\n <div style={{\n fontSize: 14,\n fontWeight: 400,\n color: COLORS.quoteText,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.5,\n }}>\n &ldquo;{quote}&rdquo;\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction CoachingColumn({ icon, label, items }) {\n if (!items || items.length === 0) return null;\n\n return (\n <div style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n borderRadius: 12,\n }}>\n {/* Column header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n }}>\n {/* Icon with circular bg */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 24,\n height: 24,\n borderRadius: 9999,\n background: COLORS.iconBg,\n flexShrink: 0,\n }}>\n {icon}\n </div>\n <span style={{\n fontSize: 16,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: \"normal\",\n }}>\n {label}\n </span>\n </div>\n\n {/* Items */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 24 }}>\n {items.map((item, i) => (\n <SectionItem key={i} item={item} />\n ))}\n </div>\n </div>\n );\n}\n\nconst UpdatedCoachingSynthesisCard = ({ data, loading, error }) => {\n React.useEffect(() => { ensureKeyframes(); }, []);\n\n // Key Strengths and Improvements sit side by side on wide layouts, but\n // stack once the viewport drops below 900px so the two text columns aren't\n // crammed together on tablet/mobile. A viewport media query (not a\n // container measurement) is used deliberately: the detail panel can\n // overflow horizontally, so the card's own clientWidth stays wide even\n // when the visible area is narrow.\n const isNarrow = useMediaQuery(\"(max-width: 900px)\");\n\n // Loading state — ThreeCirclesSpinner\n if (loading) {\n return (\n <>\n <style>{`\n @keyframes coaching-spinner-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `}</style>\n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 12,\n padding: \"48px 24px\",\n }}>\n <svg\n width={48}\n height={48}\n viewBox=\"0 0 48 48\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ animation: \"coaching-spinner-spin 1.2s linear infinite\" }}\n >\n <path\n d=\"M43 24C43 26.4951 42.5086 28.9658 41.5537 31.271C40.5989 33.5762 39.1993 35.6707 37.435 37.435C35.6707 39.1993 33.5762 40.5989 31.271 41.5537C28.9658 42.5086 26.4951 43 24 43C21.5049 43 19.0342 42.5086 16.729 41.5537C14.4238 40.5989 12.3293 39.1993 10.565 37.435C8.80066 35.6707 7.40113 33.5762 6.44629 31.271C5.49145 28.9658 5 26.4951 5 24\"\n stroke=\"#F3E7C7\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M12 24C12 22.4241 12.3104 20.8637 12.9134 19.4078C13.5165 17.9519 14.4004 16.629 15.5147 15.5147C16.629 14.4004 17.9519 13.5165 19.4078 12.9134C20.8637 12.3104 22.4241 12 24 12C25.5759 12 27.1363 12.3104 28.5922 12.9134C30.0481 13.5165 31.371 14.4004 32.4853 15.5147C33.5996 16.629 34.4835 17.9519 35.0866 19.4078C35.6896 20.8637 36 22.4241 36 24\"\n stroke=\"#00A66E\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M20 24C20 24.5253 20.1035 25.0454 20.3045 25.5307C20.5055 26.016 20.8001 26.457 21.1716 26.8284C21.543 27.1999 21.984 27.4945 22.4693 27.6955C22.9546 27.8965 23.4747 28 24 28C24.5253 28 25.0454 27.8965 25.5307 27.6955C26.016 27.4945 26.457 27.1999 26.8284 26.8284C27.1999 26.457 27.4945 26.016 27.6955 25.5307C27.8965 25.0454 28 24.5253 28 24\"\n stroke=\"#F3E7C7\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n />\n </svg>\n <span style={{\n fontSize: 14,\n color: COLORS.muted,\n fontWeight: 500,\n textAlign: \"center\",\n }}>\n Synthesizing coaching summary...\n </span>\n </div>\n </>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div style={{\n fontSize: 14,\n color: COLORS.muted,\n }}>\n Unable to generate coaching summary.\n </div>\n );\n }\n\n // No data\n if (!data) return null;\n\n const strengths = data.strengths || [];\n const improvements = data.improvements || [];\n const oneLiner = typeof data.one_liner === \"string\" ? data.one_liner : data.one_liner?.text || \"\";\n const context = typeof data.context === \"string\" ? data.context : data.context?.text || \"\";\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n background: \"#FFF\",\n }}\n >\n {/* Section header — Figma: icon + \"Coaching Summary\" 16px / 700 / #2E3236 */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n }}>\n <ShieldCheck size={20} color={COLORS.accent} strokeWidth={2} />\n <span style={{\n fontSize: 16,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.2,\n textTransform: \"uppercase\",\n }}>\n Coaching Summary\n </span>\n </div>\n\n {/* One-liner — Figma: 14px / 600 / #2E3236 */}\n {oneLiner && (\n <div style={{\n fontSize: 14,\n fontWeight: 500,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.5,\n }}>\n {oneLiner}\n </div>\n )}\n\n {/* Context row + Overall badge — Figma: horizontal, space-between */}\n <div style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 16,\n justifyContent: \"space-between\",\n }}>\n {context && (\n <div style={{\n fontSize: 14,\n fontWeight: 400,\n color: COLORS.muted,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.5,\n flex: 1,\n }}>\n {context}\n </div>\n )}\n {data.overall && <OverallBadge overall={data.overall} />}\n </div>\n\n {/* Two-column layout: Key Strengths + Improvements */}\n {/* Figma: border-top 1px #D9D9D9, padding-top 24px, gap 24px */}\n {(strengths.length > 0 || improvements.length > 0) && (\n <div style={{\n display: \"flex\",\n flexDirection: isNarrow ? \"column\" : \"row\",\n gap: 24,\n paddingTop: 24,\n borderTop: `1px solid ${COLORS.absent}`,\n }}>\n <CoachingColumn\n icon={<TrendingUp size={14} color={COLORS.strong} strokeWidth={1.5} />}\n label=\"Key Strengths\"\n items={strengths}\n />\n <CoachingColumn\n icon={<Lightbulb size={14} color={COLORS.strong} strokeWidth={1.5} />}\n label=\"Improvements\"\n items={improvements}\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default UpdatedCoachingSynthesisCard;\n","import { useEffect, useRef, useState } from 'react';\nimport { ChevronDown, ChevronUp, Pencil } from 'lucide-react';\nimport { useMediaQuery } from '../../utils/useMediaQuery';\n\n/*\n * Figma node: 101-2385 / 495-803 (Context grid + More Details expandable)\n */\n\nfunction fmtDur(seconds) {\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\nconst ROW_STYLE = {\n display: 'flex',\n justifyContent: 'space-between',\n // Extra top padding gives more breathing room between a row's bottom border\n // and the next row's content below it.\n padding: '16px 8px 12px 8px',\n alignItems: 'center',\n gap: 24,\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: 'normal',\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n};\n\n// Renders a single-line value that ellipsis-truncates when it overflows its\n// container and, only in that case, sets the native `title` so hovering\n// surfaces the full string in the browser's built-in tooltip. Re-measures\n// on resize via ResizeObserver. Keeps the existing inline styles intact.\nfunction TruncatedValue({ text, style }) {\n const ref = useRef(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return undefined;\n const measure = () => setIsTruncated(el.scrollWidth > el.clientWidth);\n measure();\n if (typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(measure);\n observer.observe(el);\n return () => observer.disconnect();\n }, [text]);\n\n return (\n <span\n ref={ref}\n title={isTruncated && text != null ? String(text) : undefined}\n style={style}\n >\n {text}\n </span>\n );\n}\n\nconst COLUMN_STYLE = {\n display: 'flex',\n flexDirection: 'column',\n flex: '1 0 0',\n gap: 0,\n minWidth: 0,\n};\n\nconst UpdatedInteractionContext = ({\n meta = {},\n callPurpose = {},\n classification = {},\n dimensions = [],\n outcomeQuality = 'Neutral',\n onMoreDetails,\n moreDetails = [],\n resolutionOutcome,\n customerIntent,\n location,\n interactionId,\n canShowEditButton = false,\n onEditInteraction,\n // Agent view (Figma node 1798-5177): show every field flat in the two-column\n // grid with no \"More Details\" toggle / dropdown and no Edit button. The\n // fields that normally sit behind \"More Details\" (Resolution Outcome,\n // Customer Intent, Paradigm) plus a \"Number\" (interaction id) render inline.\n flatView = false,\n}) => {\n const [expanded, setExpanded] = useState(false);\n const moreDetailsRef = useRef(null);\n const isPhone = useMediaQuery('(max-width: 640px)');\n\n const duration = meta.duration_seconds != null ? fmtDur(meta.duration_seconds) : null;\n const messages = meta.message_count;\n const driver = callPurpose.interaction_driver;\n const paradigm = classification.interaction_paradigm;\n\n // Helper to find a dimension by key pattern\n const findDim = (keyPattern) => dimensions.find((d) => (d.key || '').toLowerCase().includes(keyPattern));\n\n // Auto-extract known dimensions — use explicit props first, then fall back to dimensions data\n const dimResolution = findDim('resolution_outcome');\n const dimIntent = findDim('customer_intent');\n const dimLocation = findDim('location');\n const dimOutcomeQuality = findDim('outcome_quality');\n\n const fmtValue = (v) => v ? v.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase()) : null;\n\n const resolvedOutcomeQuality = outcomeQuality !== 'Neutral' ? outcomeQuality\n : dimOutcomeQuality ? fmtValue(dimOutcomeQuality.value)\n : outcomeQuality;\n\n const resolvedResolutionOutcome = resolutionOutcome ?? (dimResolution ? fmtValue(dimResolution.value) : null);\n const resolvedCustomerIntent = customerIntent ?? (dimIntent ? fmtValue(dimIntent.value) : null);\n const resolvedLocation = location ?? (dimLocation ? fmtValue(dimLocation.value) : null);\n const resolvedParadigm = paradigm != null ? fmtValue(paradigm) : null;\n\n // Keys to exclude from the generic dimensions grid (they go in dedicated spots)\n const excludedKeys = new Set(['resolution_outcome', 'customer_intent', 'location', 'outcome_quality'].map((k) => `dim.${k}`));\n const filteredDimensions = dimensions.filter((d) => !excludedKeys.has(d.key));\n\n // Build paired rows: [left, right] per line\n const pairedRows = [];\n const rawPairs = [\n [\n duration != null ? { label: 'Duration', value: duration } : null,\n messages != null ? { label: 'Messages', value: messages } : null,\n ],\n [\n driver != null ? { label: 'Driver', value: driver } : null,\n // paradigm != null ? { label: 'Paradigm', value: paradigm } : null,\n resolvedLocation != null ? { label: 'Location', value: resolvedLocation } : null,\n ],\n ];\n\n // Add remaining dimension pairs (excluding the ones we extracted)\n for (let i = 0; i < filteredDimensions.length; i += 2) {\n const left = filteredDimensions[i] ? { label: filteredDimensions[i].display_name || filteredDimensions[i].label || filteredDimensions[i].key, value: fmtValue(filteredDimensions[i].value) } : null;\n const right = filteredDimensions[i + 1] ? { label: filteredDimensions[i + 1].display_name || filteredDimensions[i + 1].label || filteredDimensions[i + 1].key, value: fmtValue(filteredDimensions[i + 1].value) } : null;\n rawPairs.push([left, right]);\n }\n\n // Last row: Outcome Quality (left) + More details toggle (right)\n rawPairs.push([\n { label: 'Outcome Quality', value: resolvedOutcomeQuality },\n { isMoreDetails: true },\n ]);\n\n rawPairs.forEach((pair) => pairedRows.push(pair));\n\n // Build \"More Details\" expanded rows — auto-extracted from dimensions\n const detailRows = [\n resolvedResolutionOutcome != null && { label: 'Resolution Outcome', value: resolvedResolutionOutcome },\n resolvedCustomerIntent != null && { label: 'Customer Intent', value: resolvedCustomerIntent },\n // resolvedLocation != null && { label: 'Location', value: resolvedLocation },\n resolvedParadigm != null && { label: 'Paradigm', value: resolvedParadigm },\n ...(moreDetails || []),\n ].filter(Boolean);\n\n // Agent flat view (Figma 1798-5177): a single ordered list of every field,\n // chunked two-per-row, with no \"More Details\" toggle. Order matches the\n // design: Duration/Messages, Driver/Location, Outcome Quality/Paradigm,\n // Resolution Outcome/Customer Intent, then Number.\n const flatPairs = [];\n if (flatView) {\n const flatFields = [\n duration != null && { label: 'Duration', value: duration },\n messages != null && { label: 'Messages', value: messages },\n driver != null && { label: 'Driver', value: driver },\n resolvedLocation != null && { label: 'Location', value: resolvedLocation },\n { label: 'Outcome Quality', value: resolvedOutcomeQuality },\n resolvedParadigm != null && { label: 'Paradigm', value: resolvedParadigm },\n resolvedResolutionOutcome != null && { label: 'Resolution Outcome', value: resolvedResolutionOutcome },\n resolvedCustomerIntent != null && { label: 'Customer Intent', value: resolvedCustomerIntent },\n ...filteredDimensions.map((d) => ({\n label: d.display_name || d.label || d.key,\n value: fmtValue(d.value),\n })),\n ...(moreDetails || []),\n interactionId != null && interactionId !== '' && { label: 'Number', value: interactionId },\n ].filter(Boolean);\n for (let i = 0; i < flatFields.length; i += 2) {\n flatPairs.push([flatFields[i], flatFields[i + 1] || null]);\n }\n }\n\n const rowsToRender = flatView ? flatPairs : pairedRows;\n\n // Close \"More Details\" dropdown on outside click\n useEffect(() => {\n if (!expanded) return;\n\n const handleOutsideClick = (event) => {\n if (moreDetailsRef.current && !moreDetailsRef.current.contains(event.target)) {\n setExpanded(false);\n }\n };\n\n document.addEventListener('mousedown', handleOutsideClick);\n return () => document.removeEventListener('mousedown', handleOutsideClick);\n }, [expanded]);\n\n const renderRow = (item) => (\n <div\n key={item.label}\n style={ROW_STYLE}\n >\n <span style={{ color: 'var(--Grey-Strong, #2E3236)', whiteSpace: 'nowrap', flexShrink: 0 }}>\n {item.label}\n </span>\n <TruncatedValue\n text={item.value}\n style={{\n color: 'var(--Grey-Muted, #808183)',\n textAlign: 'right',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n minWidth: 0,\n // Constrain so the row's `space-between` actually clips the value\n // span (without `flex: 1`, very long strings stretched the row\n // instead of truncating).\n flex: 1,\n }}\n />\n </div>\n );\n\n const renderMoreDetailsToggle = () => (\n <div\n key=\"more-details\"\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n // Match the row top padding so the toggle aligns with the sibling\n // \"Outcome Quality\" row on the left instead of sitting higher.\n padding: '16px 8px 12px 8px',\n fontFamily: 'var(--font-sans)',\n borderBottom: 'none',\n minHeight: 33,\n }}\n >\n <button\n onClick={() => {\n setExpanded((p) => !p);\n if (onMoreDetails && !expanded) onMoreDetails();\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: 0,\n color: 'var(--Grey-Strong, #2E3236)',\n fontSize: 13,\n fontWeight: 500,\n lineHeight: 'normal',\n fontFamily: 'var(--font-sans)',\n whiteSpace: 'nowrap',\n flexShrink: 0,\n }}\n >\n <span>More Details</span>\n {expanded\n ? <ChevronUp size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n : <ChevronDown size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n }\n </button>\n\n {canShowEditButton && (\n <button\n onClick={onEditInteraction || (() => {})}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '5px 12px',\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 12,\n color: 'var(--Grey-Strong, #2E3236)',\n fontSize: 13,\n fontWeight: 500,\n lineHeight: 'normal',\n fontFamily: 'var(--font-sans)',\n cursor: 'pointer',\n flexShrink: 0,\n }}\n >\n <Pencil size={15} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, lineHeight: 'normal' }}>Edit</span>\n </button>\n )}\n </div>\n );\n\n return (\n <div\n ref={moreDetailsRef}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignSelf: 'stretch',\n gap: 0,\n position: 'relative',\n overflow: 'visible',\n }}\n >\n {/* Paired rows — two columns side by side */}\n {rowsToRender.map((pair, idx) => (\n <div\n key={idx}\n style={{\n display: 'flex',\n flexDirection: isPhone ? 'column' : 'row',\n alignItems: isPhone ? 'stretch' : 'center',\n gap: isPhone ? 8 : 24,\n alignSelf: 'stretch',\n flexWrap: 'nowrap',\n }}\n >\n {/* Left cell */}\n <div style={COLUMN_STYLE}>\n {pair[0] && !pair[0].isMoreDetails ? renderRow(pair[0]) : <div style={{ flex: 1 }} />}\n </div>\n\n {/* Right cell */}\n <div style={COLUMN_STYLE}>\n {pair[1] && !pair[1].isMoreDetails\n ? renderRow(pair[1])\n : pair[1]?.isMoreDetails\n ? renderMoreDetailsToggle()\n : <div style={{ flex: 1 }} />}\n </div>\n </div>\n ))}\n\n {/* More Details dropdown — absolute, full width, left-aligned */}\n {!flatView && expanded && detailRows.length > 0 && (\n <div\n style={{\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: 4,\n display: 'flex',\n width: 340,\n maxWidth: 'calc(100vw - 32px)',\n flexDirection: 'column',\n alignItems: 'flex-start',\n borderRadius: 4,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-White, #FFF)',\n boxShadow: '-2px 2px 2px 0 rgba(0, 0, 0, 0.25)',\n overflow: 'hidden',\n fontFamily: 'var(--font-sans)',\n zIndex: 50,\n }}\n >\n {/* Dropdown header */}\n <div style={{\n padding: '12px 16px',\n fontSize: 13,\n fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n alignSelf: 'stretch',\n }}>\n More details\n </div>\n\n {/* Detail rows */}\n {detailRows.map((row) => (\n <div\n key={row.label}\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 16px',\n gap: 24,\n fontSize: 13,\n fontWeight: 400,\n lineHeight: 'normal',\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n alignSelf: 'stretch',\n }}\n >\n <span style={{ color: 'var(--Grey-Strong, #2E3236)', whiteSpace: 'nowrap', flexShrink: 0 }}>\n {row.label}\n </span>\n <span style={{\n color: 'var(--Grey-Muted, #808183)',\n fontSize: 13,\n fontStyle: 'normal',\n fontWeight: 400,\n lineHeight: '120%',\n textAlign: 'right',\n }}>\n {row.value}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n\nexport default UpdatedInteractionContext;\n","import { useState } from 'react';\nimport { ChevronDown, ChevronUp, PlayCircle, PauseCircle, FileSignal, ScrollText } from 'lucide-react';\n\n/* Hover circle wrapper for icons */\nconst HoverIcon = ({ children, size = 28, onClick, title }) => {\n const [hovered, setHovered] = useState(false);\n return (\n <div\n title={title}\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: size,\n height: size,\n borderRadius: 9999,\n background: hovered ? 'var(--surface-hover, #F3F7F7)' : 'transparent',\n cursor: 'pointer',\n flexShrink: 0,\n transition: 'background 0.15s',\n }}\n >\n {children}\n </div>\n );\n};\n\n/*\n * Figma node: 222-672 (Signals accordion)\n *\n * Header: FileSignal icon in #F3F7F7 circle + \"Signals\" 15px/500 + \"N Signals Detected\" 14px/500\n *\n * Accordion Title (collapsed): horizontal, gap: 12, pad: 8 0, border-bottom: 1px #D9D9D9\n * Name: 14px/600/#0B0A0A, lh: 171%\n * Chevron: 20x20, stroke #767473\n *\n * Accordion Body (reason): horizontal, gap: 12, pad: 8 0, space-between\n * Reason: 14px/400/#767473, lh: 150%\n * Right: ScrollText icon 16x16 #808183 + time 13px/400/#808183\n *\n * Evidence (Frame 39): horizontal, gap: 8, pad: 8 0\n * Play circle: ~17px, stroke #808183\n * Quote: 13px/400/#2E3236, lh: 120%\n */\n\nconst UpdatedInteractionSignals = ({\n signals = { signals: [], present_count: 0, total_signals_evaluated: 0 },\n expandedSignals = new Set(),\n toggleSignal = () => {},\n playEvidence = () => {},\n highlightTurns = () => {},\n onShowInTranscript = () => {},\n timelinePlaying = false,\n currentTimeSeconds = 0,\n}) => {\n const signalList = signals?.signals ?? [];\n const presentCount = signals?.present_count ?? signalList.length;\n\n const fmtMs = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n };\n\n const isEvPlaying = (ev) =>\n timelinePlaying &&\n ev.start_ms != null &&\n currentTimeSeconds * 1000 >= ev.start_ms &&\n currentTimeSeconds * 1000 <= (ev.end_ms ?? ev.start_ms + 5000);\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n alignSelf: 'stretch',\n width: '100%',\n gap: 16,\n }}>\n {/* ── Header: icon + \"Signals\" + count ── */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n width: '100%',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: 'var(--surface-hover, #F3F7F7)',\n flexShrink: 0,\n }}>\n <FileSignal size={20} color=\"#2E3236\" strokeWidth={1.5} />\n </div>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flex: 1,\n }}>\n <span style={{\n fontSize: 16,\n fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--default-font-family)',\n }}>\n Signals\n </span>\n <span style={{\n fontSize: 14,\n fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--default-font-family)',\n }}>\n {presentCount} Signals Detected\n </span>\n </div>\n </div>\n\n {/* ── Signal list (accordion) ── */}\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignSelf: 'stretch',\n background: 'var(--Grey-White, #FFF)',\n gap: 8,\n }}>\n {signalList.length === 0 && (\n <div style={{\n padding: '8px 0',\n fontSize: 14,\n color: 'var(--Grey-Muted, #808183)',\n }}>\n No signals detected.\n </div>\n )}\n\n {signalList.map((signal, idx) => {\n const key = signal.key ?? signal.id ?? idx;\n const isExpanded = expandedSignals.has(key);\n const obsCount = signal.observations?.length ?? 0;\n\n return (\n <div\n key={key}\n id={`signal-${key}`}\n style={{\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n gap: 8,\n }}\n >\n {/* ── Accordion Title — signal row ── */}\n <button\n onClick={() => toggleSignal(key)}\n style={{\n display: 'flex',\n padding: '8px 0',\n alignItems: 'center',\n gap: 12,\n alignSelf: 'stretch',\n width: '100%',\n background: 'none',\n border: 'none',\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n cursor: 'pointer',\n }}\n >\n <span style={{\n flex: 1,\n textAlign: 'left',\n fontSize: 14,\n fontWeight: 600,\n color: 'var(--text-dark, #0B0A0A)',\n lineHeight: 1.71,\n }}>\n {signal.display_name || signal.key?.replace(/_/g, ' ')}\n {obsCount > 0 && (\n <span style={{\n fontWeight: 600,\n color: 'var(--text-dark, #0B0A0A)',\n marginLeft: 6,\n }}>\n ({obsCount})\n </span>\n )}\n </span>\n {isExpanded ? (\n <ChevronUp size={20} color=\"#767473\" />\n ) : (\n <ChevronDown size={20} color=\"#767473\" />\n )}\n </button>\n\n {/* ── Expanded: Observations ── */}\n {isExpanded && signal.observations?.length > 0 && (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignSelf: 'stretch',\n gap: 0,\n }}>\n {signal.observations.map((obs, obsIdx) => (\n <div\n key={obs.key ?? obsIdx}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignSelf: 'stretch',\n gap: 8,\n }}\n >\n {/* Accordion Body — reason + timestamp */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '8px 0',\n justifyContent: 'space-between',\n }}>\n <span style={{\n flex: 1,\n fontSize: 14,\n fontWeight: 400,\n color: 'var(--text-subtle-warm, #767473)',\n lineHeight: 1.5,\n }}>\n {obs.reason || obs.explanation}\n </span>\n {obs.evidence?.[0]?.start_ms != null && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n flexShrink: 0,\n }}\n >\n <HoverIcon\n size={28}\n title=\"Show in transcript\"\n onClick={(e) => {\n e.stopPropagation();\n onShowInTranscript(obs.evidence[0].start_ms);\n }}\n >\n <ScrollText size={16} color=\"#808183\" strokeWidth={1.5} />\n </HoverIcon>\n <span style={{\n fontSize: 13,\n fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n lineHeight: 1.2,\n whiteSpace: 'nowrap',\n }}>\n {fmtMs(obs.evidence[0].start_ms)}\n </span>\n </div>\n )}\n </div>\n\n {/* Evidence quotes — Frame 39 */}\n {obs.evidence?.map((ev, evIdx) => {\n const hasTimestamps = ev.start_ms != null && ev.end_ms != null;\n return ev.text && (\n <div\n key={evIdx}\n onClick={(e) => {\n e.stopPropagation();\n if (hasTimestamps) playEvidence(ev);\n }}\n onMouseEnter={() => highlightTurns(ev.turn_ids ?? [])}\n onMouseLeave={() => highlightTurns([])}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '8px 0',\n cursor: hasTimestamps ? 'pointer' : 'default',\n }}\n >\n {hasTimestamps && (\n <HoverIcon size={28}>\n {isEvPlaying(ev) ? (\n <PauseCircle\n size={17}\n color=\"var(--Grey-Muted, #808183)\"\n strokeWidth={1.5}\n />\n ) : (\n <PlayCircle\n size={17}\n color=\"var(--Grey-Muted, #808183)\"\n strokeWidth={1}\n />\n )}\n </HoverIcon>\n )}\n <span style={{\n fontSize: 13,\n fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n &ldquo;{ev.text}&rdquo;\n </span>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport default UpdatedInteractionSignals;\n","import React, { useState, useRef } from 'react';\nimport { Info } from 'lucide-react';\nimport { useMediaQuery } from '../../utils/useMediaQuery';\n\n/*\n * Figma node: 270-6494 (Compass Score card)\n *\n * Container: padding: 24px, border-radius: 8px, border: 1px solid #D9D9D9,\n * background: #FFF, gap: 24px, vertical\n *\n * Title: \"Compass Score\" 15px/700/#2E3236\n * Description: 14px/400/#808183\n *\n * Content: horizontal, gap: 48, center both axes\n * Left: Meter 243x200 (SVG from Figma export)\n * Right: Legends vertical, gap: 8, centered\n * Each: label 12px/400/#2E3236 + Info 14px stroke=#ACACAD\n * Score bar: 5 segments 22x6, gap: 2, filled=#2E3236, empty=#E3E1D7\n */\n\nconst COLORS = {\n strong: 'var(--Grey-Strong, #2E3236)',\n muted: 'var(--Grey-Muted, #808183)',\n absent: 'var(--Grey-absent, #D9D9D9)',\n white: 'var(--Grey-White, #FFF)',\n accent: 'var(--rail-orange, #C98A5A)',\n track: 'var(--rail-surface-2, #E3E1D7)',\n infoIcon: 'var(--color-input-border, #ACACAD)',\n};\n\n// Gauge using stroke-based semi-circle arcs — matching Figma node 270-6499\n// Compass score scale: 0.5 to 5.0 (supports 0.5 increments)\n// Visual scale is always 5 segments, where each segment represents 1 point.\nconst GaugeMeter = ({ score = 4, minScore = 0, maxScore = 5 }) => {\n const svgW = 243;\n const svgH = 130;\n const cx = svgW / 2;\n const cy = svgH - 7;\n const r = 85; // mid-radius of the arc\n const sw = 30; // stroke-width (thickness of the arc band)\n const totalSeg = 5; // always render 5 visual steps\n const numericScore = Number(score);\n const clampedScore = Number.isFinite(numericScore)\n ? Math.min(Math.max(numericScore, minScore), maxScore)\n : minScore;\n const filledUnits = maxScore > minScore\n ? ((clampedScore - minScore) / (maxScore - minScore)) * totalSeg\n : 0;\n const segDeg = 180 / totalSeg; // 36° per segment\n\n // Convert polar (degrees, 0°=right, CCW) to SVG x,y (Y-down)\n const toXY = (angleDeg) => {\n const rad = (angleDeg * Math.PI) / 180;\n return {\n x: cx + r * Math.cos(rad),\n y: cy - r * Math.sin(rad),\n };\n };\n\n // SVG arc from startDeg to endDeg (both in math convention: 0=right, 180=left)\n // We draw clockwise in SVG (sweep-flag=1) from higher angle to lower angle\n const strokeArc = (fromDeg, toDeg) => {\n const s = toXY(fromDeg);\n const e = toXY(toDeg);\n const large = (fromDeg - toDeg) > 180 ? 1 : 0;\n return `M ${s.x} ${s.y} A ${r} ${r} 0 ${large} 1 ${e.x} ${e.y}`;\n };\n\n const gap = 2; // degrees gap between segments\n\n return (\n <svg width=\"100%\" viewBox={`0 0 ${svgW} ${svgH}`} fill=\"none\" style={{ maxWidth: svgW }}>\n {/* Segments from left (180°) to right (0°) */}\n {Array.from({ length: totalSeg }, (_, i) => {\n const fromA = 180 - i * segDeg - (i > 0 ? gap / 2 : 0);\n const toA = 180 - (i + 1) * segDeg + (i < totalSeg - 1 ? gap / 2 : 0);\n const segmentFill = Math.max(0, Math.min(1, filledUnits - i));\n const pathD = strokeArc(fromA, toA);\n return (\n <g key={i}>\n {/* Base track segment */}\n <path\n d={pathD}\n stroke={COLORS.track}\n strokeWidth={sw}\n strokeLinecap=\"butt\"\n fill=\"none\"\n />\n {/* Filled overlay can be full or half (or any partial) */}\n {segmentFill > 0 && (\n <path\n d={pathD}\n stroke={COLORS.strong}\n strokeWidth={sw}\n strokeLinecap=\"butt\"\n fill=\"none\"\n pathLength={1}\n strokeDasharray={`${segmentFill} 1`}\n />\n )}\n </g>\n );\n })}\n </svg>\n );\n};\n\nconst ScoreBar = ({ value = 0, maxValue = 5 }) => {\n const numericValue = Number(value);\n const clampedValue = Number.isFinite(numericValue)\n ? Math.min(Math.max(numericValue, 0), maxValue)\n : 0;\n\n return (\n <div style={{ display: 'flex', gap: 2 }}>\n {Array.from({ length: maxValue }, (_, i) => {\n const segmentFill = Math.max(0, Math.min(1, clampedValue - i));\n return (\n <div\n key={i}\n style={{\n width: 22,\n height: 6,\n borderRadius: 1,\n background: COLORS.track,\n overflow: 'hidden',\n }}\n >\n {segmentFill > 0 && (\n <div\n style={{\n width: `${segmentFill * 100}%`,\n height: '100%',\n background: COLORS.strong,\n }}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n};\n\nconst LEGEND_TOOLTIPS = {\n 'CSAT': 'Predicted Customer Satisfaction',\n 'Resolution': 'Predicted Resolution: was the issue fully resolved?',\n 'Process Adherence': 'Process Adherence: Did the agent follow procedures?',\n 'Communication': 'Predicted Communication Quality: Clarity, Empathy, Professionalism',\n};\n\nconst InfoTooltip = ({ text, children }) => {\n const [show, setShow] = useState(false);\n const ref = useRef(null);\n const [pos, setPos] = useState({ top: 0, left: 0 });\n\n const handleEnter = () => {\n if (ref.current) {\n const rect = ref.current.getBoundingClientRect();\n setPos({\n top: rect.top - 8,\n left: rect.left + rect.width / 2,\n });\n }\n setShow(true);\n };\n\n return (\n <div\n ref={ref}\n style={{ position: 'relative', display: 'inline-flex' }}\n onMouseEnter={handleEnter}\n onMouseLeave={() => setShow(false)}\n >\n {children}\n {show && (\n <div style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n transform: 'translate(-50%, -100%)',\n display: 'flex',\n width: 'max-content',\n maxWidth: 300,\n padding: 10,\n alignItems: 'center',\n borderRadius: 4,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-Strong, #2E3236)',\n zIndex: 9999,\n pointerEvents: 'none',\n }}>\n <span style={{\n color: '#FFF',\n fontSize: 12,\n fontWeight: 400,\n lineHeight: '140%',\n }}>\n {text}\n </span>\n </div>\n )}\n </div>\n );\n};\n\nconst LegendItem = ({ label, value = 0, maxValue = 5 }) => (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n padding: 8,\n alignItems: 'flex-start',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n }}>\n <span style={{\n fontSize: 12,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 'normal',\n }}>\n {label}\n </span>\n <InfoTooltip text={LEGEND_TOOLTIPS[label] || label}>\n <Info size={14} color={COLORS.infoIcon} strokeWidth={1} style={{ cursor: 'pointer' }} />\n </InfoTooltip>\n </div>\n <ScoreBar value={value} maxValue={maxValue} />\n </div>\n);\n\nconst UpdatedCompassScore = ({\n score = 4,\n minScore = 0,\n maxScore = 5,\n predictedScore = 4,\n predictedLabel = 'Predicted Objective',\n description = '',\n // Outcome value in percent (0–100), rendered in round brackets next to the\n // score, e.g. \"4 (80%)\" — Figma node 1798-5168. Null hides the bracket.\n outcomePercent = null,\n legends = [\n { label: 'CSAT', value: 3 },\n { label: 'Resolution', value: 4 },\n { label: 'Process Adherence', value: 5 },\n { label: 'Communication', value: 3 },\n ],\n}) => {\n const isPhone = useMediaQuery('(max-width: 640px)');\n const numericScore = Number(score);\n const clampedScore = Number.isFinite(numericScore)\n ? Math.min(Math.max(numericScore, minScore), maxScore)\n : minScore;\n const displayScore = clampedScore.toFixed(1);\n // Drop a trailing \".0\" so whole scores read as \"4\" (matches Figma 1798-5168)\n // while half-steps like 3.5 keep their decimal.\n const scoreText = displayScore.endsWith('.0') ? displayScore.slice(0, -2) : displayScore;\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n padding: 24,\n borderRadius: 8,\n border: `1px solid ${COLORS.absent}`,\n background: COLORS.white,\n alignSelf: 'stretch',\n flex: 1,\n gap: 24,\n }}>\n {/* Section Title — left-aligned, vertical, gap: 8 */}\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n }}>\n <span style={{\n fontSize: 15,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n }}>\n Interaction Quality\n </span>\n <span style={{\n fontSize: 14,\n fontWeight: 400,\n color: COLORS.muted,\n fontFamily: 'var(--font-sans)',\n lineHeight: 'normal',\n }}>\n {description}\n </span>\n </div>\n\n {/* Content: Meter (left) + Legends (right) — stacks on phones with the\n gauge on top and the legend details below it. */}\n <div style={{\n display: 'flex',\n flexDirection: isPhone ? 'column' : 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 24,\n flex: 1,\n overflow: isPhone ? 'visible' : 'hidden',\n }}>\n {/* Left: Gauge + Pin + Score number.\n On phones the gauge goes full-width (capped at 243) and can shrink\n below 160 so it always fits the card with no horizontal scroll. */}\n <div style={{\n position: 'relative',\n maxWidth: 243,\n minWidth: isPhone ? 0 : 160,\n flex: isPhone ? '0 0 auto' : '0 1 243px',\n width: isPhone ? '100%' : undefined,\n flexDirection: 'column',\n alignItems: 'center',\n display: 'flex',\n }}>\n <GaugeMeter score={score} minScore={minScore} maxScore={maxScore} />\n\n {/* Compass pin — centered below gauge, needle rotates to point at score */}\n {(() => {\n // Pin sits at gauge center; needle rotates from 180° (score=0) to 0° (score=max)\n const pct = maxScore > minScore ? (clampedScore - minScore) / (maxScore - minScore) : 0;\n // SVG pin's default needle points to top-right (~45°)\n // We need: score=0 → needle points left (180°), score=max → needle points right (0°)\n // Target angle on gauge: 180 - pct*180\n // Pin default orientation: needle at ~45° from top → offset is 45\n // Rotation needed: -(targetAngle - 45) to align needle with gauge position\n const targetAngle = 180 - pct * 180;\n const rotateDeg = -(targetAngle - 45);\n return (\n <svg\n width=\"34\" height=\"35\" viewBox=\"0 0 34 35\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n marginTop: -24,\n transform: `rotate(${rotateDeg}deg)`,\n transformOrigin: 'center center',\n }}\n >\n <path d=\"M16 25.2169C19.958 25.2169 23.1667 22.0083 23.1667 18.0503C23.1667 14.0922 19.958 10.8836 16 10.8836C12.042 10.8836 8.83334 14.0922 8.83334 18.0503C8.83334 22.0083 12.042 25.2169 16 25.2169Z\" fill=\"var(--rail-orange, #C98A5A)\" />\n <path fillRule=\"evenodd\" clipRule=\"evenodd\" d=\"M30.4791 11.2328L33.4351 0L21.6888 3.09113C19.9212 2.41855 18.0036 2.05025 16 2.05025C7.16344 2.05025 0 9.2137 0 18.0503C0 26.8868 7.16344 34.0503 16 34.0503C24.8366 34.0503 32 26.8868 32 18.0503C32 15.6119 31.4546 13.301 30.4791 11.2328ZM16 30.5503C22.9036 30.5503 28.5 24.9538 28.5 18.0503C28.5 11.1467 22.9036 5.55025 16 5.55025C9.09644 5.55025 3.5 11.1467 3.5 18.0503C3.5 24.9538 9.09644 30.5503 16 30.5503Z\" fill=\"var(--rail-orange, #C98A5A)\" />\n </svg>\n );\n })()}\n\n {/* Score number below gauge — with the outcome value in round\n brackets next to it (Figma 1798-5168), e.g. \"4 (80%)\". */}\n <div style={{\n fontSize: 28,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 1,\n textAlign: 'center',\n marginTop: 8,\n display: 'flex',\n alignItems: 'baseline',\n justifyContent: 'center',\n gap: 6,\n }}>\n <span>{scoreText}</span>\n {outcomePercent != null && (\n <span style={{ fontSize: 16, color: COLORS.muted, lineHeight: 1 }}>\n ({outcomePercent}%)\n </span>\n )}\n </div>\n <div style={{\n fontSize: 15,\n fontWeight: 500,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n textAlign: 'center',\n marginTop: 8,\n }}>\n Compass Score\n </div>\n </div>\n\n {/* Right: Predicted Score + Legends */}\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n alignItems: 'flex-start',\n justifyContent: 'center',\n flex: 1,\n width: isPhone ? '100%' : undefined,\n }}>\n {/* Overall Score title */}\n <div style={{\n fontSize: 15,\n fontWeight: 500,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n textAlign: 'left',\n }}>\n Interaction Quality Index\n </div>\n\n {/* Divider */}\n <div style={{\n width: '100%',\n height: 1,\n background: COLORS.absent,\n }} />\n\n {/* Legend items */}\n {legends.map((legend, i) => (\n <LegendItem\n key={i}\n label={legend.label}\n value={legend.value}\n />\n ))}\n </div>\n </div>\n </div>\n );\n};\n\nexport default UpdatedCompassScore;\n","\"use client\";\n\nimport React, { useState, useRef, useMemo, useEffect } from \"react\";\nimport { useMediaQuery } from \"../../utils/useMediaQuery\";\nimport {\n MessagesSquare,\n Ellipsis,\n CircleCheck,\n Check,\n CornerDownRight,\n Info,\n X,\n} from \"lucide-react\";\n\n/* ─── helpers ─── */\n\nconst roleColorMap = (role) => {\n if (!role) return null;\n const normalized = String(role).trim().toLowerCase();\n const roleTokens = normalized.split(/[^a-z]+/).filter(Boolean);\n if (roleTokens.includes(\"supervisor\")) return \"var(--rail-compliance, #C98A5A)\";\n if (\n roleTokens.includes(\"admin\") ||\n roleTokens.includes(\"administrator\") ||\n roleTokens.includes(\"superadmin\")\n ) {\n return \"var(--rail-discovery, #5E88B0)\";\n }\n if (roleTokens.includes(\"agent\")) return \"var(--rail-outcome, #6B7C93)\";\n return null;\n};\n\nconst extractRoleValue = (user) => {\n if (!user) return null;\n const directRole =\n user.role ??\n user.userRole ??\n user.user_role ??\n user.author_role ??\n user.roleName ??\n user.role_name ??\n user.userType ??\n user.user_type ??\n user.type;\n\n if (typeof directRole === \"string\") return directRole;\n if (Array.isArray(directRole)) return directRole.join(\" \");\n if (directRole && typeof directRole === \"object\") {\n return directRole.name || directRole.value || directRole.label || null;\n }\n\n const nestedRole =\n user.user?.role ??\n user.user?.userRole ??\n user.user?.user_role ??\n user.profile?.role ??\n user.profile?.userRole ??\n user.profile?.user_role;\n\n if (typeof nestedRole === \"string\") return nestedRole;\n if (Array.isArray(nestedRole)) return nestedRole.join(\" \");\n if (nestedRole && typeof nestedRole === \"object\") {\n return nestedRole.name || nestedRole.value || nestedRole.label || null;\n }\n\n return null;\n};\n\n/** Role-mapped color first so stale `color` from auth/session does not override role (matches thread intent). */\nconst resolveCurrentUserAvatarColor = (user) => {\n if (!user) return \"#6B7C93\";\n const role = extractRoleValue(user);\n return roleColorMap(role) || user.color || \"#6B7C93\";\n};\n\nconst getInitials = (name) =>\n (name || \"\")\n .split(\" \")\n .map((w) => w[0])\n .join(\"\")\n .toUpperCase() || \"U\";\n\nconst isWithinEditWindow = (value) => {\n if (!value) return true; // optimistic/new comments are editable\n if (value === \"Just now\") return true;\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) {\n try {\n const utcValue = /Z$|[+-]\\d{2}:\\d{2}$/.test(value) ? value : value + \"Z\";\n const d = new Date(utcValue);\n if (Number.isNaN(d.getTime())) return false;\n return (Date.now() - d.getTime()) < 15 * 60 * 1000;\n } catch { return false; }\n }\n // Parse relative timestamps like \"5 min\", \"1 h\", \"2 days\"\n const minMatch = value.match(/^(\\d+)\\s*min/);\n if (minMatch) return parseInt(minMatch[1], 10) < 15;\n // Anything in hours or days is beyond 15 min\n if (/\\d+\\s*h/.test(value) || /\\d+\\s*day/.test(value)) return false;\n return true;\n};\n\nconst formatTimestamp = (value) => {\n if (!value) return \"\";\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) return value;\n try {\n // Append Z if missing so timestamp is parsed as UTC\n const utcValue = /Z$|[+-]\\d{2}:\\d{2}$/.test(value) ? value : value + \"Z\";\n const d = new Date(utcValue);\n if (Number.isNaN(d.getTime())) return value;\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffMin = Math.floor(diffMs / 60000);\n const diffHr = Math.floor(diffMs / 3600000);\n if (diffMin < 1) return \"Just now\";\n if (diffMin < 60) return `${diffMin} min`;\n if (diffHr < 24) return `${diffHr} h`;\n const diffDays = Math.floor(diffHr / 24);\n if (diffDays === 1) return \"1 day\";\n return `${diffDays} days`;\n } catch {\n return value;\n }\n};\n\n/* ─── Avatar (36 × 36) ─── */\nconst Avatar = ({ name, initials, color, avatar, size = 36 }) => {\n if (avatar) {\n return (\n <img\n src={avatar}\n alt={name}\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n objectFit: \"cover\",\n flexShrink: 0,\n }}\n />\n );\n }\n return (\n <div\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n background: color || \"#6B7C93\",\n color: \"#FFF\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size <= 32 ? \"10px\" : \"11px\",\n fontWeight: 650,\n flexShrink: 0,\n fontFamily: \"var(--default-font-family)\",\n letterSpacing: \"0.02em\",\n }}\n title={name}\n >\n {initials || getInitials(name)}\n </div>\n );\n};\n\n/* ============================================\n COMMENT ROW — Figma node 593-1135 (top-level)\n display: flex\n width: 552px\n align-items: flex-start\n gap: 16px\n\n Reply row — Figma node 593-2042\n display: flex\n padding-left: 48px\n align-items: flex-start\n gap: 16px\n ============================================ */\nconst CommentBubble = ({\n comment,\n isReply = false,\n isConsecutive = false,\n onReply,\n onSendReply,\n onEdit,\n onDelete,\n onMenuClick,\n showReply = true,\n}) => {\n const [hovered, setHovered] = useState(false);\n const [menuOpen, setMenuOpen] = useState(false);\n const [replyOpen, setReplyOpen] = useState(false);\n const [replyValue, setReplyValue] = useState(\"\");\n const [editOpen, setEditOpen] = useState(false);\n const [editValue, setEditValue] = useState(\"\");\n const [confirmDelete, setConfirmDelete] = useState(false);\n const menuRef = useRef(null);\n const replyRef = useRef(null);\n const editRef = useRef(null);\n const author = comment.author || {};\n const authorName = author.name || comment.author_name || \"Unknown\";\n const initials = author.initials || getInitials(authorName);\n const role = author.role || comment.author_role;\n const avatarColor = author.color || roleColorMap(role) || \"#6B7C93\";\n const avatarImg = author.avatar || comment.avatar;\n const rawTimestamp = comment.timestamp || comment.created_at;\n const timestamp = formatTimestamp(rawTimestamp);\n const canEdit = isWithinEditWindow(rawTimestamp);\n const isEdited = Boolean(comment.isEdited || comment.is_edited || comment.edited);\n\n const paragraphs = Array.isArray(comment.content)\n ? comment.content\n : [comment.content || comment.text || \"\"];\n\n // Close menu on outside click\n React.useEffect(() => {\n if (!menuOpen) return;\n const handler = (e) => {\n if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [menuOpen]);\n\n // Auto-resize reply textarea\n React.useEffect(() => {\n const ta = replyRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n const max = 140;\n ta.style.height = Math.min(ta.scrollHeight, max) + \"px\";\n ta.style.overflowY = ta.scrollHeight > max ? \"auto\" : \"hidden\";\n }, [replyValue, replyOpen]);\n\n // Auto-resize edit textarea\n React.useEffect(() => {\n const ta = editRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n const max = 140;\n ta.style.height = Math.min(ta.scrollHeight, max) + \"px\";\n ta.style.overflowY = ta.scrollHeight > max ? \"auto\" : \"hidden\";\n }, [editValue, editOpen]);\n\n return (\n <div\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n paddingLeft: isReply ? 48 : 0,\n alignItems: \"flex-start\",\n gap: 16,\n paddingTop: isConsecutive ? 0 : 8,\n paddingBottom: 8,\n }}\n >\n {/* Avatar — 36 × 36 (hidden for consecutive messages, keep space) */}\n {isConsecutive ? (\n <div style={{ width: 36, flexShrink: 0 }} />\n ) : (\n <Avatar\n name={authorName}\n initials={initials}\n color={avatarColor}\n avatar={avatarImg}\n />\n )}\n\n {/* Content column */}\n <div style={{ flex: 1, minWidth: 0 }}>\n {/* Header row — always shows menu, name/time hidden for consecutive */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: isConsecutive ? \"flex-end\" : \"space-between\",\n marginBottom: isConsecutive ? 0 : 6,\n }}\n >\n {!isConsecutive && (\n <div style={{ display: \"flex\", alignItems: \"baseline\", gap: 8 }}>\n {/* Name — 13px / 650 / #1E2125 */}\n <span\n style={{\n fontSize: 13,\n fontWeight: 650,\n color: \"var(--text-ink, #1E2125)\",\n lineHeight: \"150%\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n {authorName}\n </span>\n {/* Timestamp — 12px / 400 / #808183 */}\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n lineHeight: \"150%\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n {timestamp}\n </span>\n {isEdited && (\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n lineHeight: \"150%\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n (Edited)\n </span>\n )}\n </div>\n )}\n\n {/* Three-dot menu — Ellipsis 24×24, hover only + dropdown */}\n <div style={{ position: \"relative\" }} ref={menuRef}>\n <button\n type=\"button\"\n onClick={() => setMenuOpen((p) => !p)}\n style={{\n padding: 2,\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n borderRadius: 4,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: hovered || menuOpen ? 1 : 0,\n transition: \"opacity 0.15s\",\n flexShrink: 0,\n }}\n >\n <Ellipsis size={24} color=\"var(--Grey-Muted, #808183)\" />\n </button>\n\n {/* Dropdown — Figma node 486-4493 */}\n {menuOpen && (\n <div\n style={{\n position: \"absolute\",\n top: \"100%\",\n right: 0,\n marginTop: 4,\n display: \"flex\",\n width: 99,\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n borderRadius: 4,\n border: \"1px solid var(--Grey-absent, #D9D9D9)\",\n background: \"var(--Grey-White, #FFF)\",\n boxShadow: \"-2px 2px 2px 0 rgba(0, 0, 0, 0.25)\",\n zIndex: 50,\n overflow: \"hidden\",\n }}\n >\n {onReply && (\n <button\n type=\"button\"\n onClick={() => { setMenuOpen(false); setEditOpen(false); setReplyOpen(true); }}\n style={{\n display: \"flex\",\n width: \"100%\",\n padding: \"10px 16px\",\n alignItems: \"center\",\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Strong, #2E3236)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n textAlign: \"left\",\n }}\n onMouseEnter={(e) => { e.currentTarget.style.background = \"var(--surface-hover, #F3F7F7)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"transparent\"; }}\n >\n Reply\n </button>\n )}\n {onEdit && (\n <button\n type=\"button\"\n disabled={!canEdit}\n onClick={() => {\n if (!canEdit) return;\n setMenuOpen(false);\n const text = Array.isArray(comment.content)\n ? comment.content.join(\"\\n\")\n : (comment.content || comment.text || \"\");\n setEditValue(text);\n setEditOpen(true);\n setReplyOpen(false);\n }}\n style={{\n display: \"flex\",\n width: \"100%\",\n padding: \"10px 16px\",\n alignItems: \"center\",\n border: \"none\",\n background: \"transparent\",\n cursor: canEdit ? \"pointer\" : \"not-allowed\",\n fontSize: 13,\n fontWeight: 400,\n color: canEdit ? \"var(--Grey-Strong, #2E3236)\" : \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n textAlign: \"left\",\n opacity: canEdit ? 1 : 0.5,\n }}\n onMouseEnter={(e) => { if (canEdit) e.currentTarget.style.background = \"var(--surface-hover, #F3F7F7)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"transparent\"; }}\n >\n Edit\n </button>\n )}\n {onDelete && (\n <button\n type=\"button\"\n onClick={() => { setMenuOpen(false); setConfirmDelete(true); }}\n style={{\n display: \"flex\",\n width: \"100%\",\n padding: \"10px 16px\",\n alignItems: \"center\",\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Strong, #2E3236)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n textAlign: \"left\",\n }}\n onMouseEnter={(e) => { e.currentTarget.style.background = \"var(--surface-hover, #F3F7F7)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"transparent\"; }}\n >\n Delete\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n\n {/* Edit mode — card with editable input */}\n {editOpen ? (\n <div\n style={{\n display: \"flex\",\n width: 662,\n maxWidth: \"100%\",\n padding: \"8px 12px 12px 12px\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n gap: 24,\n borderRadius: 8,\n border: \"1px solid var(--Grey-absent, #D9D9D9)\",\n background: \"var(--Grey-White, #FFF)\",\n boxSizing: \"border-box\",\n marginTop: 4,\n }}\n >\n {/* Header with author name + close */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n }}\n >\n <span\n style={{\n fontSize: 13,\n fontWeight: 600,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"normal\",\n }}\n >\n {\"\\u201C\"} {comment.author?.name || \"Unknown\"}\n </span>\n <button\n type=\"button\"\n onClick={() => setEditOpen(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: 0,\n }}\n >\n <X size={20} color=\"var(--Grey-Muted, #808183)\" />\n </button>\n </div>\n {/* Editable input + Save */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-end\",\n gap: 8,\n width: \"100%\",\n }}\n >\n <textarea\n ref={editRef}\n value={editValue}\n onChange={(e) => setEditValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n if (e.metaKey || e.ctrlKey || e.shiftKey) {\n // Allow newline insertion\n return;\n }\n e.preventDefault();\n if (editValue.trim()) {\n onEdit?.({ ...comment, content: editValue.trim(), isEdited: true });\n setEditOpen(false);\n }\n }\n if (e.key === \"Escape\") { setEditOpen(false); }\n }}\n autoFocus\n rows={1}\n style={{\n flex: 1,\n padding: \"10px 12px\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--text-ink, #1E2125)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"160%\",\n border: \"none\",\n background: \"transparent\",\n outline: \"none\",\n boxSizing: \"border-box\",\n resize: \"none\",\n minHeight: 24,\n maxHeight: 140,\n overflowY: \"hidden\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => {\n if (editValue.trim()) {\n onEdit?.({ ...comment, content: editValue.trim(), isEdited: true });\n setEditOpen(false);\n }\n }}\n disabled={!editValue.trim()}\n style={{\n display: \"flex\",\n padding: \"6px 16px\",\n justifyContent: \"center\",\n alignItems: \"center\",\n fontSize: 13,\n fontWeight: 600,\n color: editValue.trim()\n ? \"var(--Grey-White, #FFF)\"\n : \"var(--Grey-Muted, #808183)\",\n background: editValue.trim()\n ? \"var(--Grey-Strong, #2E3236)\"\n : \"var(--grey-light, #e9e8e8a1)\",\n border: \"none\",\n borderRadius: 6,\n cursor: editValue.trim() ? \"pointer\" : \"not-allowed\",\n fontFamily: \"var(--default-font-family)\",\n flexShrink: 0,\n transition: \"all 0.15s\",\n lineHeight: \"150%\",\n }}\n >\n Save\n </button>\n </div>\n </div>\n ) : (\n /* Message bubbles — stacked, gap: 4px, fit content */\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 4, alignItems: \"flex-start\" }}>\n {paragraphs.map((paragraph, idx) => (\n <div\n key={idx}\n style={{\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--text-ink, #1E2125)\",\n lineHeight: \"160%\",\n fontFamily: \"var(--default-font-family)\",\n padding: \"8px 12px\",\n background: isReply\n ? \"var(--surface-hover, #F3F7F7)\"\n : \"var(--surface-warm-40, rgba(243, 241, 229, 0.40))\",\n borderRadius: 8,\n wordBreak: \"break-word\",\n whiteSpace: \"pre-wrap\",\n }}\n >\n {paragraph}\n </div>\n ))}\n </div>\n )}\n\n {/* Inline delete confirmation */}\n {confirmDelete && (\n <div\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 8,\n marginTop: 8,\n fontSize: 13,\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n <span style={{ color: \"var(--Grey-Muted, #808183)\", fontWeight: 400 }}>\n Confirm: delete this comment?\n </span>\n <button\n type=\"button\"\n onClick={() => { setConfirmDelete(false); onDelete?.(comment); }}\n style={{\n background: \"var(--grey-light, #e9e8e8a1)\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 600,\n color: \"var(--text-ink, #1E2125)\",\n fontFamily: \"var(--default-font-family)\",\n padding: \"4px 10px\",\n borderRadius: 6,\n transition: \"background 0.15s\",\n }}\n onMouseEnter={(e) => { e.currentTarget.style.background = \"var(--Grey-absent, #D9D9D9)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"var(--grey-light, #e9e8e8a1)\"; }}\n >\n Delete\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDelete(false)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n padding: \"4px 10px\",\n borderRadius: 6,\n transition: \"background 0.15s\",\n }}\n onMouseEnter={(e) => { e.currentTarget.style.background = \"var(--grey-light, #e9e8e8a1)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"none\"; }}\n >\n Cancel\n </button>\n </div>\n )}\n\n {/* Reply action — CornerDownRight 20×20 + \"Reply\" */}\n {showReply && onReply && !replyOpen && !confirmDelete && (\n <button\n type=\"button\"\n onClick={() => { setEditOpen(false); setReplyOpen(true); }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n marginTop: 8,\n padding: 0,\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n transition: \"color 0.15s\",\n }}\n >\n <CornerDownRight size={20} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n Reply\n </button>\n )}\n\n {/* Inline reply input */}\n {replyOpen && (\n <div\n style={{\n display: \"flex\",\n width: 662,\n maxWidth: \"100%\",\n padding: \"8px 12px 12px 12px\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n gap: 24,\n borderRadius: 8,\n border: \"1px solid var(--Grey-absent, #D9D9D9)\",\n background: \"var(--Grey-White, #FFF)\",\n boxSizing: \"border-box\",\n marginTop: 12,\n }}\n >\n {/* Tagged comment quote */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8, width: \"100%\" }}>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n }}\n >\n <span\n style={{\n fontSize: 13,\n fontWeight: 600,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"normal\",\n }}\n >\n {\"\\u201C\"} {comment.author?.name || \"Unknown\"}\n </span>\n <button\n type=\"button\"\n onClick={() => { setReplyValue(\"\"); setReplyOpen(false); }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: 0,\n }}\n >\n <X size={20} color=\"var(--Grey-Muted, #808183)\" />\n </button>\n </div>\n <div\n style={{\n display: \"flex\",\n height: 36,\n padding: 16,\n alignItems: \"center\",\n gap: 5,\n borderRadius: \"0 8px 8px 8px\",\n background: \"var(--Grey-Strong, #2E3236)\",\n boxSizing: \"border-box\",\n width: \"100%\",\n }}\n >\n <span\n style={{\n color: \"var(--Grey-White, #FFF)\",\n fontSize: 13,\n fontWeight: 400,\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"normal\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {Array.isArray(comment.content) ? comment.content[0] : comment.content}\n </span>\n </div>\n </div>\n {/* Reply input + Post button */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-end\",\n gap: 8,\n width: \"100%\",\n }}\n >\n <textarea\n ref={replyRef}\n value={replyValue}\n onChange={(e) => setReplyValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n if (e.metaKey || e.ctrlKey || e.shiftKey) {\n // Allow newline insertion\n return;\n }\n e.preventDefault();\n if (replyValue.trim()) {\n onSendReply?.({ content: replyValue.trim(), parentId: comment.id });\n setReplyValue(\"\");\n setReplyOpen(false);\n }\n }\n if (e.key === \"Escape\") {\n setReplyValue(\"\");\n setReplyOpen(false);\n }\n }}\n autoFocus\n placeholder=\"Add a reply\"\n rows={1}\n style={{\n flex: 1,\n padding: \"10px 12px\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--text-ink, #1E2125)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"160%\",\n border: \"none\",\n background: \"transparent\",\n outline: \"none\",\n boxSizing: \"border-box\",\n resize: \"none\",\n minHeight: 24,\n maxHeight: 140,\n overflowY: \"hidden\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => {\n if (replyValue.trim()) {\n onSendReply?.({ content: replyValue.trim(), parentId: comment.id });\n setReplyValue(\"\");\n setReplyOpen(false);\n }\n }}\n disabled={!replyValue.trim()}\n style={{\n display: \"flex\",\n height: 28,\n padding: \"8px 12px\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gap: 8,\n fontSize: 13,\n fontWeight: 600,\n color: replyValue.trim()\n ? \"var(--Grey-White, #FFF)\"\n : \"var(--Grey-Muted, #808183)\",\n background: replyValue.trim()\n ? \"var(--Neutral-850, #272727)\"\n : \"var(--grey-light, #e9e8e8a1)\",\n border: \"none\",\n borderRadius: 10,\n cursor: replyValue.trim() ? \"pointer\" : \"not-allowed\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n }}\n >\n Post\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n};\n\n/* ============================================\n COMMENT INPUT — Figma node 237-5570\n display: flex\n width: 552px\n padding: 12px\n flex-direction: column\n justify-content: center\n align-items: flex-start\n gap: 24px\n\n border-radius: 8px\n border: 1px solid var(--Grey-absent, #D9D9D9)\n background: var(--Grey-White, #FFF)\n ============================================ */\nconst CommentInput = ({ currentUser, onSubmit }) => {\n const [value, setValue] = useState(\"\");\n const [isFocused, setIsFocused] = useState(false);\n const textareaRef = useRef(null);\n\n useEffect(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n const max = 140;\n ta.style.height = Math.min(ta.scrollHeight, max) + \"px\";\n ta.style.overflowY = ta.scrollHeight > max ? \"auto\" : \"hidden\";\n }, [value]);\n\n const handleSubmit = () => {\n const trimmed = value.trim();\n if (!trimmed) return;\n onSubmit?.(trimmed);\n setValue(\"\");\n };\n\n const handleKeyDown = (e) => {\n if (e.key === \"Enter\") {\n if (e.metaKey || e.ctrlKey || e.shiftKey) {\n // Allow newline insertion\n return;\n }\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const initials = currentUser?.initials || getInitials(currentUser?.name);\n const color = resolveCurrentUserAvatarColor(currentUser);\n const avatarImg = currentUser?.avatar;\n\n return (\n <div style={{ display: \"flex\", gap: 16, alignItems: \"flex-start\" }}>\n {/* Current user avatar */}\n <Avatar\n name={currentUser?.name}\n initials={initials}\n color={color}\n avatar={avatarImg}\n />\n\n {/* Input container — Figma: 552px, padding 12, border-radius 8 */}\n <div\n style={{\n flex: 1,\n padding: 12,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n gap: 24,\n borderRadius: 8,\n border: isFocused\n ? \"1px solid var(--Grey-Strong, #2E3236)\"\n : \"1px solid var(--Grey-absent, #D9D9D9)\",\n background: \"var(--Grey-White, #FFF)\",\n transition: \"border-color 0.15s\",\n }}\n >\n {/* Textarea + Post row */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-end\",\n gap: 8,\n width: \"100%\",\n }}\n >\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onKeyDown={handleKeyDown}\n placeholder=\"Add feedback\"\n rows={1}\n style={{\n flex: 1,\n border: \"none\",\n outline: \"none\",\n resize: \"none\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--text-ink, #1E2125)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"160%\",\n background: \"transparent\",\n padding: 0,\n minHeight: 24,\n maxHeight: 140,\n overflowY: \"hidden\",\n }}\n />\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!value.trim()}\n style={{\n display: \"flex\",\n padding: \"6px 16px\",\n justifyContent: \"center\",\n alignItems: \"center\",\n fontSize: 13,\n fontWeight: 600,\n color: value.trim()\n ? \"var(--Grey-White, #FFF)\"\n : \"var(--Grey-Muted, #808183)\",\n background: value.trim()\n ? \"var(--Grey-Strong, #2E3236)\"\n : \"var(--grey-light, #e9e8e8a1)\",\n border: \"none\",\n borderRadius: 6,\n cursor: value.trim() ? \"pointer\" : \"not-allowed\",\n fontFamily: \"var(--default-font-family)\",\n transition: \"all 0.15s\",\n flexShrink: 0,\n lineHeight: \"150%\",\n }}\n >\n Post\n </button>\n </div>\n </div>\n </div>\n );\n};\n\n/* ============================================\n MAIN COMPONENT: UpdatedThreads\n\n Outer container — full width\n Header (237-5556):\n display: flex\n height: 40px\n padding-bottom: 8px\n align-items: center\n gap: 16px\n align-self: stretch\n border-bottom: 1px solid var(--Grey-absent, #D9D9D9)\n\n Comments + Input wrapper (596-2060):\n display: flex\n padding-top: 24px\n flex-direction: column\n align-items: flex-start\n gap: 10px\n align-self: stretch\n border-top: 1px solid var(--Grey-absent, #D9D9D9)\n width: 552px (content area)\n ============================================ */\n\nconst CommentThread = ({ comment, depth = 0, isConsecutive = false, onReply, onSendReply, onEdit, onDelete, onMenuClick }) => {\n const hasReplies = comment.replies && comment.replies.length > 0;\n const isLastAtDepth = !hasReplies;\n return (\n <React.Fragment>\n <div style={{ paddingLeft: depth > 0 ? Math.min(depth * 32, 128) : 0 }}>\n <CommentBubble\n comment={comment}\n isReply={depth > 0}\n isConsecutive={isConsecutive}\n onReply={onReply}\n onSendReply={onSendReply}\n onEdit={onEdit}\n onDelete={onDelete}\n onMenuClick={onMenuClick}\n showReply={isLastAtDepth}\n />\n </div>\n {hasReplies && comment.replies.map((reply) => (\n <CommentThread\n key={reply.id}\n comment={reply}\n depth={depth + 1}\n onReply={onReply}\n onSendReply={onSendReply}\n onEdit={onEdit}\n onDelete={onDelete}\n onMenuClick={onMenuClick}\n />\n ))}\n </React.Fragment>\n );\n};\n\nconst UpdatedThreads = ({\n comments: externalComments = [],\n totalComments,\n children,\n onSendComment,\n onReply,\n onSendReply,\n onEdit,\n onDelete,\n onMenuClick,\n onMarkResolved,\n currentUser,\n isResolved = false,\n}) => {\n // Local state for optimistic updates (replies, new comments, edits, deletes)\n const [localComments, setLocalComments] = useState([]);\n const [isSending, setIsSending] = useState(false);\n\n // Merge external + local comments\n const allComments = useMemo(() => {\n const externalIds = new Set(externalComments.map((c) => c.id));\n // Filter out local comments that now exist in external (API caught up)\n const newLocal = localComments.filter((c) => !externalIds.has(c.id));\n return [...externalComments, ...newLocal];\n }, [externalComments, localComments]);\n\n // Sync: remove local comments when external updates\n React.useEffect(() => {\n const externalIds = new Set(externalComments.map((c) => c.id));\n setLocalComments((prev) => prev.filter((c) => !externalIds.has(c.id)));\n }, [externalComments]);\n\n const displayCurrentUser = useMemo(() => {\n if (!currentUser) return { name: \"You\", initials: \"YO\", color: \"#6B7C93\" };\n const name = currentUser.name || \"You\";\n const initials = currentUser.initials || getInitials(name);\n const color = resolveCurrentUserAvatarColor(currentUser);\n return { ...currentUser, name, initials, color };\n }, [currentUser]);\n\n const handleSendReply = async ({ content, parentId }) => {\n if (onSendReply) {\n // Host app mode — let API handle it, show loading\n setIsSending(true);\n try {\n await onSendReply({ content, parentId });\n } finally {\n setIsSending(false);\n }\n } else {\n // Library demo mode — optimistic local comment\n const optimisticReply = {\n id: `temp-${Date.now()}`,\n author: displayCurrentUser,\n content,\n timestamp: \"Just now\",\n parentId,\n isOptimistic: true,\n };\n setLocalComments((prev) => [...prev, optimisticReply]);\n }\n };\n\n const handleSendComment = async (text) => {\n if (onSendComment) {\n // Host app mode — let API handle it, show loading\n setIsSending(true);\n try {\n await onSendComment(text);\n } finally {\n setIsSending(false);\n }\n } else {\n // Library demo mode — optimistic local comment\n const optimisticComment = {\n id: `temp-${Date.now()}`,\n author: displayCurrentUser,\n content: text,\n timestamp: \"Just now\",\n isOptimistic: true,\n };\n setLocalComments((prev) => [...prev, optimisticComment]);\n }\n };\n\n const handleEdit = (comment) => {\n // If it's a local optimistic comment, update locally\n setLocalComments((prev) =>\n prev.map((c) => (c.id === comment.id ? { ...c, content: comment.content, isEdited: true } : c))\n );\n onEdit?.(comment);\n };\n\n const handleDelete = (comment) => {\n // Remove from local state immediately\n setLocalComments((prev) => prev.filter((c) => c.id !== comment.id));\n onDelete?.(comment);\n };\n\n const groupedComments = useMemo(() => {\n const repliesByParent = {};\n allComments.forEach((c) => {\n if (c.parentId) {\n if (!repliesByParent[c.parentId]) repliesByParent[c.parentId] = [];\n repliesByParent[c.parentId].push(c);\n }\n });\n const buildTree = (comment) => ({\n ...comment,\n replies: (repliesByParent[comment.id] || []).map(buildTree),\n });\n return allComments.filter((c) => !c.parentId).map(buildTree);\n }, [allComments]);\n\n const commentCount = totalComments ?? allComments.length;\n\n // Feedback and Guidance sit side by side on wide layouts, but two text\n // columns need real room, so we stack them once the viewport drops below\n // 900px. A viewport media query (not a container measurement) is used\n // deliberately: the detail panel can overflow horizontally, so this\n // component's own clientWidth stays wide even when the visible area is\n // narrow.\n const isNarrow = useMediaQuery(\"(max-width: 900px)\");\n const isPhone = useMediaQuery(\"(max-width: 640px)\");\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n background: \"var(--Grey-White, #FFF)\",\n width: \"100%\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n {/* ═══════════════════════════════════════════\n HEADER — FEEDBACK & GUIDANCE\n ═══════════════════════════════════════════ */}\n <div\n style={{\n display: \"flex\",\n height: 40,\n paddingBottom: 8,\n alignItems: \"center\",\n gap: 8,\n alignSelf: \"stretch\",\n }}\n >\n <MessagesSquare size={24} color=\"var(--rail-orange, #C98A5A)\" strokeWidth={1.5} />\n <span\n style={{\n fontSize: 16,\n fontWeight: 600,\n color: \"var(--Grey-Strong, #2E3236)\",\n textTransform: \"uppercase\",\n lineHeight: 1.2,\n }}\n >\n Feedback & Guidance\n </span>\n </div>\n\n {/* Divider */}\n <div style={{ width: \"100%\", height: 1, background: \"var(--Grey-absent, #D9D9D9)\" }} />\n\n {/* ═══════════════════════════════════════════\n CONTENT AREA — Two equal columns (stacks when narrow)\n ═══════════════════════════════════════════ */}\n <div\n style={{\n display: \"flex\",\n flexDirection: isNarrow ? \"column\" : \"row\",\n gap: 24,\n alignSelf: \"stretch\",\n }}\n >\n {/* Left column — Feedback / Comments */}\n <div style={{ flex: 1, minWidth: 0 }}>\n {/* Feedback sub-header */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n flexWrap: isPhone ? \"wrap\" : \"nowrap\",\n gap: isPhone ? 10 : 16,\n paddingTop: 16,\n paddingBottom: 8,\n }}\n >\n <div\n style={{\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: \"var(--surface-hover, #F3F7F7)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <MessagesSquare style={{ width: 20, height: 20, flexShrink: 0 }} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.5} />\n </div>\n <span\n style={{\n fontSize: 16,\n fontWeight: 500,\n color: \"var(--Grey-Strong, #2E3236)\",\n }}\n >\n Feedback\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n marginLeft: \"auto\",\n }}\n >\n {commentCount} Comment{commentCount !== 1 ? \"s\" : \"\"}\n </span>\n {isResolved ? (\n <div\n style={{\n display: \"inline-flex\",\n height: 32,\n padding: \"12px 16px 12px 12px\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gap: 8,\n borderRadius: 10,\n background: \"var(--Rail-Surface-2, #E3E1D7)\",\n flexShrink: 0,\n }}\n >\n <Check size={16} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={2} />\n <span\n style={{\n fontSize: 13,\n fontWeight: 500,\n color: \"var(--Grey-Strong, #2E3236)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n }}\n >\n Resolved\n </span>\n </div>\n ) : onMarkResolved ? (\n <button\n type=\"button\"\n onClick={onMarkResolved}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 8,\n padding: \"8px 16px\",\n fontSize: 13,\n fontWeight: 500,\n color: \"var(--Grey-Strong, #2E3236)\",\n background: \"var(--Grey-White, #FFF)\",\n border: \"1px solid var(--Grey-absent, #D9D9D9)\",\n borderRadius: 20,\n cursor: \"pointer\",\n fontFamily: \"var(--default-font-family)\",\n transition: \"background 0.15s\",\n lineHeight: \"150%\",\n flexShrink: 0,\n // On phones the button drops to its own full-width line.\n ...(isPhone ? { width: \"100%\", order: 1 } : {}),\n }}\n >\n <CircleCheck size={16} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.5} />\n Mark as Resolved\n </button>\n ) : null}\n </div>\n {/* Comments list */}\n {allComments.length > 0 && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 0,\n marginBottom: 24,\n maxHeight: 600,\n overflowY: allComments.length > 6 ? \"auto\" : \"visible\",\n }}\n >\n {groupedComments.map((comment, idx) => {\n const prev = idx > 0 ? groupedComments[idx - 1] : null;\n const prevAuthor = prev?.author?.name || prev?.author_name;\n const currAuthor = comment.author?.name || comment.author_name;\n const isConsecutive = prev && prevAuthor === currAuthor && (!prev.replies || prev.replies.length === 0);\n return (\n <CommentThread\n key={comment.id}\n comment={comment}\n depth={0}\n isConsecutive={!!isConsecutive}\n onReply={onReply}\n onSendReply={handleSendReply}\n onEdit={handleEdit}\n onDelete={handleDelete}\n onMenuClick={onMenuClick}\n />\n );\n })}\n </div>\n )}\n\n {/* Edit info hint */}\n {allComments.length > 0 && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n marginBottom: 16,\n marginLeft: 48,\n }}\n >\n <Info size={16} color=\"var(--Grey-Muted, #808183)\" />\n <span\n style={{\n color: \"var(--Grey-Muted, #808183)\",\n fontSize: 13,\n fontStyle: \"normal\",\n fontWeight: 400,\n lineHeight: \"normal\",\n }}\n >\n Comments can be edited within 15 minutes.\n </span>\n </div>\n )}\n\n {/* Loading indicator */}\n {isSending && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"8px 0\",\n }}\n >\n <div\n style={{\n width: 16,\n height: 16,\n border: \"2px solid var(--Grey-absent, #D9D9D9)\",\n borderTopColor: \"var(--Grey-Strong, #2E3236)\",\n borderRadius: \"50%\",\n animation: \"spin 0.8s linear infinite\",\n }}\n />\n <span\n style={{\n fontSize: 13,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n Sending...\n </span>\n <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n )}\n\n {/* Comment input */}\n <CommentInput currentUser={displayCurrentUser} onSubmit={handleSendComment} />\n </div>\n\n {/* Right column — Guidance (rendered via children) */}\n <div\n style={{\n flex: 1,\n minWidth: 0,\n }}\n >\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nexport default UpdatedThreads;\n","\"use client\";\n\nimport React, { useState } from \"react\";\nimport {\n Lightbulb,\n PlayCircle,\n PauseCircle,\n ScrollText,\n ThumbsUp,\n ThumbsDown,\n Target,\n ArrowUp,\n ArrowDown,\n ChevronDown,\n ChevronRight,\n} from \"lucide-react\";\n\n/**\n * UpdatedGuidance — Guidance list for interaction details.\n *\n * Matches the backend `interaction-guidance` block contract — everything is\n * pre-resolved server-side so this component just renders what it receives.\n * No client-side icon / tone derivation, no impact-string formatting.\n *\n * Figma node: 822-15273\n *\n * Props:\n * - items Array Guidance items (pre-sorted server-side)\n * - guidanceCount number Total count for the sub-header; defaults to items.length\n * - loading boolean Show loading state (currently unused — slot for shimmer)\n * - onPlayEvidence fn Called with { start_ms, end_ms } to play audio segment\n * - onShowInTranscript fn Called with start_ms to scroll transcript\n * - timelinePlaying boolean Whether the timeline is currently playing\n * - currentTimeSeconds number Current playback time, in seconds\n *\n * Item shape (per backend contract):\n * - title string Guidance title (top line)\n * - type string \"focus\" | \"opportunity\" | \"excellence\" (informational only)\n * - tone string \"green\" | \"amber\" | \"red\" — colors the leading icon\n * - icon string \"thumbs_up\" | \"thumbs_down\" | \"focus\" — leading icon\n * - signals Array Per-signal coaching context:\n * - signal_key string\n * - display_name string Signal label (e.g. \"Next Steps Unclear\")\n * - description string Coaching sentence, already resolved\n * - impact_label string? Pre-formatted (\"Helped score (+3.1%)\"); shown\n * as a chip when present, skipped when absent\n * - impact_direction string? \"positive\" | \"negative\" — drives chip color\n * - evidence Array? Up to 3 transcript snippets:\n * { actor, text, start_ms, end_ms }\n */\n\nconst COLORS = {\n strong: \"var(--Grey-Strong, #2E3236)\",\n muted: \"var(--Grey-Muted, #808183)\",\n border: \"var(--Grey-absent, #D9D9D9)\",\n surfaceHover: \"var(--surface-hover, #F3F7F7)\",\n warmBorder: \"var(--border-warm, #B2AEA8)\",\n quoteText: \"var(--text-subtle-warm, #767473)\",\n // Tone tints for the leading icon. NOTE: `--rail-compliance` is wired to an\n // amber/orange (#C98A5A) in the design tokens despite its name, so we use\n // `--state-present` for actual green here. Same for `--rail-attrition`.\n toneGreen: \"var(--state-present, #25A372)\",\n toneAmber: \"var(--rail-orange, #C98A5A)\",\n toneRed: \"var(--color-red-strong, #D04A4A)\",\n // Impact-chip backgrounds (light tints) + ink colours for legibility.\n impactPositiveBg: \"rgba(37, 163, 114, 0.12)\",\n impactPositiveInk: \"var(--state-present, #25A372)\",\n impactNegativeBg: \"rgba(208, 74, 74, 0.12)\",\n impactNegativeInk: \"var(--color-red-strong, #D04A4A)\",\n};\n\n// Figma uses Averta for body text; fall back to the project's --font-sans\n// token / system sans so we don't have to bundle the font file here.\nconst FONT_DISPLAY =\n \"var(--font-sans, 'Averta', ui-sans-serif, system-ui, sans-serif)\";\n\n/* ── Hover icon wrapper (matches UpdatedInteractionSignals) ── */\nconst HoverIcon = ({ children, size = 24, onClick, title }) => {\n const [hovered, setHovered] = useState(false);\n return (\n <div\n title={title}\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: size,\n height: size,\n borderRadius: 9999,\n background: hovered ? COLORS.surfaceHover : \"transparent\",\n cursor: \"pointer\",\n flexShrink: 0,\n transition: \"background 0.15s\",\n }}\n >\n {children}\n </div>\n );\n};\n\nconst fmtMs = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, \"0\")}:${seconds\n .toString()\n .padStart(2, \"0\")}`;\n};\n\nconst toneToColor = (tone) => {\n switch (tone) {\n case \"green\":\n return COLORS.toneGreen;\n case \"amber\":\n return COLORS.toneAmber;\n case \"red\":\n return COLORS.toneRed;\n default:\n return COLORS.strong;\n }\n};\n\n/* ── Leading icon driven by API `icon` field (no client derivation) ──\n Per the latest design, thumbs_up / thumbs_down are rendered as ↑/↓ arrows\n so the row reads as \"score moved up / down\" rather than a sentiment.\n `focus` stays as the Target bullseye. `tone` is accepted on the prop\n chain but unused so a future tinted variant doesn't need an API change. */\nconst LeadingIcon = ({ icon /* tone — unused */ }) => {\n const common = { size: 16, color: COLORS.strong, strokeWidth: 1.5 };\n if (icon === \"thumbs_down\") return <ArrowDown {...common} />;\n if (icon === \"focus\") return <Target {...common} />;\n // Default + thumbs_up → ArrowUp\n return <ArrowUp {...common} />;\n};\n\n/* ── Impact chip (e.g. \"Helped score (+3.1%)\") ──\n Direction is conveyed by the ↑/↓ arrow only — chip uses a neutral surface\n so the row stays calm and red/green tints don't dominate the layout. */\nconst ImpactChip = ({ label, direction }) => {\n if (!label) return null;\n const Arrow = direction === \"negative\" ? ArrowDown : ArrowUp;\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n background: COLORS.surfaceHover,\n color: COLORS.strong,\n padding: \"2px 8px\",\n borderRadius: 9999,\n fontSize: 12,\n fontWeight: 500,\n lineHeight: 1.4,\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n >\n {label}\n <Arrow size={12} color={COLORS.strong} strokeWidth={2} />\n </span>\n );\n};\n\n/* ── Single evidence quote (collapsed → expanded by parent) ── */\nconst EvidenceQuote = ({\n evidence,\n onPlayEvidence,\n onShowInTranscript,\n timelinePlaying,\n currentTimeSeconds,\n}) => {\n const startMs = evidence.start_ms ?? evidence.startMs;\n const endMs = evidence.end_ms ?? evidence.endMs;\n const hasTimestamp = startMs != null;\n const currentMs = (currentTimeSeconds ?? 0) * 1000;\n const isPlayingThis =\n timelinePlaying &&\n hasTimestamp &&\n currentMs >= startMs &&\n currentMs <= (endMs ?? startMs + 5000);\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n paddingLeft: 12,\n borderLeft: `2px solid ${COLORS.warmBorder}`,\n }}\n >\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.quoteText,\n lineHeight: 1.5,\n fontStyle: \"italic\",\n wordBreak: \"break-word\",\n }}\n >\n “{evidence.text}”\n </span>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n minHeight: 24,\n }}\n >\n {evidence.actor && (\n <span\n style={{\n fontSize: 12,\n fontWeight: 500,\n color: COLORS.muted,\n textTransform: \"capitalize\",\n }}\n >\n {evidence.actor}\n </span>\n )}\n {hasTimestamp && (\n <>\n <HoverIcon\n size={24}\n title={isPlayingThis ? \"Pause\" : \"Play evidence\"}\n onClick={() =>\n onPlayEvidence?.({ start_ms: startMs, end_ms: endMs })\n }\n >\n {isPlayingThis ? (\n <PauseCircle\n size={16}\n color={COLORS.strong}\n strokeWidth={1.25}\n />\n ) : (\n <PlayCircle\n size={16}\n color={COLORS.muted}\n strokeWidth={1.25}\n />\n )}\n </HoverIcon>\n <HoverIcon\n size={24}\n title=\"Show in transcript\"\n onClick={() => onShowInTranscript?.(startMs)}\n >\n <ScrollText size={16} color={COLORS.muted} strokeWidth={1.5} />\n </HoverIcon>\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: COLORS.muted,\n lineHeight: 1.2,\n whiteSpace: \"nowrap\",\n }}\n >\n {fmtMs(startMs)}\n </span>\n </>\n )}\n </div>\n </div>\n );\n};\n\n/* ── Signal block: name + impact chip + description + expandable evidence ── */\nconst SignalRow = ({\n signal,\n onPlayEvidence,\n onShowInTranscript,\n timelinePlaying,\n currentTimeSeconds,\n}) => {\n const evidenceList = Array.isArray(signal.evidence) ? signal.evidence : [];\n const hasEvidence = evidenceList.length > 0;\n const [expanded, setExpanded] = useState(false);\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n }}\n >\n {/* Signal name + impact chip + optional evidence toggle */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flexWrap: \"wrap\",\n }}\n >\n {/* `signal.display_name` intentionally omitted — the item title\n already conveys the coaching theme; dropping the label keeps the\n row to: impact chip + quote toggle. The value is still passed\n through on the signal object for future surfaces. */}\n <ImpactChip\n label={signal.impact_label}\n direction={signal.impact_direction}\n />\n {hasEvidence && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 2,\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n fontSize: 12,\n fontWeight: 500,\n color: COLORS.muted,\n fontFamily: \"inherit\",\n }}\n >\n {expanded ? (\n <ChevronDown size={14} color={COLORS.muted} strokeWidth={1.5} />\n ) : (\n <ChevronRight size={14} color={COLORS.muted} strokeWidth={1.5} />\n )}\n {evidenceList.length} {evidenceList.length === 1 ? \"quote\" : \"quotes\"}\n </button>\n )}\n </div>\n\n {/* Signal description intentionally omitted — the item title already\n carries the coaching sentence; rendering the signal's description\n underneath was duplicative. The string is still passed through on\n the signal object so other surfaces (or a future expanded view)\n can use it. */}\n\n {expanded && hasEvidence && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n paddingTop: 4,\n }}\n >\n {evidenceList.map((ev, i) => (\n <EvidenceQuote\n key={i}\n evidence={ev}\n onPlayEvidence={onPlayEvidence}\n onShowInTranscript={onShowInTranscript}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n />\n ))}\n </div>\n )}\n </div>\n );\n};\n\n/* ── Single guidance item ── */\nconst GuidanceItem = ({\n item,\n isLast,\n onPlayEvidence,\n onShowInTranscript,\n timelinePlaying,\n currentTimeSeconds,\n}) => {\n const signals = Array.isArray(item.signals) ? item.signals : [];\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 12,\n padding: \"16px 16px\",\n borderBottom: isLast ? \"none\" : `1px solid ${COLORS.border}`,\n }}\n >\n {/* Leading icon (driven by API `icon` + `tone`) */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 16,\n height: 16,\n flexShrink: 0,\n marginTop: 2,\n }}\n >\n <LeadingIcon icon={item.icon} tone={item.tone} />\n </div>\n\n {/* Right column: title + signals */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n flex: 1,\n minWidth: 0,\n }}\n >\n {/* Item title — matches Figma node 822:15282 (14px Averta regular,\n var(--grey/strong, #2e3236), leading-normal). */}\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 14,\n fontWeight: 400,\n color: COLORS.strong,\n lineHeight: \"normal\",\n wordBreak: \"break-word\",\n }}\n >\n {item.title || \"\"}\n </span>\n\n {signals.length > 0 && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n }}\n >\n {signals.map((sig, i) => (\n <SignalRow\n key={sig.signal_key || i}\n signal={sig}\n onPlayEvidence={onPlayEvidence}\n onShowInTranscript={onShowInTranscript}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n />\n ))}\n </div>\n )}\n </div>\n </div>\n );\n};\n\n/* ── Summary count bar (focus / opportunity / excellence) ── */\nconst SummaryCountBar = ({ summary }) => {\n if (!summary || typeof summary !== \"object\") return null;\n const focus = Number(summary.focus_count) || 0;\n const opportunity = Number(summary.opportunity_count) || 0;\n const excellence = Number(summary.excellence_count) || 0;\n if (focus + opportunity + excellence === 0) return null;\n\n // Render order per the latest design: Excellence first (positive wins\n // lead), then Opportunity (what to improve), then Focus (most critical).\n // Icons mirror the leading-icon swap below: ArrowUp for excellence,\n // ArrowDown for opportunity, Target stays for focus.\n const cells = [\n {\n key: \"excellence\",\n label: \"Excellence\",\n count: excellence,\n Icon: ArrowUp,\n color: COLORS.strong,\n },\n {\n key: \"opportunity\",\n label: \"Opportunity\",\n count: opportunity,\n Icon: ArrowDown,\n color: COLORS.strong,\n },\n {\n key: \"focus\",\n label: \"Focus\",\n count: focus,\n Icon: Target,\n color: COLORS.strong,\n },\n ].filter((c) => c.count > 0);\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n padding: \"8px 16px\",\n background: COLORS.surfaceHover,\n borderRadius: 8,\n }}\n >\n {cells.map(({ key, label, count, Icon, color }) => (\n <div\n key={key}\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n >\n <Icon size={14} color={color} strokeWidth={1.75} />\n <span\n style={{\n fontSize: 13,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: 1.2,\n }}\n >\n {count}\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.muted,\n lineHeight: 1.2,\n }}\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n );\n};\n\n/* ── Main Component ── */\n// Spec: render at most 5 items in the exact order received from the API.\nconst MAX_ITEMS = 5;\n\nconst UpdatedGuidance = ({\n items = [],\n summary,\n guidanceCount,\n loading = false,\n onPlayEvidence,\n onShowInTranscript,\n timelinePlaying = false,\n currentTimeSeconds = 0,\n}) => {\n // Defensive: clamp to 5 per spec, drop null entries.\n const visibleItems = Array.isArray(items)\n ? items.filter(Boolean).slice(0, MAX_ITEMS)\n : [];\n const count = guidanceCount ?? visibleItems.length;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n width: \"100%\",\n }}\n >\n {/* Sub-header — icon + Guidance + count */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n paddingTop: 16,\n paddingBottom: 8,\n }}\n >\n <div\n style={{\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: COLORS.surfaceHover,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <Lightbulb\n style={{ width: 20, height: 20, flexShrink: 0 }}\n color={COLORS.strong}\n strokeWidth={1.5}\n />\n </div>\n <span\n style={{\n flex: 1,\n fontSize: 16,\n fontWeight: 500,\n color: COLORS.strong,\n lineHeight: 1.2,\n }}\n >\n Guidance\n </span>\n <span\n style={{\n fontSize: 14,\n fontWeight: 500,\n color: COLORS.strong,\n lineHeight: 1.5,\n whiteSpace: \"nowrap\",\n }}\n >\n {count} Item{count !== 1 ? \"s\" : \"\"}\n </span>\n </div>\n\n {/* Optional summary count bar (focus / opportunity / excellence). Only\n renders when the backend ships a non-empty `summary` block. */}\n <SummaryCountBar summary={summary} />\n\n {visibleItems.map((item, i) => (\n <GuidanceItem\n key={i}\n item={item}\n isLast={i === visibleItems.length - 1}\n onPlayEvidence={onPlayEvidence}\n onShowInTranscript={onShowInTranscript}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n />\n ))}\n </div>\n );\n};\n\nexport default UpdatedGuidance;\n","\"use client\";\n\nimport React from \"react\";\nimport {\n Activity,\n Pause,\n Search,\n ArrowRightLeft,\n CircleDashed,\n MicOff,\n AudioLines,\n} from \"lucide-react\";\n\n/**\n * UpdatedTalkPatterns — surfaces the new `talk_patterns.summary` numbers the\n * backend started shipping alongside hold-detection v2:\n *\n * - hold_type_counts — Lookup / Formal / Extended / Transfer / Probable / Dead air\n * - stall_count / stall_rate / stall_filler_count / stall_buying_time_count\n * - agent_response_percentiles_ms / customer_response_percentiles_ms\n *\n * The component is intentionally compact and neutral-toned — no green/red, no\n * sentiment colouring. All buckets render only when they have a non-zero\n * value (defensive: ignores empty / missing summary blocks).\n *\n * Props:\n * - summary Object `components.talk_patterns.summary` from the API\n */\n\nconst COLORS = {\n strong: \"var(--Grey-Strong, #2E3236)\",\n muted: \"var(--Grey-Muted, #808183)\",\n border: \"var(--Grey-absent, #D9D9D9)\",\n surface: \"var(--Grey-White, #FFF)\",\n surfaceHover: \"var(--surface-hover, #F3F7F7)\",\n};\n\nconst FONT_DISPLAY =\n \"var(--font-sans, 'Averta', ui-sans-serif, system-ui, sans-serif)\";\n\nconst HOLD_BUCKETS = [\n { key: \"lookup_hold\", label: \"Lookup\", Icon: Search },\n { key: \"formal_hold\", label: \"Hold\", Icon: Pause },\n { key: \"extended_hold\", label: \"Extended\", Icon: Pause },\n { key: \"transfer_hold\", label: \"Transfer\", Icon: ArrowRightLeft },\n { key: \"probable_hold\", label: \"Possible\", Icon: CircleDashed },\n { key: \"dead_air\", label: \"Dead air\", Icon: MicOff },\n];\n\n// Format milliseconds → \"1.2s\" / \"850ms\". Picks units so the value fits in\n// 3-4 visible characters; we render lots of these side by side.\nconst fmtMs = (ms) => {\n if (ms == null || Number.isNaN(ms)) return \"—\";\n const num = Number(ms);\n if (!Number.isFinite(num)) return \"—\";\n if (num >= 1000) return `${(num / 1000).toFixed(1)}s`;\n return `${Math.round(num)}ms`;\n};\n\nconst fmtRate = (rate) => {\n if (rate == null || Number.isNaN(rate)) return null;\n const num = Number(rate);\n if (!Number.isFinite(num)) return null;\n // API ships as a 0-1 ratio. Render as percent.\n return `${(num * 100).toFixed(1)}%`;\n};\n\nconst fmtCount = (n) => {\n if (n == null || Number.isNaN(n)) return null;\n const num = Number(n);\n return Number.isFinite(num) ? num.toLocaleString() : null;\n};\n\n/* ── Hold-type count strip ── */\nconst HoldCounts = ({ holdTypeCounts }) => {\n if (!holdTypeCounts || typeof holdTypeCounts !== \"object\") return null;\n const cells = HOLD_BUCKETS.map((b) => ({\n ...b,\n count: Number(holdTypeCounts[b.key]) || 0,\n })).filter((c) => c.count > 0);\n if (cells.length === 0) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n flexWrap: \"wrap\",\n gap: 16,\n padding: \"8px 16px\",\n background: COLORS.surfaceHover,\n borderRadius: 8,\n }}\n >\n {cells.map(({ key, label, Icon, count }) => (\n <div\n key={key}\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n >\n <Icon size={14} color={COLORS.strong} strokeWidth={1.5} />\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: 1.2,\n }}\n >\n {count}\n </span>\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.muted,\n lineHeight: 1.2,\n }}\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n );\n};\n\n/* ── Stall metrics row ── */\nconst StallRow = ({ summary }) => {\n const total = fmtCount(summary?.stall_count);\n if (!total) return null;\n const rate = fmtRate(summary?.stall_rate);\n const filler = fmtCount(summary?.stall_filler_count);\n const buying = fmtCount(summary?.stall_buying_time_count);\n const breakdown = [];\n if (filler) breakdown.push(`filler ${filler}`);\n if (buying) breakdown.push(`buying time ${buying}`);\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flexWrap: \"wrap\",\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n lineHeight: 1.4,\n }}\n >\n <span style={{ fontWeight: 500, color: COLORS.strong }}>\n Stalls: {total}\n {rate ? ` (${rate})` : \"\"}\n </span>\n {breakdown.length > 0 && (\n <span style={{ color: COLORS.muted }}>· {breakdown.join(\" · \")}</span>\n )}\n </div>\n );\n};\n\n/* ── Response-time percentile table (agent + customer) ── */\nconst PercentileRow = ({ label, percentiles }) => {\n if (!percentiles || typeof percentiles !== \"object\") return null;\n const cells = [\n { key: \"p50\", label: \"p50\", value: percentiles.p50 },\n { key: \"p75\", label: \"p75\", value: percentiles.p75 },\n { key: \"p95\", label: \"p95\", value: percentiles.p95 },\n { key: \"p99\", label: \"p99\", value: percentiles.p99 },\n ].filter((c) => c.value != null);\n if (cells.length === 0) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"baseline\",\n gap: 12,\n flexWrap: \"wrap\",\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n lineHeight: 1.4,\n }}\n >\n <span\n style={{\n fontWeight: 500,\n color: COLORS.strong,\n minWidth: 72,\n }}\n >\n {label}\n </span>\n {cells.map((c) => (\n <span key={c.key} style={{ color: COLORS.muted }}>\n <span style={{ fontWeight: 500, color: COLORS.strong }}>{c.label}</span>{\" \"}\n {fmtMs(c.value)}\n </span>\n ))}\n </div>\n );\n};\n\n/* ── Main component ── */\nconst UpdatedTalkPatterns = ({ summary }) => {\n if (!summary || typeof summary !== \"object\") return null;\n\n const hasHolds =\n !!summary.hold_type_counts &&\n Object.values(summary.hold_type_counts).some((n) => Number(n) > 0);\n const hasStalls = (Number(summary.stall_count) || 0) > 0;\n const agentP = summary.agent_response_percentiles_ms;\n const customerP = summary.customer_response_percentiles_ms;\n const hasPercentiles =\n (agentP && Object.values(agentP).some((v) => v != null)) ||\n (customerP && Object.values(customerP).some((v) => v != null));\n\n if (!hasHolds && !hasStalls && !hasPercentiles) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: 12,\n width: \"100%\",\n }}\n >\n {/* Sub-header — matches the Guidance / other section headers */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n paddingTop: 16,\n paddingBottom: 8,\n }}\n >\n <div\n style={{\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: COLORS.surfaceHover,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <AudioLines size={20} color={COLORS.strong} strokeWidth={1.5} />\n </div>\n <span\n style={{\n flex: 1,\n fontFamily: \"Varta, var(--font-sans, sans-serif)\",\n fontSize: 16,\n fontWeight: 700,\n color: COLORS.strong,\n lineHeight: 1.2,\n whiteSpace: \"nowrap\",\n }}\n >\n Talk Patterns\n </span>\n </div>\n\n {hasHolds && <HoldCounts holdTypeCounts={summary.hold_type_counts} />}\n\n {(hasStalls || hasPercentiles) && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 10,\n padding: \"12px 16px\",\n border: `1px solid ${COLORS.border}`,\n borderRadius: 8,\n }}\n >\n {hasStalls && <StallRow summary={summary} />}\n {hasPercentiles && (\n <>\n <PercentileRow label=\"Agent\" percentiles={agentP} />\n <PercentileRow label=\"Customer\" percentiles={customerP} />\n </>\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport default UpdatedTalkPatterns;\n","\"use client\";\n\nimport React, { useState } from \"react\";\nimport { ClipboardCheck, ChevronDown, ChevronUp } from \"lucide-react\";\n\n/**\n * UpdatedProductsServices — \"PRODUCTS & SERVICES\" section.\n *\n * Figma node: 1283-2991\n *\n * Renders two side-by-side lists (products on the left, services on the\n * right) with an optional percentage next to each item. Long lists collapse\n * after `initialVisibleCount` items and reveal the rest behind an \"N More\"\n * disclosure that lives at the bottom of the affected column.\n *\n * Props:\n * - products Array Products discussed (string | { name, percent })\n * - services Array Services discussed (string | { name, percent })\n * - title string Section header label\n * - productsTitle string Left column title\n * - servicesTitle string Right column title\n * - initialVisibleCount number Items shown before \"N More\" kicks in (default 4)\n *\n * Returns null when both lists are empty so hosts can pass through API\n * payloads without guarding for missing blocks.\n */\n\nconst COLORS = {\n strong: \"var(--Grey-Strong, #2E3236)\",\n muted: \"var(--Grey-Muted, #808183)\",\n border: \"var(--Grey-absent, #D9D9D9)\",\n surfaceHover: \"var(--surface-hover, #F3F7F7)\",\n // Section header icon — Figma uses the warm orange accent used for other\n // section markers (clipboard, compass) across the interaction details.\n iconAccent: \"var(--rail-orange, #C98A5A)\",\n};\n\nconst FONT_DISPLAY =\n \"var(--font-sans, 'Averta', ui-sans-serif, system-ui, sans-serif)\";\n\n// Normalise a list entry — accepts both raw strings and { name, percent }\n// objects so callers can mix and match. A null/empty name filters the row\n// out instead of rendering a blank pill.\nconst normaliseItem = (item) => {\n if (item == null) return null;\n if (typeof item === \"string\") {\n return { name: item, percent: null };\n }\n const name = item.name ?? item.label ?? item.title ?? \"\";\n if (!name) return null;\n return {\n name,\n percent:\n item.percent != null\n ? item.percent\n : item.percentage != null\n ? item.percentage\n : null,\n };\n};\n\n// Format a 0-100 number to \"26.3 %\" (one decimal, trailing space + %).\n// Ratios in 0..1 are auto-scaled. Returns null for non-numeric values so\n// the percent column collapses cleanly.\nconst fmtPercent = (value) => {\n if (value == null) return null;\n const num = Number(value);\n if (!Number.isFinite(num)) return null;\n const scaled = Math.abs(num) <= 1 ? num * 100 : num;\n return `${scaled.toFixed(1)} %`;\n};\n\n/* ── Single row (item name + optional percent) ── */\nconst ItemRow = ({ name, percent }) => (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"12px 0\",\n borderBottom: `1px solid ${COLORS.border}`,\n width: \"100%\",\n }}\n >\n <span\n style={{\n flex: 1,\n minWidth: 0,\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.strong,\n lineHeight: \"24px\",\n wordBreak: \"break-word\",\n }}\n >\n {name}\n </span>\n {percent != null && (\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.muted,\n lineHeight: \"24px\",\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n >\n {fmtPercent(percent)}\n </span>\n )}\n </div>\n);\n\n/* ── Single column (title + list + optional disclosure) ── */\nconst Column = ({ title, items, initialVisibleCount }) => {\n const [expanded, setExpanded] = useState(false);\n if (!items.length) return null;\n const overflow = Math.max(0, items.length - initialVisibleCount);\n const visible = expanded ? items : items.slice(0, initialVisibleCount);\n\n return (\n <div\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n gap: 8,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"8px 0\",\n width: \"100%\",\n }}\n >\n <span\n style={{\n flex: 1,\n minWidth: 0,\n fontFamily: FONT_DISPLAY,\n fontSize: 15,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: \"24px\",\n wordBreak: \"break-word\",\n }}\n >\n {title}\n </span>\n </div>\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n width: \"100%\",\n }}\n >\n {visible.map((item, i) => (\n <ItemRow key={i} name={item.name} percent={item.percent} />\n ))}\n </div>\n {overflow > 0 && (\n <button\n type=\"button\"\n onClick={() => setExpanded((prev) => !prev)}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n height: 29,\n padding: \"8px 0\",\n background: \"transparent\",\n border: \"none\",\n cursor: \"pointer\",\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: 1.2,\n whiteSpace: \"nowrap\",\n }}\n >\n {expanded ? \"Show Less\" : `${overflow} More`}\n {expanded ? (\n <ChevronUp size={16} color={COLORS.strong} strokeWidth={1.75} />\n ) : (\n <ChevronDown size={16} color={COLORS.strong} strokeWidth={1.75} />\n )}\n </button>\n )}\n </div>\n );\n};\n\n/* ── Main component ── */\nconst UpdatedProductsServices = ({\n products = [],\n services = [],\n title = \"Products & Services\",\n productsTitle = \"Products Discussed\",\n servicesTitle = \"Services Discussed\",\n initialVisibleCount = 4,\n}) => {\n const normalisedProducts = (products || [])\n .map(normaliseItem)\n .filter(Boolean);\n const normalisedServices = (services || [])\n .map(normaliseItem)\n .filter(Boolean);\n\n if (!normalisedProducts.length && !normalisedServices.length) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: 16,\n width: \"100%\",\n background: \"var(--Grey-White, #FFF)\",\n }}\n >\n {/* Section header — clipboard icon + uppercase title */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n height: 40,\n borderBottom: `1px solid ${COLORS.border}`,\n width: \"100%\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flex: 1,\n minWidth: 0,\n }}\n >\n <ClipboardCheck size={24} color={COLORS.iconAccent} strokeWidth={1.5} />\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 16,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: 1.2,\n textTransform: \"uppercase\",\n whiteSpace: \"nowrap\",\n }}\n >\n {title}\n </span>\n </div>\n </div>\n\n {/* Two columns side by side. Stack on narrow viewports via flexWrap so\n the section keeps working in the side-drawer layout. */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 24,\n flexWrap: \"wrap\",\n width: \"100%\",\n }}\n >\n <Column\n title={productsTitle}\n items={normalisedProducts}\n initialVisibleCount={initialVisibleCount}\n />\n <Column\n title={servicesTitle}\n items={normalisedServices}\n initialVisibleCount={initialVisibleCount}\n />\n </div>\n </div>\n );\n};\n\nexport default UpdatedProductsServices;\n","import { useState, useRef, useEffect, useMemo } from 'react';\nimport { ArrowLeft, ArrowRight, CalendarDays, PhoneIncoming, PhoneOutgoing, ClipboardList, FileSignal, Repeat, ChevronDown, ChevronRight, Headset, CircleUser, History, ExternalLink, Mail } from 'lucide-react';\nimport UpdatedInteractionContext from './UpdatedInteractionContext';\nimport UpdatedInteractionRecording from './UpdatedInteractionRecording';\nimport UpdatedCoachingSynthesisCard from './UpdatedCoachingSynthesisCard';\nimport UpdatedInteractionSignals from './UpdatedInteractionSignals';\nimport UpdatedCompassScore from './UpdatedCompassScore';\nimport UpdatedThreads from './UpdatedThreads';\nimport UpdatedGuidance from './UpdatedGuidance';\nimport UpdatedTalkPatterns from './UpdatedTalkPatterns';\nimport UpdatedProductsServices from './UpdatedProductsServices';\nimport AgentLiftAnalysisCard from '../common/AgentLiftAnalysisCard';\nimport SideDrawer from '../common/SideDrawer';\nimport { useMediaQuery } from '../../utils/useMediaQuery';\n\n/* Hover tooltip — fixed position to escape overflow containers.\n Anchored below the trigger. */\nconst NameTooltip = ({ text, children }) => {\n const [show, setShow] = useState(false);\n const triggerRef = useRef(null);\n const [pos, setPos] = useState({ top: 0, left: 0 });\n\n if (!text) return children;\n\n const handleEnter = () => {\n if (triggerRef.current) {\n const rect = triggerRef.current.getBoundingClientRect();\n setPos({\n top: rect.bottom + 6,\n left: rect.left + rect.width / 2,\n });\n }\n setShow(true);\n };\n\n return (\n <div\n ref={triggerRef}\n style={{ position: 'relative', display: 'inline-flex' }}\n onMouseEnter={handleEnter}\n onMouseLeave={() => setShow(false)}\n >\n {children}\n {show && (\n <div style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n transform: 'translate(-50%, 0)',\n display: 'flex',\n padding: 10,\n alignItems: 'center',\n borderRadius: 4,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-Strong, #2E3236)',\n zIndex: 9999,\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n }}>\n <span style={{\n color: '#FFF',\n fontSize: 12,\n fontWeight: 400,\n lineHeight: 'normal',\n }}>\n {text}\n </span>\n </div>\n )}\n </div>\n );\n};\n\n// Static base tabs. The optional \"Products & Services\" tab is inserted at\n// runtime by `useMemo(tabs)` below — only when the host passes products /\n// services data. Order in the rendered tabstrip mirrors the section order\n// in the page body so the scroll-spy reads top-to-bottom.\nconst BASE_TABS = [\n { key: 'overview', label: 'Overview' },\n { key: 'coaching', label: 'Coaching Summary' },\n { key: 'signals', label: 'Signals & Recording' },\n { key: 'comments', label: 'Feedback' },\n];\n\nfunction isAgentRole(role) {\n return /\\bagent\\b/.test(String(role ?? '').toLowerCase());\n}\n\nfunction isAdminRole(role) {\n return /(admin|superadmin|administrator)/.test(String(role ?? '').toLowerCase());\n}\n\n/** inbound | outbound | null — for session drawer title icons */\nfunction resolveSessionDirection(session, fallbackDirection) {\n const raw =\n session?.direction ??\n session?.interaction_direction ??\n session?.call_direction ??\n fallbackDirection;\n if (raw == null || raw === '') return null;\n const d = String(raw).toLowerCase().trim();\n if (d === 'outbound' || d.startsWith('outbound')) return 'outbound';\n if (d === 'inbound' || d.startsWith('inbound')) return 'inbound';\n return null;\n}\n\nconst UpdatedInteractionDetails = ({\n title = 'Wheel Stud Replacement Enquiry',\n onBack,\n // Data props — all optional with defaults for demo\n data,\n coachingData,\n coachingLoading = false,\n audioUrl,\n // Audio/playback props — pass these when the host app manages audio externally\n // (like InteractionDetailPanel does). If omitted, UpdatedInteractionRecording\n // manages its own audio element internally.\n audioRef: externalAudioRef,\n currentTimeSeconds,\n timelinePlaying,\n playbackRate,\n timelineSegments,\n onSeek,\n onTogglePlay,\n onSeekBack,\n onSeekForward,\n onSetPlaybackRate,\n // Speaker names\n agentName: externalAgentName,\n agentFullName: externalAgentFullName,\n customerName: externalCustomerName,\n customerFullName: externalCustomerFullName,\n // Transcript props — pass real transcript data from the host app\n transcript,\n activeTurnIndex,\n turnObservations,\n highlightedTurns,\n onTurnPlayPause,\n // Signal evidence playback — host app can provide to play audio segments from signals\n onPlayEvidence,\n onHighlightTurns,\n // Context props — pass from host app to override block-derived defaults\n callPurpose: externalCallPurpose,\n classification: externalClassification,\n outcomeQuality: externalOutcomeQuality,\n // Context \"More Details\" expandable section\n resolutionOutcome,\n customerIntent,\n location,\n interactionId,\n moreDetails,\n // Compass score props\n compassScore, // gauge meter value — compass_score, range 0.5-5\n compassMaxScore = 5,\n predictedCsat, // predicted objective number (e.g. compass_score) — shown as \"03\" top-right\n predictedLabel = 'Predicted Objective',\n compassLegends,\n // Customer session history drawer\n customerSessions: customerSessionsList,\n customerSessionCount,\n onSessionClick,\n onViewAllSessions,\n // Footer navigation\n prevSessionDesc,\n prevSessionDisabled = false,\n nextSessionDesc,\n nextSessionDisabled = false,\n onPreviousSession,\n onNextSession,\n // Comments\n comments = [],\n guidance = [],\n // Optional count summary for the Guidance section: { focus_count,\n // opportunity_count, excellence_count } — drives the small count bar above\n // the items.\n guidanceSummary,\n // Optional `components.talk_patterns.summary` from the API — surfaces\n // hold_type_counts, stall metrics, and response-time percentiles. Renders\n // a \"Talk Patterns\" card next to the Guidance section. When absent the\n // card is suppressed entirely.\n talkPatterns,\n // Optional \"PRODUCTS & SERVICES\" section. Accepts the resolved lists from\n // the API ({ products: [...], services: [...] }, or two separate arrays).\n // Items may be raw strings or { name, percent } objects. When both lists\n // are empty the entire section is suppressed.\n productsServices,\n productsDiscussed,\n servicesDiscussed,\n currentUser,\n onSendComment,\n onSendReply,\n onReply,\n onEdit,\n onEditInteraction,\n onDelete,\n onMenuClick,\n onMarkResolved,\n commentsResolved,\n}) => {\n const [activeTab, setActiveTab] = useState('overview');\n const [expandedSignals, setExpandedSignals] = useState(new Set());\n const [showSessionDrawer, setShowSessionDrawer] = useState(false);\n const [hoveredSessionIdx, setHoveredSessionIdx] = useState(null);\n const [internalPlaying, setInternalPlaying] = useState(false);\n const [internalCurrentTime, setInternalCurrentTime] = useState(0);\n const [isScrolledPastHeader, setIsScrolledPastHeader] = useState(false);\n // Phone breakpoint — stacks the two-column rows and trims padding so the\n // detail view is usable on narrow screens (<= 640px).\n const isPhone = useMediaQuery('(max-width: 640px)');\n const recordingRef = useRef(null);\n\n // Section refs for scroll-to-section tab behavior\n const overviewRef = useRef(null);\n const coachingRef = useRef(null);\n const signalsRef = useRef(null);\n const productsRef = useRef(null);\n const commentsRef = useRef(null);\n const sectionRefs = {\n overview: overviewRef,\n coaching: coachingRef,\n signals: signalsRef,\n products: productsRef,\n comments: commentsRef,\n };\n const scrollContainerRef = useRef(null);\n const isClickScrolling = useRef(false);\n\n // Whether the host has actually passed product/service data. The\n // \"Products & Services\" tab + section is mounted only when at least one\n // of the two lists has items, so an interaction with no entities doesn't\n // surface an empty tab.\n const hasProductsServices = useMemo(() => {\n const products = productsServices?.products ?? productsDiscussed ?? [];\n const services = productsServices?.services ?? servicesDiscussed ?? [];\n return products.length > 0 || services.length > 0;\n }, [productsServices, productsDiscussed, servicesDiscussed]);\n\n // Tabstrip — inserts \"Products & Services\" between Signals and Feedback\n // when data is present. Stays in sync with the section order below so the\n // scroll-spy reads top-to-bottom.\n const tabs = useMemo(() => {\n if (!hasProductsServices) return BASE_TABS;\n const out = [];\n for (const t of BASE_TABS) {\n if (t.key === 'comments') {\n out.push({ key: 'products', label: 'Products & Services' });\n }\n out.push(t);\n }\n return out;\n }, [hasProductsServices]);\n\n // Scroll-spy: update active tab based on which section's top is nearest the viewport\n useEffect(() => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n const tabKeys = tabs.map((t) => t.key);\n const refs = tabKeys.map((k) => sectionRefs[k]);\n\n // Find the closest scrollable ancestor (the element that actually scrolls)\n const getScrollParent = (el) => {\n let node = el.parentElement;\n while (node) {\n const { overflow, overflowY } = window.getComputedStyle(node);\n if (/(auto|scroll)/.test(overflow + overflowY)) return node;\n node = node.parentElement;\n }\n return null;\n };\n\n const scrollParent = getScrollParent(container);\n\n const handleScroll = () => {\n if (isClickScrolling.current) return;\n\n let activeKey = tabKeys[0];\n\n // Use viewport-relative positions — works regardless of which element scrolls\n for (let i = refs.length - 1; i >= 0; i--) {\n const el = refs[i].current;\n if (!el) continue;\n const rect = el.getBoundingClientRect();\n // Section is \"active\" when its top has scrolled above 150px from viewport top\n if (rect.top <= 150) {\n activeKey = tabKeys[i];\n break;\n }\n }\n\n setActiveTab(activeKey);\n\n // Move session nav from title row to sticky tabs once content starts scrolling.\n const overviewTop = overviewRef.current?.getBoundingClientRect().top ?? Number.POSITIVE_INFINITY;\n setIsScrolledPastHeader(overviewTop <= 150);\n };\n\n // Attach to all possible scroll targets\n container.addEventListener('scroll', handleScroll, { passive: true });\n if (scrollParent && scrollParent !== container) {\n scrollParent.addEventListener('scroll', handleScroll, { passive: true });\n }\n window.addEventListener('scroll', handleScroll, { passive: true, capture: true });\n handleScroll();\n\n return () => {\n container.removeEventListener('scroll', handleScroll);\n if (scrollParent && scrollParent !== container) {\n scrollParent.removeEventListener('scroll', handleScroll);\n }\n window.removeEventListener('scroll', handleScroll, { capture: true });\n };\n // Re-run when the tab list changes (e.g. the optional Products & Services\n // tab appears/disappears) so the scroll-spy tracks the current set of\n // sections. `sectionRefs` reads stable refs created above; not in deps.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tabs]);\n\n const clickedTabRef = useRef(null);\n\n const handleTabClick = (key) => {\n setActiveTab(key);\n isClickScrolling.current = true;\n clickedTabRef.current = key;\n const el = sectionRefs[key]?.current;\n if (el) {\n // Offset scroll to account for the sticky header + tabs (~120px)\n const container = scrollContainerRef.current;\n if (container && container.scrollHeight > container.clientHeight) {\n // Container itself scrolls\n const containerTop = container.getBoundingClientRect().top;\n const elTop = el.getBoundingClientRect().top;\n const offset = elTop - containerTop + container.scrollTop - 16;\n container.scrollTo({ top: offset, behavior: 'smooth' });\n } else {\n // Page/parent scrolls — use window with offset\n const elTop = el.getBoundingClientRect().top + window.scrollY - 120;\n window.scrollTo({ top: elTop, behavior: 'smooth' });\n }\n }\n setTimeout(() => {\n isClickScrolling.current = false;\n clickedTabRef.current = null;\n }, 1200);\n };\n\n const sessionHistory = customerSessionsList || [];\n const hasPastSessions = sessionHistory.length > 1;\n\n /* Called from Signals/Guidance \"Show in transcript\" icon —\n switches to Signals section, then scrolls/highlights transcript card without playing audio. */\n const handleShowInTranscript = (startMs) => {\n setActiveTab('signals');\n const signalsEl = signalsRef.current;\n if (signalsEl) {\n const container = scrollContainerRef.current;\n if (container && container.scrollHeight > container.clientHeight) {\n const containerTop = container.getBoundingClientRect().top;\n const elTop = signalsEl.getBoundingClientRect().top;\n const offset = elTop - containerTop + container.scrollTop - 16;\n container.scrollTo({ top: offset, behavior: 'smooth' });\n } else {\n const elTop = signalsEl.getBoundingClientRect().top + window.scrollY - 120;\n window.scrollTo({ top: elTop, behavior: 'smooth' });\n }\n }\n\n const timeSec = startMs / 1000;\n // Wait briefly so section scroll starts before transcript container scroll/highlight.\n setTimeout(() => {\n if (recordingRef.current?.scrollToTranscript) {\n recordingRef.current.scrollToTranscript(timeSec);\n }\n }, 220);\n };\n\n /* Called from Signals evidence play button — seeks + plays audio segment */\n const handlePlayEvidence = (ev) => {\n setActiveTab('signals');\n const signalsEl = signalsRef.current;\n if (signalsEl) {\n const container = scrollContainerRef.current;\n if (container && container.scrollHeight > container.clientHeight) {\n const containerTop = container.getBoundingClientRect().top;\n const elTop = signalsEl.getBoundingClientRect().top;\n const offset = elTop - containerTop + container.scrollTop - 16;\n container.scrollTo({ top: offset, behavior: 'smooth' });\n } else {\n const elTop = signalsEl.getBoundingClientRect().top + window.scrollY - 120;\n window.scrollTo({ top: elTop, behavior: 'smooth' });\n }\n }\n\n const startMs = ev?.start_ms ?? ev?.startMs;\n\n // Wait briefly so section scroll starts before playback seek/play begins.\n setTimeout(() => {\n // Keep transcript highlight behavior consistent with \"Show in transcript\".\n if (startMs != null && recordingRef.current?.scrollToTranscript) {\n recordingRef.current.scrollToTranscript(startMs / 1000);\n }\n\n if (onPlayEvidence) {\n onPlayEvidence(ev);\n } else {\n // Default: seek to evidence start time via recording ref\n if (startMs != null && recordingRef.current?.seekTo) {\n recordingRef.current.seekTo(startMs / 1000);\n setInternalPlaying(true);\n setInternalCurrentTime(startMs / 1000);\n // Stop playing after evidence duration\n const endMs = ev.end_ms ?? ev.endMs ?? (startMs + 5000);\n const durationMs = endMs - startMs;\n setTimeout(() => setInternalPlaying(false), durationMs);\n }\n }\n }, 220);\n };\n\n /* Called to highlight transcript turns related to evidence */\n const handleHighlightTurns = (turnIds) => {\n if (onHighlightTurns) {\n onHighlightTurns(turnIds);\n }\n };\n\n const toggleSignal = (key) => {\n setExpandedSignals((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return next;\n });\n };\n\n // Extract data from blocks if provided\n const blocks = data?.blocks || [];\n const findBlock = (id) => blocks.find((b) => b.block_id === id)?.payload || {};\n\n const meta = findBlock('interaction-metadata');\n const ctx = findBlock('interaction-context');\n const signals = findBlock('interaction-signals');\n const outcomeLift = findBlock('interaction-outcome-lift');\n const dimensionsBlock = findBlock('interaction-dimensions');\n const blockDimensions = dimensionsBlock.dimensions || [];\n const callPurpose = ctx.call_purpose || {};\n const classification = ctx.classification || {};\n\n const resolvedMeta = meta || {};\n const resolvedCallPurpose = externalCallPurpose || callPurpose || {};\n const resolvedClassification = externalClassification || classification || {};\n const resolvedOutcomeLift = outcomeLift || {};\n const resolvedDriverLabels = (resolvedOutcomeLift.driver_signal_keys || [])\n .map((k) => k.replace(/^sig\\./, '').replace(/_/g, ' '));\n const resolvedCoaching = coachingData || null;\n const resolvedSignals = signals?.signals?.length\n ? signals\n : { present_count: 0, total_signals_evaluated: 0, signals: [] };\n const guidanceData = guidance || [];\n\n // Resolve names: explicit props → metadata block → context block → fallback\n const agentName = externalAgentName || meta.agent_name || meta.agent || ctx.agent_name || 'Agent';\n const agentFullName = externalAgentFullName || meta.agent_full_name || meta.agent_name || agentName;\n const customerName = externalCustomerName || meta.customer_name || meta.customer || ctx.customer_name || 'Customer';\n const customerFullName = externalCustomerFullName || meta.customer_full_name || meta.customer_name || customerName;\n const resolvedUserRole = String(\n currentUser?.role ??\n currentUser?.userRole ??\n currentUser?.user_role ??\n currentUser?.roleName ??\n currentUser?.role_name ??\n ''\n ).toLowerCase();\n const canEditInteraction = isAdminRole(resolvedUserRole);\n // Agent-role users don't see the Agent Lift Analysis card at all (updated\n // design, Figma node 1798-5177 — agent view is the context grid only).\n const isAgentUser = isAgentRole(resolvedUserRole);\n const sessionCount = customerSessionCount ?? sessionHistory.length;\n const rawDate = meta.created_dt || data?.created_dt || ctx.created_dt || '';\n const dateStr = rawDate\n ? new Date(/Z$|[+-]\\d{2}:\\d{2}$/.test(rawDate) ? rawDate : rawDate + 'Z').toLocaleString()\n : '';\n const direction = resolvedCallPurpose.interaction_direction === 'inbound' ? 'Inbound' : 'Outbound';\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', width: '100%', maxWidth: '100%', height: '100%', background: 'var(--Grey-White, #FFF)', overflowX: isPhone ? 'clip' : undefined }}>\n {/* Sticky Header + Tabs */}\n {/* Header */}\n <div style={{ display: 'flex', flexDirection: isPhone ? 'column' : 'row', alignItems: isPhone ? 'stretch' : 'center', gap: 12, padding: isPhone ? '16px 16px 0' : '18px 24px 0' }}>\n {/* Title row (back + divider + title). On phones the prev/next row is\n placed above this via flex `order`. */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, minWidth: 0, ...(isPhone ? { order: 2, width: '100%' } : { flex: 1 }) }}>\n <button\n onClick={onBack}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: 0,\n flexShrink: 0,\n }}\n >\n <ArrowLeft size={24} color=\"var(--Grey-Strong, #2E3236)\" />\n </button>\n <div style={{ width: 1, height: 28, background: 'var(--Base-absent, #D9D9D9)' }} />\n <h1 style={{\n color: 'var(--Grey-Strong, #2E3236)',\n fontSize: 24,\n fontStyle: 'normal',\n fontWeight: 400,\n lineHeight: 'normal',\n margin: 0,\n flex: 1,\n }}>\n {title}\n </h1>\n </div>\n\n {/* Figma node 605-1186: Previous / Next Session — inline in header.\n On phones it wraps to its own full-width row (space-between) so both\n buttons fit without horizontal scroll. On phones it always shows\n here because the scrolled-state copy lives in the (hidden) tabs bar. */}\n {(onPreviousSession || onNextSession) && (isPhone || !isScrolledPastHeader) && (\n <div style={{\n display: 'flex',\n alignItems: 'center',\n flexShrink: 0,\n ...(isPhone ? { width: '100%', justifyContent: 'space-between', order: 1 } : {}),\n }}>\n {/* Previous Session */}\n <NameTooltip text={prevSessionDesc}>\n <button\n onClick={prevSessionDisabled ? undefined : onPreviousSession}\n disabled={prevSessionDisabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 12px',\n background: 'none',\n border: 'none',\n cursor: prevSessionDisabled ? 'default' : 'pointer',\n opacity: prevSessionDisabled ? 0.4 : 1,\n }}\n >\n <ArrowLeft size={16} color=\"var(--Neutral-800, #323232)\" strokeWidth={1.5} />\n <span style={{\n color: 'var(--Neutral-800, #323232)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: '24px',\n fontFamily: 'var(--default-font-family)',\n whiteSpace: 'nowrap',\n }}>\n Previous Interaction\n </span>\n </button>\n </NameTooltip>\n\n {/* Divider */}\n <div style={{\n width: 1,\n height: 20,\n background: 'var(--Grey-absent, #D9D9D9)',\n flexShrink: 0,\n }} />\n\n {/* Next Session */}\n <NameTooltip text={nextSessionDesc}>\n <button\n onClick={nextSessionDisabled ? undefined : onNextSession}\n disabled={nextSessionDisabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 12px',\n background: 'none',\n border: 'none',\n cursor: nextSessionDisabled ? 'default' : 'pointer',\n opacity: nextSessionDisabled ? 0.4 : 1,\n }}\n >\n <span style={{\n color: 'var(--Neutral-800, #323232)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: '24px',\n fontFamily: 'var(--default-font-family)',\n whiteSpace: 'nowrap',\n }}>\n Next Interaction\n </span>\n <ArrowRight size={16} color=\"var(--Neutral-800, #323232)\" strokeWidth={1.5} />\n </button>\n </NameTooltip>\n </div>\n )}\n </div>\n\n {/* Sticky tabs bar.\n - `top: 0` so the bar sticks flush against the top of its scroll\n ancestor with no transparent gap above it. Earlier `top: 68` was\n assumed to clear a host nav, but the in-page area above the tabs\n ended up showing the page content scrolling up underneath.\n - `background: #FFFFFF` is set explicitly (not via CSS var) so the\n bar is guaranteed opaque even if the host's token sheet hasn't\n loaded yet, which prevents scrolled content from bleeding through.\n - `paddingTop: 8` replaces the previous `marginTop: 8` on the inner\n row so the white background fills the gap above the tabs (margin\n on a child can leave a translucent strip in the parent on some\n engines).\n - `zIndex: 30` keeps the bar above in-content stacking contexts\n (chart cards, gauges, etc.). */}\n {/* Tabs bar — hidden on phones (sections just scroll); avoids the\n horizontal-scroll tab strip on narrow screens. */}\n {!isPhone && (\n <div style={{\n position: 'sticky',\n top: 0,\n zIndex: 30,\n backgroundColor: '#FFFFFF',\n paddingTop: 8,\n // Defensive: small downward shadow so any sub-pixel rendering gap\n // between the sticky bar and scrolled content can't reveal what's\n // beneath. Also visually separates the bar from the section content.\n boxShadow: '0 4px 6px -4px rgba(0, 0, 0, 0.04)',\n }}>\n {/* Tabs + sticky session nav at far right */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 16,\n background: '#FFFFFF',\n borderBottom: '1px solid var(--Grey-Faint, #ACADAD)',\n padding: isPhone ? '0 16px' : '0 24px',\n }}>\n <div\n className=\"custom-thin-scrollbar-hidden\"\n style={{ display: 'flex', alignItems: 'flex-start', minWidth: 0, overflowX: isPhone ? 'auto' : 'visible' }}\n >\n {tabs.map((tab) => (\n <button\n key={tab.key}\n onClick={() => handleTabClick(tab.key)}\n style={{\n display: 'flex',\n padding: 16,\n alignItems: 'center',\n gap: 10,\n flexShrink: 0,\n background: 'none',\n border: 'none',\n borderBottom: activeTab === tab.key\n ? '3px solid var(--Grey-Strong, #2E3236)'\n : '3px solid transparent',\n cursor: 'pointer',\n fontSize: 15,\n fontWeight: activeTab === tab.key ? 500 : 400,\n color: activeTab === tab.key\n ? 'var(--Grey-Strong, #2E3236)'\n : 'var(--Grey-Muted, #808183)',\n whiteSpace: 'nowrap',\n transition: 'border-color 0.2s ease, color 0.2s ease',\n }}\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {(onPreviousSession || onNextSession) && isScrolledPastHeader && (\n <div style={{ display: 'flex', alignItems: 'center', flexShrink: 0 }}>\n <NameTooltip text={prevSessionDesc}>\n <button\n onClick={prevSessionDisabled ? undefined : onPreviousSession}\n disabled={prevSessionDisabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 12px',\n background: 'none',\n border: 'none',\n cursor: prevSessionDisabled ? 'default' : 'pointer',\n opacity: prevSessionDisabled ? 0.4 : 1,\n }}\n >\n <ArrowLeft size={16} color=\"var(--Neutral-800, #323232)\" strokeWidth={1.5} />\n <span style={{\n color: 'var(--Neutral-800, #323232)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: '24px',\n fontFamily: 'var(--default-font-family)',\n whiteSpace: 'nowrap',\n }}>\n Previous Interaction\n </span>\n </button>\n </NameTooltip>\n\n <div style={{\n width: 1,\n height: 20,\n background: 'var(--Grey-absent, #D9D9D9)',\n flexShrink: 0,\n }} />\n\n <NameTooltip text={nextSessionDesc}>\n <button\n onClick={nextSessionDisabled ? undefined : onNextSession}\n disabled={nextSessionDisabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 12px',\n background: 'none',\n border: 'none',\n cursor: nextSessionDisabled ? 'default' : 'pointer',\n opacity: nextSessionDisabled ? 0.4 : 1,\n }}\n >\n <span style={{\n color: 'var(--Neutral-800, #323232)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: '24px',\n fontFamily: 'var(--default-font-family)',\n whiteSpace: 'nowrap',\n }}>\n Next Interaction\n </span>\n <ArrowRight size={16} color=\"var(--Neutral-800, #323232)\" strokeWidth={1.5} />\n </button>\n </NameTooltip>\n </div>\n )}\n </div>\n </div>\n )}{/* end sticky header + tabs */}\n\n {/* All sections rendered — tabs scroll to them */}\n <div ref={scrollContainerRef} style={{ padding: isPhone ? 16 : 24, flex: 1, overflowY: 'auto', ...(isPhone ? { minWidth: 0, overflowX: 'hidden' } : {}) }}>\n {/* ═══ OVERVIEW SECTION ═══ */}\n <div ref={overviewRef} style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'flex-end',\n alignItems: 'flex-start',\n gap: 24,\n alignSelf: 'stretch',\n }}>\n {/* Figma node 106-3508: Section Header — horizontal, gap: 16, height: 40, center */}\n <div style={{\n display: 'flex',\n flexWrap: isPhone ? 'wrap' : 'nowrap',\n height: isPhone ? 'auto' : 40,\n alignItems: isPhone ? 'flex-start' : 'center',\n gap: isPhone ? 8 : 16,\n alignSelf: 'stretch',\n }}>\n {/* Left: Icon + Title — fills remaining space */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flex: 1 }}>\n <ClipboardList size={24} color=\"var(--rail-orange, #C98A5A)\" strokeWidth={2} />\n <span style={{\n fontSize: 16,\n fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n textTransform: 'uppercase',\n }}>\n Overview\n </span>\n </div>\n\n {/* Right: Metadata — a wrapping row. On phones the date + direction\n sit together on the first line; the agent/customer group wraps\n to its own full-width line below (so it isn't clipped). */}\n <div style={{ display: 'flex', flexDirection: 'row', flexWrap: isPhone ? 'wrap' : 'nowrap', alignItems: 'center', gap: isPhone ? '8px 16px' : 16, flexShrink: 0, ...(isPhone ? { width: '100%' } : {}) }}>\n {/* Date */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 0' }}>\n <CalendarDays size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', fontFamily: 'var(--font-sans)', lineHeight: 1.2 }}>\n {dateStr}\n </span>\n </div>\n\n {/* Direction — outbound calls show PhoneOutgoing (arrow\n leaving), inbound show PhoneIncoming (arrow entering).\n Falls back to PhoneIncoming when the API value is missing\n so the row still renders. */}\n {(() => {\n const DirectionIcon =\n resolvedCallPurpose.interaction_direction === 'outbound'\n ? PhoneOutgoing\n : PhoneIncoming;\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 0' }}>\n <DirectionIcon size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', fontFamily: 'var(--font-sans)', lineHeight: 1.2 }}>\n {direction}\n </span>\n </div>\n );\n })()}\n\n {/* Agent + Customer — border-left separator (drops the border and\n wraps on phones so the wide customer pill isn't clipped). */}\n <div style={{\n display: 'flex',\n flexWrap: isPhone ? 'wrap' : 'nowrap',\n alignItems: 'center',\n gap: isPhone ? 12 : 16,\n ...(isPhone\n ? { flexBasis: '100%', width: '100%' }\n : { paddingLeft: 16, borderLeft: '1px solid var(--Grey-absent, #D9D9D9)' }),\n }}>\n {/* Agent — Headset icon + tooltip */}\n <NameTooltip text={agentFullName}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 0', cursor: 'pointer' }}>\n <Headset size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', fontFamily: 'var(--font-sans)', lineHeight: 1.2 }}>\n {agentName}\n </span>\n </div>\n </NameTooltip>\n\n {/* Repeat icon */}\n {/* <Repeat size={16} color=\"var(--color-input-border, #ACACAD)\" strokeWidth={1.5} /> */}\n\n {/* Customer — CircleUser icon + side drawer trigger (only if > 1 session) */}\n {sessionCount > 1 ? (\n <div>\n <NameTooltip text={customerFullName}>\n <button\n onClick={() => setShowSessionDrawer(true)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n padding: '0 16px',\n height: 34,\n borderRadius: 8,\n background: 'var(--Rail-Surface-2, #E3E1D7)',\n border: 'none',\n cursor: 'pointer',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, minWidth: 0 }}>\n <CircleUser size={16} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', lineHeight: 1.2, whiteSpace: 'nowrap' }}>\n <span style={{ fontWeight: 600 }}>{customerName}</span>{' '}\n <span>({sessionCount} Interactions)</span>\n </span>\n </div>\n <ChevronRight size={16} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.7} />\n </button>\n </NameTooltip>\n </div>\n ) : (\n <NameTooltip text={customerFullName}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, padding: '8px 0', cursor: 'pointer' }}>\n <CircleUser size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', lineHeight: 1.2 }}>\n {customerName}\n </span>\n </div>\n </NameTooltip>\n )}\n </div>\n </div>\n </div>\n\n {/*\n Figma node 101-2385\n Row: Compass Score (left) | Context + Agent Lift Analysis stacked (right)\n */}\n <div style={{\n display: 'flex',\n flexDirection: isPhone ? 'column' : 'row',\n alignItems: 'stretch',\n gap: 24,\n alignSelf: 'stretch',\n }}>\n {/* Left — Compass Score */}\n <div style={{ flex: 1, minWidth: 0, display: 'flex' }}>\n <UpdatedCompassScore\n score={compassScore ?? 0.5}\n minScore={0}\n maxScore={compassMaxScore}\n predictedScore={predictedCsat ?? 0.5}\n predictedLabel={predictedLabel}\n legends={compassLegends}\n // Outcome value (interaction-outcome-lift `p_full`) shown in\n // percent, in round brackets after the score — Figma 1798-5168.\n outcomePercent={\n resolvedOutcomeLift?.p_full != null\n ? Math.round(resolvedOutcomeLift.p_full * 100)\n : null\n }\n />\n </div>\n\n {/* Right — Context grid + Agent Lift Analysis stacked.\n Admins/supervisors bottom-align the stack so the lift card's\n bottom lines up with the Interaction Quality card. Agents have\n no lift card, so the context grid top-aligns instead of being\n pushed to the bottom of the taller row. */}\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'stretch',\n justifyContent: isAgentUser ? 'flex-start' : 'flex-end',\n gap: 24,\n flex: 1,\n minWidth: 0,\n }}>\n <UpdatedInteractionContext\n meta={resolvedMeta}\n callPurpose={resolvedCallPurpose}\n classification={resolvedClassification}\n outcomeQuality={externalOutcomeQuality || 'Neutral'}\n dimensions={blockDimensions}\n resolutionOutcome={resolutionOutcome}\n customerIntent={customerIntent}\n location={location ?? meta.location ?? meta.location_name ?? ctx.location}\n interactionId={interactionId ?? meta.interaction_id}\n moreDetails={moreDetails}\n canShowEditButton={canEditInteraction}\n onEditInteraction={onEditInteraction}\n // Agents get the flat context grid (no \"More Details\" toggle)\n // per Figma node 1798-5177.\n flatView={isAgentUser}\n />\n {/* Agent Lift Analysis — two-column gauge card (Figma node\n 1463:4261): Interaction Difficulty + Agent Impact. The\n `interaction-outcome-lift` API block ships `p_expected`\n (call-difficulty baseline) and `lift_raw` (probability\n delta the agent contributed); we map those onto the card's\n normalised [-1, +1] gauge inputs. The Outcome column was\n removed per the updated design — for every user role.\n Hidden entirely for Agent-role users (Figma node\n 1798-5177 — agents see the context grid only). */}\n {!isAgentUser && (() => {\n const liftData = resolvedOutcomeLift || {};\n\n // ── Pull every value used in the card straight from the\n // API payload. Nothing on this card is invented or\n // derived from a different field — if the API doesn't\n // ship a value, the corresponding piece of UI is hidden.\n const difficultyScore = liftData.difficulty;\n const difficultyBand = liftData.difficulty_band;\n // \"X% Score impact\" footer source (Figma 1463:4261): the\n // API ships either an explicit `score_impact` or, when it\n // doesn't, the baseline `p_expected` carries that meaning\n // and is what the Figma comp uses. We don't invent a value\n // — we read one of two API-provided probabilities.\n const pExpected = liftData.p_expected;\n const scoreImpact = liftData.score_impact ?? pExpected;\n\n const liftRaw = liftData.lift_raw;\n const liftDisplay = liftData.lift_display;\n const liftBand = liftData.interpretation?.lift_band;\n\n const pFull = liftData.p_full;\n const interpretationDescription =\n liftData.interpretation?.description;\n\n // Card-level gate: only hide if the API shipped literally\n // nothing useful. As soon as ANY field is present we\n // render the full three-column layout; missing columns\n // show \"—\" placeholders rather than being suppressed.\n const hasAnyData =\n difficultyScore != null ||\n difficultyBand != null ||\n liftRaw != null ||\n liftBand != null ||\n pFull != null ||\n interpretationDescription != null;\n if (!hasAnyData) {\n return null;\n }\n\n const clampVal = (v, lo, hi) =>\n Math.max(lo, Math.min(hi, v));\n\n // Difficulty gauge — drive the needle from the API's\n // 0-100 `difficulty` score. 50 sits at the centre; lower\n // values pull the needle left (\"easier\"), higher right\n // (\"harder\"). Pure linear map, no smoothing.\n const difficultyValue =\n difficultyScore != null\n ? clampVal((difficultyScore - 50) / 50, -1, 1)\n : 0;\n\n // Impact gauge — `lift_raw` is a probability delta\n // typically within ±0.3; the ×3 spread is display-only\n // so the needle visibly moves at realistic lift sizes.\n // No label, no numeric readout is derived from this —\n // those come from API string fields below.\n const impactValue =\n liftRaw != null ? clampVal(liftRaw * 3, -1, 1) : 0;\n\n // \"X% Score impact\" footer for the Difficulty column —\n // only renders when the API explicitly ships\n // `score_impact`. We don't substitute another field\n // under the same label.\n const scoreImpactPercent =\n scoreImpact != null\n ? Math.round(scoreImpact * 100)\n : null;\n\n // Title-case API band strings (\"strong_negative\" →\n // \"Strong Negative\") for the gauge centre labels.\n const prettyBand = (band) => {\n if (!band) return undefined;\n return String(band)\n .split('_')\n .map((w) =>\n w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()\n )\n .join(' ');\n };\n const difficultyLabel = prettyBand(difficultyBand);\n const impactLabel = prettyBand(liftBand);\n\n // `impactPercent` is what the card uses to build its\n // \"X% Score impact\" footer. Source it from the API's\n // pre-formatted `lift_display` (\"-6.9%\") when possible\n // so on-screen rounding matches the backend; fall back\n // to `lift_raw * 100` only when `lift_display` is absent.\n const impactPercent = (() => {\n if (typeof liftDisplay === 'string') {\n const parsed = parseFloat(liftDisplay.replace('%', ''));\n if (Number.isFinite(parsed)) return parsed;\n }\n if (liftRaw != null) {\n return Math.round(liftRaw * 100);\n }\n return null;\n })();\n\n return (\n <AgentLiftAnalysisCard\n title=\"Agent Lift Analysis\"\n // Both gauge columns always render. When a column's\n // numeric/label data is null the card swaps in \"—\"\n // placeholders so the layout stays consistent across\n // calls with partial data. The Outcome column was removed\n // per the updated design (Figma 1463:4261).\n interactionDifficulty={{\n value:\n difficultyScore != null ? difficultyValue : null,\n label: difficultyLabel,\n sublabel: 'Based on interaction type',\n footer:\n scoreImpactPercent != null\n ? `${scoreImpactPercent}% Score impact`\n : undefined,\n }}\n agentImpact={{\n value: liftRaw != null ? impactValue : null,\n label: impactLabel,\n // Sublabel slot (rendered immediately below the\n // lift-band label) carries the API's\n // `interpretation.description`.\n sublabel: interpretationDescription,\n impactPercent,\n // When the API ships `lift_band: \"learning\"` the model\n // doesn't have enough signal for this interaction type\n // yet. The card swaps the gauge for a \"Compass is\n // Learning..\" placeholder (Figma node 1211:4526).\n isLearning:\n String(liftBand ?? '').toLowerCase() === 'learning',\n }}\n />\n );\n })()}\n </div>\n </div>\n\n </div>\n\n {/* ═══ COACHING SUMMARY SECTION ═══ */}\n <div ref={coachingRef} style={{ paddingTop: 24 }}>\n <UpdatedCoachingSynthesisCard data={coachingLoading ? null : resolvedCoaching} loading={coachingLoading} />\n </div>\n\n {/* ═══ SIGNALS & RECORDING SECTION ═══ */}\n <div ref={signalsRef} style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n alignSelf: 'stretch',\n paddingTop: 24,\n }}>\n {/* Section header */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n }}>\n <FileSignal size={24} color=\"#C98A5A\" strokeWidth={2} />\n <span style={{\n fontSize: 16,\n fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n textTransform: 'uppercase',\n }}>\n Signals & Recording\n </span>\n </div>\n\n {/* Content: Signals (left) | Recording+Transcript (right) */}\n <div style={{\n display: 'flex',\n flexDirection: isPhone ? 'column' : 'row',\n alignItems: isPhone ? 'stretch' : 'flex-start',\n gap: 24,\n alignSelf: 'stretch',\n paddingTop: 16,\n borderTop: '1px solid #D9D9D9',\n }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <UpdatedInteractionSignals\n signals={resolvedSignals}\n expandedSignals={expandedSignals}\n toggleSignal={toggleSignal}\n playEvidence={handlePlayEvidence}\n highlightTurns={handleHighlightTurns}\n onShowInTranscript={handleShowInTranscript}\n timelinePlaying={timelinePlaying || internalPlaying}\n currentTimeSeconds={currentTimeSeconds ?? internalCurrentTime}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <UpdatedInteractionRecording\n ref={recordingRef}\n audioUrl={audioUrl}\n durationSeconds={resolvedMeta.duration_seconds}\n audioRef={externalAudioRef}\n agentName={agentName}\n customerName={customerName}\n currentTimeSeconds={currentTimeSeconds}\n timelinePlaying={timelinePlaying}\n playbackRate={playbackRate}\n timelineSegments={timelineSegments}\n onSeek={onSeek}\n onTogglePlay={onTogglePlay}\n onSeekBack={onSeekBack}\n onSeekForward={onSeekForward}\n onSetPlaybackRate={onSetPlaybackRate}\n transcript={transcript}\n activeTurnIndex={activeTurnIndex}\n turnObservations={turnObservations}\n highlightedTurns={highlightedTurns}\n onTurnPlayPause={onTurnPlayPause}\n setExpandedSignals={setExpandedSignals}\n />\n </div>\n </div>\n </div>\n\n {/* ═══ PRODUCTS & SERVICES SECTION ═══\n Sits between the recording / signals area and the feedback /\n guidance threads. Accepts either a single `productsServices`\n object ({ products, services }) or two flat arrays so hosts can\n wire it straight from the API payload they prefer. The component\n self-suppresses when both lists are empty. */}\n {(() => {\n const products =\n productsServices?.products ?? productsDiscussed ?? [];\n const services =\n productsServices?.services ?? servicesDiscussed ?? [];\n if (!products.length && !services.length) return null;\n return (\n // ref={productsRef} so the \"Products & Services\" tab's click\n // handler and the scroll-spy can target this section like the\n // other top-level sections.\n <div ref={productsRef} style={{ paddingTop: 24 }}>\n <UpdatedProductsServices\n products={products}\n services={services}\n />\n </div>\n );\n })()}\n\n {/* ═══ FEEDBACK SECTION ═══ */}\n <div ref={commentsRef} style={{ paddingTop: 24 }}>\n <UpdatedThreads\n comments={comments}\n totalComments={comments.length}\n currentUser={currentUser}\n onSendComment={onSendComment || (() => {})}\n onSendReply={onSendReply || (() => {})}\n onReply={onReply || (() => {})}\n onEdit={onEdit || (() => {})}\n onDelete={onDelete || (() => {})}\n onMenuClick={onMenuClick || (() => {})}\n onMarkResolved={onMarkResolved || (() => {})}\n isResolved={commentsResolved}\n >\n <UpdatedGuidance\n items={guidanceData}\n summary={guidanceSummary}\n guidanceCount={guidanceData.length}\n onPlayEvidence={handlePlayEvidence}\n onShowInTranscript={handleShowInTranscript}\n timelinePlaying={timelinePlaying || internalPlaying}\n currentTimeSeconds={currentTimeSeconds ?? internalCurrentTime}\n />\n {/* Talk Patterns (hold-type counts + stall metrics + response\n percentiles). Mounted after Guidance so the order matches\n the Feedback-tab section flow. Self-suppresses when the\n summary block is absent or all metrics are zero. */}\n <UpdatedTalkPatterns summary={talkPatterns} />\n </UpdatedThreads>\n </div>\n </div>\n\n <SideDrawer\n open={showSessionDrawer}\n onClose={() => setShowSessionDrawer(false)}\n title={(\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>\n <div style={{\n width: 34,\n height: 34,\n borderRadius: '50%',\n background: 'var(--surface-hover, #F3F7F7)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}>\n <CircleUser size={20} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.7} />\n </div>\n <div style={{ minWidth: 0 }}>\n <div style={{\n fontSize: 16,\n fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}>\n {customerName}\n </div>\n </div>\n </div>\n )}\n subtitle={hasPastSessions ? (\n <span style={{\n fontSize: 13,\n fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n lineHeight: 1.5,\n }}>\n {sessionCount} Interactions\n </span>\n ) : null}\n width={470}\n height=\"100vh\"\n topOffset={70}\n footer={hasPastSessions ? (\n <div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>\n <button\n onClick={() => { if (onViewAllSessions) onViewAllSessions(); setShowSessionDrawer(false); }}\n style={{\n display: 'flex',\n height: 40,\n padding: '0 20px 0 18px',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 7,\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 10,\n cursor: 'pointer',\n }}\n >\n <History size={18} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 15, fontWeight: 600, color: 'var(--Grey-Strong, #2E3236)' }}>\n View All Interactions\n </span>\n </button>\n </div>\n ) : null}\n >\n <div\n style={{\n borderTop: '1px solid var(--Grey-absent, #D9D9D9)',\n maxHeight: '100%',\n overflowY: 'auto',\n }}\n >\n {hasPastSessions ? sessionHistory.map((session, i) => {\n // The row representing the session the user is currently viewing\n // gets a non-interactive, highlighted treatment: Ask Compass beige\n // background, a slightly larger / bolder title, and no hover /\n // click / external-link affordances (you can't navigate to the\n // page you're already on).\n const isCurrent = !!session.isCurrent;\n const isHovered = !isCurrent && hoveredSessionIdx === i;\n const sessionDirection = resolveSessionDirection(\n session,\n resolvedCallPurpose.interaction_direction\n );\n const SessionDirectionIcon =\n sessionDirection === 'outbound' ? PhoneOutgoing : PhoneIncoming;\n return (\n <div\n key={session.id || i}\n onClick={\n isCurrent\n ? undefined\n : () => {\n if (onSessionClick) onSessionClick(session);\n setShowSessionDrawer(false);\n }\n }\n onMouseEnter={isCurrent ? undefined : () => setHoveredSessionIdx(i)}\n onMouseLeave={isCurrent ? undefined : () => setHoveredSessionIdx(null)}\n aria-current={isCurrent ? 'page' : undefined}\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n gap: 12,\n padding: '16px 12px',\n borderTop: i === 0 ? 'none' : '1px solid var(--Grey-absent, #D9D9D9)',\n background: isCurrent\n ? '#E3E1D7'\n : isHovered\n ? 'var(--surface-hover, #F3F7F7)'\n : 'var(--Grey-White, #FFF)',\n cursor: isCurrent ? 'default' : 'pointer',\n transition: 'background 0.15s',\n }}\n >\n <div style={{ minWidth: 0 }}>\n <div\n style={{\n fontSize: isCurrent ? 15 : 14,\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n fontWeight: isCurrent ? 500 : 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n marginBottom: 8,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {/* {session.title} */}\n {sessionDirection && (\n <SessionDirectionIcon\n size={16}\n color=\"var(--Grey-Muted, #808183)\"\n strokeWidth={1.5}\n style={{ flexShrink: 0 }}\n aria-hidden\n />\n )}\n <span\n style={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n minWidth: 0,\n }}\n >\n {session.title}\n </span>\n </div>\n {session.status && (\n <div style={{ fontSize: 13, color: 'var(--Grey-Strong, #2E3236)', marginBottom: 12, lineHeight: 1.2 }}>\n <span style={{ fontWeight: 400 }}>Location: </span>\n <span style={{ fontWeight: 400, color: 'var(--Grey-Muted, #808183)' }}>{session.location}</span>\n </div>\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap' }}>\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.1 }}>\n <CalendarDays size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.8} />\n {session.date}\n </span>\n {(session.agent || session.agent_name) && (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.1 }}>\n <Headset size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.8} />\n {session.agent || session.agent_name}\n </span>\n )}\n </div>\n </div>\n {/* External-link affordance is hidden for the current row —\n there's nowhere to navigate to. */}\n {!isCurrent && isHovered && (\n <ExternalLink size={20} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.7} style={{ flexShrink: 0 }} />\n )}\n </div>\n );\n }) : (\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: 140,\n padding: '24px 12px',\n color: 'var(--Grey-Muted, #808183)',\n fontSize: 14,\n fontStyle: 'italic',\n textAlign: 'center',\n }}\n >\n No other interactions available\n </div>\n )}\n </div>\n </SideDrawer>\n\n </div>\n );\n};\n\nexport default UpdatedInteractionDetails;\n","import React from 'react';\nimport { ThumbsUp, ThumbsDown } from 'lucide-react';\nimport { useMediaQuery } from '../../utils/useMediaQuery';\n// import { Info } from 'lucide-react';\n\n/*\n * Figma node: 101-2386 (Agent Lift Analysis)\n *\n * Container: fill=#F3F1E5, padding: 24px, gap: 24px, vertical,\n * border-radius: 8px, border: 1px solid #D9D9D9\n *\n * Header (Frame 12): vertical, gap: 32\n * Row (Frame 20): horizontal, space-between, center\n * \"Agent Lift Analysis\" — 15px/700/#2E3236, lh=120%\n * Right (Frame 18): horizontal, gap: 8, center\n * \"vs. Average Agent:\" — 13px/400/#2E3236, lh=120%\n * \"+4.3pp\" — 14px/700/#2E3236, lh=120%\n * Divider: border-left 1px #D9D9D9, padding-left: 8\n * ThumbsUp 14x14 + \"Positive\" 13px/700/#2E3236\n *\n * Metrics (Frame 15): horizontal, gap: 24, align: bottom\n * Col 1 (Frame 8): vertical, gap: 16, center\n * \"94%\" — 28px/400/#808183, lh=120%\n * Labels: vertical, gap: 8\n * \"Expected Outcome\" — 13px/400/#2E3236\n * \"Based on call type & difficulty\" — 13px/400/#808183\n * Plus icon: 16x16, fill=#2E3236, radius: 24, white stroke\n * Col 2 (Frame 9): vertical, gap: 16, pad-left: 24, border-left: 1px #D9D9D9\n * \"-11.0pp\" — 28px/400/#808183\n * \"Agent Impact\" — 13px/400/#2E3236\n * \"Behavior-driven change\" — 13px/400/#808183\n * Col 3 (Frame 7): vertical, gap: 16, pad-left: 24, border-left: 1px #D9D9D9\n * \"83%\" — 28px/400/#2E3236 (highlighted)\n * \"Predicted Outcome\" — 13px/700/#2E3236\n * \"With agent behaviors\" — 13px/400/#808183\n *\n * Key Drivers (Frame 13): vertical, gap: 4\n * \"Key Drivers\" — 12px/700/#2E3236, lh=120%\n * Chips (Frame 16): horizontal, gap: 4\n * Each: bg=#FFF, pad=8, radius=4, border 1px #D9D9D9\n * Text: 12px/400/#2E3236, lh=120%\n */\n\nconst COLORS = {\n strong: 'var(--Grey-Strong, #2E3236)',\n muted: 'var(--Grey-Muted, #808183)',\n absent: 'var(--Grey-absent, #D9D9D9)',\n white: 'var(--Grey-White, #FFF)',\n cardBg: 'var(--surface-warm-40, rgba(243, 241, 229, 0.40))',\n};\n\nconst LH = 1.2;\nconst MAX_VISIBLE_DRIVERS = 3;\n\nconst fmtPct = (v) => (v != null ? Math.round(v * 100) + '%' : '\\u2014');\n\nconst fmtPp = (v) => {\n if (v == null) return '\\u2014';\n const pp = (v * 100).toFixed(1);\n return v > 0 ? `+${pp}pp` : `${pp}pp`;\n};\n\n// /** Figma node 1199-2892 — 24px partial-ring gauge beside outcome % */\n// const OutcomeGauge = ({ value, size = 24 }) => {\n// const pct = value != null ? Math.min(1, Math.max(0, value)) : 0;\n// const r = 9;\n// const stroke = 2.5;\n// const arcLen = 2 * Math.PI * r * 0.75;\n// const filled = arcLen * pct;\n//\n// return (\n// <svg width={size} height={size} viewBox=\"0 0 24 24\" aria-hidden>\n// <circle\n// cx=\"12\"\n// cy=\"12\"\n// r={r}\n// fill=\"none\"\n// stroke={COLORS.absent}\n// strokeWidth={stroke}\n// strokeLinecap=\"round\"\n// strokeDasharray={`${arcLen} ${2 * Math.PI * r}`}\n// transform=\"rotate(135 12 12)\"\n// />\n// <circle\n// cx=\"12\"\n// cy=\"12\"\n// r={r}\n// fill=\"none\"\n// stroke={COLORS.strong}\n// strokeWidth={stroke}\n// strokeLinecap=\"round\"\n// strokeDasharray={`${filled} ${2 * Math.PI * r}`}\n// transform=\"rotate(135 12 12)\"\n// />\n// </svg>\n// );\n// };\n\nconst UpdatedInteractionScores = ({ outcomeLift, driverLabels = [], showOutcomeOnly = false }) => {\n const isPhone = useMediaQuery('(max-width: 640px)');\n if (!outcomeLift || outcomeLift.lift == null) return null;\n\n const pExpected = outcomeLift.p_expected;\n const pFull = outcomeLift.p_full;\n const liftRaw =\n outcomeLift.lift_raw ??\n (pFull != null && pExpected != null ? pFull - pExpected : null);\n const liftRecentered = outcomeLift.lift;\n\n const liftBand = outcomeLift.interpretation?.lift_band\n ? outcomeLift.interpretation.lift_band.replace(/_/g, ' ')\n : liftRecentered >= 0\n ? 'Positive'\n : 'Negative';\n\n const liftBandCapitalized =\n liftBand.charAt(0).toUpperCase() + liftBand.slice(1);\n\n const isNegativeBand = /negative/i.test(liftBand);\n const LiftIcon = isNegativeBand ? ThumbsDown : ThumbsUp;\n\n const visibleDrivers = driverLabels.slice(0, MAX_VISIBLE_DRIVERS);\n const overflowCount = driverLabels.length - MAX_VISIBLE_DRIVERS;\n\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n padding: 24,\n gap: showOutcomeOnly ? 16 : 24,\n borderRadius: 8,\n border: `1px solid ${COLORS.absent}`,\n background: showOutcomeOnly ? '#faf9f5' : COLORS.cardBg,\n alignSelf: 'stretch',\n }}\n >\n {/* Frame 12: Header + Metrics — vertical, gap: 32 (agent-only: 24) */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: showOutcomeOnly ? 24 : 32 }}>\n\n {/* Frame 20: Title row — horizontal, space-between, center */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 24,\n alignSelf: 'stretch',\n }}\n >\n <span\n style={{\n fontSize: 15,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n }}\n >\n Agent Lift Analysis\n </span>\n\n {/* Frame 18: right meta — horizontal, gap: 8, center */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontFamily: 'var(--font-sans)',\n }}\n >\n {/* <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, lineHeight: LH }}>\n vs. Average Agent:\n </span> */}\n {/* Frame 19: value */}\n {/* <span style={{ fontSize: 14, fontWeight: 600, color: COLORS.strong, lineHeight: LH }}>\n {fmtPp(liftRecentered)}\n </span> */}\n {/* Frame 21: divider + thumbsup + band */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n paddingLeft: 8,\n // borderLeft: `1px solid ${COLORS.absent}`,\n }}\n >\n <LiftIcon size={14} color={COLORS.strong} />\n <span style={{ fontSize: 13, fontWeight: 600, color: COLORS.strong, lineHeight: LH }}>\n {liftBandCapitalized}\n </span>\n </div>\n </div>\n </div>\n\n {/* Frame 15: Metrics row — horizontal, gap: 24 (stacks on phone) */}\n <div\n style={{\n display: 'flex',\n flexDirection: isPhone && !showOutcomeOnly ? 'column' : 'row',\n alignItems: isPhone && !showOutcomeOnly ? 'stretch' : 'center',\n gap: isPhone && !showOutcomeOnly ? 16 : 24,\n ...(showOutcomeOnly ? { justifyContent: 'center', width: '100%' } : {}),\n }}\n >\n {!showOutcomeOnly && (\n <>\n {/* Frame 8: Expected Outcome — flex: 1, equal width */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'flex-start', flex: 1, minWidth: 0 }}>\n <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>\n {fmtPct(pExpected)}\n </span>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'flex-start', minHeight: 48 }}>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH, whiteSpace: 'nowrap' }}>\n Expected Outcome\n </span>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'left' }}>\n Based on call type &amp; difficulty\n </span>\n </div>\n </div>\n\n {/* Frame 9: Agent Impact — flex: 1, equal width, border-left (top border when stacked) */}\n <div style={{\n display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'flex-start',\n ...(isPhone\n ? { paddingTop: 16, borderTop: `1px solid ${COLORS.absent}`, width: '100%' }\n : { paddingLeft: 24, borderLeft: `1px solid ${COLORS.absent}`, flex: 1, minWidth: 0 }),\n }}>\n <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>\n {fmtPp(liftRaw)}\n </span>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'flex-start', minHeight: 48 }}>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH, whiteSpace: 'nowrap' }}>\n Agent Impact\n </span>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'left' }}>\n Behavior-driven change\n </span>\n </div>\n </div>\n </>\n )}\n\n {/* Frame 7: Outcome — centered horizontal when agent-only (Figma 1199-2875) */}\n <div style={{\n display: 'flex',\n flexDirection: showOutcomeOnly ? 'row' : 'column',\n gap: showOutcomeOnly ? 16 : 16,\n alignItems: showOutcomeOnly ? 'center' : 'flex-start',\n justifyContent: showOutcomeOnly ? 'center' : undefined,\n ...(showOutcomeOnly\n ? {}\n : isPhone\n ? { paddingTop: 16, borderTop: `1px solid ${COLORS.absent}`, width: '100%' }\n : { paddingLeft: 24, borderLeft: `1px solid ${COLORS.absent}`, flex: 1, minWidth: 0 }),\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n {/* {showOutcomeOnly && <OutcomeGauge value={pFull} />} */}\n <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH }}>\n {fmtPct(pFull)}\n </span>\n </div>\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n alignItems: showOutcomeOnly ? 'flex-start' : 'flex-start',\n minHeight: showOutcomeOnly ? undefined : 48,\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n <span style={{\n fontSize: 13,\n fontWeight: showOutcomeOnly ? 400 : 600,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n whiteSpace: 'nowrap',\n }}>\n Outcome\n </span>\n {/* {showOutcomeOnly && (\n <Info size={14} color={COLORS.strong} strokeWidth={1.5} aria-label=\"Outcome information\" />\n )} */}\n </div>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'left' }}>\n With agent behaviors\n </span>\n </div>\n </div>\n </div>\n </div>\n\n {/* Frame 13: Key Drivers — vertical, gap: 4 */}\n {driverLabels.length > 0 && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, alignSelf: 'stretch' }}>\n <span\n style={{\n fontSize: 12,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n }}\n >\n Key Drivers\n </span>\n {/* Frame 16: chips — horizontal, gap: 4 */}\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {visibleDrivers.map((label, i) => (\n <div\n key={i}\n style={{\n display: 'flex',\n padding: 8,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 4,\n border: `1px solid ${COLORS.absent}`,\n background: COLORS.white,\n }}\n >\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n maxWidth: 200,\n }}\n >\n {label}\n </span>\n </div>\n ))}\n {overflowCount > 0 && (\n <div\n style={{\n display: 'flex',\n padding: 8,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 4,\n border: `1px solid ${COLORS.absent}`,\n background: COLORS.white,\n }}\n >\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n whiteSpace: 'nowrap',\n }}\n >\n + {overflowCount}\n </span>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default UpdatedInteractionScores;\n"],"names":["COLORS","OVERALL_MAP","STYLE_ID","ensureKeyframes","style","OverallIcon","overall","common","jsx","ArrowUp","ArrowDown","ArrowLeftRight","ThumbsUp","OverallBadge","label","jsxs","getDisplayQuote","quote","s","SectionItem","item","text","CoachingColumn","icon","items","i","UpdatedCoachingSynthesisCard","data","loading","error","React","isNarrow","useMediaQuery","Fragment","strengths","improvements","oneLiner","_a","context","_b","ShieldCheck","TrendingUp","Lightbulb","fmtDur","seconds","m","ROW_STYLE","TruncatedValue","ref","useRef","isTruncated","setIsTruncated","useState","useEffect","el","measure","observer","COLUMN_STYLE","UpdatedInteractionContext","meta","callPurpose","classification","dimensions","outcomeQuality","onMoreDetails","moreDetails","resolutionOutcome","customerIntent","location","interactionId","canShowEditButton","onEditInteraction","flatView","expanded","setExpanded","moreDetailsRef","isPhone","duration","messages","driver","paradigm","findDim","keyPattern","d","dimResolution","dimIntent","dimLocation","dimOutcomeQuality","fmtValue","v","c","resolvedOutcomeQuality","resolvedResolutionOutcome","resolvedCustomerIntent","resolvedLocation","resolvedParadigm","excludedKeys","k","filteredDimensions","pairedRows","rawPairs","left","right","pair","detailRows","flatPairs","flatFields","rowsToRender","handleOutsideClick","event","renderRow","renderMoreDetailsToggle","p","ChevronUp","ChevronDown","Pencil","idx","row","HoverIcon","children","size","onClick","title","hovered","setHovered","UpdatedInteractionSignals","signals","expandedSignals","toggleSignal","playEvidence","highlightTurns","onShowInTranscript","timelinePlaying","currentTimeSeconds","signalList","presentCount","fmtMs","ms","minutes","isEvPlaying","ev","FileSignal","signal","key","isExpanded","obsCount","_c","obs","obsIdx","e","ScrollText","evIdx","hasTimestamps","PauseCircle","PlayCircle","GaugeMeter","score","minScore","maxScore","numericScore","clampedScore","filledUnits","segDeg","toXY","angleDeg","rad","strokeArc","fromDeg","toDeg","large","gap","_","fromA","toA","segmentFill","pathD","ScoreBar","value","maxValue","numericValue","clampedValue","LEGEND_TOOLTIPS","InfoTooltip","show","setShow","pos","setPos","handleEnter","rect","LegendItem","Info","UpdatedCompassScore","predictedScore","predictedLabel","description","outcomePercent","legends","displayScore","scoreText","rotateDeg","legend","roleColorMap","role","roleTokens","extractRoleValue","user","directRole","nestedRole","_d","_e","_f","resolveCurrentUserAvatarColor","getInitials","name","w","isWithinEditWindow","utcValue","minMatch","formatTimestamp","diffMs","diffMin","diffHr","diffDays","Avatar","initials","color","avatar","CommentBubble","comment","isReply","isConsecutive","onReply","onSendReply","onEdit","onDelete","onMenuClick","showReply","menuOpen","setMenuOpen","replyOpen","setReplyOpen","replyValue","setReplyValue","editOpen","setEditOpen","editValue","setEditValue","confirmDelete","setConfirmDelete","menuRef","replyRef","editRef","author","authorName","avatarColor","avatarImg","rawTimestamp","timestamp","canEdit","isEdited","paragraphs","handler","ta","max","Ellipsis","X","paragraph","CornerDownRight","CommentInput","currentUser","onSubmit","setValue","isFocused","setIsFocused","textareaRef","handleSubmit","trimmed","handleKeyDown","CommentThread","depth","hasReplies","isLastAtDepth","reply","UpdatedThreads","externalComments","totalComments","onSendComment","onMarkResolved","isResolved","localComments","setLocalComments","isSending","setIsSending","allComments","useMemo","externalIds","newLocal","prev","displayCurrentUser","handleSendReply","content","parentId","optimisticReply","handleSendComment","optimisticComment","handleEdit","handleDelete","groupedComments","repliesByParent","buildTree","commentCount","MessagesSquare","Check","CircleCheck","prevAuthor","currAuthor","FONT_DISPLAY","LeadingIcon","Target","ImpactChip","direction","Arrow","EvidenceQuote","evidence","onPlayEvidence","startMs","endMs","hasTimestamp","currentMs","isPlayingThis","SignalRow","evidenceList","hasEvidence","ChevronRight","GuidanceItem","isLast","sig","SummaryCountBar","summary","focus","opportunity","excellence","cells","count","Icon","MAX_ITEMS","UpdatedGuidance","guidanceCount","visibleItems","HOLD_BUCKETS","Search","Pause","ArrowRightLeft","CircleDashed","MicOff","num","fmtRate","rate","fmtCount","n","HoldCounts","holdTypeCounts","b","StallRow","total","filler","buying","breakdown","PercentileRow","percentiles","UpdatedTalkPatterns","hasHolds","hasStalls","agentP","customerP","hasPercentiles","AudioLines","normaliseItem","fmtPercent","ItemRow","percent","Column","initialVisibleCount","overflow","visible","UpdatedProductsServices","products","services","productsTitle","servicesTitle","normalisedProducts","normalisedServices","ClipboardCheck","NameTooltip","triggerRef","BASE_TABS","isAgentRole","isAdminRole","resolveSessionDirection","session","fallbackDirection","raw","UpdatedInteractionDetails","onBack","coachingData","coachingLoading","audioUrl","externalAudioRef","playbackRate","timelineSegments","onSeek","onTogglePlay","onSeekBack","onSeekForward","onSetPlaybackRate","externalAgentName","externalAgentFullName","externalCustomerName","externalCustomerFullName","transcript","activeTurnIndex","turnObservations","highlightedTurns","onTurnPlayPause","onHighlightTurns","externalCallPurpose","externalClassification","externalOutcomeQuality","compassScore","compassMaxScore","predictedCsat","compassLegends","customerSessionsList","customerSessionCount","onSessionClick","onViewAllSessions","prevSessionDesc","prevSessionDisabled","nextSessionDesc","nextSessionDisabled","onPreviousSession","onNextSession","comments","guidance","guidanceSummary","talkPatterns","productsServices","productsDiscussed","servicesDiscussed","commentsResolved","activeTab","setActiveTab","setExpandedSignals","showSessionDrawer","setShowSessionDrawer","hoveredSessionIdx","setHoveredSessionIdx","internalPlaying","setInternalPlaying","internalCurrentTime","setInternalCurrentTime","isScrolledPastHeader","setIsScrolledPastHeader","recordingRef","overviewRef","coachingRef","signalsRef","productsRef","commentsRef","sectionRefs","scrollContainerRef","isClickScrolling","hasProductsServices","tabs","out","t","container","tabKeys","refs","scrollParent","node","overflowY","handleScroll","activeKey","overviewTop","clickedTabRef","handleTabClick","containerTop","offset","elTop","sessionHistory","hasPastSessions","handleShowInTranscript","signalsEl","timeSec","handlePlayEvidence","durationMs","handleHighlightTurns","turnIds","next","blocks","findBlock","id","ctx","outcomeLift","blockDimensions","resolvedMeta","resolvedCallPurpose","resolvedClassification","resolvedOutcomeLift","resolvedCoaching","resolvedSignals","guidanceData","agentName","agentFullName","customerName","customerFullName","resolvedUserRole","canEditInteraction","isAgentUser","sessionCount","rawDate","dateStr","ArrowLeft","ArrowRight","tab","ClipboardList","CalendarDays","DirectionIcon","PhoneOutgoing","PhoneIncoming","Headset","CircleUser","liftData","difficultyScore","difficultyBand","pExpected","scoreImpact","liftRaw","liftDisplay","liftBand","pFull","interpretationDescription","clampVal","lo","hi","difficultyValue","impactValue","scoreImpactPercent","prettyBand","band","difficultyLabel","impactLabel","impactPercent","parsed","AgentLiftAnalysisCard","UpdatedInteractionRecording","SideDrawer","History","isCurrent","isHovered","sessionDirection","SessionDirectionIcon","ExternalLink","LH","MAX_VISIBLE_DRIVERS","fmtPct","fmtPp","pp","UpdatedInteractionScores","driverLabels","showOutcomeOnly","liftRecentered","liftBandCapitalized","LiftIcon","ThumbsDown","visibleDrivers","overflowCount"],"mappings":"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"}
1
+ {"version":3,"file":"UpdatedInteractionDetails.cjs.js","sources":["../../src/components/UpdatedInteractionDetails/UpdatedCoachingSynthesisCard.jsx","../../src/components/UpdatedInteractionDetails/UpdatedInteractionContext.jsx","../../src/components/UpdatedInteractionDetails/UpdatedInteractionSignals.jsx","../../src/components/UpdatedInteractionDetails/UpdatedCompassScore.jsx","../../src/components/UpdatedInteractionDetails/UpdatedThreads.jsx","../../src/components/UpdatedInteractionDetails/UpdatedGuidance.jsx","../../src/components/UpdatedInteractionDetails/UpdatedTalkPatterns.jsx","../../src/components/UpdatedInteractionDetails/UpdatedProductsServices.jsx","../../src/components/UpdatedInteractionDetails/UpdatedInteractionDetails.jsx","../../src/components/UpdatedInteractionDetails/UpdatedInteractionScores.jsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { useMediaQuery } from \"../../utils/useMediaQuery\";\nimport {\n ShieldCheck,\n ThumbsUp,\n TrendingUp,\n Lightbulb,\n ArrowUp,\n ArrowDown,\n ArrowLeftRight,\n} from \"lucide-react\";\n\n/**\n * UpdatedCoachingSynthesisCard — \"COACHING SUMMARY\" section matching Figma node 113-7216.\n *\n * Props:\n * - data object Coaching synthesis response\n * - loading boolean Show shimmer loading state\n * - error string Error message to display\n *\n * Data shape:\n * - one_liner string\n * - context string\n * - strengths Array<{ text: string, quote?: string }>\n * - improvements Array<{ text: string, quote?: string }>\n * - overall string \"effective\" | \"strong\" | \"needs_improvement\" | \"mixed\"\n */\n\nconst COLORS = {\n strong: \"var(--Grey-Strong, #2E3236)\",\n muted: \"var(--Grey-Muted, #808183)\",\n absent: \"var(--Grey-absent, #D9D9D9)\",\n accent: \"var(--rail-orange, #C98A5A)\",\n itemText: \"var(--text-item, #3F3F3F)\",\n quoteLine: \"var(--border-warm, #B2AEA8)\",\n quoteText: \"var(--text-subtle-warm, #767473)\",\n iconBg: \"var(--surface-hover, #F3F7F7)\",\n};\n\nconst OVERALL_MAP = {\n effective: \"Effective\",\n strong: \"Strong\",\n needs_improvement: \"Needs Improvement\",\n mixed: \"Mixed\",\n};\n\nconst STYLE_ID = \"updated-coaching-synthesis-keyframes\";\n\nfunction ensureKeyframes() {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n @keyframes updated-coaching-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n @keyframes updated-coaching-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n }\n `;\n document.head.appendChild(style);\n}\n\n// Maps an `overall` value to the icon next to the label. Per the Figma\n// (node 1160-4631):\n// strong / effective → ArrowUp (improving)\n// needs_improvement → ArrowDown (declining)\n// mixed → ArrowLeftRight (two horizontal arrows)\n// `ThumbsUp` stays imported as a defensive fallback for unknown values so\n// the badge keeps rendering even if the API ships a new state we haven't\n// mapped yet.\nfunction OverallIcon({ overall }) {\n const common = { size: 14, color: COLORS.strong, strokeWidth: 1.5 };\n switch (overall) {\n case \"strong\":\n case \"effective\":\n return <ArrowUp {...common} />;\n case \"needs_improvement\":\n return <ArrowDown {...common} />;\n case \"mixed\":\n return <ArrowLeftRight {...common} />;\n default:\n return <ThumbsUp {...common} />;\n }\n}\n\nfunction OverallBadge({ overall }) {\n const label = OVERALL_MAP[overall] || (overall ? overall.replace(/_/g, \" \") : \"\");\n\n return (\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flexShrink: 0,\n }}>\n <span style={{\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.2,\n }}>\n Overall:\n </span>\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n }}>\n <OverallIcon overall={overall} />\n <span style={{\n fontSize: 13,\n fontWeight:600,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.2,\n }}>\n {label}\n </span>\n </div>\n </div>\n );\n}\n\nfunction getDisplayQuote(quote) {\n if (quote == null) return null;\n const s = String(quote).trim();\n if (!s || s.toLowerCase() === \"null\" || s.toLowerCase() === \"undefined\") return null;\n return s;\n}\n\nfunction SectionItem({ item }) {\n const text = typeof item === \"string\" ? item : item?.text || \"\";\n const quote = getDisplayQuote(typeof item === \"object\" ? item?.quote : null);\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 14 }}>\n <div style={{\n fontSize: 14,\n fontWeight: 600,\n color: COLORS.itemText,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.5,\n }}>\n {text}\n </div>\n {quote && (\n <div style={{\n display: \"flex\",\n gap: 10,\n }}>\n <div style={{\n width: 1,\n flexShrink: 0,\n alignSelf: \"stretch\",\n background: COLORS.quoteLine,\n }} />\n <div style={{\n fontSize: 14,\n fontWeight: 400,\n color: COLORS.quoteText,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.5,\n }}>\n &ldquo;{quote}&rdquo;\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction CoachingColumn({ icon, label, items }) {\n if (!items || items.length === 0) return null;\n\n return (\n <div style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n borderRadius: 12,\n }}>\n {/* Column header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n }}>\n {/* Icon with circular bg */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 24,\n height: 24,\n borderRadius: 9999,\n background: COLORS.iconBg,\n flexShrink: 0,\n }}>\n {icon}\n </div>\n <span style={{\n fontSize: 16,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: \"normal\",\n }}>\n {label}\n </span>\n </div>\n\n {/* Items */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 24 }}>\n {items.map((item, i) => (\n <SectionItem key={i} item={item} />\n ))}\n </div>\n </div>\n );\n}\n\nconst UpdatedCoachingSynthesisCard = ({ data, loading, error }) => {\n React.useEffect(() => { ensureKeyframes(); }, []);\n\n // Key Strengths and Improvements sit side by side on wide layouts, but\n // stack once the viewport drops below 900px so the two text columns aren't\n // crammed together on tablet/mobile. A viewport media query (not a\n // container measurement) is used deliberately: the detail panel can\n // overflow horizontally, so the card's own clientWidth stays wide even\n // when the visible area is narrow.\n const isNarrow = useMediaQuery(\"(max-width: 900px)\");\n\n // Loading state — ThreeCirclesSpinner\n if (loading) {\n return (\n <>\n <style>{`\n @keyframes coaching-spinner-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `}</style>\n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 12,\n padding: \"48px 24px\",\n }}>\n <svg\n width={48}\n height={48}\n viewBox=\"0 0 48 48\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ animation: \"coaching-spinner-spin 1.2s linear infinite\" }}\n >\n <path\n d=\"M43 24C43 26.4951 42.5086 28.9658 41.5537 31.271C40.5989 33.5762 39.1993 35.6707 37.435 37.435C35.6707 39.1993 33.5762 40.5989 31.271 41.5537C28.9658 42.5086 26.4951 43 24 43C21.5049 43 19.0342 42.5086 16.729 41.5537C14.4238 40.5989 12.3293 39.1993 10.565 37.435C8.80066 35.6707 7.40113 33.5762 6.44629 31.271C5.49145 28.9658 5 26.4951 5 24\"\n stroke=\"#F3E7C7\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M12 24C12 22.4241 12.3104 20.8637 12.9134 19.4078C13.5165 17.9519 14.4004 16.629 15.5147 15.5147C16.629 14.4004 17.9519 13.5165 19.4078 12.9134C20.8637 12.3104 22.4241 12 24 12C25.5759 12 27.1363 12.3104 28.5922 12.9134C30.0481 13.5165 31.371 14.4004 32.4853 15.5147C33.5996 16.629 34.4835 17.9519 35.0866 19.4078C35.6896 20.8637 36 22.4241 36 24\"\n stroke=\"#00A66E\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n />\n <path\n d=\"M20 24C20 24.5253 20.1035 25.0454 20.3045 25.5307C20.5055 26.016 20.8001 26.457 21.1716 26.8284C21.543 27.1999 21.984 27.4945 22.4693 27.6955C22.9546 27.8965 23.4747 28 24 28C24.5253 28 25.0454 27.8965 25.5307 27.6955C26.016 27.4945 26.457 27.1999 26.8284 26.8284C27.1999 26.457 27.4945 26.016 27.6955 25.5307C27.8965 25.0454 28 24.5253 28 24\"\n stroke=\"#F3E7C7\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n />\n </svg>\n <span style={{\n fontSize: 14,\n color: COLORS.muted,\n fontWeight: 500,\n textAlign: \"center\",\n }}>\n Synthesizing coaching summary...\n </span>\n </div>\n </>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div style={{\n fontSize: 14,\n color: COLORS.muted,\n }}>\n Unable to generate coaching summary.\n </div>\n );\n }\n\n // No data\n if (!data) return null;\n\n const strengths = data.strengths || [];\n const improvements = data.improvements || [];\n const oneLiner = typeof data.one_liner === \"string\" ? data.one_liner : data.one_liner?.text || \"\";\n const context = typeof data.context === \"string\" ? data.context : data.context?.text || \"\";\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n background: \"#FFF\",\n }}\n >\n {/* Section header — Figma: icon + \"Coaching Summary\" 16px / 700 / #2E3236 */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n }}>\n <ShieldCheck size={20} color={COLORS.accent} strokeWidth={2} />\n <span style={{\n fontSize: 16,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.2,\n textTransform: \"uppercase\",\n }}>\n Coaching Summary\n </span>\n </div>\n\n {/* One-liner — Figma: 14px / 600 / #2E3236 */}\n {oneLiner && (\n <div style={{\n fontSize: 14,\n fontWeight: 500,\n color: COLORS.strong,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.5,\n }}>\n {oneLiner}\n </div>\n )}\n\n {/* Context row + Overall badge — Figma: horizontal, space-between */}\n <div style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 16,\n justifyContent: \"space-between\",\n }}>\n {context && (\n <div style={{\n fontSize: 14,\n fontWeight: 400,\n color: COLORS.muted,\n fontFamily: \"var(--font-sans)\",\n lineHeight: 1.5,\n flex: 1,\n }}>\n {context}\n </div>\n )}\n {data.overall && <OverallBadge overall={data.overall} />}\n </div>\n\n {/* Two-column layout: Key Strengths + Improvements */}\n {/* Figma: border-top 1px #D9D9D9, padding-top 24px, gap 24px */}\n {(strengths.length > 0 || improvements.length > 0) && (\n <div style={{\n display: \"flex\",\n flexDirection: isNarrow ? \"column\" : \"row\",\n gap: 24,\n paddingTop: 24,\n borderTop: `1px solid ${COLORS.absent}`,\n }}>\n <CoachingColumn\n icon={<TrendingUp size={14} color={COLORS.strong} strokeWidth={1.5} />}\n label=\"Key Strengths\"\n items={strengths}\n />\n <CoachingColumn\n icon={<Lightbulb size={14} color={COLORS.strong} strokeWidth={1.5} />}\n label=\"Improvements\"\n items={improvements}\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default UpdatedCoachingSynthesisCard;\n","import { useEffect, useRef, useState } from 'react';\nimport { ChevronDown, ChevronUp, Pencil } from 'lucide-react';\nimport { useMediaQuery } from '../../utils/useMediaQuery';\n\n/*\n * Figma node: 101-2385 / 495-803 (Context grid + More Details expandable)\n */\n\nfunction fmtDur(seconds) {\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\nconst ROW_STYLE = {\n display: 'flex',\n justifyContent: 'space-between',\n // Extra top padding gives more breathing room between a row's bottom border\n // and the next row's content below it.\n padding: '16px 8px 12px 8px',\n alignItems: 'center',\n gap: 24,\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: 'normal',\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n};\n\n// Renders a single-line value that ellipsis-truncates when it overflows its\n// container and, only in that case, sets the native `title` so hovering\n// surfaces the full string in the browser's built-in tooltip. Re-measures\n// on resize via ResizeObserver. Keeps the existing inline styles intact.\nfunction TruncatedValue({ text, style }) {\n const ref = useRef(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return undefined;\n const measure = () => setIsTruncated(el.scrollWidth > el.clientWidth);\n measure();\n if (typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(measure);\n observer.observe(el);\n return () => observer.disconnect();\n }, [text]);\n\n return (\n <span\n ref={ref}\n title={isTruncated && text != null ? String(text) : undefined}\n style={style}\n >\n {text}\n </span>\n );\n}\n\nconst COLUMN_STYLE = {\n display: 'flex',\n flexDirection: 'column',\n flex: '1 0 0',\n gap: 0,\n minWidth: 0,\n};\n\nconst UpdatedInteractionContext = ({\n meta = {},\n callPurpose = {},\n classification = {},\n dimensions = [],\n outcomeQuality = 'Neutral',\n onMoreDetails,\n moreDetails = [],\n resolutionOutcome,\n customerIntent,\n location,\n interactionId,\n canShowEditButton = false,\n onEditInteraction,\n // Agent view (Figma node 1798-5177): show every field flat in the two-column\n // grid with no \"More Details\" toggle / dropdown and no Edit button. The\n // fields that normally sit behind \"More Details\" (Resolution Outcome,\n // Customer Intent, Paradigm) plus a \"Number\" (interaction id) render inline.\n flatView = false,\n}) => {\n const [expanded, setExpanded] = useState(false);\n const moreDetailsRef = useRef(null);\n const isPhone = useMediaQuery('(max-width: 640px)');\n\n const duration = meta.duration_seconds != null ? fmtDur(meta.duration_seconds) : null;\n const messages = meta.message_count;\n const driver = callPurpose.interaction_driver;\n const paradigm = classification.interaction_paradigm;\n\n // Helper to find a dimension by key pattern\n const findDim = (keyPattern) => dimensions.find((d) => (d.key || '').toLowerCase().includes(keyPattern));\n\n // Auto-extract known dimensions — use explicit props first, then fall back to dimensions data\n const dimResolution = findDim('resolution_outcome');\n const dimIntent = findDim('customer_intent');\n const dimLocation = findDim('location');\n const dimOutcomeQuality = findDim('outcome_quality');\n\n const fmtValue = (v) => v ? v.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase()) : null;\n\n const resolvedOutcomeQuality = outcomeQuality !== 'Neutral' ? outcomeQuality\n : dimOutcomeQuality ? fmtValue(dimOutcomeQuality.value)\n : outcomeQuality;\n\n const resolvedResolutionOutcome = resolutionOutcome ?? (dimResolution ? fmtValue(dimResolution.value) : null);\n const resolvedCustomerIntent = customerIntent ?? (dimIntent ? fmtValue(dimIntent.value) : null);\n const resolvedLocation = location ?? (dimLocation ? fmtValue(dimLocation.value) : null);\n const resolvedParadigm = paradigm != null ? fmtValue(paradigm) : null;\n\n // Keys to exclude from the generic dimensions grid (they go in dedicated spots)\n const excludedKeys = new Set(['resolution_outcome', 'customer_intent', 'location', 'outcome_quality'].map((k) => `dim.${k}`));\n const filteredDimensions = dimensions.filter((d) => !excludedKeys.has(d.key));\n\n // Build paired rows: [left, right] per line\n const pairedRows = [];\n const rawPairs = [\n [\n duration != null ? { label: 'Duration', value: duration } : null,\n messages != null ? { label: 'Messages', value: messages } : null,\n ],\n [\n driver != null ? { label: 'Driver', value: driver } : null,\n // paradigm != null ? { label: 'Paradigm', value: paradigm } : null,\n resolvedLocation != null ? { label: 'Location', value: resolvedLocation } : null,\n ],\n ];\n\n // Add remaining dimension pairs (excluding the ones we extracted)\n for (let i = 0; i < filteredDimensions.length; i += 2) {\n const left = filteredDimensions[i] ? { label: filteredDimensions[i].display_name || filteredDimensions[i].label || filteredDimensions[i].key, value: fmtValue(filteredDimensions[i].value) } : null;\n const right = filteredDimensions[i + 1] ? { label: filteredDimensions[i + 1].display_name || filteredDimensions[i + 1].label || filteredDimensions[i + 1].key, value: fmtValue(filteredDimensions[i + 1].value) } : null;\n rawPairs.push([left, right]);\n }\n\n // Last row: Outcome Quality (left) + More details toggle (right)\n rawPairs.push([\n { label: 'Outcome Quality', value: resolvedOutcomeQuality },\n { isMoreDetails: true },\n ]);\n\n rawPairs.forEach((pair) => pairedRows.push(pair));\n\n // Build \"More Details\" expanded rows — auto-extracted from dimensions\n const detailRows = [\n resolvedResolutionOutcome != null && { label: 'Resolution Outcome', value: resolvedResolutionOutcome },\n resolvedCustomerIntent != null && { label: 'Customer Intent', value: resolvedCustomerIntent },\n // resolvedLocation != null && { label: 'Location', value: resolvedLocation },\n resolvedParadigm != null && { label: 'Paradigm', value: resolvedParadigm },\n ...(moreDetails || []),\n ].filter(Boolean);\n\n // Agent flat view (Figma 1798-5177): a single ordered list of every field,\n // chunked two-per-row, with no \"More Details\" toggle. Order matches the\n // design: Duration/Messages, Driver/Location, Outcome Quality/Paradigm,\n // Resolution Outcome/Customer Intent, then Number.\n const flatPairs = [];\n if (flatView) {\n const flatFields = [\n duration != null && { label: 'Duration', value: duration },\n messages != null && { label: 'Messages', value: messages },\n driver != null && { label: 'Driver', value: driver },\n resolvedLocation != null && { label: 'Location', value: resolvedLocation },\n { label: 'Outcome Quality', value: resolvedOutcomeQuality },\n resolvedParadigm != null && { label: 'Paradigm', value: resolvedParadigm },\n resolvedResolutionOutcome != null && { label: 'Resolution Outcome', value: resolvedResolutionOutcome },\n resolvedCustomerIntent != null && { label: 'Customer Intent', value: resolvedCustomerIntent },\n ...filteredDimensions.map((d) => ({\n label: d.display_name || d.label || d.key,\n value: fmtValue(d.value),\n })),\n ...(moreDetails || []),\n interactionId != null && interactionId !== '' && { label: 'Number', value: interactionId },\n ].filter(Boolean);\n for (let i = 0; i < flatFields.length; i += 2) {\n flatPairs.push([flatFields[i], flatFields[i + 1] || null]);\n }\n }\n\n const rowsToRender = flatView ? flatPairs : pairedRows;\n\n // Close \"More Details\" dropdown on outside click\n useEffect(() => {\n if (!expanded) return;\n\n const handleOutsideClick = (event) => {\n if (moreDetailsRef.current && !moreDetailsRef.current.contains(event.target)) {\n setExpanded(false);\n }\n };\n\n document.addEventListener('mousedown', handleOutsideClick);\n return () => document.removeEventListener('mousedown', handleOutsideClick);\n }, [expanded]);\n\n const renderRow = (item) => (\n <div\n key={item.label}\n style={ROW_STYLE}\n >\n <span style={{ color: 'var(--Grey-Strong, #2E3236)', whiteSpace: 'nowrap', flexShrink: 0 }}>\n {item.label}\n </span>\n <TruncatedValue\n text={item.value}\n style={{\n color: 'var(--Grey-Muted, #808183)',\n textAlign: 'right',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n minWidth: 0,\n // Constrain so the row's `space-between` actually clips the value\n // span (without `flex: 1`, very long strings stretched the row\n // instead of truncating).\n flex: 1,\n }}\n />\n </div>\n );\n\n const renderMoreDetailsToggle = () => (\n <div\n key=\"more-details\"\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n // Match the row top padding so the toggle aligns with the sibling\n // \"Outcome Quality\" row on the left instead of sitting higher.\n padding: '16px 8px 12px 8px',\n fontFamily: 'var(--font-sans)',\n borderBottom: 'none',\n minHeight: 33,\n }}\n >\n <button\n onClick={() => {\n setExpanded((p) => !p);\n if (onMoreDetails && !expanded) onMoreDetails();\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: 0,\n color: 'var(--Grey-Strong, #2E3236)',\n fontSize: 13,\n fontWeight: 500,\n lineHeight: 'normal',\n fontFamily: 'var(--font-sans)',\n whiteSpace: 'nowrap',\n flexShrink: 0,\n }}\n >\n <span>More Details</span>\n {expanded\n ? <ChevronUp size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n : <ChevronDown size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n }\n </button>\n\n {canShowEditButton && (\n <button\n onClick={onEditInteraction || (() => {})}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '5px 12px',\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 12,\n color: 'var(--Grey-Strong, #2E3236)',\n fontSize: 13,\n fontWeight: 500,\n lineHeight: 'normal',\n fontFamily: 'var(--font-sans)',\n cursor: 'pointer',\n flexShrink: 0,\n }}\n >\n <Pencil size={15} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, lineHeight: 'normal' }}>Edit</span>\n </button>\n )}\n </div>\n );\n\n return (\n <div\n ref={moreDetailsRef}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignSelf: 'stretch',\n gap: 0,\n position: 'relative',\n overflow: 'visible',\n }}\n >\n {/* Paired rows — two columns side by side */}\n {rowsToRender.map((pair, idx) => (\n <div\n key={idx}\n style={{\n display: 'flex',\n flexDirection: isPhone ? 'column' : 'row',\n alignItems: isPhone ? 'stretch' : 'center',\n gap: isPhone ? 8 : 24,\n alignSelf: 'stretch',\n flexWrap: 'nowrap',\n }}\n >\n {/* Left cell */}\n <div style={COLUMN_STYLE}>\n {pair[0] && !pair[0].isMoreDetails ? renderRow(pair[0]) : <div style={{ flex: 1 }} />}\n </div>\n\n {/* Right cell */}\n <div style={COLUMN_STYLE}>\n {pair[1] && !pair[1].isMoreDetails\n ? renderRow(pair[1])\n : pair[1]?.isMoreDetails\n ? renderMoreDetailsToggle()\n : <div style={{ flex: 1 }} />}\n </div>\n </div>\n ))}\n\n {/* More Details dropdown — absolute, full width, left-aligned */}\n {!flatView && expanded && detailRows.length > 0 && (\n <div\n style={{\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: 4,\n display: 'flex',\n width: 340,\n maxWidth: 'calc(100vw - 32px)',\n flexDirection: 'column',\n alignItems: 'flex-start',\n borderRadius: 4,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-White, #FFF)',\n boxShadow: '-2px 2px 2px 0 rgba(0, 0, 0, 0.25)',\n overflow: 'hidden',\n fontFamily: 'var(--font-sans)',\n zIndex: 50,\n }}\n >\n {/* Dropdown header */}\n <div style={{\n padding: '12px 16px',\n fontSize: 13,\n fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n alignSelf: 'stretch',\n }}>\n More details\n </div>\n\n {/* Detail rows */}\n {detailRows.map((row) => (\n <div\n key={row.label}\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 16px',\n gap: 24,\n fontSize: 13,\n fontWeight: 400,\n lineHeight: 'normal',\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n alignSelf: 'stretch',\n }}\n >\n <span style={{ color: 'var(--Grey-Strong, #2E3236)', whiteSpace: 'nowrap', flexShrink: 0 }}>\n {row.label}\n </span>\n <span style={{\n color: 'var(--Grey-Muted, #808183)',\n fontSize: 13,\n fontStyle: 'normal',\n fontWeight: 400,\n lineHeight: '120%',\n textAlign: 'right',\n }}>\n {row.value}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n\nexport default UpdatedInteractionContext;\n","import { useState } from 'react';\nimport { ChevronDown, ChevronUp, PlayCircle, PauseCircle, FileSignal, ScrollText } from 'lucide-react';\n\n/* Hover circle wrapper for icons */\nconst HoverIcon = ({ children, size = 28, onClick, title }) => {\n const [hovered, setHovered] = useState(false);\n return (\n <div\n title={title}\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: size,\n height: size,\n borderRadius: 9999,\n background: hovered ? 'var(--surface-hover, #F3F7F7)' : 'transparent',\n cursor: 'pointer',\n flexShrink: 0,\n transition: 'background 0.15s',\n }}\n >\n {children}\n </div>\n );\n};\n\n/*\n * Figma node: 222-672 (Signals accordion)\n *\n * Header: FileSignal icon in #F3F7F7 circle + \"Signals\" 15px/500 + \"N Signals Detected\" 14px/500\n *\n * Accordion Title (collapsed): horizontal, gap: 12, pad: 8 0, border-bottom: 1px #D9D9D9\n * Name: 14px/600/#0B0A0A, lh: 171%\n * Chevron: 20x20, stroke #767473\n *\n * Accordion Body (reason): horizontal, gap: 12, pad: 8 0, space-between\n * Reason: 14px/400/#767473, lh: 150%\n * Right: ScrollText icon 16x16 #808183 + time 13px/400/#808183\n *\n * Evidence (Frame 39): horizontal, gap: 8, pad: 8 0\n * Play circle: ~17px, stroke #808183\n * Quote: 13px/400/#2E3236, lh: 120%\n */\n\nconst UpdatedInteractionSignals = ({\n signals = { signals: [], present_count: 0, total_signals_evaluated: 0 },\n expandedSignals = new Set(),\n toggleSignal = () => {},\n playEvidence = () => {},\n highlightTurns = () => {},\n onShowInTranscript = () => {},\n timelinePlaying = false,\n currentTimeSeconds = 0,\n}) => {\n const signalList = signals?.signals ?? [];\n const presentCount = signals?.present_count ?? signalList.length;\n\n const fmtMs = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;\n };\n\n const isEvPlaying = (ev) =>\n timelinePlaying &&\n ev.start_ms != null &&\n currentTimeSeconds * 1000 >= ev.start_ms &&\n currentTimeSeconds * 1000 <= (ev.end_ms ?? ev.start_ms + 5000);\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n alignSelf: 'stretch',\n width: '100%',\n gap: 16,\n }}>\n {/* ── Header: icon + \"Signals\" + count ── */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n width: '100%',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: 'var(--surface-hover, #F3F7F7)',\n flexShrink: 0,\n }}>\n <FileSignal size={20} color=\"#2E3236\" strokeWidth={1.5} />\n </div>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flex: 1,\n }}>\n <span style={{\n fontSize: 16,\n fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--default-font-family)',\n }}>\n Signals\n </span>\n <span style={{\n fontSize: 14,\n fontWeight: 500,\n color: 'var(--Grey-Strong, #2E3236)',\n fontFamily: 'var(--default-font-family)',\n }}>\n {presentCount} Signals Detected\n </span>\n </div>\n </div>\n\n {/* ── Signal list (accordion) ── */}\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignSelf: 'stretch',\n background: 'var(--Grey-White, #FFF)',\n gap: 8,\n }}>\n {signalList.length === 0 && (\n <div style={{\n padding: '8px 0',\n fontSize: 14,\n color: 'var(--Grey-Muted, #808183)',\n }}>\n No signals detected.\n </div>\n )}\n\n {signalList.map((signal, idx) => {\n const key = signal.key ?? signal.id ?? idx;\n const isExpanded = expandedSignals.has(key);\n const obsCount = signal.observations?.length ?? 0;\n\n return (\n <div\n key={key}\n id={`signal-${key}`}\n style={{\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n gap: 8,\n }}\n >\n {/* ── Accordion Title — signal row ── */}\n <button\n onClick={() => toggleSignal(key)}\n style={{\n display: 'flex',\n padding: '8px 0',\n alignItems: 'center',\n gap: 12,\n alignSelf: 'stretch',\n width: '100%',\n background: 'none',\n border: 'none',\n borderBottom: '1px solid var(--Grey-absent, #D9D9D9)',\n cursor: 'pointer',\n }}\n >\n <span style={{\n flex: 1,\n textAlign: 'left',\n fontSize: 14,\n fontWeight: 600,\n color: 'var(--text-dark, #0B0A0A)',\n lineHeight: 1.71,\n }}>\n {signal.display_name || signal.key?.replace(/_/g, ' ')}\n {obsCount > 0 && (\n <span style={{\n fontWeight: 600,\n color: 'var(--text-dark, #0B0A0A)',\n marginLeft: 6,\n }}>\n ({obsCount})\n </span>\n )}\n </span>\n {isExpanded ? (\n <ChevronUp size={20} color=\"#767473\" />\n ) : (\n <ChevronDown size={20} color=\"#767473\" />\n )}\n </button>\n\n {/* ── Expanded: Observations ── */}\n {isExpanded && signal.observations?.length > 0 && (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignSelf: 'stretch',\n gap: 0,\n }}>\n {signal.observations.map((obs, obsIdx) => (\n <div\n key={obs.key ?? obsIdx}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignSelf: 'stretch',\n gap: 8,\n }}\n >\n {/* Accordion Body — reason + timestamp */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '8px 0',\n justifyContent: 'space-between',\n }}>\n <span style={{\n flex: 1,\n fontSize: 14,\n fontWeight: 400,\n color: 'var(--text-subtle-warm, #767473)',\n lineHeight: 1.5,\n }}>\n {obs.reason || obs.explanation}\n </span>\n {obs.evidence?.[0]?.start_ms != null && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n flexShrink: 0,\n }}\n >\n <HoverIcon\n size={28}\n title=\"Show in transcript\"\n onClick={(e) => {\n e.stopPropagation();\n onShowInTranscript(obs.evidence[0].start_ms);\n }}\n >\n <ScrollText size={16} color=\"#808183\" strokeWidth={1.5} />\n </HoverIcon>\n <span style={{\n fontSize: 13,\n fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n lineHeight: 1.2,\n whiteSpace: 'nowrap',\n }}>\n {fmtMs(obs.evidence[0].start_ms)}\n </span>\n </div>\n )}\n </div>\n\n {/* Evidence quotes — Frame 39 */}\n {obs.evidence?.map((ev, evIdx) => {\n const hasTimestamps = ev.start_ms != null && ev.end_ms != null;\n return ev.text && (\n <div\n key={evIdx}\n onClick={(e) => {\n e.stopPropagation();\n if (hasTimestamps) playEvidence(ev);\n }}\n onMouseEnter={() => highlightTurns(ev.turn_ids ?? [])}\n onMouseLeave={() => highlightTurns([])}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '8px 0',\n cursor: hasTimestamps ? 'pointer' : 'default',\n }}\n >\n {hasTimestamps && (\n <HoverIcon size={28}>\n {isEvPlaying(ev) ? (\n <PauseCircle\n size={17}\n color=\"var(--Grey-Muted, #808183)\"\n strokeWidth={1.5}\n />\n ) : (\n <PlayCircle\n size={17}\n color=\"var(--Grey-Muted, #808183)\"\n strokeWidth={1}\n />\n )}\n </HoverIcon>\n )}\n <span style={{\n fontSize: 13,\n fontWeight: 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n }}>\n &ldquo;{ev.text}&rdquo;\n </span>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport default UpdatedInteractionSignals;\n","import React, { useState, useRef } from 'react';\nimport { Info } from 'lucide-react';\nimport { useMediaQuery } from '../../utils/useMediaQuery';\n\n/*\n * Figma node: 270-6494 (Compass Score card)\n *\n * Container: padding: 24px, border-radius: 8px, border: 1px solid #D9D9D9,\n * background: #FFF, gap: 24px, vertical\n *\n * Title: \"Compass Score\" 15px/700/#2E3236\n * Description: 14px/400/#808183\n *\n * Content: horizontal, gap: 48, center both axes\n * Left: Meter 243x200 (SVG from Figma export)\n * Right: Legends vertical, gap: 8, centered\n * Each: label 12px/400/#2E3236 + Info 14px stroke=#ACACAD\n * Score bar: 5 segments 22x6, gap: 2, filled=#2E3236, empty=#E3E1D7\n */\n\nconst COLORS = {\n strong: 'var(--Grey-Strong, #2E3236)',\n muted: 'var(--Grey-Muted, #808183)',\n absent: 'var(--Grey-absent, #D9D9D9)',\n white: 'var(--Grey-White, #FFF)',\n accent: 'var(--rail-orange, #C98A5A)',\n track: 'var(--rail-surface-2, #E3E1D7)',\n infoIcon: 'var(--color-input-border, #ACACAD)',\n};\n\n// Gauge using stroke-based semi-circle arcs — matching Figma node 270-6499\n// Compass score scale: 0.5 to 5.0 (supports 0.5 increments)\n// Visual scale is always 5 segments, where each segment represents 1 point.\nconst GaugeMeter = ({ score = 4, minScore = 0, maxScore = 5 }) => {\n const svgW = 243;\n const svgH = 130;\n const cx = svgW / 2;\n const cy = svgH - 7;\n const r = 85; // mid-radius of the arc\n const sw = 30; // stroke-width (thickness of the arc band)\n const totalSeg = 5; // always render 5 visual steps\n const numericScore = Number(score);\n const clampedScore = Number.isFinite(numericScore)\n ? Math.min(Math.max(numericScore, minScore), maxScore)\n : minScore;\n const filledUnits = maxScore > minScore\n ? ((clampedScore - minScore) / (maxScore - minScore)) * totalSeg\n : 0;\n const segDeg = 180 / totalSeg; // 36° per segment\n\n // Convert polar (degrees, 0°=right, CCW) to SVG x,y (Y-down)\n const toXY = (angleDeg) => {\n const rad = (angleDeg * Math.PI) / 180;\n return {\n x: cx + r * Math.cos(rad),\n y: cy - r * Math.sin(rad),\n };\n };\n\n // SVG arc from startDeg to endDeg (both in math convention: 0=right, 180=left)\n // We draw clockwise in SVG (sweep-flag=1) from higher angle to lower angle\n const strokeArc = (fromDeg, toDeg) => {\n const s = toXY(fromDeg);\n const e = toXY(toDeg);\n const large = (fromDeg - toDeg) > 180 ? 1 : 0;\n return `M ${s.x} ${s.y} A ${r} ${r} 0 ${large} 1 ${e.x} ${e.y}`;\n };\n\n const gap = 2; // degrees gap between segments\n\n return (\n <svg width=\"100%\" viewBox={`0 0 ${svgW} ${svgH}`} fill=\"none\" style={{ maxWidth: svgW }}>\n {/* Segments from left (180°) to right (0°) */}\n {Array.from({ length: totalSeg }, (_, i) => {\n const fromA = 180 - i * segDeg - (i > 0 ? gap / 2 : 0);\n const toA = 180 - (i + 1) * segDeg + (i < totalSeg - 1 ? gap / 2 : 0);\n const segmentFill = Math.max(0, Math.min(1, filledUnits - i));\n const pathD = strokeArc(fromA, toA);\n return (\n <g key={i}>\n {/* Base track segment */}\n <path\n d={pathD}\n stroke={COLORS.track}\n strokeWidth={sw}\n strokeLinecap=\"butt\"\n fill=\"none\"\n />\n {/* Filled overlay can be full or half (or any partial) */}\n {segmentFill > 0 && (\n <path\n d={pathD}\n stroke={COLORS.strong}\n strokeWidth={sw}\n strokeLinecap=\"butt\"\n fill=\"none\"\n pathLength={1}\n strokeDasharray={`${segmentFill} 1`}\n />\n )}\n </g>\n );\n })}\n </svg>\n );\n};\n\nconst ScoreBar = ({ value = 0, maxValue = 5 }) => {\n const numericValue = Number(value);\n const clampedValue = Number.isFinite(numericValue)\n ? Math.min(Math.max(numericValue, 0), maxValue)\n : 0;\n\n return (\n <div style={{ display: 'flex', gap: 2 }}>\n {Array.from({ length: maxValue }, (_, i) => {\n const segmentFill = Math.max(0, Math.min(1, clampedValue - i));\n return (\n <div\n key={i}\n style={{\n width: 22,\n height: 6,\n borderRadius: 1,\n background: COLORS.track,\n overflow: 'hidden',\n }}\n >\n {segmentFill > 0 && (\n <div\n style={{\n width: `${segmentFill * 100}%`,\n height: '100%',\n background: COLORS.strong,\n }}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n};\n\nconst LEGEND_TOOLTIPS = {\n 'CSAT': 'Predicted Customer Satisfaction',\n 'Resolution': 'Predicted Resolution: was the issue fully resolved?',\n 'Process Adherence': 'Process Adherence: Did the agent follow procedures?',\n 'Communication': 'Predicted Communication Quality: Clarity, Empathy, Professionalism',\n};\n\nconst InfoTooltip = ({ text, children }) => {\n const [show, setShow] = useState(false);\n const ref = useRef(null);\n const [pos, setPos] = useState({ top: 0, left: 0 });\n\n const handleEnter = () => {\n if (ref.current) {\n const rect = ref.current.getBoundingClientRect();\n setPos({\n top: rect.top - 8,\n left: rect.left + rect.width / 2,\n });\n }\n setShow(true);\n };\n\n return (\n <div\n ref={ref}\n style={{ position: 'relative', display: 'inline-flex' }}\n onMouseEnter={handleEnter}\n onMouseLeave={() => setShow(false)}\n >\n {children}\n {show && (\n <div style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n transform: 'translate(-50%, -100%)',\n display: 'flex',\n width: 'max-content',\n maxWidth: 300,\n padding: 10,\n alignItems: 'center',\n borderRadius: 4,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-Strong, #2E3236)',\n zIndex: 9999,\n pointerEvents: 'none',\n }}>\n <span style={{\n color: '#FFF',\n fontSize: 12,\n fontWeight: 400,\n lineHeight: '140%',\n }}>\n {text}\n </span>\n </div>\n )}\n </div>\n );\n};\n\nconst LegendItem = ({ label, value = 0, maxValue = 5 }) => (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n padding: 8,\n alignItems: 'flex-start',\n }}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n }}>\n <span style={{\n fontSize: 12,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 'normal',\n }}>\n {label}\n </span>\n <InfoTooltip text={LEGEND_TOOLTIPS[label] || label}>\n <Info size={14} color={COLORS.infoIcon} strokeWidth={1} style={{ cursor: 'pointer' }} />\n </InfoTooltip>\n </div>\n <ScoreBar value={value} maxValue={maxValue} />\n </div>\n);\n\nconst UpdatedCompassScore = ({\n score = 4,\n minScore = 0,\n maxScore = 5,\n predictedScore = 4,\n predictedLabel = 'Predicted Objective',\n description = '',\n // Outcome value in percent (0–100), rendered in round brackets next to the\n // score, e.g. \"4 (80%)\" — Figma node 1798-5168. Null hides the bracket.\n outcomePercent = null,\n legends = [\n { label: 'CSAT', value: 3 },\n { label: 'Resolution', value: 4 },\n { label: 'Process Adherence', value: 5 },\n { label: 'Communication', value: 3 },\n ],\n}) => {\n const isPhone = useMediaQuery('(max-width: 640px)');\n const numericScore = Number(score);\n const clampedScore = Number.isFinite(numericScore)\n ? Math.min(Math.max(numericScore, minScore), maxScore)\n : minScore;\n const displayScore = clampedScore.toFixed(1);\n // Drop a trailing \".0\" so whole scores read as \"4\" (matches Figma 1798-5168)\n // while half-steps like 3.5 keep their decimal.\n const scoreText = displayScore.endsWith('.0') ? displayScore.slice(0, -2) : displayScore;\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n padding: 24,\n borderRadius: 8,\n border: `1px solid ${COLORS.absent}`,\n background: COLORS.white,\n alignSelf: 'stretch',\n flex: 1,\n gap: 24,\n }}>\n {/* Section Title — left-aligned, vertical, gap: 8 */}\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n }}>\n <span style={{\n fontSize: 15,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n }}>\n Interaction Quality\n </span>\n <span style={{\n fontSize: 14,\n fontWeight: 400,\n color: COLORS.muted,\n fontFamily: 'var(--font-sans)',\n lineHeight: 'normal',\n }}>\n {description}\n </span>\n </div>\n\n {/* Content: Meter (left) + Legends (right) — stacks on phones with the\n gauge on top and the legend details below it. */}\n <div style={{\n display: 'flex',\n flexDirection: isPhone ? 'column' : 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 24,\n flex: 1,\n overflow: isPhone ? 'visible' : 'hidden',\n }}>\n {/* Left: Gauge + Pin + Score number.\n On phones the gauge goes full-width (capped at 243) and can shrink\n below 160 so it always fits the card with no horizontal scroll. */}\n <div style={{\n position: 'relative',\n maxWidth: 243,\n minWidth: isPhone ? 0 : 160,\n flex: isPhone ? '0 0 auto' : '0 1 243px',\n width: isPhone ? '100%' : undefined,\n flexDirection: 'column',\n alignItems: 'center',\n display: 'flex',\n }}>\n <GaugeMeter score={score} minScore={minScore} maxScore={maxScore} />\n\n {/* Compass pin — centered below gauge, needle rotates to point at score */}\n {(() => {\n // Pin sits at gauge center; needle rotates from 180° (score=0) to 0° (score=max)\n const pct = maxScore > minScore ? (clampedScore - minScore) / (maxScore - minScore) : 0;\n // SVG pin's default needle points to top-right (~45°)\n // We need: score=0 → needle points left (180°), score=max → needle points right (0°)\n // Target angle on gauge: 180 - pct*180\n // Pin default orientation: needle at ~45° from top → offset is 45\n // Rotation needed: -(targetAngle - 45) to align needle with gauge position\n const targetAngle = 180 - pct * 180;\n const rotateDeg = -(targetAngle - 45);\n return (\n <svg\n width=\"34\" height=\"35\" viewBox=\"0 0 34 35\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n marginTop: -24,\n transform: `rotate(${rotateDeg}deg)`,\n transformOrigin: 'center center',\n }}\n >\n <path d=\"M16 25.2169C19.958 25.2169 23.1667 22.0083 23.1667 18.0503C23.1667 14.0922 19.958 10.8836 16 10.8836C12.042 10.8836 8.83334 14.0922 8.83334 18.0503C8.83334 22.0083 12.042 25.2169 16 25.2169Z\" fill=\"var(--rail-orange, #C98A5A)\" />\n <path fillRule=\"evenodd\" clipRule=\"evenodd\" d=\"M30.4791 11.2328L33.4351 0L21.6888 3.09113C19.9212 2.41855 18.0036 2.05025 16 2.05025C7.16344 2.05025 0 9.2137 0 18.0503C0 26.8868 7.16344 34.0503 16 34.0503C24.8366 34.0503 32 26.8868 32 18.0503C32 15.6119 31.4546 13.301 30.4791 11.2328ZM16 30.5503C22.9036 30.5503 28.5 24.9538 28.5 18.0503C28.5 11.1467 22.9036 5.55025 16 5.55025C9.09644 5.55025 3.5 11.1467 3.5 18.0503C3.5 24.9538 9.09644 30.5503 16 30.5503Z\" fill=\"var(--rail-orange, #C98A5A)\" />\n </svg>\n );\n })()}\n\n {/* Score number below gauge — with the outcome value in round\n brackets next to it (Figma 1798-5168), e.g. \"4 (80%)\". */}\n <div style={{\n fontSize: 28,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 1,\n textAlign: 'center',\n marginTop: 8,\n display: 'flex',\n alignItems: 'baseline',\n justifyContent: 'center',\n gap: 6,\n }}>\n <span>{scoreText}</span>\n {outcomePercent != null && (\n <span style={{ fontSize: 16, color: COLORS.muted, lineHeight: 1 }}>\n ({outcomePercent}%)\n </span>\n )}\n </div>\n <div style={{\n fontSize: 15,\n fontWeight: 500,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n textAlign: 'center',\n marginTop: 8,\n }}>\n Compass Score\n </div>\n </div>\n\n {/* Right: Predicted Score + Legends */}\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n alignItems: 'flex-start',\n justifyContent: 'center',\n flex: 1,\n width: isPhone ? '100%' : undefined,\n }}>\n {/* Overall Score title */}\n <div style={{\n fontSize: 15,\n fontWeight: 500,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: 1.2,\n textAlign: 'left',\n }}>\n Interaction Quality Index\n </div>\n\n {/* Divider */}\n <div style={{\n width: '100%',\n height: 1,\n background: COLORS.absent,\n }} />\n\n {/* Legend items */}\n {legends.map((legend, i) => (\n <LegendItem\n key={i}\n label={legend.label}\n value={legend.value}\n />\n ))}\n </div>\n </div>\n </div>\n );\n};\n\nexport default UpdatedCompassScore;\n","\"use client\";\n\nimport React, { useState, useRef, useMemo, useEffect } from \"react\";\nimport { useMediaQuery } from \"../../utils/useMediaQuery\";\nimport {\n MessagesSquare,\n Ellipsis,\n CircleCheck,\n Check,\n CornerDownRight,\n Info,\n X,\n} from \"lucide-react\";\n\n/* ─── helpers ─── */\n\nconst roleColorMap = (role) => {\n if (!role) return null;\n const normalized = String(role).trim().toLowerCase();\n const roleTokens = normalized.split(/[^a-z]+/).filter(Boolean);\n if (roleTokens.includes(\"supervisor\")) return \"var(--rail-compliance, #C98A5A)\";\n if (\n roleTokens.includes(\"admin\") ||\n roleTokens.includes(\"administrator\") ||\n roleTokens.includes(\"superadmin\")\n ) {\n return \"var(--rail-discovery, #5E88B0)\";\n }\n if (roleTokens.includes(\"agent\")) return \"var(--rail-outcome, #6B7C93)\";\n return null;\n};\n\nconst extractRoleValue = (user) => {\n if (!user) return null;\n const directRole =\n user.role ??\n user.userRole ??\n user.user_role ??\n user.author_role ??\n user.roleName ??\n user.role_name ??\n user.userType ??\n user.user_type ??\n user.type;\n\n if (typeof directRole === \"string\") return directRole;\n if (Array.isArray(directRole)) return directRole.join(\" \");\n if (directRole && typeof directRole === \"object\") {\n return directRole.name || directRole.value || directRole.label || null;\n }\n\n const nestedRole =\n user.user?.role ??\n user.user?.userRole ??\n user.user?.user_role ??\n user.profile?.role ??\n user.profile?.userRole ??\n user.profile?.user_role;\n\n if (typeof nestedRole === \"string\") return nestedRole;\n if (Array.isArray(nestedRole)) return nestedRole.join(\" \");\n if (nestedRole && typeof nestedRole === \"object\") {\n return nestedRole.name || nestedRole.value || nestedRole.label || null;\n }\n\n return null;\n};\n\n/** Role-mapped color first so stale `color` from auth/session does not override role (matches thread intent). */\nconst resolveCurrentUserAvatarColor = (user) => {\n if (!user) return \"#6B7C93\";\n const role = extractRoleValue(user);\n return roleColorMap(role) || user.color || \"#6B7C93\";\n};\n\nconst getInitials = (name) =>\n (name || \"\")\n .split(\" \")\n .map((w) => w[0])\n .join(\"\")\n .toUpperCase() || \"U\";\n\nconst isWithinEditWindow = (value) => {\n if (!value) return true; // optimistic/new comments are editable\n if (value === \"Just now\") return true;\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) {\n try {\n const utcValue = /Z$|[+-]\\d{2}:\\d{2}$/.test(value) ? value : value + \"Z\";\n const d = new Date(utcValue);\n if (Number.isNaN(d.getTime())) return false;\n return (Date.now() - d.getTime()) < 15 * 60 * 1000;\n } catch { return false; }\n }\n // Parse relative timestamps like \"5 min\", \"1 h\", \"2 days\"\n const minMatch = value.match(/^(\\d+)\\s*min/);\n if (minMatch) return parseInt(minMatch[1], 10) < 15;\n // Anything in hours or days is beyond 15 min\n if (/\\d+\\s*h/.test(value) || /\\d+\\s*day/.test(value)) return false;\n return true;\n};\n\nconst formatTimestamp = (value) => {\n if (!value) return \"\";\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) return value;\n try {\n // Append Z if missing so timestamp is parsed as UTC\n const utcValue = /Z$|[+-]\\d{2}:\\d{2}$/.test(value) ? value : value + \"Z\";\n const d = new Date(utcValue);\n if (Number.isNaN(d.getTime())) return value;\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffMin = Math.floor(diffMs / 60000);\n const diffHr = Math.floor(diffMs / 3600000);\n if (diffMin < 1) return \"Just now\";\n if (diffMin < 60) return `${diffMin} min`;\n if (diffHr < 24) return `${diffHr} h`;\n const diffDays = Math.floor(diffHr / 24);\n if (diffDays === 1) return \"1 day\";\n return `${diffDays} days`;\n } catch {\n return value;\n }\n};\n\n/* ─── Avatar (36 × 36) ─── */\nconst Avatar = ({ name, initials, color, avatar, size = 36 }) => {\n if (avatar) {\n return (\n <img\n src={avatar}\n alt={name}\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n objectFit: \"cover\",\n flexShrink: 0,\n }}\n />\n );\n }\n return (\n <div\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n background: color || \"#6B7C93\",\n color: \"#FFF\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size <= 32 ? \"10px\" : \"11px\",\n fontWeight: 650,\n flexShrink: 0,\n fontFamily: \"var(--default-font-family)\",\n letterSpacing: \"0.02em\",\n }}\n title={name}\n >\n {initials || getInitials(name)}\n </div>\n );\n};\n\n/* ============================================\n COMMENT ROW — Figma node 593-1135 (top-level)\n display: flex\n width: 552px\n align-items: flex-start\n gap: 16px\n\n Reply row — Figma node 593-2042\n display: flex\n padding-left: 48px\n align-items: flex-start\n gap: 16px\n ============================================ */\nconst CommentBubble = ({\n comment,\n isReply = false,\n isConsecutive = false,\n onReply,\n onSendReply,\n onEdit,\n onDelete,\n onMenuClick,\n showReply = true,\n}) => {\n const [hovered, setHovered] = useState(false);\n const [menuOpen, setMenuOpen] = useState(false);\n const [replyOpen, setReplyOpen] = useState(false);\n const [replyValue, setReplyValue] = useState(\"\");\n const [editOpen, setEditOpen] = useState(false);\n const [editValue, setEditValue] = useState(\"\");\n const [confirmDelete, setConfirmDelete] = useState(false);\n const menuRef = useRef(null);\n const replyRef = useRef(null);\n const editRef = useRef(null);\n const author = comment.author || {};\n const authorName = author.name || comment.author_name || \"Unknown\";\n const initials = author.initials || getInitials(authorName);\n const role = author.role || comment.author_role;\n const avatarColor = author.color || roleColorMap(role) || \"#6B7C93\";\n const avatarImg = author.avatar || comment.avatar;\n const rawTimestamp = comment.timestamp || comment.created_at;\n const timestamp = formatTimestamp(rawTimestamp);\n const canEdit = isWithinEditWindow(rawTimestamp);\n const isEdited = Boolean(comment.isEdited || comment.is_edited || comment.edited);\n\n const paragraphs = Array.isArray(comment.content)\n ? comment.content\n : [comment.content || comment.text || \"\"];\n\n // Close menu on outside click\n React.useEffect(() => {\n if (!menuOpen) return;\n const handler = (e) => {\n if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [menuOpen]);\n\n // Auto-resize reply textarea\n React.useEffect(() => {\n const ta = replyRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n const max = 140;\n ta.style.height = Math.min(ta.scrollHeight, max) + \"px\";\n ta.style.overflowY = ta.scrollHeight > max ? \"auto\" : \"hidden\";\n }, [replyValue, replyOpen]);\n\n // Auto-resize edit textarea\n React.useEffect(() => {\n const ta = editRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n const max = 140;\n ta.style.height = Math.min(ta.scrollHeight, max) + \"px\";\n ta.style.overflowY = ta.scrollHeight > max ? \"auto\" : \"hidden\";\n }, [editValue, editOpen]);\n\n return (\n <div\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n paddingLeft: isReply ? 48 : 0,\n alignItems: \"flex-start\",\n gap: 16,\n paddingTop: isConsecutive ? 0 : 8,\n paddingBottom: 8,\n }}\n >\n {/* Avatar — 36 × 36 (hidden for consecutive messages, keep space) */}\n {isConsecutive ? (\n <div style={{ width: 36, flexShrink: 0 }} />\n ) : (\n <Avatar\n name={authorName}\n initials={initials}\n color={avatarColor}\n avatar={avatarImg}\n />\n )}\n\n {/* Content column */}\n <div style={{ flex: 1, minWidth: 0 }}>\n {/* Header row — always shows menu, name/time hidden for consecutive */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: isConsecutive ? \"flex-end\" : \"space-between\",\n marginBottom: isConsecutive ? 0 : 6,\n }}\n >\n {!isConsecutive && (\n <div style={{ display: \"flex\", alignItems: \"baseline\", gap: 8 }}>\n {/* Name — 13px / 650 / #1E2125 */}\n <span\n style={{\n fontSize: 13,\n fontWeight: 650,\n color: \"var(--text-ink, #1E2125)\",\n lineHeight: \"150%\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n {authorName}\n </span>\n {/* Timestamp — 12px / 400 / #808183 */}\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n lineHeight: \"150%\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n {timestamp}\n </span>\n {isEdited && (\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n lineHeight: \"150%\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n (Edited)\n </span>\n )}\n </div>\n )}\n\n {/* Three-dot menu — Ellipsis 24×24, hover only + dropdown */}\n <div style={{ position: \"relative\" }} ref={menuRef}>\n <button\n type=\"button\"\n onClick={() => setMenuOpen((p) => !p)}\n style={{\n padding: 2,\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n borderRadius: 4,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: hovered || menuOpen ? 1 : 0,\n transition: \"opacity 0.15s\",\n flexShrink: 0,\n }}\n >\n <Ellipsis size={24} color=\"var(--Grey-Muted, #808183)\" />\n </button>\n\n {/* Dropdown — Figma node 486-4493 */}\n {menuOpen && (\n <div\n style={{\n position: \"absolute\",\n top: \"100%\",\n right: 0,\n marginTop: 4,\n display: \"flex\",\n width: 99,\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n borderRadius: 4,\n border: \"1px solid var(--Grey-absent, #D9D9D9)\",\n background: \"var(--Grey-White, #FFF)\",\n boxShadow: \"-2px 2px 2px 0 rgba(0, 0, 0, 0.25)\",\n zIndex: 50,\n overflow: \"hidden\",\n }}\n >\n {onReply && (\n <button\n type=\"button\"\n onClick={() => { setMenuOpen(false); setEditOpen(false); setReplyOpen(true); }}\n style={{\n display: \"flex\",\n width: \"100%\",\n padding: \"10px 16px\",\n alignItems: \"center\",\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Strong, #2E3236)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n textAlign: \"left\",\n }}\n onMouseEnter={(e) => { e.currentTarget.style.background = \"var(--surface-hover, #F3F7F7)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"transparent\"; }}\n >\n Reply\n </button>\n )}\n {onEdit && (\n <button\n type=\"button\"\n disabled={!canEdit}\n onClick={() => {\n if (!canEdit) return;\n setMenuOpen(false);\n const text = Array.isArray(comment.content)\n ? comment.content.join(\"\\n\")\n : (comment.content || comment.text || \"\");\n setEditValue(text);\n setEditOpen(true);\n setReplyOpen(false);\n }}\n style={{\n display: \"flex\",\n width: \"100%\",\n padding: \"10px 16px\",\n alignItems: \"center\",\n border: \"none\",\n background: \"transparent\",\n cursor: canEdit ? \"pointer\" : \"not-allowed\",\n fontSize: 13,\n fontWeight: 400,\n color: canEdit ? \"var(--Grey-Strong, #2E3236)\" : \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n textAlign: \"left\",\n opacity: canEdit ? 1 : 0.5,\n }}\n onMouseEnter={(e) => { if (canEdit) e.currentTarget.style.background = \"var(--surface-hover, #F3F7F7)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"transparent\"; }}\n >\n Edit\n </button>\n )}\n {onDelete && (\n <button\n type=\"button\"\n onClick={() => { setMenuOpen(false); setConfirmDelete(true); }}\n style={{\n display: \"flex\",\n width: \"100%\",\n padding: \"10px 16px\",\n alignItems: \"center\",\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Strong, #2E3236)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n textAlign: \"left\",\n }}\n onMouseEnter={(e) => { e.currentTarget.style.background = \"var(--surface-hover, #F3F7F7)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"transparent\"; }}\n >\n Delete\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n\n {/* Edit mode — card with editable input */}\n {editOpen ? (\n <div\n style={{\n display: \"flex\",\n width: 662,\n maxWidth: \"100%\",\n padding: \"8px 12px 12px 12px\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n gap: 24,\n borderRadius: 8,\n border: \"1px solid var(--Grey-absent, #D9D9D9)\",\n background: \"var(--Grey-White, #FFF)\",\n boxSizing: \"border-box\",\n marginTop: 4,\n }}\n >\n {/* Header with author name + close */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n }}\n >\n <span\n style={{\n fontSize: 13,\n fontWeight: 600,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"normal\",\n }}\n >\n {\"\\u201C\"} {comment.author?.name || \"Unknown\"}\n </span>\n <button\n type=\"button\"\n onClick={() => setEditOpen(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: 0,\n }}\n >\n <X size={20} color=\"var(--Grey-Muted, #808183)\" />\n </button>\n </div>\n {/* Editable input + Save */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-end\",\n gap: 8,\n width: \"100%\",\n }}\n >\n <textarea\n ref={editRef}\n value={editValue}\n onChange={(e) => setEditValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n if (e.metaKey || e.ctrlKey || e.shiftKey) {\n // Allow newline insertion\n return;\n }\n e.preventDefault();\n if (editValue.trim()) {\n onEdit?.({ ...comment, content: editValue.trim(), isEdited: true });\n setEditOpen(false);\n }\n }\n if (e.key === \"Escape\") { setEditOpen(false); }\n }}\n autoFocus\n rows={1}\n style={{\n flex: 1,\n padding: \"10px 12px\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--text-ink, #1E2125)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"160%\",\n border: \"none\",\n background: \"transparent\",\n outline: \"none\",\n boxSizing: \"border-box\",\n resize: \"none\",\n minHeight: 24,\n maxHeight: 140,\n overflowY: \"hidden\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => {\n if (editValue.trim()) {\n onEdit?.({ ...comment, content: editValue.trim(), isEdited: true });\n setEditOpen(false);\n }\n }}\n disabled={!editValue.trim()}\n style={{\n display: \"flex\",\n padding: \"6px 16px\",\n justifyContent: \"center\",\n alignItems: \"center\",\n fontSize: 13,\n fontWeight: 600,\n color: editValue.trim()\n ? \"var(--Grey-White, #FFF)\"\n : \"var(--Grey-Muted, #808183)\",\n background: editValue.trim()\n ? \"var(--Grey-Strong, #2E3236)\"\n : \"var(--grey-light, #e9e8e8a1)\",\n border: \"none\",\n borderRadius: 6,\n cursor: editValue.trim() ? \"pointer\" : \"not-allowed\",\n fontFamily: \"var(--default-font-family)\",\n flexShrink: 0,\n transition: \"all 0.15s\",\n lineHeight: \"150%\",\n }}\n >\n Save\n </button>\n </div>\n </div>\n ) : (\n /* Message bubbles — stacked, gap: 4px, fit content */\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 4, alignItems: \"flex-start\" }}>\n {paragraphs.map((paragraph, idx) => (\n <div\n key={idx}\n style={{\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--text-ink, #1E2125)\",\n lineHeight: \"160%\",\n fontFamily: \"var(--default-font-family)\",\n padding: \"8px 12px\",\n background: isReply\n ? \"var(--surface-hover, #F3F7F7)\"\n : \"var(--surface-warm-40, rgba(243, 241, 229, 0.40))\",\n borderRadius: 8,\n wordBreak: \"break-word\",\n whiteSpace: \"pre-wrap\",\n }}\n >\n {paragraph}\n </div>\n ))}\n </div>\n )}\n\n {/* Inline delete confirmation */}\n {confirmDelete && (\n <div\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 8,\n marginTop: 8,\n fontSize: 13,\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n <span style={{ color: \"var(--Grey-Muted, #808183)\", fontWeight: 400 }}>\n Confirm: delete this comment?\n </span>\n <button\n type=\"button\"\n onClick={() => { setConfirmDelete(false); onDelete?.(comment); }}\n style={{\n background: \"var(--grey-light, #e9e8e8a1)\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 600,\n color: \"var(--text-ink, #1E2125)\",\n fontFamily: \"var(--default-font-family)\",\n padding: \"4px 10px\",\n borderRadius: 6,\n transition: \"background 0.15s\",\n }}\n onMouseEnter={(e) => { e.currentTarget.style.background = \"var(--Grey-absent, #D9D9D9)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"var(--grey-light, #e9e8e8a1)\"; }}\n >\n Delete\n </button>\n <button\n type=\"button\"\n onClick={() => setConfirmDelete(false)}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n padding: \"4px 10px\",\n borderRadius: 6,\n transition: \"background 0.15s\",\n }}\n onMouseEnter={(e) => { e.currentTarget.style.background = \"var(--grey-light, #e9e8e8a1)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = \"none\"; }}\n >\n Cancel\n </button>\n </div>\n )}\n\n {/* Reply action — CornerDownRight 20×20 + \"Reply\" */}\n {showReply && onReply && !replyOpen && !confirmDelete && (\n <button\n type=\"button\"\n onClick={() => { setEditOpen(false); setReplyOpen(true); }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n marginTop: 8,\n padding: 0,\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n transition: \"color 0.15s\",\n }}\n >\n <CornerDownRight size={20} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n Reply\n </button>\n )}\n\n {/* Inline reply input */}\n {replyOpen && (\n <div\n style={{\n display: \"flex\",\n width: 662,\n maxWidth: \"100%\",\n padding: \"8px 12px 12px 12px\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n gap: 24,\n borderRadius: 8,\n border: \"1px solid var(--Grey-absent, #D9D9D9)\",\n background: \"var(--Grey-White, #FFF)\",\n boxSizing: \"border-box\",\n marginTop: 12,\n }}\n >\n {/* Tagged comment quote */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8, width: \"100%\" }}>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n }}\n >\n <span\n style={{\n fontSize: 13,\n fontWeight: 600,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"normal\",\n }}\n >\n {\"\\u201C\"} {comment.author?.name || \"Unknown\"}\n </span>\n <button\n type=\"button\"\n onClick={() => { setReplyValue(\"\"); setReplyOpen(false); }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: 0,\n }}\n >\n <X size={20} color=\"var(--Grey-Muted, #808183)\" />\n </button>\n </div>\n <div\n style={{\n display: \"flex\",\n height: 36,\n padding: 16,\n alignItems: \"center\",\n gap: 5,\n borderRadius: \"0 8px 8px 8px\",\n background: \"var(--Grey-Strong, #2E3236)\",\n boxSizing: \"border-box\",\n width: \"100%\",\n }}\n >\n <span\n style={{\n color: \"var(--Grey-White, #FFF)\",\n fontSize: 13,\n fontWeight: 400,\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"normal\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {Array.isArray(comment.content) ? comment.content[0] : comment.content}\n </span>\n </div>\n </div>\n {/* Reply input + Post button */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-end\",\n gap: 8,\n width: \"100%\",\n }}\n >\n <textarea\n ref={replyRef}\n value={replyValue}\n onChange={(e) => setReplyValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n if (e.metaKey || e.ctrlKey || e.shiftKey) {\n // Allow newline insertion\n return;\n }\n e.preventDefault();\n if (replyValue.trim()) {\n onSendReply?.({ content: replyValue.trim(), parentId: comment.id });\n setReplyValue(\"\");\n setReplyOpen(false);\n }\n }\n if (e.key === \"Escape\") {\n setReplyValue(\"\");\n setReplyOpen(false);\n }\n }}\n autoFocus\n placeholder=\"Add a reply\"\n rows={1}\n style={{\n flex: 1,\n padding: \"10px 12px\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--text-ink, #1E2125)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"160%\",\n border: \"none\",\n background: \"transparent\",\n outline: \"none\",\n boxSizing: \"border-box\",\n resize: \"none\",\n minHeight: 24,\n maxHeight: 140,\n overflowY: \"hidden\",\n }}\n />\n <button\n type=\"button\"\n onClick={() => {\n if (replyValue.trim()) {\n onSendReply?.({ content: replyValue.trim(), parentId: comment.id });\n setReplyValue(\"\");\n setReplyOpen(false);\n }\n }}\n disabled={!replyValue.trim()}\n style={{\n display: \"flex\",\n height: 28,\n padding: \"8px 12px\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gap: 8,\n fontSize: 13,\n fontWeight: 600,\n color: replyValue.trim()\n ? \"var(--Grey-White, #FFF)\"\n : \"var(--Grey-Muted, #808183)\",\n background: replyValue.trim()\n ? \"var(--Neutral-850, #272727)\"\n : \"var(--grey-light, #e9e8e8a1)\",\n border: \"none\",\n borderRadius: 10,\n cursor: replyValue.trim() ? \"pointer\" : \"not-allowed\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n }}\n >\n Post\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n};\n\n/* ============================================\n COMMENT INPUT — Figma node 237-5570\n display: flex\n width: 552px\n padding: 12px\n flex-direction: column\n justify-content: center\n align-items: flex-start\n gap: 24px\n\n border-radius: 8px\n border: 1px solid var(--Grey-absent, #D9D9D9)\n background: var(--Grey-White, #FFF)\n ============================================ */\nconst CommentInput = ({ currentUser, onSubmit }) => {\n const [value, setValue] = useState(\"\");\n const [isFocused, setIsFocused] = useState(false);\n const textareaRef = useRef(null);\n\n useEffect(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n const max = 140;\n ta.style.height = Math.min(ta.scrollHeight, max) + \"px\";\n ta.style.overflowY = ta.scrollHeight > max ? \"auto\" : \"hidden\";\n }, [value]);\n\n const handleSubmit = () => {\n const trimmed = value.trim();\n if (!trimmed) return;\n onSubmit?.(trimmed);\n setValue(\"\");\n };\n\n const handleKeyDown = (e) => {\n if (e.key === \"Enter\") {\n if (e.metaKey || e.ctrlKey || e.shiftKey) {\n // Allow newline insertion\n return;\n }\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const initials = currentUser?.initials || getInitials(currentUser?.name);\n const color = resolveCurrentUserAvatarColor(currentUser);\n const avatarImg = currentUser?.avatar;\n\n return (\n <div style={{ display: \"flex\", gap: 16, alignItems: \"flex-start\" }}>\n {/* Current user avatar */}\n <Avatar\n name={currentUser?.name}\n initials={initials}\n color={color}\n avatar={avatarImg}\n />\n\n {/* Input container — Figma: 552px, padding 12, border-radius 8 */}\n <div\n style={{\n flex: 1,\n padding: 12,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"flex-start\",\n gap: 24,\n borderRadius: 8,\n border: isFocused\n ? \"1px solid var(--Grey-Strong, #2E3236)\"\n : \"1px solid var(--Grey-absent, #D9D9D9)\",\n background: \"var(--Grey-White, #FFF)\",\n transition: \"border-color 0.15s\",\n }}\n >\n {/* Textarea + Post row */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-end\",\n gap: 8,\n width: \"100%\",\n }}\n >\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onKeyDown={handleKeyDown}\n placeholder=\"Add feedback\"\n rows={1}\n style={{\n flex: 1,\n border: \"none\",\n outline: \"none\",\n resize: \"none\",\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--text-ink, #1E2125)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"160%\",\n background: \"transparent\",\n padding: 0,\n minHeight: 24,\n maxHeight: 140,\n overflowY: \"hidden\",\n }}\n />\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!value.trim()}\n style={{\n display: \"flex\",\n padding: \"6px 16px\",\n justifyContent: \"center\",\n alignItems: \"center\",\n fontSize: 13,\n fontWeight: 600,\n color: value.trim()\n ? \"var(--Grey-White, #FFF)\"\n : \"var(--Grey-Muted, #808183)\",\n background: value.trim()\n ? \"var(--Grey-Strong, #2E3236)\"\n : \"var(--grey-light, #e9e8e8a1)\",\n border: \"none\",\n borderRadius: 6,\n cursor: value.trim() ? \"pointer\" : \"not-allowed\",\n fontFamily: \"var(--default-font-family)\",\n transition: \"all 0.15s\",\n flexShrink: 0,\n lineHeight: \"150%\",\n }}\n >\n Post\n </button>\n </div>\n </div>\n </div>\n );\n};\n\n/* ============================================\n MAIN COMPONENT: UpdatedThreads\n\n Outer container — full width\n Header (237-5556):\n display: flex\n height: 40px\n padding-bottom: 8px\n align-items: center\n gap: 16px\n align-self: stretch\n border-bottom: 1px solid var(--Grey-absent, #D9D9D9)\n\n Comments + Input wrapper (596-2060):\n display: flex\n padding-top: 24px\n flex-direction: column\n align-items: flex-start\n gap: 10px\n align-self: stretch\n border-top: 1px solid var(--Grey-absent, #D9D9D9)\n width: 552px (content area)\n ============================================ */\n\nconst CommentThread = ({ comment, depth = 0, isConsecutive = false, onReply, onSendReply, onEdit, onDelete, onMenuClick }) => {\n const hasReplies = comment.replies && comment.replies.length > 0;\n const isLastAtDepth = !hasReplies;\n return (\n <React.Fragment>\n <div style={{ paddingLeft: depth > 0 ? Math.min(depth * 32, 128) : 0 }}>\n <CommentBubble\n comment={comment}\n isReply={depth > 0}\n isConsecutive={isConsecutive}\n onReply={onReply}\n onSendReply={onSendReply}\n onEdit={onEdit}\n onDelete={onDelete}\n onMenuClick={onMenuClick}\n showReply={isLastAtDepth}\n />\n </div>\n {hasReplies && comment.replies.map((reply) => (\n <CommentThread\n key={reply.id}\n comment={reply}\n depth={depth + 1}\n onReply={onReply}\n onSendReply={onSendReply}\n onEdit={onEdit}\n onDelete={onDelete}\n onMenuClick={onMenuClick}\n />\n ))}\n </React.Fragment>\n );\n};\n\nconst UpdatedThreads = ({\n comments: externalComments = [],\n totalComments,\n children,\n onSendComment,\n onReply,\n onSendReply,\n onEdit,\n onDelete,\n onMenuClick,\n onMarkResolved,\n currentUser,\n isResolved = false,\n}) => {\n // Local state for optimistic updates (replies, new comments, edits, deletes)\n const [localComments, setLocalComments] = useState([]);\n const [isSending, setIsSending] = useState(false);\n\n // Merge external + local comments\n const allComments = useMemo(() => {\n const externalIds = new Set(externalComments.map((c) => c.id));\n // Filter out local comments that now exist in external (API caught up)\n const newLocal = localComments.filter((c) => !externalIds.has(c.id));\n return [...externalComments, ...newLocal];\n }, [externalComments, localComments]);\n\n // Sync: remove local comments when external updates\n React.useEffect(() => {\n const externalIds = new Set(externalComments.map((c) => c.id));\n setLocalComments((prev) => prev.filter((c) => !externalIds.has(c.id)));\n }, [externalComments]);\n\n const displayCurrentUser = useMemo(() => {\n if (!currentUser) return { name: \"You\", initials: \"YO\", color: \"#6B7C93\" };\n const name = currentUser.name || \"You\";\n const initials = currentUser.initials || getInitials(name);\n const color = resolveCurrentUserAvatarColor(currentUser);\n return { ...currentUser, name, initials, color };\n }, [currentUser]);\n\n const handleSendReply = async ({ content, parentId }) => {\n if (onSendReply) {\n // Host app mode — let API handle it, show loading\n setIsSending(true);\n try {\n await onSendReply({ content, parentId });\n } finally {\n setIsSending(false);\n }\n } else {\n // Library demo mode — optimistic local comment\n const optimisticReply = {\n id: `temp-${Date.now()}`,\n author: displayCurrentUser,\n content,\n timestamp: \"Just now\",\n parentId,\n isOptimistic: true,\n };\n setLocalComments((prev) => [...prev, optimisticReply]);\n }\n };\n\n const handleSendComment = async (text) => {\n if (onSendComment) {\n // Host app mode — let API handle it, show loading\n setIsSending(true);\n try {\n await onSendComment(text);\n } finally {\n setIsSending(false);\n }\n } else {\n // Library demo mode — optimistic local comment\n const optimisticComment = {\n id: `temp-${Date.now()}`,\n author: displayCurrentUser,\n content: text,\n timestamp: \"Just now\",\n isOptimistic: true,\n };\n setLocalComments((prev) => [...prev, optimisticComment]);\n }\n };\n\n const handleEdit = (comment) => {\n // If it's a local optimistic comment, update locally\n setLocalComments((prev) =>\n prev.map((c) => (c.id === comment.id ? { ...c, content: comment.content, isEdited: true } : c))\n );\n onEdit?.(comment);\n };\n\n const handleDelete = (comment) => {\n // Remove from local state immediately\n setLocalComments((prev) => prev.filter((c) => c.id !== comment.id));\n onDelete?.(comment);\n };\n\n const groupedComments = useMemo(() => {\n const repliesByParent = {};\n allComments.forEach((c) => {\n if (c.parentId) {\n if (!repliesByParent[c.parentId]) repliesByParent[c.parentId] = [];\n repliesByParent[c.parentId].push(c);\n }\n });\n const buildTree = (comment) => ({\n ...comment,\n replies: (repliesByParent[comment.id] || []).map(buildTree),\n });\n return allComments.filter((c) => !c.parentId).map(buildTree);\n }, [allComments]);\n\n const commentCount = totalComments ?? allComments.length;\n\n // Feedback and Guidance sit side by side on wide layouts, but two text\n // columns need real room, so we stack them once the viewport drops below\n // 900px. A viewport media query (not a container measurement) is used\n // deliberately: the detail panel can overflow horizontally, so this\n // component's own clientWidth stays wide even when the visible area is\n // narrow.\n const isNarrow = useMediaQuery(\"(max-width: 900px)\");\n const isPhone = useMediaQuery(\"(max-width: 640px)\");\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n background: \"var(--Grey-White, #FFF)\",\n width: \"100%\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n {/* ═══════════════════════════════════════════\n HEADER — FEEDBACK & GUIDANCE\n ═══════════════════════════════════════════ */}\n <div\n style={{\n display: \"flex\",\n height: 40,\n paddingBottom: 8,\n alignItems: \"center\",\n gap: 8,\n alignSelf: \"stretch\",\n }}\n >\n <MessagesSquare size={24} color=\"var(--rail-orange, #C98A5A)\" strokeWidth={1.5} />\n <span\n style={{\n fontSize: 16,\n fontWeight: 600,\n color: \"var(--Grey-Strong, #2E3236)\",\n textTransform: \"uppercase\",\n lineHeight: 1.2,\n }}\n >\n Feedback & Guidance\n </span>\n </div>\n\n {/* Divider */}\n <div style={{ width: \"100%\", height: 1, background: \"var(--Grey-absent, #D9D9D9)\" }} />\n\n {/* ═══════════════════════════════════════════\n CONTENT AREA — Two equal columns (stacks when narrow)\n ═══════════════════════════════════════════ */}\n <div\n style={{\n display: \"flex\",\n flexDirection: isNarrow ? \"column\" : \"row\",\n gap: 24,\n alignSelf: \"stretch\",\n }}\n >\n {/* Left column — Feedback / Comments */}\n <div style={{ flex: 1, minWidth: 0 }}>\n {/* Feedback sub-header */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n flexWrap: isPhone ? \"wrap\" : \"nowrap\",\n gap: isPhone ? 10 : 16,\n paddingTop: 16,\n paddingBottom: 8,\n }}\n >\n <div\n style={{\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: \"var(--surface-hover, #F3F7F7)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <MessagesSquare style={{ width: 20, height: 20, flexShrink: 0 }} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.5} />\n </div>\n <span\n style={{\n fontSize: 16,\n fontWeight: 500,\n color: \"var(--Grey-Strong, #2E3236)\",\n }}\n >\n Feedback\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n marginLeft: \"auto\",\n }}\n >\n {commentCount} Comment{commentCount !== 1 ? \"s\" : \"\"}\n </span>\n {isResolved ? (\n <div\n style={{\n display: \"inline-flex\",\n height: 32,\n padding: \"12px 16px 12px 12px\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gap: 8,\n borderRadius: 10,\n background: \"var(--Rail-Surface-2, #E3E1D7)\",\n flexShrink: 0,\n }}\n >\n <Check size={16} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={2} />\n <span\n style={{\n fontSize: 13,\n fontWeight: 500,\n color: \"var(--Grey-Strong, #2E3236)\",\n fontFamily: \"var(--default-font-family)\",\n lineHeight: \"150%\",\n }}\n >\n Resolved\n </span>\n </div>\n ) : onMarkResolved ? (\n <button\n type=\"button\"\n onClick={onMarkResolved}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 8,\n padding: \"8px 16px\",\n fontSize: 13,\n fontWeight: 500,\n color: \"var(--Grey-Strong, #2E3236)\",\n background: \"var(--Grey-White, #FFF)\",\n border: \"1px solid var(--Grey-absent, #D9D9D9)\",\n borderRadius: 20,\n cursor: \"pointer\",\n fontFamily: \"var(--default-font-family)\",\n transition: \"background 0.15s\",\n lineHeight: \"150%\",\n flexShrink: 0,\n // On phones the button drops to its own full-width line.\n ...(isPhone ? { width: \"100%\", order: 1 } : {}),\n }}\n >\n <CircleCheck size={16} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.5} />\n Mark as Resolved\n </button>\n ) : null}\n </div>\n {/* Comments list */}\n {allComments.length > 0 && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 0,\n marginBottom: 24,\n maxHeight: 600,\n overflowY: allComments.length > 6 ? \"auto\" : \"visible\",\n }}\n >\n {groupedComments.map((comment, idx) => {\n const prev = idx > 0 ? groupedComments[idx - 1] : null;\n const prevAuthor = prev?.author?.name || prev?.author_name;\n const currAuthor = comment.author?.name || comment.author_name;\n const isConsecutive = prev && prevAuthor === currAuthor && (!prev.replies || prev.replies.length === 0);\n return (\n <CommentThread\n key={comment.id}\n comment={comment}\n depth={0}\n isConsecutive={!!isConsecutive}\n onReply={onReply}\n onSendReply={handleSendReply}\n onEdit={handleEdit}\n onDelete={handleDelete}\n onMenuClick={onMenuClick}\n />\n );\n })}\n </div>\n )}\n\n {/* Edit info hint */}\n {allComments.length > 0 && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n marginBottom: 16,\n marginLeft: 48,\n }}\n >\n <Info size={16} color=\"var(--Grey-Muted, #808183)\" />\n <span\n style={{\n color: \"var(--Grey-Muted, #808183)\",\n fontSize: 13,\n fontStyle: \"normal\",\n fontWeight: 400,\n lineHeight: \"normal\",\n }}\n >\n Comments can be edited within 15 minutes.\n </span>\n </div>\n )}\n\n {/* Loading indicator */}\n {isSending && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"8px 0\",\n }}\n >\n <div\n style={{\n width: 16,\n height: 16,\n border: \"2px solid var(--Grey-absent, #D9D9D9)\",\n borderTopColor: \"var(--Grey-Strong, #2E3236)\",\n borderRadius: \"50%\",\n animation: \"spin 0.8s linear infinite\",\n }}\n />\n <span\n style={{\n fontSize: 13,\n color: \"var(--Grey-Muted, #808183)\",\n fontFamily: \"var(--default-font-family)\",\n }}\n >\n Sending...\n </span>\n <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n )}\n\n {/* Comment input */}\n <CommentInput currentUser={displayCurrentUser} onSubmit={handleSendComment} />\n </div>\n\n {/* Right column — Guidance (rendered via children) */}\n <div\n style={{\n flex: 1,\n minWidth: 0,\n }}\n >\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nexport default UpdatedThreads;\n","\"use client\";\n\nimport React, { useState } from \"react\";\nimport {\n Lightbulb,\n PlayCircle,\n PauseCircle,\n ScrollText,\n ThumbsUp,\n ThumbsDown,\n Target,\n ArrowUp,\n ArrowDown,\n ChevronDown,\n ChevronRight,\n} from \"lucide-react\";\n\n/**\n * UpdatedGuidance — Guidance list for interaction details.\n *\n * Matches the backend `interaction-guidance` block contract — everything is\n * pre-resolved server-side so this component just renders what it receives.\n * No client-side icon / tone derivation, no impact-string formatting.\n *\n * Figma node: 822-15273\n *\n * Props:\n * - items Array Guidance items (pre-sorted server-side)\n * - guidanceCount number Total count for the sub-header; defaults to items.length\n * - loading boolean Show loading state (currently unused — slot for shimmer)\n * - onPlayEvidence fn Called with { start_ms, end_ms } to play audio segment\n * - onShowInTranscript fn Called with start_ms to scroll transcript\n * - timelinePlaying boolean Whether the timeline is currently playing\n * - currentTimeSeconds number Current playback time, in seconds\n *\n * Item shape (per backend contract):\n * - title string Guidance title (top line)\n * - type string \"focus\" | \"opportunity\" | \"excellence\" (informational only)\n * - tone string \"green\" | \"amber\" | \"red\" — colors the leading icon\n * - icon string \"thumbs_up\" | \"thumbs_down\" | \"focus\" — leading icon\n * - signals Array Per-signal coaching context:\n * - signal_key string\n * - display_name string Signal label (e.g. \"Next Steps Unclear\")\n * - description string Coaching sentence, already resolved\n * - impact_label string? Pre-formatted (\"Helped score (+3.1%)\"); shown\n * as a chip when present, skipped when absent\n * - impact_direction string? \"positive\" | \"negative\" — drives chip color\n * - evidence Array? Up to 3 transcript snippets:\n * { actor, text, start_ms, end_ms }\n */\n\nconst COLORS = {\n strong: \"var(--Grey-Strong, #2E3236)\",\n muted: \"var(--Grey-Muted, #808183)\",\n border: \"var(--Grey-absent, #D9D9D9)\",\n surfaceHover: \"var(--surface-hover, #F3F7F7)\",\n warmBorder: \"var(--border-warm, #B2AEA8)\",\n quoteText: \"var(--text-subtle-warm, #767473)\",\n // Tone tints for the leading icon. NOTE: `--rail-compliance` is wired to an\n // amber/orange (#C98A5A) in the design tokens despite its name, so we use\n // `--state-present` for actual green here. Same for `--rail-attrition`.\n toneGreen: \"var(--state-present, #25A372)\",\n toneAmber: \"var(--rail-orange, #C98A5A)\",\n toneRed: \"var(--color-red-strong, #D04A4A)\",\n // Impact-chip backgrounds (light tints) + ink colours for legibility.\n impactPositiveBg: \"rgba(37, 163, 114, 0.12)\",\n impactPositiveInk: \"var(--state-present, #25A372)\",\n impactNegativeBg: \"rgba(208, 74, 74, 0.12)\",\n impactNegativeInk: \"var(--color-red-strong, #D04A4A)\",\n};\n\n// Figma uses Averta for body text; fall back to the project's --font-sans\n// token / system sans so we don't have to bundle the font file here.\nconst FONT_DISPLAY =\n \"var(--font-sans, 'Averta', ui-sans-serif, system-ui, sans-serif)\";\n\n/* ── Hover icon wrapper (matches UpdatedInteractionSignals) ── */\nconst HoverIcon = ({ children, size = 24, onClick, title }) => {\n const [hovered, setHovered] = useState(false);\n return (\n <div\n title={title}\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: size,\n height: size,\n borderRadius: 9999,\n background: hovered ? COLORS.surfaceHover : \"transparent\",\n cursor: \"pointer\",\n flexShrink: 0,\n transition: \"background 0.15s\",\n }}\n >\n {children}\n </div>\n );\n};\n\nconst fmtMs = (ms) => {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${minutes.toString().padStart(2, \"0\")}:${seconds\n .toString()\n .padStart(2, \"0\")}`;\n};\n\nconst toneToColor = (tone) => {\n switch (tone) {\n case \"green\":\n return COLORS.toneGreen;\n case \"amber\":\n return COLORS.toneAmber;\n case \"red\":\n return COLORS.toneRed;\n default:\n return COLORS.strong;\n }\n};\n\n/* ── Leading icon driven by API `icon` field (no client derivation) ──\n Per the latest design, thumbs_up / thumbs_down are rendered as ↑/↓ arrows\n so the row reads as \"score moved up / down\" rather than a sentiment.\n `focus` stays as the Target bullseye. `tone` is accepted on the prop\n chain but unused so a future tinted variant doesn't need an API change. */\nconst LeadingIcon = ({ icon /* tone — unused */ }) => {\n const common = { size: 16, color: COLORS.strong, strokeWidth: 1.5 };\n if (icon === \"thumbs_down\") return <ArrowDown {...common} />;\n if (icon === \"focus\") return <Target {...common} />;\n // Default + thumbs_up → ArrowUp\n return <ArrowUp {...common} />;\n};\n\n/* ── Impact chip (e.g. \"Helped score (+3.1%)\") ──\n Direction is conveyed by the ↑/↓ arrow only — chip uses a neutral surface\n so the row stays calm and red/green tints don't dominate the layout. */\nconst ImpactChip = ({ label, direction }) => {\n if (!label) return null;\n const Arrow = direction === \"negative\" ? ArrowDown : ArrowUp;\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n background: COLORS.surfaceHover,\n color: COLORS.strong,\n padding: \"2px 8px\",\n borderRadius: 9999,\n fontSize: 12,\n fontWeight: 500,\n lineHeight: 1.4,\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n >\n {label}\n <Arrow size={12} color={COLORS.strong} strokeWidth={2} />\n </span>\n );\n};\n\n/* ── Single evidence quote (collapsed → expanded by parent) ── */\nconst EvidenceQuote = ({\n evidence,\n onPlayEvidence,\n onShowInTranscript,\n timelinePlaying,\n currentTimeSeconds,\n}) => {\n const startMs = evidence.start_ms ?? evidence.startMs;\n const endMs = evidence.end_ms ?? evidence.endMs;\n const hasTimestamp = startMs != null;\n const currentMs = (currentTimeSeconds ?? 0) * 1000;\n const isPlayingThis =\n timelinePlaying &&\n hasTimestamp &&\n currentMs >= startMs &&\n currentMs <= (endMs ?? startMs + 5000);\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n paddingLeft: 12,\n borderLeft: `2px solid ${COLORS.warmBorder}`,\n }}\n >\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.quoteText,\n lineHeight: 1.5,\n fontStyle: \"italic\",\n wordBreak: \"break-word\",\n }}\n >\n “{evidence.text}”\n </span>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n minHeight: 24,\n }}\n >\n {evidence.actor && (\n <span\n style={{\n fontSize: 12,\n fontWeight: 500,\n color: COLORS.muted,\n textTransform: \"capitalize\",\n }}\n >\n {evidence.actor}\n </span>\n )}\n {hasTimestamp && (\n <>\n <HoverIcon\n size={24}\n title={isPlayingThis ? \"Pause\" : \"Play evidence\"}\n onClick={() =>\n onPlayEvidence?.({ start_ms: startMs, end_ms: endMs })\n }\n >\n {isPlayingThis ? (\n <PauseCircle\n size={16}\n color={COLORS.strong}\n strokeWidth={1.25}\n />\n ) : (\n <PlayCircle\n size={16}\n color={COLORS.muted}\n strokeWidth={1.25}\n />\n )}\n </HoverIcon>\n <HoverIcon\n size={24}\n title=\"Show in transcript\"\n onClick={() => onShowInTranscript?.(startMs)}\n >\n <ScrollText size={16} color={COLORS.muted} strokeWidth={1.5} />\n </HoverIcon>\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: COLORS.muted,\n lineHeight: 1.2,\n whiteSpace: \"nowrap\",\n }}\n >\n {fmtMs(startMs)}\n </span>\n </>\n )}\n </div>\n </div>\n );\n};\n\n/* ── Signal block: name + impact chip + description + expandable evidence ── */\nconst SignalRow = ({\n signal,\n onPlayEvidence,\n onShowInTranscript,\n timelinePlaying,\n currentTimeSeconds,\n}) => {\n const evidenceList = Array.isArray(signal.evidence) ? signal.evidence : [];\n const hasEvidence = evidenceList.length > 0;\n const [expanded, setExpanded] = useState(false);\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n }}\n >\n {/* Signal name + impact chip + optional evidence toggle */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flexWrap: \"wrap\",\n }}\n >\n {/* `signal.display_name` intentionally omitted — the item title\n already conveys the coaching theme; dropping the label keeps the\n row to: impact chip + quote toggle. The value is still passed\n through on the signal object for future surfaces. */}\n <ImpactChip\n label={signal.impact_label}\n direction={signal.impact_direction}\n />\n {hasEvidence && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 2,\n background: \"transparent\",\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n fontSize: 12,\n fontWeight: 500,\n color: COLORS.muted,\n fontFamily: \"inherit\",\n }}\n >\n {expanded ? (\n <ChevronDown size={14} color={COLORS.muted} strokeWidth={1.5} />\n ) : (\n <ChevronRight size={14} color={COLORS.muted} strokeWidth={1.5} />\n )}\n {evidenceList.length} {evidenceList.length === 1 ? \"quote\" : \"quotes\"}\n </button>\n )}\n </div>\n\n {/* Signal description intentionally omitted — the item title already\n carries the coaching sentence; rendering the signal's description\n underneath was duplicative. The string is still passed through on\n the signal object so other surfaces (or a future expanded view)\n can use it. */}\n\n {expanded && hasEvidence && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n paddingTop: 4,\n }}\n >\n {evidenceList.map((ev, i) => (\n <EvidenceQuote\n key={i}\n evidence={ev}\n onPlayEvidence={onPlayEvidence}\n onShowInTranscript={onShowInTranscript}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n />\n ))}\n </div>\n )}\n </div>\n );\n};\n\n/* ── Single guidance item ── */\nconst GuidanceItem = ({\n item,\n isLast,\n onPlayEvidence,\n onShowInTranscript,\n timelinePlaying,\n currentTimeSeconds,\n}) => {\n const signals = Array.isArray(item.signals) ? item.signals : [];\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 12,\n padding: \"16px 16px\",\n borderBottom: isLast ? \"none\" : `1px solid ${COLORS.border}`,\n }}\n >\n {/* Leading icon (driven by API `icon` + `tone`) */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 16,\n height: 16,\n flexShrink: 0,\n marginTop: 2,\n }}\n >\n <LeadingIcon icon={item.icon} tone={item.tone} />\n </div>\n\n {/* Right column: title + signals */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n flex: 1,\n minWidth: 0,\n }}\n >\n {/* Item title — matches Figma node 822:15282 (14px Averta regular,\n var(--grey/strong, #2e3236), leading-normal). */}\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 14,\n fontWeight: 400,\n color: COLORS.strong,\n lineHeight: \"normal\",\n wordBreak: \"break-word\",\n }}\n >\n {item.title || \"\"}\n </span>\n\n {signals.length > 0 && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 12,\n }}\n >\n {signals.map((sig, i) => (\n <SignalRow\n key={sig.signal_key || i}\n signal={sig}\n onPlayEvidence={onPlayEvidence}\n onShowInTranscript={onShowInTranscript}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n />\n ))}\n </div>\n )}\n </div>\n </div>\n );\n};\n\n/* ── Summary count bar (focus / opportunity / excellence) ── */\nconst SummaryCountBar = ({ summary }) => {\n if (!summary || typeof summary !== \"object\") return null;\n const focus = Number(summary.focus_count) || 0;\n const opportunity = Number(summary.opportunity_count) || 0;\n const excellence = Number(summary.excellence_count) || 0;\n if (focus + opportunity + excellence === 0) return null;\n\n // Render order per the latest design: Excellence first (positive wins\n // lead), then Opportunity (what to improve), then Focus (most critical).\n // Icons mirror the leading-icon swap below: ArrowUp for excellence,\n // ArrowDown for opportunity, Target stays for focus.\n const cells = [\n {\n key: \"excellence\",\n label: \"Excellence\",\n count: excellence,\n Icon: ArrowUp,\n color: COLORS.strong,\n },\n {\n key: \"opportunity\",\n label: \"Opportunity\",\n count: opportunity,\n Icon: ArrowDown,\n color: COLORS.strong,\n },\n {\n key: \"focus\",\n label: \"Focus\",\n count: focus,\n Icon: Target,\n color: COLORS.strong,\n },\n ].filter((c) => c.count > 0);\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n padding: \"8px 16px\",\n background: COLORS.surfaceHover,\n borderRadius: 8,\n }}\n >\n {cells.map(({ key, label, count, Icon, color }) => (\n <div\n key={key}\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n >\n <Icon size={14} color={color} strokeWidth={1.75} />\n <span\n style={{\n fontSize: 13,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: 1.2,\n }}\n >\n {count}\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.muted,\n lineHeight: 1.2,\n }}\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n );\n};\n\n/* ── Main Component ── */\n// Spec: render at most 5 items in the exact order received from the API.\nconst MAX_ITEMS = 5;\n\nconst UpdatedGuidance = ({\n items = [],\n summary,\n guidanceCount,\n loading = false,\n onPlayEvidence,\n onShowInTranscript,\n timelinePlaying = false,\n currentTimeSeconds = 0,\n}) => {\n // Defensive: clamp to 5 per spec, drop null entries.\n const visibleItems = Array.isArray(items)\n ? items.filter(Boolean).slice(0, MAX_ITEMS)\n : [];\n const count = guidanceCount ?? visibleItems.length;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n width: \"100%\",\n }}\n >\n {/* Sub-header — icon + Guidance + count */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n paddingTop: 16,\n paddingBottom: 8,\n }}\n >\n <div\n style={{\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: COLORS.surfaceHover,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <Lightbulb\n style={{ width: 20, height: 20, flexShrink: 0 }}\n color={COLORS.strong}\n strokeWidth={1.5}\n />\n </div>\n <span\n style={{\n flex: 1,\n fontSize: 16,\n fontWeight: 500,\n color: COLORS.strong,\n lineHeight: 1.2,\n }}\n >\n Guidance\n </span>\n <span\n style={{\n fontSize: 14,\n fontWeight: 500,\n color: COLORS.strong,\n lineHeight: 1.5,\n whiteSpace: \"nowrap\",\n }}\n >\n {count} Item{count !== 1 ? \"s\" : \"\"}\n </span>\n </div>\n\n {/* Optional summary count bar (focus / opportunity / excellence). Only\n renders when the backend ships a non-empty `summary` block. */}\n <SummaryCountBar summary={summary} />\n\n {visibleItems.map((item, i) => (\n <GuidanceItem\n key={i}\n item={item}\n isLast={i === visibleItems.length - 1}\n onPlayEvidence={onPlayEvidence}\n onShowInTranscript={onShowInTranscript}\n timelinePlaying={timelinePlaying}\n currentTimeSeconds={currentTimeSeconds}\n />\n ))}\n </div>\n );\n};\n\nexport default UpdatedGuidance;\n","\"use client\";\n\nimport React from \"react\";\nimport {\n Activity,\n Pause,\n Search,\n ArrowRightLeft,\n CircleDashed,\n MicOff,\n AudioLines,\n} from \"lucide-react\";\n\n/**\n * UpdatedTalkPatterns — surfaces the new `talk_patterns.summary` numbers the\n * backend started shipping alongside hold-detection v2:\n *\n * - hold_type_counts — Lookup / Formal / Extended / Transfer / Probable / Dead air\n * - stall_count / stall_rate / stall_filler_count / stall_buying_time_count\n * - agent_response_percentiles_ms / customer_response_percentiles_ms\n *\n * The component is intentionally compact and neutral-toned — no green/red, no\n * sentiment colouring. All buckets render only when they have a non-zero\n * value (defensive: ignores empty / missing summary blocks).\n *\n * Props:\n * - summary Object `components.talk_patterns.summary` from the API\n */\n\nconst COLORS = {\n strong: \"var(--Grey-Strong, #2E3236)\",\n muted: \"var(--Grey-Muted, #808183)\",\n border: \"var(--Grey-absent, #D9D9D9)\",\n surface: \"var(--Grey-White, #FFF)\",\n surfaceHover: \"var(--surface-hover, #F3F7F7)\",\n};\n\nconst FONT_DISPLAY =\n \"var(--font-sans, 'Averta', ui-sans-serif, system-ui, sans-serif)\";\n\nconst HOLD_BUCKETS = [\n { key: \"lookup_hold\", label: \"Lookup\", Icon: Search },\n { key: \"formal_hold\", label: \"Hold\", Icon: Pause },\n { key: \"extended_hold\", label: \"Extended\", Icon: Pause },\n { key: \"transfer_hold\", label: \"Transfer\", Icon: ArrowRightLeft },\n { key: \"probable_hold\", label: \"Possible\", Icon: CircleDashed },\n { key: \"dead_air\", label: \"Dead air\", Icon: MicOff },\n];\n\n// Format milliseconds → \"1.2s\" / \"850ms\". Picks units so the value fits in\n// 3-4 visible characters; we render lots of these side by side.\nconst fmtMs = (ms) => {\n if (ms == null || Number.isNaN(ms)) return \"—\";\n const num = Number(ms);\n if (!Number.isFinite(num)) return \"—\";\n if (num >= 1000) return `${(num / 1000).toFixed(1)}s`;\n return `${Math.round(num)}ms`;\n};\n\nconst fmtRate = (rate) => {\n if (rate == null || Number.isNaN(rate)) return null;\n const num = Number(rate);\n if (!Number.isFinite(num)) return null;\n // API ships as a 0-1 ratio. Render as percent.\n return `${(num * 100).toFixed(1)}%`;\n};\n\nconst fmtCount = (n) => {\n if (n == null || Number.isNaN(n)) return null;\n const num = Number(n);\n return Number.isFinite(num) ? num.toLocaleString() : null;\n};\n\n/* ── Hold-type count strip ── */\nconst HoldCounts = ({ holdTypeCounts }) => {\n if (!holdTypeCounts || typeof holdTypeCounts !== \"object\") return null;\n const cells = HOLD_BUCKETS.map((b) => ({\n ...b,\n count: Number(holdTypeCounts[b.key]) || 0,\n })).filter((c) => c.count > 0);\n if (cells.length === 0) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n flexWrap: \"wrap\",\n gap: 16,\n padding: \"8px 16px\",\n background: COLORS.surfaceHover,\n borderRadius: 8,\n }}\n >\n {cells.map(({ key, label, Icon, count }) => (\n <div\n key={key}\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n >\n <Icon size={14} color={COLORS.strong} strokeWidth={1.5} />\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: 1.2,\n }}\n >\n {count}\n </span>\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.muted,\n lineHeight: 1.2,\n }}\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n );\n};\n\n/* ── Stall metrics row ── */\nconst StallRow = ({ summary }) => {\n const total = fmtCount(summary?.stall_count);\n if (!total) return null;\n const rate = fmtRate(summary?.stall_rate);\n const filler = fmtCount(summary?.stall_filler_count);\n const buying = fmtCount(summary?.stall_buying_time_count);\n const breakdown = [];\n if (filler) breakdown.push(`filler ${filler}`);\n if (buying) breakdown.push(`buying time ${buying}`);\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flexWrap: \"wrap\",\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n lineHeight: 1.4,\n }}\n >\n <span style={{ fontWeight: 500, color: COLORS.strong }}>\n Stalls: {total}\n {rate ? ` (${rate})` : \"\"}\n </span>\n {breakdown.length > 0 && (\n <span style={{ color: COLORS.muted }}>· {breakdown.join(\" · \")}</span>\n )}\n </div>\n );\n};\n\n/* ── Response-time percentile table (agent + customer) ── */\nconst PercentileRow = ({ label, percentiles }) => {\n if (!percentiles || typeof percentiles !== \"object\") return null;\n const cells = [\n { key: \"p50\", label: \"p50\", value: percentiles.p50 },\n { key: \"p75\", label: \"p75\", value: percentiles.p75 },\n { key: \"p95\", label: \"p95\", value: percentiles.p95 },\n { key: \"p99\", label: \"p99\", value: percentiles.p99 },\n ].filter((c) => c.value != null);\n if (cells.length === 0) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"baseline\",\n gap: 12,\n flexWrap: \"wrap\",\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n lineHeight: 1.4,\n }}\n >\n <span\n style={{\n fontWeight: 500,\n color: COLORS.strong,\n minWidth: 72,\n }}\n >\n {label}\n </span>\n {cells.map((c) => (\n <span key={c.key} style={{ color: COLORS.muted }}>\n <span style={{ fontWeight: 500, color: COLORS.strong }}>{c.label}</span>{\" \"}\n {fmtMs(c.value)}\n </span>\n ))}\n </div>\n );\n};\n\n/* ── Main component ── */\nconst UpdatedTalkPatterns = ({ summary }) => {\n if (!summary || typeof summary !== \"object\") return null;\n\n const hasHolds =\n !!summary.hold_type_counts &&\n Object.values(summary.hold_type_counts).some((n) => Number(n) > 0);\n const hasStalls = (Number(summary.stall_count) || 0) > 0;\n const agentP = summary.agent_response_percentiles_ms;\n const customerP = summary.customer_response_percentiles_ms;\n const hasPercentiles =\n (agentP && Object.values(agentP).some((v) => v != null)) ||\n (customerP && Object.values(customerP).some((v) => v != null));\n\n if (!hasHolds && !hasStalls && !hasPercentiles) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: 12,\n width: \"100%\",\n }}\n >\n {/* Sub-header — matches the Guidance / other section headers */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n paddingTop: 16,\n paddingBottom: 8,\n }}\n >\n <div\n style={{\n width: 34,\n height: 34,\n borderRadius: 9999,\n background: COLORS.surfaceHover,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <AudioLines size={20} color={COLORS.strong} strokeWidth={1.5} />\n </div>\n <span\n style={{\n flex: 1,\n fontFamily: \"Varta, var(--font-sans, sans-serif)\",\n fontSize: 16,\n fontWeight: 700,\n color: COLORS.strong,\n lineHeight: 1.2,\n whiteSpace: \"nowrap\",\n }}\n >\n Talk Patterns\n </span>\n </div>\n\n {hasHolds && <HoldCounts holdTypeCounts={summary.hold_type_counts} />}\n\n {(hasStalls || hasPercentiles) && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 10,\n padding: \"12px 16px\",\n border: `1px solid ${COLORS.border}`,\n borderRadius: 8,\n }}\n >\n {hasStalls && <StallRow summary={summary} />}\n {hasPercentiles && (\n <>\n <PercentileRow label=\"Agent\" percentiles={agentP} />\n <PercentileRow label=\"Customer\" percentiles={customerP} />\n </>\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport default UpdatedTalkPatterns;\n","\"use client\";\n\nimport React, { useState } from \"react\";\nimport { ClipboardCheck, ChevronDown, ChevronUp } from \"lucide-react\";\n\n/**\n * UpdatedProductsServices — \"PRODUCTS & SERVICES\" section.\n *\n * Figma node: 1283-2991\n *\n * Renders two side-by-side lists (products on the left, services on the\n * right) with an optional percentage next to each item. Long lists collapse\n * after `initialVisibleCount` items and reveal the rest behind an \"N More\"\n * disclosure that lives at the bottom of the affected column.\n *\n * Props:\n * - products Array Products discussed (string | { name, percent })\n * - services Array Services discussed (string | { name, percent })\n * - title string Section header label\n * - productsTitle string Left column title\n * - servicesTitle string Right column title\n * - initialVisibleCount number Items shown before \"N More\" kicks in (default 4)\n *\n * Returns null when both lists are empty so hosts can pass through API\n * payloads without guarding for missing blocks.\n */\n\nconst COLORS = {\n strong: \"var(--Grey-Strong, #2E3236)\",\n muted: \"var(--Grey-Muted, #808183)\",\n border: \"var(--Grey-absent, #D9D9D9)\",\n surfaceHover: \"var(--surface-hover, #F3F7F7)\",\n // Section header icon — Figma uses the warm orange accent used for other\n // section markers (clipboard, compass) across the interaction details.\n iconAccent: \"var(--rail-orange, #C98A5A)\",\n};\n\nconst FONT_DISPLAY =\n \"var(--font-sans, 'Averta', ui-sans-serif, system-ui, sans-serif)\";\n\n// Normalise a list entry — accepts both raw strings and { name, percent }\n// objects so callers can mix and match. A null/empty name filters the row\n// out instead of rendering a blank pill.\nconst normaliseItem = (item) => {\n if (item == null) return null;\n if (typeof item === \"string\") {\n return { name: item, percent: null };\n }\n const name = item.name ?? item.label ?? item.title ?? \"\";\n if (!name) return null;\n return {\n name,\n percent:\n item.percent != null\n ? item.percent\n : item.percentage != null\n ? item.percentage\n : null,\n };\n};\n\n// Format a 0-100 number to \"26.3 %\" (one decimal, trailing space + %).\n// Ratios in 0..1 are auto-scaled. Returns null for non-numeric values so\n// the percent column collapses cleanly.\nconst fmtPercent = (value) => {\n if (value == null) return null;\n const num = Number(value);\n if (!Number.isFinite(num)) return null;\n const scaled = Math.abs(num) <= 1 ? num * 100 : num;\n return `${scaled.toFixed(1)} %`;\n};\n\n/* ── Single row (item name + optional percent) ── */\nconst ItemRow = ({ name, percent }) => (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"12px 0\",\n borderBottom: `1px solid ${COLORS.border}`,\n width: \"100%\",\n }}\n >\n <span\n style={{\n flex: 1,\n minWidth: 0,\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.strong,\n lineHeight: \"24px\",\n wordBreak: \"break-word\",\n }}\n >\n {name}\n </span>\n {percent != null && (\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 400,\n color: COLORS.muted,\n lineHeight: \"24px\",\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n >\n {fmtPercent(percent)}\n </span>\n )}\n </div>\n);\n\n/* ── Single column (title + list + optional disclosure) ── */\nconst Column = ({ title, items, initialVisibleCount }) => {\n const [expanded, setExpanded] = useState(false);\n if (!items.length) return null;\n const overflow = Math.max(0, items.length - initialVisibleCount);\n const visible = expanded ? items : items.slice(0, initialVisibleCount);\n\n return (\n <div\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n gap: 8,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"8px 0\",\n width: \"100%\",\n }}\n >\n <span\n style={{\n flex: 1,\n minWidth: 0,\n fontFamily: FONT_DISPLAY,\n fontSize: 15,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: \"24px\",\n wordBreak: \"break-word\",\n }}\n >\n {title}\n </span>\n </div>\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n width: \"100%\",\n }}\n >\n {visible.map((item, i) => (\n <ItemRow key={i} name={item.name} percent={item.percent} />\n ))}\n </div>\n {overflow > 0 && (\n <button\n type=\"button\"\n onClick={() => setExpanded((prev) => !prev)}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n height: 29,\n padding: \"8px 0\",\n background: \"transparent\",\n border: \"none\",\n cursor: \"pointer\",\n fontFamily: FONT_DISPLAY,\n fontSize: 13,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: 1.2,\n whiteSpace: \"nowrap\",\n }}\n >\n {expanded ? \"Show Less\" : `${overflow} More`}\n {expanded ? (\n <ChevronUp size={16} color={COLORS.strong} strokeWidth={1.75} />\n ) : (\n <ChevronDown size={16} color={COLORS.strong} strokeWidth={1.75} />\n )}\n </button>\n )}\n </div>\n );\n};\n\n/* ── Main component ── */\nconst UpdatedProductsServices = ({\n products = [],\n services = [],\n title = \"Products & Services\",\n productsTitle = \"Products Discussed\",\n servicesTitle = \"Services Discussed\",\n initialVisibleCount = 4,\n}) => {\n const normalisedProducts = (products || [])\n .map(normaliseItem)\n .filter(Boolean);\n const normalisedServices = (services || [])\n .map(normaliseItem)\n .filter(Boolean);\n\n if (!normalisedProducts.length && !normalisedServices.length) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: 16,\n width: \"100%\",\n background: \"var(--Grey-White, #FFF)\",\n }}\n >\n {/* Section header — clipboard icon + uppercase title */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 16,\n height: 40,\n borderBottom: `1px solid ${COLORS.border}`,\n width: \"100%\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flex: 1,\n minWidth: 0,\n }}\n >\n <ClipboardCheck size={24} color={COLORS.iconAccent} strokeWidth={1.5} />\n <span\n style={{\n fontFamily: FONT_DISPLAY,\n fontSize: 16,\n fontWeight: 600,\n color: COLORS.strong,\n lineHeight: 1.2,\n textTransform: \"uppercase\",\n whiteSpace: \"nowrap\",\n }}\n >\n {title}\n </span>\n </div>\n </div>\n\n {/* Two columns side by side. Stack on narrow viewports via flexWrap so\n the section keeps working in the side-drawer layout. */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 24,\n flexWrap: \"wrap\",\n width: \"100%\",\n }}\n >\n <Column\n title={productsTitle}\n items={normalisedProducts}\n initialVisibleCount={initialVisibleCount}\n />\n <Column\n title={servicesTitle}\n items={normalisedServices}\n initialVisibleCount={initialVisibleCount}\n />\n </div>\n </div>\n );\n};\n\nexport default UpdatedProductsServices;\n","import { useState, useRef, useEffect, useMemo } from 'react';\nimport { ArrowLeft, ArrowRight, CalendarDays, PhoneIncoming, PhoneOutgoing, ClipboardList, FileSignal, Repeat, ChevronDown, ChevronRight, Headset, CircleUser, History, ExternalLink, Mail } from 'lucide-react';\nimport UpdatedInteractionContext from './UpdatedInteractionContext';\nimport UpdatedInteractionRecording from './UpdatedInteractionRecording';\nimport UpdatedCoachingSynthesisCard from './UpdatedCoachingSynthesisCard';\nimport UpdatedInteractionSignals from './UpdatedInteractionSignals';\nimport UpdatedCompassScore from './UpdatedCompassScore';\nimport UpdatedThreads from './UpdatedThreads';\nimport UpdatedGuidance from './UpdatedGuidance';\nimport UpdatedTalkPatterns from './UpdatedTalkPatterns';\nimport UpdatedProductsServices from './UpdatedProductsServices';\nimport AgentLiftAnalysisCard from '../common/AgentLiftAnalysisCard';\nimport SideDrawer from '../common/SideDrawer';\nimport { useMediaQuery } from '../../utils/useMediaQuery';\n\n/* Hover tooltip — fixed position to escape overflow containers.\n Anchored below the trigger. */\nconst NameTooltip = ({ text, children }) => {\n const [show, setShow] = useState(false);\n const triggerRef = useRef(null);\n const [pos, setPos] = useState({ top: 0, left: 0 });\n\n if (!text) return children;\n\n const handleEnter = () => {\n if (triggerRef.current) {\n const rect = triggerRef.current.getBoundingClientRect();\n setPos({\n top: rect.bottom + 6,\n left: rect.left + rect.width / 2,\n });\n }\n setShow(true);\n };\n\n return (\n <div\n ref={triggerRef}\n style={{ position: 'relative', display: 'inline-flex' }}\n onMouseEnter={handleEnter}\n onMouseLeave={() => setShow(false)}\n >\n {children}\n {show && (\n <div style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n transform: 'translate(-50%, 0)',\n display: 'flex',\n padding: 10,\n alignItems: 'center',\n borderRadius: 4,\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n background: 'var(--Grey-Strong, #2E3236)',\n zIndex: 9999,\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n }}>\n <span style={{\n color: '#FFF',\n fontSize: 12,\n fontWeight: 400,\n lineHeight: 'normal',\n }}>\n {text}\n </span>\n </div>\n )}\n </div>\n );\n};\n\n// Static base tabs. The optional \"Products & Services\" tab is inserted at\n// runtime by `useMemo(tabs)` below — only when the host passes products /\n// services data. Order in the rendered tabstrip mirrors the section order\n// in the page body so the scroll-spy reads top-to-bottom.\nconst BASE_TABS = [\n { key: 'overview', label: 'Overview' },\n { key: 'coaching', label: 'Coaching Summary' },\n { key: 'signals', label: 'Signals & Recording' },\n { key: 'comments', label: 'Feedback' },\n];\n\nfunction isAgentRole(role) {\n return /\\bagent\\b/.test(String(role ?? '').toLowerCase());\n}\n\nfunction isAdminRole(role) {\n return /(admin|superadmin|administrator)/.test(String(role ?? '').toLowerCase());\n}\n\n/** inbound | outbound | null — for session drawer title icons */\nfunction resolveSessionDirection(session, fallbackDirection) {\n const raw =\n session?.direction ??\n session?.interaction_direction ??\n session?.call_direction ??\n fallbackDirection;\n if (raw == null || raw === '') return null;\n const d = String(raw).toLowerCase().trim();\n if (d === 'outbound' || d.startsWith('outbound')) return 'outbound';\n if (d === 'inbound' || d.startsWith('inbound')) return 'inbound';\n return null;\n}\n\nconst UpdatedInteractionDetails = ({\n title = 'Wheel Stud Replacement Enquiry',\n onBack,\n // Data props — all optional with defaults for demo\n data,\n coachingData,\n coachingLoading = false,\n audioUrl,\n // Audio/playback props — pass these when the host app manages audio externally\n // (like InteractionDetailPanel does). If omitted, UpdatedInteractionRecording\n // manages its own audio element internally.\n audioRef: externalAudioRef,\n currentTimeSeconds,\n timelinePlaying,\n playbackRate,\n timelineSegments,\n onSeek,\n onTogglePlay,\n onSeekBack,\n onSeekForward,\n onSetPlaybackRate,\n // Speaker names\n agentName: externalAgentName,\n agentFullName: externalAgentFullName,\n customerName: externalCustomerName,\n customerFullName: externalCustomerFullName,\n // Transcript props — pass real transcript data from the host app\n transcript,\n activeTurnIndex,\n turnObservations,\n highlightedTurns,\n onTurnPlayPause,\n // Signal evidence playback — host app can provide to play audio segments from signals\n onPlayEvidence,\n onHighlightTurns,\n // Context props — pass from host app to override block-derived defaults\n callPurpose: externalCallPurpose,\n classification: externalClassification,\n outcomeQuality: externalOutcomeQuality,\n // Context \"More Details\" expandable section\n resolutionOutcome,\n customerIntent,\n location,\n interactionId,\n moreDetails,\n // Compass score props\n compassScore, // gauge meter value — compass_score, range 0.5-5\n compassMaxScore = 5,\n // Compass score as a backend-computed percentage (0–100), shown in the\n // bracket next to the score, e.g. \"3.5 (62.5%)\". Prefer this over any local\n // score→percent conversion; null hides the bracket.\n compassScorePct = null,\n predictedCsat, // predicted objective number (e.g. compass_score) — shown as \"03\" top-right\n predictedLabel = 'Predicted Objective',\n compassLegends,\n // Customer session history drawer\n customerSessions: customerSessionsList,\n customerSessionCount,\n onSessionClick,\n onViewAllSessions,\n // Footer navigation\n prevSessionDesc,\n prevSessionDisabled = false,\n nextSessionDesc,\n nextSessionDisabled = false,\n onPreviousSession,\n onNextSession,\n // Comments\n comments = [],\n guidance = [],\n // Optional count summary for the Guidance section: { focus_count,\n // opportunity_count, excellence_count } — drives the small count bar above\n // the items.\n guidanceSummary,\n // Optional `components.talk_patterns.summary` from the API — surfaces\n // hold_type_counts, stall metrics, and response-time percentiles. Renders\n // a \"Talk Patterns\" card next to the Guidance section. When absent the\n // card is suppressed entirely.\n talkPatterns,\n // Optional \"PRODUCTS & SERVICES\" section. Accepts the resolved lists from\n // the API ({ products: [...], services: [...] }, or two separate arrays).\n // Items may be raw strings or { name, percent } objects. When both lists\n // are empty the entire section is suppressed.\n productsServices,\n productsDiscussed,\n servicesDiscussed,\n currentUser,\n onSendComment,\n onSendReply,\n onReply,\n onEdit,\n onEditInteraction,\n onDelete,\n onMenuClick,\n onMarkResolved,\n commentsResolved,\n}) => {\n const [activeTab, setActiveTab] = useState('overview');\n const [expandedSignals, setExpandedSignals] = useState(new Set());\n const [showSessionDrawer, setShowSessionDrawer] = useState(false);\n const [hoveredSessionIdx, setHoveredSessionIdx] = useState(null);\n const [internalPlaying, setInternalPlaying] = useState(false);\n const [internalCurrentTime, setInternalCurrentTime] = useState(0);\n const [isScrolledPastHeader, setIsScrolledPastHeader] = useState(false);\n // Phone breakpoint — stacks the two-column rows and trims padding so the\n // detail view is usable on narrow screens (<= 640px).\n const isPhone = useMediaQuery('(max-width: 640px)');\n const recordingRef = useRef(null);\n\n // Section refs for scroll-to-section tab behavior\n const overviewRef = useRef(null);\n const coachingRef = useRef(null);\n const signalsRef = useRef(null);\n const productsRef = useRef(null);\n const commentsRef = useRef(null);\n const sectionRefs = {\n overview: overviewRef,\n coaching: coachingRef,\n signals: signalsRef,\n products: productsRef,\n comments: commentsRef,\n };\n const scrollContainerRef = useRef(null);\n const isClickScrolling = useRef(false);\n\n // Whether the host has actually passed product/service data. The\n // \"Products & Services\" tab + section is mounted only when at least one\n // of the two lists has items, so an interaction with no entities doesn't\n // surface an empty tab.\n const hasProductsServices = useMemo(() => {\n const products = productsServices?.products ?? productsDiscussed ?? [];\n const services = productsServices?.services ?? servicesDiscussed ?? [];\n return products.length > 0 || services.length > 0;\n }, [productsServices, productsDiscussed, servicesDiscussed]);\n\n // Tabstrip — inserts \"Products & Services\" between Signals and Feedback\n // when data is present. Stays in sync with the section order below so the\n // scroll-spy reads top-to-bottom.\n const tabs = useMemo(() => {\n if (!hasProductsServices) return BASE_TABS;\n const out = [];\n for (const t of BASE_TABS) {\n if (t.key === 'comments') {\n out.push({ key: 'products', label: 'Products & Services' });\n }\n out.push(t);\n }\n return out;\n }, [hasProductsServices]);\n\n // Scroll-spy: update active tab based on which section's top is nearest the viewport\n useEffect(() => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n const tabKeys = tabs.map((t) => t.key);\n const refs = tabKeys.map((k) => sectionRefs[k]);\n\n // Find the closest scrollable ancestor (the element that actually scrolls)\n const getScrollParent = (el) => {\n let node = el.parentElement;\n while (node) {\n const { overflow, overflowY } = window.getComputedStyle(node);\n if (/(auto|scroll)/.test(overflow + overflowY)) return node;\n node = node.parentElement;\n }\n return null;\n };\n\n const scrollParent = getScrollParent(container);\n\n const handleScroll = () => {\n if (isClickScrolling.current) return;\n\n let activeKey = tabKeys[0];\n\n // Use viewport-relative positions — works regardless of which element scrolls\n for (let i = refs.length - 1; i >= 0; i--) {\n const el = refs[i].current;\n if (!el) continue;\n const rect = el.getBoundingClientRect();\n // Section is \"active\" when its top has scrolled above 150px from viewport top\n if (rect.top <= 150) {\n activeKey = tabKeys[i];\n break;\n }\n }\n\n setActiveTab(activeKey);\n\n // Move session nav from title row to sticky tabs once content starts scrolling.\n const overviewTop = overviewRef.current?.getBoundingClientRect().top ?? Number.POSITIVE_INFINITY;\n setIsScrolledPastHeader(overviewTop <= 150);\n };\n\n // Attach to all possible scroll targets\n container.addEventListener('scroll', handleScroll, { passive: true });\n if (scrollParent && scrollParent !== container) {\n scrollParent.addEventListener('scroll', handleScroll, { passive: true });\n }\n window.addEventListener('scroll', handleScroll, { passive: true, capture: true });\n handleScroll();\n\n return () => {\n container.removeEventListener('scroll', handleScroll);\n if (scrollParent && scrollParent !== container) {\n scrollParent.removeEventListener('scroll', handleScroll);\n }\n window.removeEventListener('scroll', handleScroll, { capture: true });\n };\n // Re-run when the tab list changes (e.g. the optional Products & Services\n // tab appears/disappears) so the scroll-spy tracks the current set of\n // sections. `sectionRefs` reads stable refs created above; not in deps.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tabs]);\n\n const clickedTabRef = useRef(null);\n\n const handleTabClick = (key) => {\n setActiveTab(key);\n isClickScrolling.current = true;\n clickedTabRef.current = key;\n const el = sectionRefs[key]?.current;\n if (el) {\n // Offset scroll to account for the sticky header + tabs (~120px)\n const container = scrollContainerRef.current;\n if (container && container.scrollHeight > container.clientHeight) {\n // Container itself scrolls\n const containerTop = container.getBoundingClientRect().top;\n const elTop = el.getBoundingClientRect().top;\n const offset = elTop - containerTop + container.scrollTop - 16;\n container.scrollTo({ top: offset, behavior: 'smooth' });\n } else {\n // Page/parent scrolls — use window with offset\n const elTop = el.getBoundingClientRect().top + window.scrollY - 120;\n window.scrollTo({ top: elTop, behavior: 'smooth' });\n }\n }\n setTimeout(() => {\n isClickScrolling.current = false;\n clickedTabRef.current = null;\n }, 1200);\n };\n\n const sessionHistory = customerSessionsList || [];\n const hasPastSessions = sessionHistory.length > 1;\n\n /* Called from Signals/Guidance \"Show in transcript\" icon —\n switches to Signals section, then scrolls/highlights transcript card without playing audio. */\n const handleShowInTranscript = (startMs) => {\n setActiveTab('signals');\n const signalsEl = signalsRef.current;\n if (signalsEl) {\n const container = scrollContainerRef.current;\n if (container && container.scrollHeight > container.clientHeight) {\n const containerTop = container.getBoundingClientRect().top;\n const elTop = signalsEl.getBoundingClientRect().top;\n const offset = elTop - containerTop + container.scrollTop - 16;\n container.scrollTo({ top: offset, behavior: 'smooth' });\n } else {\n const elTop = signalsEl.getBoundingClientRect().top + window.scrollY - 120;\n window.scrollTo({ top: elTop, behavior: 'smooth' });\n }\n }\n\n const timeSec = startMs / 1000;\n // Wait briefly so section scroll starts before transcript container scroll/highlight.\n setTimeout(() => {\n if (recordingRef.current?.scrollToTranscript) {\n recordingRef.current.scrollToTranscript(timeSec);\n }\n }, 220);\n };\n\n /* Called from Signals evidence play button — seeks + plays audio segment */\n const handlePlayEvidence = (ev) => {\n setActiveTab('signals');\n const signalsEl = signalsRef.current;\n if (signalsEl) {\n const container = scrollContainerRef.current;\n if (container && container.scrollHeight > container.clientHeight) {\n const containerTop = container.getBoundingClientRect().top;\n const elTop = signalsEl.getBoundingClientRect().top;\n const offset = elTop - containerTop + container.scrollTop - 16;\n container.scrollTo({ top: offset, behavior: 'smooth' });\n } else {\n const elTop = signalsEl.getBoundingClientRect().top + window.scrollY - 120;\n window.scrollTo({ top: elTop, behavior: 'smooth' });\n }\n }\n\n const startMs = ev?.start_ms ?? ev?.startMs;\n\n // Wait briefly so section scroll starts before playback seek/play begins.\n setTimeout(() => {\n // Keep transcript highlight behavior consistent with \"Show in transcript\".\n if (startMs != null && recordingRef.current?.scrollToTranscript) {\n recordingRef.current.scrollToTranscript(startMs / 1000);\n }\n\n if (onPlayEvidence) {\n onPlayEvidence(ev);\n } else {\n // Default: seek to evidence start time via recording ref\n if (startMs != null && recordingRef.current?.seekTo) {\n recordingRef.current.seekTo(startMs / 1000);\n setInternalPlaying(true);\n setInternalCurrentTime(startMs / 1000);\n // Stop playing after evidence duration\n const endMs = ev.end_ms ?? ev.endMs ?? (startMs + 5000);\n const durationMs = endMs - startMs;\n setTimeout(() => setInternalPlaying(false), durationMs);\n }\n }\n }, 220);\n };\n\n /* Called to highlight transcript turns related to evidence */\n const handleHighlightTurns = (turnIds) => {\n if (onHighlightTurns) {\n onHighlightTurns(turnIds);\n }\n };\n\n const toggleSignal = (key) => {\n setExpandedSignals((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return next;\n });\n };\n\n // Extract data from blocks if provided\n const blocks = data?.blocks || [];\n const findBlock = (id) => blocks.find((b) => b.block_id === id)?.payload || {};\n\n const meta = findBlock('interaction-metadata');\n const ctx = findBlock('interaction-context');\n const signals = findBlock('interaction-signals');\n const outcomeLift = findBlock('interaction-outcome-lift');\n const dimensionsBlock = findBlock('interaction-dimensions');\n const blockDimensions = dimensionsBlock.dimensions || [];\n const callPurpose = ctx.call_purpose || {};\n const classification = ctx.classification || {};\n\n const resolvedMeta = meta || {};\n const resolvedCallPurpose = externalCallPurpose || callPurpose || {};\n const resolvedClassification = externalClassification || classification || {};\n const resolvedOutcomeLift = outcomeLift || {};\n const resolvedDriverLabels = (resolvedOutcomeLift.driver_signal_keys || [])\n .map((k) => k.replace(/^sig\\./, '').replace(/_/g, ' '));\n const resolvedCoaching = coachingData || null;\n const resolvedSignals = signals?.signals?.length\n ? signals\n : { present_count: 0, total_signals_evaluated: 0, signals: [] };\n const guidanceData = guidance || [];\n\n // Resolve names: explicit props → metadata block → context block → fallback\n const agentName = externalAgentName || meta.agent_name || meta.agent || ctx.agent_name || 'Agent';\n const agentFullName = externalAgentFullName || meta.agent_full_name || meta.agent_name || agentName;\n const customerName = externalCustomerName || meta.customer_name || meta.customer || ctx.customer_name || 'Customer';\n const customerFullName = externalCustomerFullName || meta.customer_full_name || meta.customer_name || customerName;\n const resolvedUserRole = String(\n currentUser?.role ??\n currentUser?.userRole ??\n currentUser?.user_role ??\n currentUser?.roleName ??\n currentUser?.role_name ??\n ''\n ).toLowerCase();\n const canEditInteraction = isAdminRole(resolvedUserRole);\n // Agent-role users don't see the Agent Lift Analysis card at all (updated\n // design, Figma node 1798-5177 — agent view is the context grid only).\n const isAgentUser = isAgentRole(resolvedUserRole);\n const sessionCount = customerSessionCount ?? sessionHistory.length;\n const rawDate = meta.created_dt || data?.created_dt || ctx.created_dt || '';\n const dateStr = rawDate\n ? new Date(/Z$|[+-]\\d{2}:\\d{2}$/.test(rawDate) ? rawDate : rawDate + 'Z').toLocaleString()\n : '';\n const direction = resolvedCallPurpose.interaction_direction === 'inbound' ? 'Inbound' : 'Outbound';\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', width: '100%', maxWidth: '100%', height: '100%', background: 'var(--Grey-White, #FFF)', overflowX: isPhone ? 'clip' : undefined }}>\n {/* Sticky Header + Tabs */}\n {/* Header */}\n <div style={{ display: 'flex', flexDirection: isPhone ? 'column' : 'row', alignItems: isPhone ? 'stretch' : 'center', gap: 12, padding: isPhone ? '16px 16px 0' : '18px 24px 0' }}>\n {/* Title row (back + divider + title). On phones the prev/next row is\n placed above this via flex `order`. */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, minWidth: 0, ...(isPhone ? { order: 2, width: '100%' } : { flex: 1 }) }}>\n <button\n onClick={onBack}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: 0,\n flexShrink: 0,\n }}\n >\n <ArrowLeft size={24} color=\"var(--Grey-Strong, #2E3236)\" />\n </button>\n <div style={{ width: 1, height: 28, background: 'var(--Base-absent, #D9D9D9)' }} />\n <h1 style={{\n color: 'var(--Grey-Strong, #2E3236)',\n fontSize: 24,\n fontStyle: 'normal',\n fontWeight: 400,\n lineHeight: 'normal',\n margin: 0,\n flex: 1,\n }}>\n {title}\n </h1>\n </div>\n\n {/* Figma node 605-1186: Previous / Next Session — inline in header.\n On phones it wraps to its own full-width row (space-between) so both\n buttons fit without horizontal scroll. On phones it always shows\n here because the scrolled-state copy lives in the (hidden) tabs bar. */}\n {(onPreviousSession || onNextSession) && (isPhone || !isScrolledPastHeader) && (\n <div style={{\n display: 'flex',\n alignItems: 'center',\n flexShrink: 0,\n ...(isPhone ? { width: '100%', justifyContent: 'space-between', order: 1 } : {}),\n }}>\n {/* Previous Session */}\n <NameTooltip text={prevSessionDesc}>\n <button\n onClick={prevSessionDisabled ? undefined : onPreviousSession}\n disabled={prevSessionDisabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 12px',\n background: 'none',\n border: 'none',\n cursor: prevSessionDisabled ? 'default' : 'pointer',\n opacity: prevSessionDisabled ? 0.4 : 1,\n }}\n >\n <ArrowLeft size={16} color=\"var(--Neutral-800, #323232)\" strokeWidth={1.5} />\n <span style={{\n color: 'var(--Neutral-800, #323232)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: '24px',\n fontFamily: 'var(--default-font-family)',\n whiteSpace: 'nowrap',\n }}>\n Previous Interaction\n </span>\n </button>\n </NameTooltip>\n\n {/* Divider */}\n <div style={{\n width: 1,\n height: 20,\n background: 'var(--Grey-absent, #D9D9D9)',\n flexShrink: 0,\n }} />\n\n {/* Next Session */}\n <NameTooltip text={nextSessionDesc}>\n <button\n onClick={nextSessionDisabled ? undefined : onNextSession}\n disabled={nextSessionDisabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 12px',\n background: 'none',\n border: 'none',\n cursor: nextSessionDisabled ? 'default' : 'pointer',\n opacity: nextSessionDisabled ? 0.4 : 1,\n }}\n >\n <span style={{\n color: 'var(--Neutral-800, #323232)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: '24px',\n fontFamily: 'var(--default-font-family)',\n whiteSpace: 'nowrap',\n }}>\n Next Interaction\n </span>\n <ArrowRight size={16} color=\"var(--Neutral-800, #323232)\" strokeWidth={1.5} />\n </button>\n </NameTooltip>\n </div>\n )}\n </div>\n\n {/* Sticky tabs bar.\n - `top: 0` so the bar sticks flush against the top of its scroll\n ancestor with no transparent gap above it. Earlier `top: 68` was\n assumed to clear a host nav, but the in-page area above the tabs\n ended up showing the page content scrolling up underneath.\n - `background: #FFFFFF` is set explicitly (not via CSS var) so the\n bar is guaranteed opaque even if the host's token sheet hasn't\n loaded yet, which prevents scrolled content from bleeding through.\n - `paddingTop: 8` replaces the previous `marginTop: 8` on the inner\n row so the white background fills the gap above the tabs (margin\n on a child can leave a translucent strip in the parent on some\n engines).\n - `zIndex: 30` keeps the bar above in-content stacking contexts\n (chart cards, gauges, etc.). */}\n {/* Tabs bar — hidden on phones (sections just scroll); avoids the\n horizontal-scroll tab strip on narrow screens. */}\n {!isPhone && (\n <div style={{\n position: 'sticky',\n top: 0,\n zIndex: 30,\n backgroundColor: '#FFFFFF',\n paddingTop: 8,\n // Defensive: small downward shadow so any sub-pixel rendering gap\n // between the sticky bar and scrolled content can't reveal what's\n // beneath. Also visually separates the bar from the section content.\n boxShadow: '0 4px 6px -4px rgba(0, 0, 0, 0.04)',\n }}>\n {/* Tabs + sticky session nav at far right */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 16,\n background: '#FFFFFF',\n borderBottom: '1px solid var(--Grey-Faint, #ACADAD)',\n padding: isPhone ? '0 16px' : '0 24px',\n }}>\n <div\n className=\"custom-thin-scrollbar-hidden\"\n style={{ display: 'flex', alignItems: 'flex-start', minWidth: 0, overflowX: isPhone ? 'auto' : 'visible' }}\n >\n {tabs.map((tab) => (\n <button\n key={tab.key}\n onClick={() => handleTabClick(tab.key)}\n style={{\n display: 'flex',\n padding: 16,\n alignItems: 'center',\n gap: 10,\n flexShrink: 0,\n background: 'none',\n border: 'none',\n borderBottom: activeTab === tab.key\n ? '3px solid var(--Grey-Strong, #2E3236)'\n : '3px solid transparent',\n cursor: 'pointer',\n fontSize: 15,\n fontWeight: activeTab === tab.key ? 500 : 400,\n color: activeTab === tab.key\n ? 'var(--Grey-Strong, #2E3236)'\n : 'var(--Grey-Muted, #808183)',\n whiteSpace: 'nowrap',\n transition: 'border-color 0.2s ease, color 0.2s ease',\n }}\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {(onPreviousSession || onNextSession) && isScrolledPastHeader && (\n <div style={{ display: 'flex', alignItems: 'center', flexShrink: 0 }}>\n <NameTooltip text={prevSessionDesc}>\n <button\n onClick={prevSessionDisabled ? undefined : onPreviousSession}\n disabled={prevSessionDisabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 12px',\n background: 'none',\n border: 'none',\n cursor: prevSessionDisabled ? 'default' : 'pointer',\n opacity: prevSessionDisabled ? 0.4 : 1,\n }}\n >\n <ArrowLeft size={16} color=\"var(--Neutral-800, #323232)\" strokeWidth={1.5} />\n <span style={{\n color: 'var(--Neutral-800, #323232)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: '24px',\n fontFamily: 'var(--default-font-family)',\n whiteSpace: 'nowrap',\n }}>\n Previous Interaction\n </span>\n </button>\n </NameTooltip>\n\n <div style={{\n width: 1,\n height: 20,\n background: 'var(--Grey-absent, #D9D9D9)',\n flexShrink: 0,\n }} />\n\n <NameTooltip text={nextSessionDesc}>\n <button\n onClick={nextSessionDisabled ? undefined : onNextSession}\n disabled={nextSessionDisabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 12px',\n background: 'none',\n border: 'none',\n cursor: nextSessionDisabled ? 'default' : 'pointer',\n opacity: nextSessionDisabled ? 0.4 : 1,\n }}\n >\n <span style={{\n color: 'var(--Neutral-800, #323232)',\n fontSize: 13,\n fontWeight: 400,\n lineHeight: '24px',\n fontFamily: 'var(--default-font-family)',\n whiteSpace: 'nowrap',\n }}>\n Next Interaction\n </span>\n <ArrowRight size={16} color=\"var(--Neutral-800, #323232)\" strokeWidth={1.5} />\n </button>\n </NameTooltip>\n </div>\n )}\n </div>\n </div>\n )}{/* end sticky header + tabs */}\n\n {/* All sections rendered — tabs scroll to them */}\n <div ref={scrollContainerRef} style={{ padding: isPhone ? 16 : 24, flex: 1, overflowY: 'auto', ...(isPhone ? { minWidth: 0, overflowX: 'hidden' } : {}) }}>\n {/* ═══ OVERVIEW SECTION ═══ */}\n <div ref={overviewRef} style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'flex-end',\n alignItems: 'flex-start',\n gap: 24,\n alignSelf: 'stretch',\n }}>\n {/* Figma node 106-3508: Section Header — horizontal, gap: 16, height: 40, center */}\n <div style={{\n display: 'flex',\n flexWrap: isPhone ? 'wrap' : 'nowrap',\n height: isPhone ? 'auto' : 40,\n alignItems: isPhone ? 'flex-start' : 'center',\n gap: isPhone ? 8 : 16,\n alignSelf: 'stretch',\n }}>\n {/* Left: Icon + Title — fills remaining space */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, flex: 1 }}>\n <ClipboardList size={24} color=\"var(--rail-orange, #C98A5A)\" strokeWidth={2} />\n <span style={{\n fontSize: 16,\n fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n textTransform: 'uppercase',\n }}>\n Overview\n </span>\n </div>\n\n {/* Right: Metadata — a wrapping row. On phones the date + direction\n sit together on the first line; the agent/customer group wraps\n to its own full-width line below (so it isn't clipped). */}\n <div style={{ display: 'flex', flexDirection: 'row', flexWrap: isPhone ? 'wrap' : 'nowrap', alignItems: 'center', gap: isPhone ? '8px 16px' : 16, flexShrink: 0, ...(isPhone ? { width: '100%' } : {}) }}>\n {/* Date */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 0' }}>\n <CalendarDays size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', fontFamily: 'var(--font-sans)', lineHeight: 1.2 }}>\n {dateStr}\n </span>\n </div>\n\n {/* Direction — outbound calls show PhoneOutgoing (arrow\n leaving), inbound show PhoneIncoming (arrow entering).\n Falls back to PhoneIncoming when the API value is missing\n so the row still renders. */}\n {(() => {\n const DirectionIcon =\n resolvedCallPurpose.interaction_direction === 'outbound'\n ? PhoneOutgoing\n : PhoneIncoming;\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 0' }}>\n <DirectionIcon size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', fontFamily: 'var(--font-sans)', lineHeight: 1.2 }}>\n {direction}\n </span>\n </div>\n );\n })()}\n\n {/* Agent + Customer — border-left separator (drops the border and\n wraps on phones so the wide customer pill isn't clipped). */}\n <div style={{\n display: 'flex',\n flexWrap: isPhone ? 'wrap' : 'nowrap',\n alignItems: 'center',\n gap: isPhone ? 12 : 16,\n ...(isPhone\n ? { flexBasis: '100%', width: '100%' }\n : { paddingLeft: 16, borderLeft: '1px solid var(--Grey-absent, #D9D9D9)' }),\n }}>\n {/* Agent — Headset icon + tooltip */}\n <NameTooltip text={agentFullName}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '8px 0', cursor: 'pointer' }}>\n <Headset size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', fontFamily: 'var(--font-sans)', lineHeight: 1.2 }}>\n {agentName}\n </span>\n </div>\n </NameTooltip>\n\n {/* Repeat icon */}\n {/* <Repeat size={16} color=\"var(--color-input-border, #ACACAD)\" strokeWidth={1.5} /> */}\n\n {/* Customer — CircleUser icon + side drawer trigger (only if > 1 session) */}\n {sessionCount > 1 ? (\n <div>\n <NameTooltip text={customerFullName}>\n <button\n onClick={() => setShowSessionDrawer(true)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n padding: '0 16px',\n height: 34,\n borderRadius: 8,\n background: 'var(--Rail-Surface-2, #E3E1D7)',\n border: 'none',\n cursor: 'pointer',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, minWidth: 0 }}>\n <CircleUser size={16} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', lineHeight: 1.2, whiteSpace: 'nowrap' }}>\n <span style={{ fontWeight: 600 }}>{customerName}</span>{' '}\n <span>({sessionCount} Interactions)</span>\n </span>\n </div>\n <ChevronRight size={16} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.7} />\n </button>\n </NameTooltip>\n </div>\n ) : (\n <NameTooltip text={customerFullName}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, padding: '8px 0', cursor: 'pointer' }}>\n <CircleUser size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', lineHeight: 1.2 }}>\n {customerName}\n </span>\n </div>\n </NameTooltip>\n )}\n </div>\n </div>\n </div>\n\n {/*\n Figma node 101-2385\n Row: Compass Score (left) | Context + Agent Lift Analysis stacked (right)\n */}\n <div style={{\n display: 'flex',\n flexDirection: isPhone ? 'column' : 'row',\n alignItems: 'stretch',\n gap: 24,\n alignSelf: 'stretch',\n }}>\n {/* Left — Compass Score */}\n <div style={{ flex: 1, minWidth: 0, display: 'flex' }}>\n <UpdatedCompassScore\n score={compassScore ?? 0.5}\n minScore={0}\n maxScore={compassMaxScore}\n predictedScore={predictedCsat ?? 0.5}\n predictedLabel={predictedLabel}\n legends={compassLegends}\n // Compass score as a percentage (0–100) in round brackets after\n // the score — Figma 1798-5168. Purely backend-driven via\n // `compass_score_pct`; no local score→percent conversion. Null\n // (field absent) hides the bracket.\n outcomePercent={compassScorePct != null ? compassScorePct : null}\n />\n </div>\n\n {/* Right — Context grid + Agent Lift Analysis stacked.\n Admins/supervisors bottom-align the stack so the lift card's\n bottom lines up with the Interaction Quality card. Agents have\n no lift card, so the context grid top-aligns instead of being\n pushed to the bottom of the taller row. */}\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'stretch',\n justifyContent: isAgentUser ? 'flex-start' : 'flex-end',\n gap: 24,\n flex: 1,\n minWidth: 0,\n }}>\n <UpdatedInteractionContext\n meta={resolvedMeta}\n callPurpose={resolvedCallPurpose}\n classification={resolvedClassification}\n outcomeQuality={externalOutcomeQuality || 'Neutral'}\n dimensions={blockDimensions}\n resolutionOutcome={resolutionOutcome}\n customerIntent={customerIntent}\n location={location ?? meta.location ?? meta.location_name ?? ctx.location}\n interactionId={interactionId ?? meta.interaction_id}\n moreDetails={moreDetails}\n canShowEditButton={canEditInteraction}\n onEditInteraction={onEditInteraction}\n // Agents get the flat context grid (no \"More Details\" toggle)\n // per Figma node 1798-5177.\n flatView={isAgentUser}\n />\n {/* Agent Lift Analysis — two-column gauge card (Figma node\n 1463:4261): Interaction Difficulty + Agent Impact. The\n `interaction-outcome-lift` API block ships `p_expected`\n (call-difficulty baseline) and `lift_raw` (probability\n delta the agent contributed); we map those onto the card's\n normalised [-1, +1] gauge inputs. The Outcome column was\n removed per the updated design — for every user role.\n Hidden entirely for Agent-role users (Figma node\n 1798-5177 — agents see the context grid only). */}\n {!isAgentUser && (() => {\n const liftData = resolvedOutcomeLift || {};\n\n // ── Pull every value used in the card straight from the\n // API payload. Nothing on this card is invented or\n // derived from a different field — if the API doesn't\n // ship a value, the corresponding piece of UI is hidden.\n const difficultyScore = liftData.difficulty;\n const difficultyBand = liftData.difficulty_band;\n // \"X% Score impact\" footer source (Figma 1463:4261): the\n // API ships either an explicit `score_impact` or, when it\n // doesn't, the baseline `p_expected` carries that meaning\n // and is what the Figma comp uses. We don't invent a value\n // — we read one of two API-provided probabilities.\n const pExpected = liftData.p_expected;\n const scoreImpact = liftData.score_impact ?? pExpected;\n\n const liftRaw = liftData.lift_raw;\n const liftDisplay = liftData.lift_display;\n const liftBand = liftData.interpretation?.lift_band;\n\n const pFull = liftData.p_full;\n const interpretationDescription =\n liftData.interpretation?.description;\n\n // Card-level gate: only hide if the API shipped literally\n // nothing useful. As soon as ANY field is present we\n // render the full three-column layout; missing columns\n // show \"—\" placeholders rather than being suppressed.\n const hasAnyData =\n difficultyScore != null ||\n difficultyBand != null ||\n liftRaw != null ||\n liftBand != null ||\n pFull != null ||\n interpretationDescription != null;\n if (!hasAnyData) {\n return null;\n }\n\n const clampVal = (v, lo, hi) =>\n Math.max(lo, Math.min(hi, v));\n\n // Difficulty gauge — drive the needle from the API's\n // 0-100 `difficulty` score. 50 sits at the centre; lower\n // values pull the needle left (\"easier\"), higher right\n // (\"harder\"). Pure linear map, no smoothing.\n const difficultyValue =\n difficultyScore != null\n ? clampVal((difficultyScore - 50) / 50, -1, 1)\n : 0;\n\n // Impact gauge — `lift_raw` is a probability delta\n // typically within ±0.3; the ×3 spread is display-only\n // so the needle visibly moves at realistic lift sizes.\n // No label, no numeric readout is derived from this —\n // those come from API string fields below.\n const impactValue =\n liftRaw != null ? clampVal(liftRaw * 3, -1, 1) : 0;\n\n // \"X% Score impact\" footer for the Difficulty column —\n // only renders when the API explicitly ships\n // `score_impact`. We don't substitute another field\n // under the same label.\n const scoreImpactPercent =\n scoreImpact != null\n ? Math.round(scoreImpact * 100)\n : null;\n\n // Title-case API band strings (\"strong_negative\" →\n // \"Strong Negative\") for the gauge centre labels.\n const prettyBand = (band) => {\n if (!band) return undefined;\n return String(band)\n .split('_')\n .map((w) =>\n w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()\n )\n .join(' ');\n };\n const difficultyLabel = prettyBand(difficultyBand);\n const impactLabel = prettyBand(liftBand);\n\n // `impactPercent` is what the card uses to build its\n // \"X% Score impact\" footer. Source it from the API's\n // pre-formatted `lift_display` (\"-6.9%\") when possible\n // so on-screen rounding matches the backend; fall back\n // to `lift_raw * 100` only when `lift_display` is absent.\n const impactPercent = (() => {\n if (typeof liftDisplay === 'string') {\n const parsed = parseFloat(liftDisplay.replace('%', ''));\n if (Number.isFinite(parsed)) return parsed;\n }\n if (liftRaw != null) {\n return Math.round(liftRaw * 100);\n }\n return null;\n })();\n\n return (\n <AgentLiftAnalysisCard\n title=\"Agent Lift Analysis\"\n // Both gauge columns always render. When a column's\n // numeric/label data is null the card swaps in \"—\"\n // placeholders so the layout stays consistent across\n // calls with partial data. The Outcome column was removed\n // per the updated design (Figma 1463:4261).\n interactionDifficulty={{\n value:\n difficultyScore != null ? difficultyValue : null,\n label: difficultyLabel,\n sublabel: 'Based on interaction type',\n footer:\n scoreImpactPercent != null\n ? `${scoreImpactPercent}% Score impact`\n : undefined,\n }}\n agentImpact={{\n value: liftRaw != null ? impactValue : null,\n label: impactLabel,\n // Sublabel slot (rendered immediately below the\n // lift-band label) carries the API's\n // `interpretation.description`.\n sublabel: interpretationDescription,\n impactPercent,\n // When the API ships `lift_band: \"learning\"` the model\n // doesn't have enough signal for this interaction type\n // yet. The card swaps the gauge for a \"Compass is\n // Learning..\" placeholder (Figma node 1211:4526).\n isLearning:\n String(liftBand ?? '').toLowerCase() === 'learning',\n }}\n />\n );\n })()}\n </div>\n </div>\n\n </div>\n\n {/* ═══ COACHING SUMMARY SECTION ═══ */}\n <div ref={coachingRef} style={{ paddingTop: 24 }}>\n <UpdatedCoachingSynthesisCard data={coachingLoading ? null : resolvedCoaching} loading={coachingLoading} />\n </div>\n\n {/* ═══ SIGNALS & RECORDING SECTION ═══ */}\n <div ref={signalsRef} style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 16,\n alignSelf: 'stretch',\n paddingTop: 24,\n }}>\n {/* Section header */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n }}>\n <FileSignal size={24} color=\"#C98A5A\" strokeWidth={2} />\n <span style={{\n fontSize: 16,\n fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n textTransform: 'uppercase',\n }}>\n Signals & Recording\n </span>\n </div>\n\n {/* Content: Signals (left) | Recording+Transcript (right) */}\n <div style={{\n display: 'flex',\n flexDirection: isPhone ? 'column' : 'row',\n alignItems: isPhone ? 'stretch' : 'flex-start',\n gap: 24,\n alignSelf: 'stretch',\n paddingTop: 16,\n borderTop: '1px solid #D9D9D9',\n }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <UpdatedInteractionSignals\n signals={resolvedSignals}\n expandedSignals={expandedSignals}\n toggleSignal={toggleSignal}\n playEvidence={handlePlayEvidence}\n highlightTurns={handleHighlightTurns}\n onShowInTranscript={handleShowInTranscript}\n timelinePlaying={timelinePlaying || internalPlaying}\n currentTimeSeconds={currentTimeSeconds ?? internalCurrentTime}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <UpdatedInteractionRecording\n ref={recordingRef}\n audioUrl={audioUrl}\n durationSeconds={resolvedMeta.duration_seconds}\n audioRef={externalAudioRef}\n agentName={agentName}\n customerName={customerName}\n currentTimeSeconds={currentTimeSeconds}\n timelinePlaying={timelinePlaying}\n playbackRate={playbackRate}\n timelineSegments={timelineSegments}\n onSeek={onSeek}\n onTogglePlay={onTogglePlay}\n onSeekBack={onSeekBack}\n onSeekForward={onSeekForward}\n onSetPlaybackRate={onSetPlaybackRate}\n transcript={transcript}\n activeTurnIndex={activeTurnIndex}\n turnObservations={turnObservations}\n highlightedTurns={highlightedTurns}\n onTurnPlayPause={onTurnPlayPause}\n setExpandedSignals={setExpandedSignals}\n />\n </div>\n </div>\n </div>\n\n {/* ═══ PRODUCTS & SERVICES SECTION ═══\n Sits between the recording / signals area and the feedback /\n guidance threads. Accepts either a single `productsServices`\n object ({ products, services }) or two flat arrays so hosts can\n wire it straight from the API payload they prefer. The component\n self-suppresses when both lists are empty. */}\n {(() => {\n const products =\n productsServices?.products ?? productsDiscussed ?? [];\n const services =\n productsServices?.services ?? servicesDiscussed ?? [];\n if (!products.length && !services.length) return null;\n return (\n // ref={productsRef} so the \"Products & Services\" tab's click\n // handler and the scroll-spy can target this section like the\n // other top-level sections.\n <div ref={productsRef} style={{ paddingTop: 24 }}>\n <UpdatedProductsServices\n products={products}\n services={services}\n />\n </div>\n );\n })()}\n\n {/* ═══ FEEDBACK SECTION ═══ */}\n <div ref={commentsRef} style={{ paddingTop: 24 }}>\n <UpdatedThreads\n comments={comments}\n totalComments={comments.length}\n currentUser={currentUser}\n onSendComment={onSendComment || (() => {})}\n onSendReply={onSendReply || (() => {})}\n onReply={onReply || (() => {})}\n onEdit={onEdit || (() => {})}\n onDelete={onDelete || (() => {})}\n onMenuClick={onMenuClick || (() => {})}\n onMarkResolved={onMarkResolved || (() => {})}\n isResolved={commentsResolved}\n >\n <UpdatedGuidance\n items={guidanceData}\n summary={guidanceSummary}\n guidanceCount={guidanceData.length}\n onPlayEvidence={handlePlayEvidence}\n onShowInTranscript={handleShowInTranscript}\n timelinePlaying={timelinePlaying || internalPlaying}\n currentTimeSeconds={currentTimeSeconds ?? internalCurrentTime}\n />\n {/* Talk Patterns (hold-type counts + stall metrics + response\n percentiles). Mounted after Guidance so the order matches\n the Feedback-tab section flow. Self-suppresses when the\n summary block is absent or all metrics are zero. */}\n <UpdatedTalkPatterns summary={talkPatterns} />\n </UpdatedThreads>\n </div>\n </div>\n\n <SideDrawer\n open={showSessionDrawer}\n onClose={() => setShowSessionDrawer(false)}\n title={(\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>\n <div style={{\n width: 34,\n height: 34,\n borderRadius: '50%',\n background: 'var(--surface-hover, #F3F7F7)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}>\n <CircleUser size={20} color=\"var(--Grey-Strong, #2E3236)\" strokeWidth={1.7} />\n </div>\n <div style={{ minWidth: 0 }}>\n <div style={{\n fontSize: 16,\n fontWeight: 600,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}>\n {customerName}\n </div>\n </div>\n </div>\n )}\n subtitle={hasPastSessions ? (\n <span style={{\n fontSize: 13,\n fontWeight: 400,\n color: 'var(--Grey-Muted, #808183)',\n lineHeight: 1.5,\n }}>\n {sessionCount} Interactions\n </span>\n ) : null}\n width={470}\n height=\"100vh\"\n topOffset={70}\n footer={hasPastSessions ? (\n <div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>\n <button\n onClick={() => { if (onViewAllSessions) onViewAllSessions(); setShowSessionDrawer(false); }}\n style={{\n display: 'flex',\n height: 40,\n padding: '0 20px 0 18px',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 7,\n background: 'var(--Grey-White, #FFF)',\n border: '1px solid var(--Grey-absent, #D9D9D9)',\n borderRadius: 10,\n cursor: 'pointer',\n }}\n >\n <History size={18} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.5} />\n <span style={{ fontSize: 15, fontWeight: 600, color: 'var(--Grey-Strong, #2E3236)' }}>\n View All Interactions\n </span>\n </button>\n </div>\n ) : null}\n >\n <div\n style={{\n borderTop: '1px solid var(--Grey-absent, #D9D9D9)',\n maxHeight: '100%',\n overflowY: 'auto',\n }}\n >\n {hasPastSessions ? sessionHistory.map((session, i) => {\n // The row representing the session the user is currently viewing\n // gets a non-interactive, highlighted treatment: Ask Compass beige\n // background, a slightly larger / bolder title, and no hover /\n // click / external-link affordances (you can't navigate to the\n // page you're already on).\n const isCurrent = !!session.isCurrent;\n const isHovered = !isCurrent && hoveredSessionIdx === i;\n const sessionDirection = resolveSessionDirection(\n session,\n resolvedCallPurpose.interaction_direction\n );\n const SessionDirectionIcon =\n sessionDirection === 'outbound' ? PhoneOutgoing : PhoneIncoming;\n return (\n <div\n key={session.id || i}\n onClick={\n isCurrent\n ? undefined\n : () => {\n if (onSessionClick) onSessionClick(session);\n setShowSessionDrawer(false);\n }\n }\n onMouseEnter={isCurrent ? undefined : () => setHoveredSessionIdx(i)}\n onMouseLeave={isCurrent ? undefined : () => setHoveredSessionIdx(null)}\n aria-current={isCurrent ? 'page' : undefined}\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n gap: 12,\n padding: '16px 12px',\n borderTop: i === 0 ? 'none' : '1px solid var(--Grey-absent, #D9D9D9)',\n background: isCurrent\n ? '#E3E1D7'\n : isHovered\n ? 'var(--surface-hover, #F3F7F7)'\n : 'var(--Grey-White, #FFF)',\n cursor: isCurrent ? 'default' : 'pointer',\n transition: 'background 0.15s',\n }}\n >\n <div style={{ minWidth: 0 }}>\n <div\n style={{\n fontSize: isCurrent ? 15 : 14,\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n fontWeight: isCurrent ? 500 : 400,\n color: 'var(--Grey-Strong, #2E3236)',\n lineHeight: 1.2,\n marginBottom: 8,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {/* {session.title} */}\n {sessionDirection && (\n <SessionDirectionIcon\n size={16}\n color=\"var(--Grey-Muted, #808183)\"\n strokeWidth={1.5}\n style={{ flexShrink: 0 }}\n aria-hidden\n />\n )}\n <span\n style={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n minWidth: 0,\n }}\n >\n {session.title}\n </span>\n </div>\n {session.status && (\n <div style={{ fontSize: 13, color: 'var(--Grey-Strong, #2E3236)', marginBottom: 12, lineHeight: 1.2 }}>\n <span style={{ fontWeight: 400 }}>Location: </span>\n <span style={{ fontWeight: 400, color: 'var(--Grey-Muted, #808183)' }}>{session.location}</span>\n </div>\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap' }}>\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.1 }}>\n <CalendarDays size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.8} />\n {session.date}\n </span>\n {(session.agent || session.agent_name) && (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 13, fontWeight: 400, color: 'var(--Grey-Muted, #808183)', lineHeight: 1.1 }}>\n <Headset size={16} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.8} />\n {session.agent || session.agent_name}\n </span>\n )}\n </div>\n </div>\n {/* External-link affordance is hidden for the current row —\n there's nowhere to navigate to. */}\n {!isCurrent && isHovered && (\n <ExternalLink size={20} color=\"var(--Grey-Muted, #808183)\" strokeWidth={1.7} style={{ flexShrink: 0 }} />\n )}\n </div>\n );\n }) : (\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: 140,\n padding: '24px 12px',\n color: 'var(--Grey-Muted, #808183)',\n fontSize: 14,\n fontStyle: 'italic',\n textAlign: 'center',\n }}\n >\n No other interactions available\n </div>\n )}\n </div>\n </SideDrawer>\n\n </div>\n );\n};\n\nexport default UpdatedInteractionDetails;\n","import React from 'react';\nimport { ThumbsUp, ThumbsDown } from 'lucide-react';\nimport { useMediaQuery } from '../../utils/useMediaQuery';\n// import { Info } from 'lucide-react';\n\n/*\n * Figma node: 101-2386 (Agent Lift Analysis)\n *\n * Container: fill=#F3F1E5, padding: 24px, gap: 24px, vertical,\n * border-radius: 8px, border: 1px solid #D9D9D9\n *\n * Header (Frame 12): vertical, gap: 32\n * Row (Frame 20): horizontal, space-between, center\n * \"Agent Lift Analysis\" — 15px/700/#2E3236, lh=120%\n * Right (Frame 18): horizontal, gap: 8, center\n * \"vs. Average Agent:\" — 13px/400/#2E3236, lh=120%\n * \"+4.3pp\" — 14px/700/#2E3236, lh=120%\n * Divider: border-left 1px #D9D9D9, padding-left: 8\n * ThumbsUp 14x14 + \"Positive\" 13px/700/#2E3236\n *\n * Metrics (Frame 15): horizontal, gap: 24, align: bottom\n * Col 1 (Frame 8): vertical, gap: 16, center\n * \"94%\" — 28px/400/#808183, lh=120%\n * Labels: vertical, gap: 8\n * \"Expected Outcome\" — 13px/400/#2E3236\n * \"Based on call type & difficulty\" — 13px/400/#808183\n * Plus icon: 16x16, fill=#2E3236, radius: 24, white stroke\n * Col 2 (Frame 9): vertical, gap: 16, pad-left: 24, border-left: 1px #D9D9D9\n * \"-11.0pp\" — 28px/400/#808183\n * \"Agent Impact\" — 13px/400/#2E3236\n * \"Behavior-driven change\" — 13px/400/#808183\n * Col 3 (Frame 7): vertical, gap: 16, pad-left: 24, border-left: 1px #D9D9D9\n * \"83%\" — 28px/400/#2E3236 (highlighted)\n * \"Predicted Outcome\" — 13px/700/#2E3236\n * \"With agent behaviors\" — 13px/400/#808183\n *\n * Key Drivers (Frame 13): vertical, gap: 4\n * \"Key Drivers\" — 12px/700/#2E3236, lh=120%\n * Chips (Frame 16): horizontal, gap: 4\n * Each: bg=#FFF, pad=8, radius=4, border 1px #D9D9D9\n * Text: 12px/400/#2E3236, lh=120%\n */\n\nconst COLORS = {\n strong: 'var(--Grey-Strong, #2E3236)',\n muted: 'var(--Grey-Muted, #808183)',\n absent: 'var(--Grey-absent, #D9D9D9)',\n white: 'var(--Grey-White, #FFF)',\n cardBg: 'var(--surface-warm-40, rgba(243, 241, 229, 0.40))',\n};\n\nconst LH = 1.2;\nconst MAX_VISIBLE_DRIVERS = 3;\n\nconst fmtPct = (v) => (v != null ? Math.round(v * 100) + '%' : '\\u2014');\n\nconst fmtPp = (v) => {\n if (v == null) return '\\u2014';\n const pp = (v * 100).toFixed(1);\n return v > 0 ? `+${pp}pp` : `${pp}pp`;\n};\n\n// /** Figma node 1199-2892 — 24px partial-ring gauge beside outcome % */\n// const OutcomeGauge = ({ value, size = 24 }) => {\n// const pct = value != null ? Math.min(1, Math.max(0, value)) : 0;\n// const r = 9;\n// const stroke = 2.5;\n// const arcLen = 2 * Math.PI * r * 0.75;\n// const filled = arcLen * pct;\n//\n// return (\n// <svg width={size} height={size} viewBox=\"0 0 24 24\" aria-hidden>\n// <circle\n// cx=\"12\"\n// cy=\"12\"\n// r={r}\n// fill=\"none\"\n// stroke={COLORS.absent}\n// strokeWidth={stroke}\n// strokeLinecap=\"round\"\n// strokeDasharray={`${arcLen} ${2 * Math.PI * r}`}\n// transform=\"rotate(135 12 12)\"\n// />\n// <circle\n// cx=\"12\"\n// cy=\"12\"\n// r={r}\n// fill=\"none\"\n// stroke={COLORS.strong}\n// strokeWidth={stroke}\n// strokeLinecap=\"round\"\n// strokeDasharray={`${filled} ${2 * Math.PI * r}`}\n// transform=\"rotate(135 12 12)\"\n// />\n// </svg>\n// );\n// };\n\nconst UpdatedInteractionScores = ({ outcomeLift, driverLabels = [], showOutcomeOnly = false }) => {\n const isPhone = useMediaQuery('(max-width: 640px)');\n if (!outcomeLift || outcomeLift.lift == null) return null;\n\n const pExpected = outcomeLift.p_expected;\n const pFull = outcomeLift.p_full;\n const liftRaw =\n outcomeLift.lift_raw ??\n (pFull != null && pExpected != null ? pFull - pExpected : null);\n const liftRecentered = outcomeLift.lift;\n\n const liftBand = outcomeLift.interpretation?.lift_band\n ? outcomeLift.interpretation.lift_band.replace(/_/g, ' ')\n : liftRecentered >= 0\n ? 'Positive'\n : 'Negative';\n\n const liftBandCapitalized =\n liftBand.charAt(0).toUpperCase() + liftBand.slice(1);\n\n const isNegativeBand = /negative/i.test(liftBand);\n const LiftIcon = isNegativeBand ? ThumbsDown : ThumbsUp;\n\n const visibleDrivers = driverLabels.slice(0, MAX_VISIBLE_DRIVERS);\n const overflowCount = driverLabels.length - MAX_VISIBLE_DRIVERS;\n\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n padding: 24,\n gap: showOutcomeOnly ? 16 : 24,\n borderRadius: 8,\n border: `1px solid ${COLORS.absent}`,\n background: showOutcomeOnly ? '#faf9f5' : COLORS.cardBg,\n alignSelf: 'stretch',\n }}\n >\n {/* Frame 12: Header + Metrics — vertical, gap: 32 (agent-only: 24) */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: showOutcomeOnly ? 24 : 32 }}>\n\n {/* Frame 20: Title row — horizontal, space-between, center */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 24,\n alignSelf: 'stretch',\n }}\n >\n <span\n style={{\n fontSize: 15,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n }}\n >\n Agent Lift Analysis\n </span>\n\n {/* Frame 18: right meta — horizontal, gap: 8, center */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontFamily: 'var(--font-sans)',\n }}\n >\n {/* <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, lineHeight: LH }}>\n vs. Average Agent:\n </span> */}\n {/* Frame 19: value */}\n {/* <span style={{ fontSize: 14, fontWeight: 600, color: COLORS.strong, lineHeight: LH }}>\n {fmtPp(liftRecentered)}\n </span> */}\n {/* Frame 21: divider + thumbsup + band */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n paddingLeft: 8,\n // borderLeft: `1px solid ${COLORS.absent}`,\n }}\n >\n <LiftIcon size={14} color={COLORS.strong} />\n <span style={{ fontSize: 13, fontWeight: 600, color: COLORS.strong, lineHeight: LH }}>\n {liftBandCapitalized}\n </span>\n </div>\n </div>\n </div>\n\n {/* Frame 15: Metrics row — horizontal, gap: 24 (stacks on phone) */}\n <div\n style={{\n display: 'flex',\n flexDirection: isPhone && !showOutcomeOnly ? 'column' : 'row',\n alignItems: isPhone && !showOutcomeOnly ? 'stretch' : 'center',\n gap: isPhone && !showOutcomeOnly ? 16 : 24,\n ...(showOutcomeOnly ? { justifyContent: 'center', width: '100%' } : {}),\n }}\n >\n {!showOutcomeOnly && (\n <>\n {/* Frame 8: Expected Outcome — flex: 1, equal width */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'flex-start', flex: 1, minWidth: 0 }}>\n <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>\n {fmtPct(pExpected)}\n </span>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'flex-start', minHeight: 48 }}>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH, whiteSpace: 'nowrap' }}>\n Expected Outcome\n </span>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'left' }}>\n Based on call type &amp; difficulty\n </span>\n </div>\n </div>\n\n {/* Frame 9: Agent Impact — flex: 1, equal width, border-left (top border when stacked) */}\n <div style={{\n display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'flex-start',\n ...(isPhone\n ? { paddingTop: 16, borderTop: `1px solid ${COLORS.absent}`, width: '100%' }\n : { paddingLeft: 24, borderLeft: `1px solid ${COLORS.absent}`, flex: 1, minWidth: 0 }),\n }}>\n <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>\n {fmtPp(liftRaw)}\n </span>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'flex-start', minHeight: 48 }}>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH, whiteSpace: 'nowrap' }}>\n Agent Impact\n </span>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'left' }}>\n Behavior-driven change\n </span>\n </div>\n </div>\n </>\n )}\n\n {/* Frame 7: Outcome — centered horizontal when agent-only (Figma 1199-2875) */}\n <div style={{\n display: 'flex',\n flexDirection: showOutcomeOnly ? 'row' : 'column',\n gap: showOutcomeOnly ? 16 : 16,\n alignItems: showOutcomeOnly ? 'center' : 'flex-start',\n justifyContent: showOutcomeOnly ? 'center' : undefined,\n ...(showOutcomeOnly\n ? {}\n : isPhone\n ? { paddingTop: 16, borderTop: `1px solid ${COLORS.absent}`, width: '100%' }\n : { paddingLeft: 24, borderLeft: `1px solid ${COLORS.absent}`, flex: 1, minWidth: 0 }),\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n {/* {showOutcomeOnly && <OutcomeGauge value={pFull} />} */}\n <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH }}>\n {fmtPct(pFull)}\n </span>\n </div>\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n alignItems: showOutcomeOnly ? 'flex-start' : 'flex-start',\n minHeight: showOutcomeOnly ? undefined : 48,\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n <span style={{\n fontSize: 13,\n fontWeight: showOutcomeOnly ? 400 : 600,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n whiteSpace: 'nowrap',\n }}>\n Outcome\n </span>\n {/* {showOutcomeOnly && (\n <Info size={14} color={COLORS.strong} strokeWidth={1.5} aria-label=\"Outcome information\" />\n )} */}\n </div>\n <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'left' }}>\n With agent behaviors\n </span>\n </div>\n </div>\n </div>\n </div>\n\n {/* Frame 13: Key Drivers — vertical, gap: 4 */}\n {driverLabels.length > 0 && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, alignSelf: 'stretch' }}>\n <span\n style={{\n fontSize: 12,\n fontWeight: 600,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n }}\n >\n Key Drivers\n </span>\n {/* Frame 16: chips — horizontal, gap: 4 */}\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {visibleDrivers.map((label, i) => (\n <div\n key={i}\n style={{\n display: 'flex',\n padding: 8,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 4,\n border: `1px solid ${COLORS.absent}`,\n background: COLORS.white,\n }}\n >\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n maxWidth: 200,\n }}\n >\n {label}\n </span>\n </div>\n ))}\n {overflowCount > 0 && (\n <div\n style={{\n display: 'flex',\n padding: 8,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 4,\n border: `1px solid ${COLORS.absent}`,\n background: COLORS.white,\n }}\n >\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n color: COLORS.strong,\n fontFamily: 'var(--font-sans)',\n lineHeight: LH,\n whiteSpace: 'nowrap',\n }}\n >\n + {overflowCount}\n </span>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default UpdatedInteractionScores;\n"],"names":["COLORS","OVERALL_MAP","STYLE_ID","ensureKeyframes","style","OverallIcon","overall","common","jsx","ArrowUp","ArrowDown","ArrowLeftRight","ThumbsUp","OverallBadge","label","jsxs","getDisplayQuote","quote","s","SectionItem","item","text","CoachingColumn","icon","items","i","UpdatedCoachingSynthesisCard","data","loading","error","React","isNarrow","useMediaQuery","Fragment","strengths","improvements","oneLiner","_a","context","_b","ShieldCheck","TrendingUp","Lightbulb","fmtDur","seconds","m","ROW_STYLE","TruncatedValue","ref","useRef","isTruncated","setIsTruncated","useState","useEffect","el","measure","observer","COLUMN_STYLE","UpdatedInteractionContext","meta","callPurpose","classification","dimensions","outcomeQuality","onMoreDetails","moreDetails","resolutionOutcome","customerIntent","location","interactionId","canShowEditButton","onEditInteraction","flatView","expanded","setExpanded","moreDetailsRef","isPhone","duration","messages","driver","paradigm","findDim","keyPattern","d","dimResolution","dimIntent","dimLocation","dimOutcomeQuality","fmtValue","v","c","resolvedOutcomeQuality","resolvedResolutionOutcome","resolvedCustomerIntent","resolvedLocation","resolvedParadigm","excludedKeys","k","filteredDimensions","pairedRows","rawPairs","left","right","pair","detailRows","flatPairs","flatFields","rowsToRender","handleOutsideClick","event","renderRow","renderMoreDetailsToggle","p","ChevronUp","ChevronDown","Pencil","idx","row","HoverIcon","children","size","onClick","title","hovered","setHovered","UpdatedInteractionSignals","signals","expandedSignals","toggleSignal","playEvidence","highlightTurns","onShowInTranscript","timelinePlaying","currentTimeSeconds","signalList","presentCount","fmtMs","ms","minutes","isEvPlaying","ev","FileSignal","signal","key","isExpanded","obsCount","_c","obs","obsIdx","e","ScrollText","evIdx","hasTimestamps","PauseCircle","PlayCircle","GaugeMeter","score","minScore","maxScore","numericScore","clampedScore","filledUnits","segDeg","toXY","angleDeg","rad","strokeArc","fromDeg","toDeg","large","gap","_","fromA","toA","segmentFill","pathD","ScoreBar","value","maxValue","numericValue","clampedValue","LEGEND_TOOLTIPS","InfoTooltip","show","setShow","pos","setPos","handleEnter","rect","LegendItem","Info","UpdatedCompassScore","predictedScore","predictedLabel","description","outcomePercent","legends","displayScore","scoreText","rotateDeg","legend","roleColorMap","role","roleTokens","extractRoleValue","user","directRole","nestedRole","_d","_e","_f","resolveCurrentUserAvatarColor","getInitials","name","w","isWithinEditWindow","utcValue","minMatch","formatTimestamp","diffMs","diffMin","diffHr","diffDays","Avatar","initials","color","avatar","CommentBubble","comment","isReply","isConsecutive","onReply","onSendReply","onEdit","onDelete","onMenuClick","showReply","menuOpen","setMenuOpen","replyOpen","setReplyOpen","replyValue","setReplyValue","editOpen","setEditOpen","editValue","setEditValue","confirmDelete","setConfirmDelete","menuRef","replyRef","editRef","author","authorName","avatarColor","avatarImg","rawTimestamp","timestamp","canEdit","isEdited","paragraphs","handler","ta","max","Ellipsis","X","paragraph","CornerDownRight","CommentInput","currentUser","onSubmit","setValue","isFocused","setIsFocused","textareaRef","handleSubmit","trimmed","handleKeyDown","CommentThread","depth","hasReplies","isLastAtDepth","reply","UpdatedThreads","externalComments","totalComments","onSendComment","onMarkResolved","isResolved","localComments","setLocalComments","isSending","setIsSending","allComments","useMemo","externalIds","newLocal","prev","displayCurrentUser","handleSendReply","content","parentId","optimisticReply","handleSendComment","optimisticComment","handleEdit","handleDelete","groupedComments","repliesByParent","buildTree","commentCount","MessagesSquare","Check","CircleCheck","prevAuthor","currAuthor","FONT_DISPLAY","LeadingIcon","Target","ImpactChip","direction","Arrow","EvidenceQuote","evidence","onPlayEvidence","startMs","endMs","hasTimestamp","currentMs","isPlayingThis","SignalRow","evidenceList","hasEvidence","ChevronRight","GuidanceItem","isLast","sig","SummaryCountBar","summary","focus","opportunity","excellence","cells","count","Icon","MAX_ITEMS","UpdatedGuidance","guidanceCount","visibleItems","HOLD_BUCKETS","Search","Pause","ArrowRightLeft","CircleDashed","MicOff","num","fmtRate","rate","fmtCount","n","HoldCounts","holdTypeCounts","b","StallRow","total","filler","buying","breakdown","PercentileRow","percentiles","UpdatedTalkPatterns","hasHolds","hasStalls","agentP","customerP","hasPercentiles","AudioLines","normaliseItem","fmtPercent","ItemRow","percent","Column","initialVisibleCount","overflow","visible","UpdatedProductsServices","products","services","productsTitle","servicesTitle","normalisedProducts","normalisedServices","ClipboardCheck","NameTooltip","triggerRef","BASE_TABS","isAgentRole","isAdminRole","resolveSessionDirection","session","fallbackDirection","raw","UpdatedInteractionDetails","onBack","coachingData","coachingLoading","audioUrl","externalAudioRef","playbackRate","timelineSegments","onSeek","onTogglePlay","onSeekBack","onSeekForward","onSetPlaybackRate","externalAgentName","externalAgentFullName","externalCustomerName","externalCustomerFullName","transcript","activeTurnIndex","turnObservations","highlightedTurns","onTurnPlayPause","onHighlightTurns","externalCallPurpose","externalClassification","externalOutcomeQuality","compassScore","compassMaxScore","compassScorePct","predictedCsat","compassLegends","customerSessionsList","customerSessionCount","onSessionClick","onViewAllSessions","prevSessionDesc","prevSessionDisabled","nextSessionDesc","nextSessionDisabled","onPreviousSession","onNextSession","comments","guidance","guidanceSummary","talkPatterns","productsServices","productsDiscussed","servicesDiscussed","commentsResolved","activeTab","setActiveTab","setExpandedSignals","showSessionDrawer","setShowSessionDrawer","hoveredSessionIdx","setHoveredSessionIdx","internalPlaying","setInternalPlaying","internalCurrentTime","setInternalCurrentTime","isScrolledPastHeader","setIsScrolledPastHeader","recordingRef","overviewRef","coachingRef","signalsRef","productsRef","commentsRef","sectionRefs","scrollContainerRef","isClickScrolling","hasProductsServices","tabs","out","t","container","tabKeys","refs","scrollParent","node","overflowY","handleScroll","activeKey","overviewTop","clickedTabRef","handleTabClick","containerTop","offset","elTop","sessionHistory","hasPastSessions","handleShowInTranscript","signalsEl","timeSec","handlePlayEvidence","durationMs","handleHighlightTurns","turnIds","next","blocks","findBlock","id","ctx","outcomeLift","blockDimensions","resolvedMeta","resolvedCallPurpose","resolvedClassification","resolvedOutcomeLift","resolvedCoaching","resolvedSignals","guidanceData","agentName","agentFullName","customerName","customerFullName","resolvedUserRole","canEditInteraction","isAgentUser","sessionCount","rawDate","dateStr","ArrowLeft","ArrowRight","tab","ClipboardList","CalendarDays","DirectionIcon","PhoneOutgoing","PhoneIncoming","Headset","CircleUser","liftData","difficultyScore","difficultyBand","pExpected","scoreImpact","liftRaw","liftDisplay","liftBand","pFull","interpretationDescription","clampVal","lo","hi","difficultyValue","impactValue","scoreImpactPercent","prettyBand","band","difficultyLabel","impactLabel","impactPercent","parsed","AgentLiftAnalysisCard","UpdatedInteractionRecording","SideDrawer","History","isCurrent","isHovered","sessionDirection","SessionDirectionIcon","ExternalLink","LH","MAX_VISIBLE_DRIVERS","fmtPct","fmtPp","pp","UpdatedInteractionScores","driverLabels","showOutcomeOnly","liftRecentered","liftBandCapitalized","LiftIcon","ThumbsDown","visibleDrivers","overflowCount"],"mappings":"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"}