style(insights): trends-row equal-height + mood-chart gridline density parity

Two coupled fixes pinned by Marc on the v1.4.25 W3 walkthrough:

1. Trends row equal-height
   The three trend cards (BP / Weight / Mood) on /insights sit in a
   `grid-cols-1 md:grid-cols-3` grid. The `min-h-[300px]` floor
   guarantees a sensible mobile height, but the AI annotation prose
   varies card-to-card on desktop, leaving the tallest card pushing
   only its own row member down — siblings stayed short. Added
   `md:auto-rows-fr md:items-stretch` on the grid container and
   `h-full` on each direct child so the row pins every card to the
   tallest member's height.

2. Mood chart gridline density parity
   The mood chart's YAxis pins ticks to [1,2,3,4,5] (mood scale). By
   default Recharts syncs CartesianGrid coordinates with YAxis ticks,
   so the mini variant painted five horizontal lines while the
   BP/Weight/Pulse minis painted six (their auto-generated YAxis
   ticks land on ~six bands in typical health ranges). Added a
   `horizontalCoordinatesGenerator` that emits six evenly-spaced
   lines inside the plot area so the trends row reads as a single
   rhythm.

Both changes are presentational — no chart data shape changes, no
behaviour changes, no API touched.
This commit is contained in:
Marc-André Bombeck committed 2026-05-14 12:00:45 +02:00
1 parent beb61b78bf
commit 60541803f2
2 files changed
+32 -6

No files matched your search

+22
View File
@@ -621,10 +621,32 @@ export function MoodChart({
data={chartDataWithCompare ?? chartData}
margin={{ top: 10, right: 8, bottom: 8, left: 8 }}
>
{/* v1.4.25 W3 — the mood chart's YAxis is pinned to
five mood-score ticks ([1,2,3,4,5]), which Recharts
syncs with CartesianGrid by default. That left the
mini variant painting five horizontal lines while
the BP / Weight / Pulse minis painted six (their
auto-generated YAxis ticks land on six bands in
typical health ranges). The explicit coordinates
generator below produces six evenly-spaced lines
so the trends row reads as a single rhythm. */}
<CartesianGrid
strokeDasharray="3 3"
stroke="hsl(var(--border))"
opacity={0.5}
horizontalCoordinatesGenerator={({ offset }) => {
// `offset` carries the chart's plot-area metrics.
// Six evenly-spaced y-coordinates inside the plot
// area (top + 4 intermediate + bottom) match the
// density of the BP/Weight/Pulse minis.
const top = offset.top ?? 0;
const height = offset.height ?? 0;
if (height <= 0) return [];
const lines = 6;
return Array.from({ length: lines }, (_, i) =>
Math.round(top + (height * i) / (lines - 1)),
);
}}
/>
{showBands &&
VALUE_BANDS.map((band) => (
+10 -6
View File
@@ -98,13 +98,17 @@ export function TrendsRow({ annotations, confidence }: TrendsRowProps) {
three cards on visibly different baselines. Each card is now
a flex column with `min-h-[300px]` so the chart anchors to
the top and the annotation grows downward into a shared
minimum height. The grid + min-h together preserve the visual
rhythm even on a row where only one annotation is multi-line. */}
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
minimum height.
v1.4.25 W3 — strengthen the equal-height contract with
`md:auto-rows-fr` + `md:items-stretch` on the grid and
`h-full` on each card so the tallest annotation still pins
every row member to a single baseline. The `min-h-[300px]`
floor stays in place for the single-column mobile view. */}
<div className="grid grid-cols-1 gap-4 md:auto-rows-fr md:grid-cols-3 md:items-stretch">
<div
data-slot="trends-row-card"
data-metric="bp"
className="flex min-h-[300px] flex-col gap-2"
className="flex h-full min-h-[300px] flex-col gap-2"
>
<HealthChart
types={["BLOOD_PRESSURE_SYS", "BLOOD_PRESSURE_DIA"]}
@@ -123,7 +127,7 @@ export function TrendsRow({ annotations, confidence }: TrendsRowProps) {
<div
data-slot="trends-row-card"
data-metric="weight"
className="flex min-h-[300px] flex-col gap-2"
className="flex h-full min-h-[300px] flex-col gap-2"
>
<HealthChart
types={["WEIGHT"]}
@@ -141,7 +145,7 @@ export function TrendsRow({ annotations, confidence }: TrendsRowProps) {
<div
data-slot="trends-row-card"
data-metric="mood"
className="flex min-h-[300px] flex-col gap-2"
className="flex h-full min-h-[300px] flex-col gap-2"
>
<MoodChart title={t("charts.mood")} mini />
<TrendAnnotation