Skip to content

Commit eb98b01

Browse files
authored
fix(cohort): make the comparison scannable at a glance (#1189)
1 parent 5485088 commit eb98b01

2 files changed

Lines changed: 66 additions & 10 deletions

File tree

frontend/src/app/globals.css

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,3 +470,40 @@
470470
.dark .cl-formFieldHintText {
471471
color: hsl(var(--muted-foreground));
472472
}
473+
474+
/*
475+
* Cycling "." -> ".." -> "..." for copy that sits beside in-flight work.
476+
* Only opacity moves: the dots keep their slots in the line, so the sentence
477+
* ahead of them holds still instead of jittering once per step. The first dot
478+
* is always on, so the cycle reads as one/two/three rather than blinking
479+
* through an empty frame.
480+
*/
481+
.ellipsis-dot-2 {
482+
animation: ellipsis-dot-2 1.2s infinite;
483+
}
484+
485+
.ellipsis-dot-3 {
486+
animation: ellipsis-dot-3 1.2s infinite;
487+
}
488+
489+
@keyframes ellipsis-dot-2 {
490+
0%,
491+
33% {
492+
opacity: 0;
493+
}
494+
34%,
495+
100% {
496+
opacity: 1;
497+
}
498+
}
499+
500+
@keyframes ellipsis-dot-3 {
501+
0%,
502+
66% {
503+
opacity: 0;
504+
}
505+
67%,
506+
100% {
507+
opacity: 1;
508+
}
509+
}

frontend/src/components/cohort-comparison-section.tsx

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ function stepRange(stepIds: number[]): string {
4141
return lo === hi ? `[${lo}]` : `[${lo}-${hi}]`;
4242
}
4343

44+
/** A "." → ".." → "..." cycle for the generating copy. All three dots occupy
45+
* their slot from the start and only their opacity cycles, so the sentence
46+
* ahead of them never reflows. Hidden from assistive tech: the sentence
47+
* already says the work is in flight. */
48+
function EllipsisDots() {
49+
return (
50+
<span aria-hidden="true">
51+
.<span className="ellipsis-dot-2">.</span>
52+
<span className="ellipsis-dot-3">.</span>
53+
</span>
54+
);
55+
}
56+
4457
function ObservationList({
4558
items,
4659
taskId,
@@ -62,9 +75,12 @@ function ObservationList({
6275
<a
6376
key={j}
6477
href={evidenceHref(taskId, ev.trial_id, taskVersionId)}
65-
className="text-xs text-muted-foreground hover:underline"
78+
className="text-xs text-muted-foreground underline-offset-4 hover:underline"
6679
>
67-
<span className="font-mono">
80+
{/* Only the component + step range carries the link colour. The
81+
quote is the agent's own words, and colouring it too turns a
82+
paragraph of body text blue. */}
83+
<span className="font-mono text-blue-600 dark:text-blue-400">
6884
{componentLabel(ev.trajectory_component)} {stepRange(ev.step_ids)}
6985
</span>{" "}
7086
{ev.quote}
@@ -110,8 +126,8 @@ export function CohortComparisonSection({
110126
<section className="border-border flex flex-col gap-2 border-b p-4">
111127
<h3 className="text-sm font-semibold">Successful vs failing agents</h3>
112128
<p className="text-muted-foreground animate-pulse text-xs">
113-
Comparing successful and failing runs. The first view generates this,
114-
which takes a moment.
129+
Analyzing agent behavior across successful and failing runs
130+
<EllipsisDots />
115131
</p>
116132
</section>
117133
);
@@ -138,7 +154,7 @@ export function CohortComparisonSection({
138154
<p className="text-muted-foreground text-xs">
139155
No differences held up against the stored trajectories for these{" "}
140156
{data.cohort_success.length} successful and {data.cohort_failure.length}{" "}
141-
failing runs.
157+
failed runs.
142158
</p>
143159
</section>
144160
);
@@ -149,7 +165,7 @@ export function CohortComparisonSection({
149165
<div className="flex items-baseline gap-3">
150166
<h3 className="text-sm font-semibold">Successful vs failing agents</h3>
151167
<span className="text-xs text-muted-foreground">
152-
{data.cohort_success.length} successful, {data.cohort_failure.length} failing
168+
{data.cohort_success.length} successful, {data.cohort_failure.length} failed
153169
</span>
154170
</div>
155171
{data.thin_coverage?.length ? (
@@ -160,14 +176,17 @@ export function CohortComparisonSection({
160176
</p>
161177
) : null}
162178
{data.categories.map((cat, i) => (
163-
<div key={i} className="flex flex-col gap-2 border-t pt-3">
179+
<div
180+
key={i}
181+
className="border-border bg-background/40 flex flex-col gap-2 rounded-lg border p-3"
182+
>
164183
<h4 className="text-sm font-medium">
165184
{CATEGORY_LABELS[cat.category] ?? cat.category}
166185
{cat.label ? `: ${cat.label}` : ""}
167186
</h4>
168187
<div className="grid gap-6 md:grid-cols-2">
169188
<div className="flex flex-col gap-2">
170-
<span className="text-xs uppercase tracking-wide text-muted-foreground">
189+
<span className="text-xs uppercase tracking-wide text-emerald-600 dark:text-emerald-400">
171190
Successful
172191
</span>
173192
<ObservationList
@@ -177,8 +196,8 @@ export function CohortComparisonSection({
177196
/>
178197
</div>
179198
<div className="flex flex-col gap-2">
180-
<span className="text-xs uppercase tracking-wide text-muted-foreground">
181-
Failing
199+
<span className="text-xs uppercase tracking-wide text-red-600 dark:text-red-400">
200+
Failed
182201
</span>
183202
<ObservationList
184203
items={cat.failing}

0 commit comments

Comments
 (0)