chordia-ui 3.4.7 → 3.4.8

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,4 +1,4 @@
1
- import { useState, useRef } from 'react';
1
+ import { useState, useRef, useEffect } from 'react';
2
2
  import { ArrowLeft, ArrowRight, CalendarDays, PhoneIncoming, ClipboardList, FileSignal, Repeat, ChevronDown, ChevronUp, Headset, CircleUser, History, ExternalLink } from 'lucide-react';
3
3
  import UpdatedInteractionContext from './UpdatedInteractionContext';
4
4
  import UpdatedInteractionRecording from './UpdatedInteractionRecording';
@@ -6,6 +6,7 @@ import UpdatedInteractionScores from './UpdatedInteractionScores';
6
6
  import UpdatedCoachingSynthesisCard from './UpdatedCoachingSynthesisCard';
7
7
  import UpdatedInteractionSignals from './UpdatedInteractionSignals';
8
8
  import UpdatedCompassScore from './UpdatedCompassScore';
9
+ import UpdatedThreads from './UpdatedThreads';
9
10
 
10
11
  const TABS = [
11
12
  { key: 'overview', label: 'Overview' },
@@ -20,6 +21,7 @@ const UpdatedInteractionDetails = ({
20
21
  // Data props — all optional with defaults for demo
21
22
  data,
22
23
  coachingData,
24
+ coachingLoading = false,
23
25
  audioUrl,
24
26
  // Audio/playback props — pass these when the host app manages audio externally
25
27
  // (like InteractionDetailPanel does). If omitted, UpdatedInteractionRecording
@@ -50,8 +52,13 @@ const UpdatedInteractionDetails = ({
50
52
  callPurpose: externalCallPurpose,
51
53
  classification: externalClassification,
52
54
  outcomeQuality: externalOutcomeQuality,
55
+ // Context "More Details" expandable section
56
+ resolutionOutcome,
57
+ customerIntent,
58
+ interactionId,
59
+ moreDetails,
53
60
  // Compass score props
54
- compassScore, // gauge meter value (e.g. outcomeLift.p_full) drives meter fill, range 1-10
61
+ compassScore, // gauge meter value — compass_score, range 1-5
55
62
  compassMaxScore = 10,
56
63
  predictedCsat, // predicted objective number (e.g. compass_score) — shown as "03" top-right
57
64
  predictedLabel = 'Predicted Objective',
@@ -85,13 +92,51 @@ const UpdatedInteractionDetails = ({
85
92
  const signalsRef = useRef(null);
86
93
  const commentsRef = useRef(null);
87
94
  const sectionRefs = { overview: overviewRef, coaching: coachingRef, signals: signalsRef, comments: commentsRef };
95
+ const scrollContainerRef = useRef(null);
96
+ const isClickScrolling = useRef(false);
97
+
98
+ // Scroll-spy: update active tab based on which section is most visible
99
+ useEffect(() => {
100
+ const container = scrollContainerRef.current;
101
+ if (!container) return;
102
+
103
+ const tabKeys = ['overview', 'coaching', 'signals', 'comments'];
104
+ const refs = [overviewRef, coachingRef, signalsRef, commentsRef];
105
+
106
+ const observer = new IntersectionObserver(
107
+ (entries) => {
108
+ if (isClickScrolling.current) return;
109
+ let bestKey = null;
110
+ let bestRatio = 0;
111
+ for (const entry of entries) {
112
+ if (entry.isIntersecting && entry.intersectionRatio > bestRatio) {
113
+ const idx = refs.findIndex((r) => r.current === entry.target);
114
+ if (idx !== -1) {
115
+ bestKey = tabKeys[idx];
116
+ bestRatio = entry.intersectionRatio;
117
+ }
118
+ }
119
+ }
120
+ if (bestKey) setActiveTab(bestKey);
121
+ },
122
+ { root: container, threshold: [0, 0.1, 0.25, 0.5, 0.75, 1] }
123
+ );
124
+
125
+ refs.forEach((ref) => {
126
+ if (ref.current) observer.observe(ref.current);
127
+ });
128
+
129
+ return () => observer.disconnect();
130
+ }, []);
88
131
 
89
132
  const handleTabClick = (key) => {
90
133
  setActiveTab(key);
134
+ isClickScrolling.current = true;
91
135
  const ref = sectionRefs[key];
92
136
  if (ref?.current) {
93
137
  ref.current.scrollIntoView({ behavior: 'smooth', block: 'start' });
94
138
  }
139
+ setTimeout(() => { isClickScrolling.current = false; }, 800);
95
140
  };
96
141
 
97
142
  const sessionHistory = customerSessionsList || [];
@@ -281,7 +326,7 @@ const UpdatedInteractionDetails = ({
281
326
  </div>{/* end sticky header + tabs */}
282
327
 
283
328
  {/* All sections rendered — tabs scroll to them */}
284
- <div style={{ padding: 24, flex: 1, overflowY: 'auto' }}>
329
+ <div ref={scrollContainerRef} style={{ padding: 24, flex: 1, overflowY: 'auto' }}>
285
330
  {/* ═══ OVERVIEW SECTION ═══ */}
286
331
  <div ref={overviewRef} style={{
287
332
  display: 'flex',
@@ -348,142 +393,150 @@ const UpdatedInteractionDetails = ({
348
393
  {/* Repeat icon */}
349
394
  <Repeat size={16} color="var(--color-input-border, #ACACAD)" strokeWidth={1.5} />
350
395
 
351
- {/* Customer — CircleUser icon + dropdown */}
352
- <div style={{ position: 'relative' }}>
353
- <button
354
- onClick={() => setShowSessionDropdown((prev) => !prev)}
355
- style={{
356
- display: 'flex', alignItems: 'center', gap: 4, padding: '8px 0',
357
- background: 'none', border: 'none', cursor: 'pointer',
358
- }}
359
- >
360
- <CircleUser size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
361
- <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', lineHeight: 1.2 }}>
362
- {customerName} ({sessionCount} Sessions)
363
- </span>
364
- {showSessionDropdown
365
- ? <ChevronUp size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
366
- : <ChevronDown size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
367
- }
368
- </button>
369
-
370
- {/* Figma node 311-1302: Session history dropdown */}
371
- {showSessionDropdown && (
372
- <div style={{
373
- position: 'absolute',
374
- top: '100%',
375
- right: 0,
376
- marginTop: 4,
377
- width: 264,
378
- background: 'var(--Grey-White, #FFF)',
379
- borderRadius: 4,
380
- border: '1px solid var(--Grey-absent, #D9D9D9)',
381
- boxShadow: '0 4px 16px rgba(0,0,0,0.12)',
382
- zIndex: 50,
383
- overflow: 'hidden',
384
- }}>
385
- {/* Header: customer name + session count */}
386
- {/* Header — Figma node 312-1321: horizontal, gap: 8 */}
396
+ {/* Customer — CircleUser icon + dropdown (only if > 1 session) */}
397
+ {sessionCount > 1 ? (
398
+ <div style={{ position: 'relative' }}>
399
+ <button
400
+ onClick={() => setShowSessionDropdown((prev) => !prev)}
401
+ style={{
402
+ display: 'flex', alignItems: 'center', gap: 4, padding: '8px 0',
403
+ background: 'none', border: 'none', cursor: 'pointer',
404
+ }}
405
+ >
406
+ <CircleUser size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
407
+ <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', lineHeight: 1.2 }}>
408
+ {customerName} ({sessionCount} Sessions)
409
+ </span>
410
+ {showSessionDropdown
411
+ ? <ChevronUp size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
412
+ : <ChevronDown size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
413
+ }
414
+ </button>
415
+
416
+ {/* Figma node 311-1302: Session history dropdown */}
417
+ {showSessionDropdown && (
387
418
  <div style={{
388
- display: 'flex', alignItems: 'flex-start', gap: 8,
389
- padding: 16,
419
+ position: 'absolute',
420
+ top: '100%',
421
+ right: 0,
422
+ marginTop: 4,
423
+ width: 264,
424
+ background: 'var(--Grey-White, #FFF)',
425
+ borderRadius: 4,
426
+ border: '1px solid var(--Grey-absent, #D9D9D9)',
427
+ boxShadow: '0 4px 16px rgba(0,0,0,0.12)',
428
+ zIndex: 50,
429
+ overflow: 'hidden',
390
430
  }}>
391
- <CircleUser size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} style={{ marginTop: 2, flexShrink: 0 }} />
392
- <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
393
- <span style={{
394
- fontSize: 16, fontWeight: 600,
395
- color: 'var(--Grey-Strong, #2E3236)',
396
- lineHeight: 1,
397
- }}>
398
- {customerName}
399
- </span>
400
- <span style={{
401
- fontSize: 13, fontWeight: 400,
402
- color: 'var(--Grey-Muted, #808183)',
403
- lineHeight: 1,
404
- }}>
405
- {sessionCount} Sessions in past
406
- </span>
407
- </div>
408
- </div>
409
-
410
- {/* Session list — Figma: 264px, pad 12 16, space-between, center */}
411
- {sessionHistory.slice(0, 5).map((session, i) => (
412
- <div
413
- key={session.id || i}
414
- onClick={() => { if (onSessionClick) onSessionClick(session); setShowSessionDropdown(false); }}
415
- onMouseEnter={() => setHoveredSessionIdx(i)}
416
- onMouseLeave={() => setHoveredSessionIdx(null)}
417
- style={{
418
- display: 'flex',
419
- width: 264,
420
- padding: '12px 16px',
421
- justifyContent: 'space-between',
422
- alignItems: 'center',
423
- background: hoveredSessionIdx === i
424
- ? 'var(--surface-hover, #F3F7F7)'
425
- : 'var(--Grey-White, #FFF)',
426
- borderTop: '1px solid var(--Grey-absent, #D9D9D9)',
427
- cursor: 'pointer',
428
- boxSizing: 'border-box',
429
- transition: 'background 0.15s',
430
- }}
431
- >
432
- <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
431
+ {/* Header Figma node 312-1321: horizontal, gap: 8 */}
432
+ <div style={{
433
+ display: 'flex', alignItems: 'flex-start', gap: 8,
434
+ padding: 16,
435
+ }}>
436
+ <CircleUser size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} style={{ marginTop: 2, flexShrink: 0 }} />
437
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
433
438
  <span style={{
434
- fontSize: 13, fontWeight: 400,
439
+ fontSize: 16, fontWeight: 600,
435
440
  color: 'var(--Grey-Strong, #2E3236)',
436
441
  lineHeight: 1,
437
442
  }}>
438
- {session.title}
443
+ {customerName}
439
444
  </span>
440
445
  <span style={{
441
- fontSize: 12, fontWeight: 400,
446
+ fontSize: 13, fontWeight: 400,
442
447
  color: 'var(--Grey-Muted, #808183)',
443
448
  lineHeight: 1,
444
449
  }}>
445
- {session.date}
450
+ {sessionCount} Sessions in past
446
451
  </span>
447
452
  </div>
448
- {hoveredSessionIdx === i && (
449
- <ExternalLink size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1} style={{ flexShrink: 0 }} />
450
- )}
451
453
  </div>
452
- ))}
453
454
 
454
- {/* View All Sessions button — Figma node 312-1347 */}
455
- <div style={{
456
- padding: 16,
457
- borderTop: '1px solid var(--Grey-absent, #D9D9D9)',
458
- display: 'flex',
459
- justifyContent: 'center',
460
- }}>
461
- <button
462
- onClick={() => { if (onViewAllSessions) onViewAllSessions(); setShowSessionDropdown(false); }}
463
- style={{
455
+ {/* Session list */}
456
+ {sessionHistory.slice(0, 5).map((session, i) => (
457
+ <div
458
+ key={session.id || i}
459
+ onClick={() => { if (onSessionClick) onSessionClick(session); setShowSessionDropdown(false); }}
460
+ onMouseEnter={() => setHoveredSessionIdx(i)}
461
+ onMouseLeave={() => setHoveredSessionIdx(null)}
462
+ style={{
463
+ display: 'flex',
464
+ width: 264,
465
+ padding: '12px 16px',
466
+ justifyContent: 'space-between',
467
+ alignItems: 'center',
468
+ background: hoveredSessionIdx === i
469
+ ? 'var(--surface-hover, #F3F7F7)'
470
+ : 'var(--Grey-White, #FFF)',
471
+ borderTop: '1px solid var(--Grey-absent, #D9D9D9)',
472
+ cursor: 'pointer',
473
+ boxSizing: 'border-box',
474
+ transition: 'background 0.15s',
475
+ }}
476
+ >
477
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
478
+ <span style={{
479
+ fontSize: 13, fontWeight: 400,
480
+ color: 'var(--Grey-Strong, #2E3236)',
481
+ lineHeight: 1,
482
+ }}>
483
+ {session.title}
484
+ </span>
485
+ <span style={{
486
+ fontSize: 12, fontWeight: 400,
487
+ color: 'var(--Grey-Muted, #808183)',
488
+ lineHeight: 1,
489
+ }}>
490
+ {session.date}
491
+ </span>
492
+ </div>
493
+ {hoveredSessionIdx === i && (
494
+ <ExternalLink size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1} style={{ flexShrink: 0 }} />
495
+ )}
496
+ </div>
497
+ ))}
498
+
499
+ {/* View All Sessions button */}
500
+ <div style={{
501
+ padding: 16,
502
+ borderTop: '1px solid var(--Grey-absent, #D9D9D9)',
464
503
  display: 'flex',
465
- height: 32,
466
- padding: '16px 16px 16px 12px',
467
504
  justifyContent: 'center',
468
- alignItems: 'center',
469
- gap: 6,
470
- background: 'var(--Grey-White, #FFF)',
471
- border: '1px solid var(--Grey-absent, #D9D9D9)',
472
- borderRadius: 10,
473
- cursor: 'pointer',
474
505
  }}>
475
- <History size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
476
- <span style={{
477
- fontSize: 14, fontWeight: 600,
478
- color: 'var(--Grey-Strong, #2E3236)',
506
+ <button
507
+ onClick={() => { if (onViewAllSessions) onViewAllSessions(); setShowSessionDropdown(false); }}
508
+ style={{
509
+ display: 'flex',
510
+ height: 32,
511
+ padding: '16px 16px 16px 12px',
512
+ justifyContent: 'center',
513
+ alignItems: 'center',
514
+ gap: 6,
515
+ background: 'var(--Grey-White, #FFF)',
516
+ border: '1px solid var(--Grey-absent, #D9D9D9)',
517
+ borderRadius: 10,
518
+ cursor: 'pointer',
479
519
  }}>
480
- View All Sessions
481
- </span>
482
- </button>
520
+ <History size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
521
+ <span style={{
522
+ fontSize: 14, fontWeight: 600,
523
+ color: 'var(--Grey-Strong, #2E3236)',
524
+ }}>
525
+ View All Sessions
526
+ </span>
527
+ </button>
528
+ </div>
483
529
  </div>
484
- </div>
485
- )}
486
- </div>
530
+ )}
531
+ </div>
532
+ ) : (
533
+ <div style={{ display: 'flex', alignItems: 'center', gap: 4, padding: '8px 0' }}>
534
+ <CircleUser size={16} color="var(--Grey-Muted, #808183)" strokeWidth={1.5} />
535
+ <span style={{ fontSize: 13, fontWeight: 400, color: 'var(--Grey-Strong, #2E3236)', lineHeight: 1.2 }}>
536
+ {customerName}
537
+ </span>
538
+ </div>
539
+ )}
487
540
  </div>
488
541
  </div>
489
542
  </div>
@@ -501,8 +554,8 @@ const UpdatedInteractionDetails = ({
501
554
  {/* Left — Compass Score */}
502
555
  <div style={{ flex: 1, minWidth: 0, display: 'flex' }}>
503
556
  <UpdatedCompassScore
504
- score={compassScore != null ? Math.round(compassScore * 100) : 0}
505
- maxScore={100}
557
+ score={compassScore ?? 0}
558
+ maxScore={5}
506
559
  predictedScore={predictedCsat ?? 0}
507
560
  predictedLabel={predictedLabel}
508
561
  legends={compassLegends}
@@ -524,6 +577,10 @@ const UpdatedInteractionDetails = ({
524
577
  callPurpose={externalCallPurpose || demoCallPurpose}
525
578
  classification={externalClassification || demoClassification}
526
579
  outcomeQuality={externalOutcomeQuality || 'Neutral'}
580
+ resolutionOutcome={resolutionOutcome ?? 'Unknown'}
581
+ customerIntent={customerIntent ?? 'Get Information'}
582
+ interactionId={interactionId ?? meta.interaction_id ?? '1a369e01-5924-4d10-bfc7-d1321be71b2b'}
583
+ moreDetails={moreDetails}
527
584
  />
528
585
  <UpdatedInteractionScores
529
586
  outcomeLift={demoOutcomeLift}
@@ -536,7 +593,7 @@ const UpdatedInteractionDetails = ({
536
593
 
537
594
  {/* ═══ COACHING SUMMARY SECTION ═══ */}
538
595
  <div ref={coachingRef} style={{ paddingTop: 24 }}>
539
- <UpdatedCoachingSynthesisCard data={demoCoaching} />
596
+ <UpdatedCoachingSynthesisCard data={coachingLoading ? null : demoCoaching} loading={coachingLoading} />
540
597
  </div>
541
598
 
542
599
  {/* ═══ SIGNALS & RECORDING SECTION ═══ */}
@@ -616,9 +673,7 @@ const UpdatedInteractionDetails = ({
616
673
 
617
674
  {/* ═══ COMMENTS SECTION ═══ */}
618
675
  <div ref={commentsRef} style={{ paddingTop: 24 }}>
619
- <div style={{ fontSize: 14, color: 'var(--Grey-Muted, #808183)', fontFamily: 'var(--font-sans)' }}>
620
- No comments yet.
621
- </div>
676
+ <UpdatedThreads />
622
677
  </div>
623
678
  </div>
624
679
 
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { ThumbsUp, Plus } from 'lucide-react';
2
+ import { ThumbsUp, ThumbsDown, Plus } from 'lucide-react';
3
3
 
4
4
  /*
5
5
  * Figma node: 101-2386 (Agent Lift Analysis)
@@ -77,6 +77,9 @@ const UpdatedInteractionScores = ({ outcomeLift, driverLabels = [] }) => {
77
77
  const liftBandCapitalized =
78
78
  liftBand.charAt(0).toUpperCase() + liftBand.slice(1);
79
79
 
80
+ const isNegativeBand = /negative/i.test(liftBand);
81
+ const LiftIcon = isNegativeBand ? ThumbsDown : ThumbsUp;
82
+
80
83
  const visibleDrivers = driverLabels.slice(0, MAX_VISIBLE_DRIVERS);
81
84
  const overflowCount = driverLabels.length - MAX_VISIBLE_DRIVERS;
82
85
 
@@ -144,7 +147,7 @@ const UpdatedInteractionScores = ({ outcomeLift, driverLabels = [] }) => {
144
147
  borderLeft: `1px solid ${COLORS.absent}`,
145
148
  }}
146
149
  >
147
- <ThumbsUp size={14} color={COLORS.strong} />
150
+ <LiftIcon size={14} color={COLORS.strong} />
148
151
  <span style={{ fontSize: 13, fontWeight: 600, color: COLORS.strong, lineHeight: LH }}>
149
152
  {liftBandCapitalized}
150
153
  </span>
@@ -160,68 +163,52 @@ const UpdatedInteractionScores = ({ outcomeLift, driverLabels = [] }) => {
160
163
  gap: 24,
161
164
  }}
162
165
  >
163
- {/* Frame 8: Expected Outcome — vertical, gap: 16, center */}
164
- <div style={{ display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'center' }}>
166
+ {/* Frame 8: Expected Outcome — flex: 1, equal width */}
167
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'center', flex: 1, minWidth: 0 }}>
165
168
  <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
166
169
  {fmtPct(pExpected)}
167
170
  </span>
168
- <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
169
- <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
171
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'center' }}>
172
+ <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH, whiteSpace: 'nowrap' }}>
170
173
  Expected Outcome
171
174
  </span>
172
- <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
173
- Based on call type & difficulty
175
+ <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'center' }}>
176
+ Based on call type &amp; difficulty
174
177
  </span>
175
178
  </div>
176
179
  </div>
177
180
 
178
- {/* Plus icon: 16x16, fill=#2E3236, radius: 24 */}
179
- {/* <div
180
- style={{
181
- width: 16,
182
- height: 16,
183
- borderRadius: 24,
184
- background: COLORS.strong,
185
- display: 'flex',
186
- alignItems: 'center',
187
- justifyContent: 'center',
188
- flexShrink: 0,
189
- }}
190
- >
191
- <Plus size={9.33} color={COLORS.white} strokeWidth={1} />
192
- </div> */}
193
-
194
- {/* Frame 9: Agent Impact — vertical, gap: 16, pad-left: 24, border-left */}
181
+ {/* Frame 9: Agent Impact — flex: 1, equal width, border-left */}
195
182
  <div style={{
196
183
  display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'center',
197
- paddingLeft: 24, borderLeft: `1px solid ${COLORS.absent}`,
184
+ paddingLeft: 24, borderLeft: `1px solid ${COLORS.absent}`, flex: 1, minWidth: 0,
198
185
  }}>
199
186
  <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
200
187
  {fmtPp(liftRaw)}
201
188
  </span>
202
- <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
203
- <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
189
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'center' }}>
190
+ <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH, whiteSpace: 'nowrap' }}>
204
191
  Agent Impact
205
192
  </span>
206
- <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
193
+ <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'center' }}>
207
194
  Behavior-driven change
208
195
  </span>
209
196
  </div>
210
197
  </div>
211
198
 
212
- {/* Frame 7: Predicted Outcome — vertical, gap: 16, pad-left: 24, border-left */}
199
+ {/* Frame 7: Predicted Outcome — flex: 1, equal width, border-left */}
213
200
  <div style={{
214
201
  display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'center',
215
- paddingLeft: 24, borderLeft: `1px solid ${COLORS.absent}`,
202
+ paddingLeft: 24, borderLeft: `1px solid ${COLORS.absent}`, flex: 1, minWidth: 0,
216
203
  }}>
217
204
  <span style={{ fontSize: 28, fontWeight: 400, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
218
205
  {fmtPct(pFull)}
219
206
  </span>
220
- <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
221
- <span style={{ fontSize: 13, fontWeight: 600, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
207
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'center' }}>
208
+ <span style={{ fontSize: 13, fontWeight: 600, color: COLORS.strong, fontFamily: 'var(--font-sans)', lineHeight: LH, whiteSpace: 'nowrap' }}>
222
209
  Predicted Outcome
223
210
  </span>
224
- <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH }}>
211
+ <span style={{ fontSize: 13, fontWeight: 400, color: COLORS.muted, fontFamily: 'var(--font-sans)', lineHeight: LH, textAlign: 'center' }}>
225
212
  With agent behaviors
226
213
  </span>
227
214
  </div>