From beb2b40f7d44f69b16cc156e983432dc6c48f297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Fri, 15 May 2026 18:34:53 +0200 Subject: [PATCH] chore(coach): lift the rail-tray chevrons out of the overlay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mobile history + sources tray triggers used to mount as absolute chevron buttons over the message thread, so they (a) overlapped the first message bubble, (b) sat at a 28 px tap target (`h-7`), and (c) relied on `backdrop-blur` to stay legible — which still failed on busy threads. Lift them into a sub-header strip above the thread: a flex row with two ghost buttons at `min-h-11`. The strip itself carries `xl:hidden` since both rails are inline at xl+; the history trigger keeps its own `lg:hidden` because the history rail mounts inline already at lg+. While the rail surface is in scope, drop the `opacity-0 group-hover:opacity-100` reveal on the history-rail per-row delete button — touch surfaces have no hover, so the affordance was invisible on mobile. The button now sits at `size-11` always-visible; the confirming state still styles via `data-confirming`. Test re-baselined to assert the new strip wrapper + `min-h-11` floor. --- .../coach-drawer-mobile-trays.test.tsx | 30 +++++--- .../coach-panel/coach-drawer-body.tsx | 68 +++++++++++-------- .../insights/coach-panel/history-rail.tsx | 12 +++- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/src/components/insights/coach-panel/__tests__/coach-drawer-mobile-trays.test.tsx b/src/components/insights/coach-panel/__tests__/coach-drawer-mobile-trays.test.tsx index 9261e8486..186a12705 100644 --- a/src/components/insights/coach-panel/__tests__/coach-drawer-mobile-trays.test.tsx +++ b/src/components/insights/coach-panel/__tests__/coach-drawer-mobile-trays.test.tsx @@ -41,18 +41,22 @@ describe(" — mobile rail trays", () => { }); it("hides the history trigger on >=lg and the sources trigger on >=xl", () => { + // v1.4.27 R3d MB2 — the strip wrapper carries `xl:hidden` so the + // sources trigger inherits the breakpoint; the history trigger + // keeps its own `lg:hidden` because the history rail mounts + // inline already on lg+ while the sources rail still needs the + // chevron until xl. const html = render(); + const strip = html.match( + /]*data-slot="coach-drawer-rail-tray-strip"[^>]*>/, + ); + expect(strip?.[0]).toContain("xl:hidden"); + const historyTrigger = html.match( /]*data-slot="coach-drawer-history-tray-trigger"[^>]*>/, ); expect(historyTrigger).not.toBeNull(); expect(historyTrigger?.[0]).toContain("lg:hidden"); - - const sourcesTrigger = html.match( - /]*data-slot="coach-drawer-sources-tray-trigger"[^>]*>/, - ); - expect(sourcesTrigger).not.toBeNull(); - expect(sourcesTrigger?.[0]).toContain("xl:hidden"); }); it("renders the desktop history rail (lg+) and sources rail (xl+)", () => { @@ -95,12 +99,16 @@ describe(" — mobile rail trays", () => { expect(html).toContain("Worauf ich zugreife"); }); - it("the thread region wraps the rail triggers in a relative container", () => { - // The triggers use absolute positioning; the thread region must - // be `relative` for them to anchor inside it. + it("renders the rail triggers in a sub-header strip above the thread", () => { + // v1.4.27 R3d MB2 — the triggers were lifted out of the absolute + // overlay into a sub-header strip so the chevrons sit at a 44 px + // tap target and never overlay the first message bubble. The + // strip lives above the thread within the centre column. const html = render(); - expect(html).toMatch( - /]*data-slot="coach-drawer-thread"[^>]*relative/, + expect(html).toMatch(/data-slot="coach-drawer-rail-tray-strip"/); + const trigger = html.match( + /]*data-slot="coach-drawer-history-tray-trigger"[^>]*>/, ); + expect(trigger?.[0]).toContain("min-h-11"); }); }); diff --git a/src/components/insights/coach-panel/coach-drawer-body.tsx b/src/components/insights/coach-panel/coach-drawer-body.tsx index b92e62727..0832000ea 100644 --- a/src/components/insights/coach-panel/coach-drawer-body.tsx +++ b/src/components/insights/coach-panel/coach-drawer-body.tsx @@ -59,36 +59,48 @@ export function CoachDrawerBody({ {/* Centre — message thread. */}
- {/* v1.4.20 phase B4 — mobile rail tray triggers. Hidden on - `>=lg` because the rails are inline there. */} - - {/* Sources tray trigger stays visible up to xl since the - inline sources rail is xl+ only. */} - + + {/* Sources tray trigger stays visible up to xl since the + inline sources rail is xl+ only. The empty `` to + the left keeps the right-aligned button placement when + the history trigger hides at lg+. */} + + {/* v1.4.27 R3d MB2 — drop the hover-only `opacity-0` + reveal: touch surfaces have no hover, so the delete + affordance was invisible on mobile. The button now + sits at 44 px always-visible per the WCAG 2.5.5 + floor; confirming state stays styled via the + `data-confirming` attribute. */} );