fix(mobile): keep Coach composer above the bottom nav, restore full hub labels

Size the full-page Coach surface to clear the mobile BottomNav band plus the
iOS safe area so the docked composer and Stop control never sit under the nav;
desktop full-bleed height is unchanged (the nav is mobile-only).

Stop truncating the More-hub labels: shrink the label type and allow a
two-line clamp so long words (German Benachrichtigungen, and the long es/fr/it
labels) read in full instead of ellipsising.

Raise the lab reading-history edit/delete controls to 44px on touch
(compact on desktop), and drop the lab-detail Add button to icon-only on the
narrowest phones.
This commit is contained in:
Marc-André Bombeck committed 2026-06-20 17:15:35 +02:00
1 parent 1706b67dcf
commit 8ef61b02fe
4 files changed
+31 -14

No files matched your search

+9 -1
View File
@@ -69,7 +69,15 @@ export default function CoachPage() {
// `<CoachConversation>` paints directly onto the page so it reads as
// one continuous conversation, not a window inside a window. The
// separate bottom-right FAB/overlay drawer stays the compact surface.
className="bg-background -mx-4 -mt-6 -mb-20 flex h-[calc(100dvh-4rem)] min-h-[32rem] flex-col overflow-hidden md:-mx-6"
//
// v1.18.10 (W10) — height is mobile-aware. The fixed `<BottomNav>`
// (64px + iOS home-indicator inset) is mobile-only; the desktop
// full-bleed layout has no bottom nav. On mobile the page must subtract
// the TopBar (`4rem`) AND the BottomNav band (`4rem` +
// `env(safe-area-inset-bottom)`) so the docked composer / Stop control
// always clears the nav instead of sitting under it. On `md+` the nav
// is hidden, so the page reclaims the full height below the TopBar.
className="bg-background -mx-4 -mt-6 -mb-20 flex h-[calc(100dvh-8rem-env(safe-area-inset-bottom,0px))] min-h-[32rem] flex-col overflow-hidden md:-mx-6 md:h-[calc(100dvh-4rem)]"
>
<CoachConversation
surface="page"
+7 -2
View File
@@ -165,10 +165,15 @@ export function LabBiomarkerDetail({ biomarkerId }: { biomarkerId: string }) {
/>
<Button
onClick={() => setAddOpen(true)}
className="min-h-11 shrink-0 sm:min-h-9"
// v1.18.10 (W10) — on the narrowest phones the h1 + Edit + Delete +
// text "Add" button crowd the row and truncate the title hard.
// Drop the Add button to icon-only under `sm` (label kept for
// screen readers via `aria-label`); the full text returns at `sm+`.
className="min-h-11 min-w-11 shrink-0 sm:min-h-9 sm:min-w-0"
aria-label={t("labs.addResult")}
>
<Plus className="h-4 w-4" />
{t("labs.addResult")}
<span className="hidden sm:inline">{t("labs.addResult")}</span>
</Button>
</div>
</div>
+4 -2
View File
@@ -228,7 +228,9 @@ export function LabHistoryList({ readings }: { readings: LabResultDto[] }) {
<Button
size="icon"
variant="ghost"
className="size-9"
// v1.18.10 (W10) — 44px touch target on mobile (WCAG 2.5.5),
// compact 36px on desktop. The primary edit control for a row.
className="size-11 sm:size-9"
onClick={() => void openEdit(r)}
aria-label={t("labs.editReading")}
>
@@ -239,7 +241,7 @@ export function LabHistoryList({ readings }: { readings: LabResultDto[] }) {
title={t("labs.deleteConfirmTitle")}
description={t("labs.deleteConfirmDescription")}
confirmLabel={t("labs.deleteReading")}
className="size-9"
className="size-11 sm:size-9"
iconClassName="h-4 w-4"
/>
</div>
+11 -9
View File
@@ -247,16 +247,18 @@ export function BottomNav() {
)}
>
<item.icon className="h-5 w-5 shrink-0" aria-hidden="true" />
{/* v1.18.10 (W7) — keep every label on ONE line. The longest
single-word label (German "Benachrichtigungen") used to
wrap to two lines via `break-words`, which left the tile
visually unbalanced beside its single-line neighbours.
`min-w-0` lets the flex child shrink below its content
width and `truncate` (nowrap + ellipsis) trims the
overflow instead of breaking the word. `title` keeps the
full label discoverable on hover/long-press. */}
{/* v1.18.10 (W10) — show the FULL label, never an ellipsis
that hides meaning. The W7 `truncate` clipped long words
("Benachrichtigungen" → "Benachrichtigun…"); the goal is a
readable label, not a balanced tile. Shrink the type to
`text-xs` so long single-word locales (de/es/fr/it) fit on
one line at ~110px, and allow a 2-line `line-clamp-2`
fallback (with `[overflow-wrap:anywhere]` so a long word
breaks rather than overflowing) for the rare label that
still cannot fit one line. `min-w-0` lets the flex child
shrink below its content width. */}
<span
className="min-w-0 truncate text-sm leading-tight font-medium"
className="line-clamp-2 min-w-0 text-xs leading-tight font-medium [overflow-wrap:anywhere]"
title={t(item.tKey)}
>
{t(item.tKey)}