From ae82b3e484dac936214918b4c94301ee34e32300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Tue, 2 Jun 2026 10:00:02 +0200 Subject: [PATCH] fix(insights): style the fallback trend caption like the advisor caption Extract the advisor caption's bordered card + icon + foreground prose shell into a shared TrendCaptionCard and render the additive-metric fallback caption through it, so the Trends-row captions read with one typography instead of the plain muted line standing out below the chart. The two paths now share a single presentational shell and can't drift apart. --- src/components/insights/trend-annotation.tsx | 93 +++++++++++++------- src/components/insights/trends-row.tsx | 18 ++-- 2 files changed, 74 insertions(+), 37 deletions(-) diff --git a/src/components/insights/trend-annotation.tsx b/src/components/insights/trend-annotation.tsx index 3ebdc243a..009528e0a 100644 --- a/src/components/insights/trend-annotation.tsx +++ b/src/components/insights/trend-annotation.tsx @@ -43,6 +43,55 @@ export type TrendAnnotationConfidenceBand = "low" | "moderate" | "high"; export type TrendAnnotationStatus = "pending" | "needs_data" | "generated"; +/** + * Shared presentational shell for a filled trend caption — the bordered + * card + Sparkles affordance + `text-foreground` prose treatment. Both + * the advisor-authored annotation (the legacy triple) and the additive + * metric's standard description (`captionKey`) render through this shell + * so the Trends row reads with a single typographic rhythm and the two + * paths can't drift apart. `children` carries the line(s) below the + * caption prose (e.g. a confidence chip). `slot` / `metric` pass through + * to the wrapper's `data-*` hooks so each call site keeps its own + * test-stable selector. + */ +export function TrendCaptionCard({ + text, + slot, + metric, + children, +}: { + text: string; + slot: string; + metric: string; + children?: React.ReactNode; +}) { + return ( +
+
+ ); +} + interface TrendAnnotationProps { /** The metric this annotation describes. Drives the empty-state copy. */ metric: "bp" | "weight" | "mood"; @@ -122,36 +171,20 @@ export function TrendAnnotation({ } return ( -
-
+ {confidence ? ( + + {t(CONFIDENCE_LABEL_KEY[confidence])} + + ) : null} + ); } diff --git a/src/components/insights/trends-row.tsx b/src/components/insights/trends-row.tsx index 77bc0e29d..1bfc94499 100644 --- a/src/components/insights/trends-row.tsx +++ b/src/components/insights/trends-row.tsx @@ -13,6 +13,7 @@ import { } from "@/lib/insights/trend-chart-select"; import { TrendAnnotation, + TrendCaptionCard, type TrendAnnotationConfidenceBand, type TrendAnnotationStatus, } from "./trend-annotation"; @@ -216,13 +217,16 @@ export function TrendsRow({ // v1.8.6 W8 — additive metrics carry no advisor // annotation. Paint the metric's standard one-line // description so the card is never caption-less. -

- {t(config.captionKey)} -

+ // v1.8.7 W-E — render that description through the same + // `` shell the advisor caption uses, so + // the fallback caption shares the bordered card, Sparkles + // affordance, and `text-foreground` typography rather than + // standing out as a plain muted line. + )} );