From 163e2abb606439627ee2af5578fa25581ef391ae Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 7 Sep 2026 09:20:57 +0000 Subject: [PATCH 1/3] Keep three compare slots two-across until lg so titles stay readable PR #2681 moved three slots to three-across from the sm breakpoint. That fits the tiles but not their titles: at around 660px each tile leaves roughly 100px for text, so "Major depressive disorder" rendered as "Major depressi..." and "Persistent depressive disorder" as "Persistent depressi...". Truncated names are the fault that redesign existed to fix, reintroduced in the one width band it was never checked at. Three slots go back to two-across until lg. A third tile wrapping to its own row reads better than three clipped ones. The four-slot case keeps the 2x2 layout from #2681, which was the real improvement there. Verified against the running dev server at 660px and 1280px: no title is clipped at either width (scrollHeight equals clientHeight on every tile title), where 660px clipped two of three before the change. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015JVB9VaJjH9dKL7gJ6ZGu3 --- src/components/compare/compare-slot-strip.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/compare/compare-slot-strip.tsx b/src/components/compare/compare-slot-strip.tsx index 7cea7b3396..d82ed12c12 100644 --- a/src/components/compare/compare-slot-strip.tsx +++ b/src/components/compare/compare-slot-strip.tsx @@ -9,12 +9,18 @@ import { compareSlotBadgeBase, compareSlotBadgeClass } from "@/components/compar import { cn } from "@/components/ui-primitives"; /** - * Slot columns follow the slot count, so three slots fill a row of three and four - * fill two rows of two. A fixed `lg:grid-cols-3` orphaned the fourth tile alone. + * Slot columns follow the slot count, so four slots fill two rows of two rather + * than leaving the fourth tile alone on a row of its own under `lg:grid-cols-3`. + * + * Three slots stay two-across until `lg`. Three-across from `sm` fits the tiles + * but not their titles: at ~660px each tile leaves about 100px for text, which + * truncates the very names this layout exists to keep readable ("Major + * depressive disorder" became "Major depressi..."). A third tile wrapping to its + * own row reads better than three clipped ones. */ function slotGridColumns(count: number) { if (count >= 4) return "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4"; - if (count === 3) return "grid-cols-1 sm:grid-cols-3"; + if (count === 3) return "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"; return "grid-cols-1 sm:grid-cols-2"; } From a769c7d7928945938a8335a843d4189c68bf6118 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 7 Sep 2026 09:43:05 +0000 Subject: [PATCH 2/3] Size compare slot columns by the strip's width, not the viewport's Codex review on this PR was right: lg is not a proxy for usable width. The desktop sidebar takes 20rem expanded and 5.25rem collapsed, so the same lg viewport hands this strip either ~876px or ~640px. Reproduced on /dsm/compare at 1024px with the sidebar expanded: the strip is 640px and two of three titles clip, which is the fault the previous commit set out to fix. The same review also reported a clip at 1280px expanded; that one did not reproduce (strip 896px, no title clipped). The strip now declares @container and the column rules key off its own width. Thresholds are measured, not guessed: forcing each column count and sweeping the strip width, the last width that clips a title is 560px at two columns, 864px at three and 1152px at four. Each breakpoint sits just above its measured floor. Swept 390px to 1920px against both sidebar states: no title clips in any configuration on this page. Two side effects, both improvements. A 640px viewport now shows one column rather than two, because a 592px strip was below the two-column floor and clipped. A 1024px viewport with the sidebar collapsed shows two columns rather than three, trading a column for the headroom that longer therapy titles need. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015JVB9VaJjH9dKL7gJ6ZGu3 --- src/components/compare/compare-slot-strip.tsx | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/components/compare/compare-slot-strip.tsx b/src/components/compare/compare-slot-strip.tsx index d82ed12c12..87a8728ef5 100644 --- a/src/components/compare/compare-slot-strip.tsx +++ b/src/components/compare/compare-slot-strip.tsx @@ -9,19 +9,23 @@ import { compareSlotBadgeBase, compareSlotBadgeClass } from "@/components/compar import { cn } from "@/components/ui-primitives"; /** - * Slot columns follow the slot count, so four slots fill two rows of two rather - * than leaving the fourth tile alone on a row of its own under `lg:grid-cols-3`. + * Slot columns follow the slot count against the strip's own width, not the + * viewport's. A viewport breakpoint is the wrong signal here because the desktop + * sidebar takes 20rem when expanded and 5.25rem when collapsed, so the same + * `lg` viewport hands this strip either ~876px or ~640px. Keying off `lg` + * truncated titles in the expanded state — the fault this layout exists to + * prevent. * - * Three slots stay two-across until `lg`. Three-across from `sm` fits the tiles - * but not their titles: at ~660px each tile leaves about 100px for text, which - * truncates the very names this layout exists to keep readable ("Major - * depressive disorder" became "Major depressi..."). A third tile wrapping to its - * own row reads better than three clipped ones. + * Thresholds are measured, not guessed. Forcing each column count and sweeping + * the strip width on `/dsm/compare` (longest title "Persistent depressive + * disorder (dysthymia)"), the last width that clips a title is 560px at two + * columns, 864px at three and 1152px at four. Each breakpoint below sits just + * above its measured floor, so a tile always has room for two lines of title. */ function slotGridColumns(count: number) { - if (count >= 4) return "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4"; - if (count === 3) return "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"; - return "grid-cols-1 sm:grid-cols-2"; + if (count >= 4) return "grid-cols-1 @min-[38rem]:grid-cols-2 @min-[74rem]:grid-cols-4"; + if (count === 3) return "grid-cols-1 @min-[38rem]:grid-cols-2 @min-[55rem]:grid-cols-3"; + return "grid-cols-1 @min-[38rem]:grid-cols-2"; } function CompareSlotTile({ @@ -168,7 +172,7 @@ export function CompareSlotStrip({ const pickerButtonLabel = filledCount === 0 && actionLabel ? actionLabel : changeLabel; return ( -
+
{showPipSummary ? (
Date: Mon, 7 Sep 2026 10:47:50 +0000 Subject: [PATCH 3/3] Widen the phone compare rail so long titles are not clipped The phone snap rail capped tiles at 11.5rem. Measured on /dsm/compare at 390px, that left the title 86px once the badge and the 48px clear-button gutter were taken out, so "Persistent depressive disorder (dysthymia)" clipped even at the three-line clamp. It is the same fault as the desktop one this PR started with, in the layout the grid rules never reached: they are inert under display flex. Swept tile width against the clear gutter at 390px: 224px of tile still clips, 248px does not. The rail now runs 15.5rem to 17rem. Shrinking the gutter instead was rejected because the clear button is a 48px tap target and the repo holds production targets at 48px. Verified at 360, 390, 430 and 540px: no title clipped, no page overflow, and the 264px tile on a 358px strip still shows the next tile, so the rail keeps its scroll affordance. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015JVB9VaJjH9dKL7gJ6ZGu3 --- src/components/compare/compare-slot-strip.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/compare/compare-slot-strip.tsx b/src/components/compare/compare-slot-strip.tsx index 87a8728ef5..c0d2d83533 100644 --- a/src/components/compare/compare-slot-strip.tsx +++ b/src/components/compare/compare-slot-strip.tsx @@ -258,7 +258,15 @@ export function CompareSlotStrip({ key={`${slot.label}-${index}`} className={cn( pair && "contents", - compactRail && "min-w-[9.75rem] max-w-[11.5rem] shrink-0 snap-start sm:min-w-0 sm:max-w-none", + compactRail && + // Phone rail tile width. 11.5rem left the title 86px once the + // badge and the 48px clear-button gutter were taken out, which + // clipped "Persistent depressive disorder (dysthymia)" even at + // three lines. Measured on `/dsm/compare` at 390px: 224px of + // tile still clips, 248px does not. 15.5rem is the first clean + // width, and a 358px strip still shows ~110px of the next tile, + // so the rail keeps its scroll affordance. + "min-w-[15.5rem] max-w-[17rem] shrink-0 snap-start sm:min-w-0 sm:max-w-none", )} >