From 1b0e81ae425d0d166bfb92be734ad27a3be8cc43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 16 May 2026 01:45:03 +0200 Subject: [PATCH] fix(targets): make the coach launch an icon-only affordance The per-card Coach CTA was rendering a labelled ghost pill (chat glyph + 'Coach fragen' text). On a card already carrying a status pill, range bar, consistency strip, headline number, edit cog and a source link, the labelled pill dominated the optical hierarchy. Drop the visible label, keep the chat-bubble glyph, and surface the affordance via aria-label + title so screen readers and tooltips still announce 'Ask Coach' / 'Coach fragen'. Collapse the footer flex container to a single horizontal row at every breakpoint now that the button is icon-sized. --- .../__tests__/target-coach-button.test.tsx | 8 +++++++- src/components/targets/target-card.tsx | 19 +++++++++---------- .../targets/target-coach-button.tsx | 19 +++++++++++++++---- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/components/targets/__tests__/target-coach-button.test.tsx b/src/components/targets/__tests__/target-coach-button.test.tsx index 650968cfa..ea017ac77 100644 --- a/src/components/targets/__tests__/target-coach-button.test.tsx +++ b/src/components/targets/__tests__/target-coach-button.test.tsx @@ -28,7 +28,13 @@ describe("", () => { it("renders the button when aiEnabled is true", () => { const html = render({ ...baseProps, aiEnabled: true }); expect(html).toContain('data-slot="target-coach-cta"'); - expect(html).toContain("Ask Coach"); + // v1.4.28 FB-L1 — the affordance is now icon-only; the label + // survives as an aria-label + title so screen readers + tooltips + // still surface "Ask Coach" / "Coach fragen". + expect(html).toContain('aria-label="Ask Coach"'); + expect(html).toContain('title="Ask Coach"'); + // No visible text label — only the chat-bubble glyph. + expect(html).not.toMatch(/>Ask Coach { diff --git a/src/components/targets/target-card.tsx b/src/components/targets/target-card.tsx index 1bc0c22a7..b39f05879 100644 --- a/src/components/targets/target-card.tsx +++ b/src/components/targets/target-card.tsx @@ -656,20 +656,19 @@ export function TargetCard({ )} - {/* Row 6: footer. Mobile-first reflow: - - default (<640px): stack vertically; the Coach CTA - spans full width so the touch target is generous, the - source link sits beneath it right-aligned. - - sm+ (≥640px): horizontal row, Coach left + source right. - `mt-auto` pins to card bottom so grid cells align. */} -
+ {/* Row 6: footer. v1.4.28 FB-L1 — the Coach CTA is now an + icon-only affordance (chat-bubble glyph + aria-label), so + the row stays horizontal at every breakpoint: icon left, + source link right. `mt-auto` pins to card bottom so grid + cells align. */} +
{aiEnabled && ( )} {sourceLink ? ( @@ -677,13 +676,13 @@ export function TargetCard({ href={sourceLink} target="_blank" rel="noopener noreferrer" - className="text-muted-foreground hover:text-foreground inline-flex items-center gap-1 self-end text-xs sm:ml-auto sm:self-auto" + className="text-muted-foreground hover:text-foreground ml-auto inline-flex items-center gap-1 text-xs" > {target.source}