diff --git a/src/components/insights/__tests__/health-score-card.test.tsx b/src/components/insights/__tests__/health-score-card.test.tsx index 723b438dd..a89e0c868 100644 --- a/src/components/insights/__tests__/health-score-card.test.tsx +++ b/src/components/insights/__tests__/health-score-card.test.tsx @@ -260,6 +260,50 @@ describe("", () => { expect(progressMatch?.[1]).toBe("100%"); }); + // ── v1.4.28 R3c-Insights — equal-height contract (FB-H1/H2) ─────── + it("opts the wrapper into the parent's flex-stretch row via h-full + flex-col", () => { + // The hero strip's row now uses `items-stretch`; the card has to + // declare `h-full flex flex-col` so the stretched shell actually + // affects its rendered height. Pin both classes so a refactor + // can't silently drop one. + const html = ssr( + , + ); + const cardOpen = html.match( + /]*data-slot="health-score-card"[^>]*>/, + ); + expect(cardOpen).not.toBeNull(); + expect(cardOpen?.[0]).toContain("h-full"); + expect(cardOpen?.[0]).toContain("flex"); + expect(cardOpen?.[0]).toContain("flex-col"); + }); + + it("pins the disclaimer to the bottom of the stretched card via mt-auto", () => { + // Without `mt-auto` the disclaimer rides directly under the + // provenance accordion and leaves the recovered space below the + // disclaimer instead of between the body and the footer. The + // FB-H2 contract is "score number on top, disclaimer on bottom, + // recovered space in the middle". + const html = ssr( + , + ); + const disclaimerOpen = html.match( + /]*data-slot="health-score-card-disclaimer"[^>]*>/, + ); + expect(disclaimerOpen).not.toBeNull(); + expect(disclaimerOpen?.[0]).toContain("mt-auto"); + }); + it("exposes the progressbar role + ARIA values for screen readers", () => { const html = ssr( ", () => { // is present so the panel sits beside the title block on desktop. expect(html).toContain("lg:flex-row"); }); + + // ── v1.4.28 R3c-Insights — equal-height contract (FB-H1/H2) ─────── + it("stretches the row's cross-axis when the HealthScore card mounts (md+/lg+)", () => { + // Per Inv-4 the right column painted 75-110 px shorter than the + // left column on desktop. Switching the parent flex row from + // `items-start` to `items-stretch` gives the card a stretched + // shell to grow into. The class is load-bearing for FB-H1/H2 — + // if a future refactor reverts to `items-start` the height gap + // returns. + const html = render( + , + ); + expect(html).toContain("md:items-stretch"); + expect(html).toContain("lg:items-stretch"); + expect(html).not.toContain("md:items-start"); + }); + + it("does NOT stretch the row when healthScore is omitted", () => { + // Pin the negative case so a future refactor can't blanket-apply + // the stretch contract on the no-score layout (no right column + // means nothing to stretch toward). + const html = render(); + expect(html).not.toContain("md:items-stretch"); + }); }); diff --git a/src/components/insights/health-score-card.tsx b/src/components/insights/health-score-card.tsx index be8221d8b..4944b2024 100644 --- a/src/components/insights/health-score-card.tsx +++ b/src/components/insights/health-score-card.tsx @@ -241,9 +241,16 @@ export function HealthScoreCard({ // (~36 % at md, ~40 % at xl) but cede headroom when the parent // narrows. "w-full md:basis-[22rem] md:shrink-0 md:grow-0 xl:basis-[26rem]", + // v1.4.28 R3c-Insights — stretch to match the parent's + // `items-stretch` row height (FB-H1/H2). `h-full` + an inner + // flex column lets the disclaimer ride to the bottom with + // `mt-auto` so the headline number stays at the top and the + // recovered vertical space pads through the middle rather + // than under the disclaimer. + "flex h-full flex-col", )} > -
+

{t("insights.healthScore.disclaimer")}

diff --git a/src/components/insights/hero-strip.tsx b/src/components/insights/hero-strip.tsx index 52a270a8a..7d2f936f6 100644 --- a/src/components/insights/hero-strip.tsx +++ b/src/components/insights/hero-strip.tsx @@ -151,11 +151,23 @@ export function HeroStrip({ * `lg:` modifiers alongside so existing snapshot/assertion tests * that grep for `lg:flex-row` continue to find it. */} + {/* + * v1.4.28 R3c-Insights — switch the row's cross-axis alignment + * from `items-start` to `items-stretch` so the right-column + * HealthScore card grows to match the left column's natural + * height (greeting + subtitle + baseline meta + action row + + * suggested-prompts strip). Per Inv-4 the card was painting + * 75-110 px shorter than the left column on desktop; the + * stretch contract pulls the card's bottom edge down to the + * "Wirkt mein Medikament?" chip. The card itself owns + * `h-full` + `mt-auto` on its disclaimer to redistribute the + * recovered space without visual jank. + */}