fix(dashboard): extend rail edge fades to the track clipping edge (#1731)

This commit is contained in:
4gray authored and GitHub committed 2026-09-29 17:30:04 +02:00
1 parent bcc6186c88
commit 0f768b6e20
3 files changed
+24 -8

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
---
type: fix
area: dashboard
---
Dashboard rails no longer show a thin strip of the partly visible card past the soft edge fade, and the focus outline of the first or last card in a rail is no longer cut off.
+4
View File
@@ -143,6 +143,10 @@ hooks: `dashboard-hero`, `dashboard-hero-slide` (`data-hero-kind`),
optional `aspectRatio` (default `'2 / 3'`), optional `testId`.
2. Behavior: horizontal flex track with `scroll-snap-type: x mandatory`.
3. Chevron buttons fade in on hover (desktop only via `@media (hover: none)`).
Edge fades follow the chevrons' visibility. The track bleeds
`--rail-bleed` past the viewport on every side so card focus rings and
hover lift are not clipped; the fades are offset by the same variable so
they reach the track's clipping edge and no card strip shows beyond them.
4. Cards are keyboard-focusable router links; `scroll-snap-align: start`
means arrow-key nav lands on card boundaries.
5. Image handling: `loading="lazy"`, `decoding="async"`, fallback icon tile
@@ -3,6 +3,11 @@
--rail-card-width: var(--cover-rail-width, 172px);
--rail-gap: var(--cover-gap, 14px);
--rail-radius: 12px;
// How far the scrolling track bleeds past the viewport on every side:
// room for a card's focus ring (2px outline + 3px offset) plus its 2px
// hover lift, so neither is clipped. The track clips partially visible
// cards at this outer edge, so the edge fades extend by the same amount.
--rail-bleed: 8px;
}
.rail {
@@ -81,13 +86,14 @@
// Soft edge gradients hint at horizontal scroll without any interaction.
// Anchored to the viewport so they appear/disappear in sync with the
// chevrons' `.rail__chev--visible` state.
// chevrons' `.rail__chev--visible` state, but offset by the track bleed
// so each fade ends exactly where the track clips the partial card.
&::before,
&::after {
content: '';
position: absolute;
top: 0;
bottom: 0;
top: calc(-1 * var(--rail-bleed));
bottom: calc(-1 * var(--rail-bleed));
width: 32px;
pointer-events: none;
z-index: 1;
@@ -96,7 +102,7 @@
}
&::before {
left: 0;
left: calc(-1 * var(--rail-bleed));
background: linear-gradient(
to right,
var(--app-content-bg, #161a22) 0%,
@@ -105,7 +111,7 @@
}
&::after {
right: 0;
right: calc(-1 * var(--rail-bleed));
background: linear-gradient(
to left,
var(--app-content-bg, #161a22) 0%,
@@ -135,10 +141,10 @@
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x mandatory;
scroll-padding-inline-start: 4px;
scroll-padding-inline-start: var(--rail-bleed);
scrollbar-width: none;
padding: 4px;
margin: -4px;
padding: var(--rail-bleed);
margin: calc(-1 * var(--rail-bleed));
&::-webkit-scrollbar {
display: none;