From 83503fe7a3bc010f90907d912c7f4eb677495a62 Mon Sep 17 00:00:00 2001 From: Jonathan Hvid Date: Tue, 12 May 2026 14:35:02 +0200 Subject: [PATCH] =?UTF-8?q?fix(route):=20overflow-y:=20visible=20=E2=80=94?= =?UTF-8?q?=20hover=20cards=20never=20clip=20vertically=20again?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The root cause of the hover-clipping we kept band-aiding with larger track-heights: a scroll container with overflow-x: auto implicitly clips on the perpendicular axis too. Explicit overflow-y: visible lets cards expand above and below the track freely. Implementation matches the spec's belt-and-braces pattern. New layered markup: .rr-wrap → position: relative, anchors fades .rr-scroll → overflow-x: auto + overflow-y: visible, padding 60/60/80, scroll-padding 60/60 sides .rr-scroll-inner → structural, no layout effect .rr-track → positioned at the inner wrapper The padding-top: 60px / padding-bottom: 80px on .rr-scroll gives cards room to grow above and below the track without ever hitting a clip boundary, even on browsers that mis-handle the overflow-x/y mix. Edge fades reposition: top: 60px / bottom: 80px (was 0 / 16) so they only cover the track itself, not the overflow padding zones above and below where hover-expanded cards now live. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/settings.local.json | 3 ++- src/components/RoadmapRoute.astro | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 5d46556..224805c 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -45,7 +45,8 @@ "Bash(pnpm db:seed)", "Bash(curl -s -c /tmp/jar.txt -d \"email=lars@virk2.dk&password=cab123\" http://localhost:4321/login -o /dev/null -i)", "Bash(curl -s -c /tmp/jar.txt -d \"email=lars@virk2.dk&password=cab123\" http://localhost:4321/login -o /dev/null)", - "Bash(curl -s -b /tmp/jar.txt http://localhost:4321/roadmap)" + "Bash(curl -s -b /tmp/jar.txt http://localhost:4321/roadmap)", + "Bash(grep -nE \"\\\\.rr-fade-left, \\\\.rr-fade-right|rr-fade-left \\\\{|rr-fade-right \\\\{\" src/components/RoadmapRoute.astro)" ] } } diff --git a/src/components/RoadmapRoute.astro b/src/components/RoadmapRoute.astro index ae32db5..70a073b 100644 --- a/src/components/RoadmapRoute.astro +++ b/src/components/RoadmapRoute.astro @@ -72,7 +72,8 @@ const initialShippingX = lastShippingIndex >= 0 ? layout.itemX[lastShippingIndex
-
+
+
))} +
@@ -239,18 +241,24 @@ const initialShippingX = lastShippingIndex >= 0 ? layout.itemX[lastShippingIndex /* ── Desktop route ──────────────────────────────────────────────── */ .rr-wrap { position: relative; } .rr-scroll { + /* overflow-x: auto + overflow-y: visible is the only thing that lets + hovered cards expand above/below the track without being clipped. + The previous fix bandaged it with extra trackHeight; this is the + real fix. The .rr-scroll-inner wrapper is the spec-recommended + belt-and-braces in case a browser misbehaves on this combination. */ overflow-x: auto; + overflow-y: visible; scroll-snap-type: x mandatory; scroll-behavior: smooth; scrollbar-width: none; - /* 60px is enough for a 220px card centred under a dot 60px from - the edge — card extends 50px past the dot, sits inside the - padded container. */ - padding: 0 60px 8px; + /* Top/bottom give cards room to grow above/below the track. The 60px + sides give the first/last cards room when fully scrolled. */ + padding: 60px 60px 80px; scroll-padding-left: 60px; scroll-padding-right: 60px; } .rr-scroll::-webkit-scrollbar { display: none; } + .rr-scroll-inner { /* structural — keeps the track on its own layer */ } .rr-track { position: relative; } .rr-path { position: absolute; top: 0; left: 0; pointer-events: none; } @@ -376,11 +384,13 @@ const initialShippingX = lastShippingIndex >= 0 ? layout.itemX[lastShippingIndex margin: 0; } - /* Edge fades */ + /* Edge fades cover only the track itself — the top/bottom padding + zones (60/80) on .rr-scroll exist so hover cards can overflow there + without clipping, so the fades shouldn't paint over them. */ .rr-fade-left, .rr-fade-right { position: absolute; - top: 0; - bottom: 16px; + top: 60px; + bottom: 80px; pointer-events: none; transition: opacity .25s ease; }