Skip to content

fix(web): time-grid pinned panes occlude scrolled content (opaque backdrop) - #341

Merged
thomasluizon merged 1 commit into
mainfrom
fix/calendar-allday-overlap
Jun 27, 2026
Merged

fix(web): time-grid pinned panes occlude scrolled content (opaque backdrop)#341
thomasluizon merged 1 commit into
mainfrom
fix/calendar-allday-overlap

Conversation

@thomasluizon

Copy link
Copy Markdown
Owner

Fix the all-day band overlapping the hour labels on scroll

The week/interval time-grid's pinned panes (day-header, all-day "DIA INTEIRO" band, left hour gutter) were backed by the translucent var(--bg-card) (rgba(...,0.04) on dark), so when the hourly body scrolled underneath, the 8:00+ gutter labels and column tops bled straight through the all-day band — it looked like overlap. (z-ordering was already correct; the panes were just see-through.)

Fix

The pinned panes now use an opaque backdrop — var(--bg) canvas with the card tint layered on top (linear-gradient(var(--bg-card), var(--bg-card))) — the exact same color but fully occluding scrolled content. Applied to all five pinned sub-elements; the outer card stays intentionally translucent; #339's horizontal scroll + pinned gutter untouched.

Mobile was already correct (separate clipped ScrollViews with a reserved all-day-band height) — no change.

Validation

type-check 3/3; lint 0 errors; web 1752, mobile 725 pass; new regression test asserts the all-day band carries an opaque backdrop.

🤖 Generated with Claude Code

…hours

In the week and interval time-grid (#339), the three pinned panes (the
day-header row, the "DIA INTEIRO" all-day band, and the left hour gutter)
were backed by --bg-card, which is translucent on dark (alpha 0.04). As
the hourly body scrolled underneath, the gutter hour labels and
day-column content bled through the all-day band (the 8:00 label rendered
behind it) and through the gutter. The z-index layering (z-3 header,
z-2 band, z-1 gutter) was already correct; only the backdrop was
see-through.

Back the pinned panes with an opaque equivalent of the card surface
(opaque --bg canvas plus the --bg-card tint layered on top) so they fully
occlude the scrolling content while matching the card's appearance. The
all-day band now reads as its own zone with the hourly grid cleanly
below it, and the horizontal scroll plus pinned gutter still work.

Mobile already isolates the zones with separate clipped scroll regions
and a reserved all-day band height, so it never had the overlap and
needs no change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
orbit-ui-mobile-web Ignored Ignored Jun 27, 2026 10:33pm

Request Review

@sonarqubecloud

Copy link
Copy Markdown

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: PR #341

Scope: PR #341 — fix(web): time-grid pinned panes occlude scrolled content (opaque backdrop)
Recommendation: APPROVE

Summary

PR #341 fixes a visual bleed-through bug in the web calendar time-grid where semi-transparent pinned panes (day header, all-day band, hour gutter) let scrolling body content show through. The fix replaces background: var(--bg-card) with a two-layer CSS backdrop (backgroundColor: var(--bg) + backgroundImage: linear-gradient(var(--bg-card), var(--bg-card))), making the panes opaque while preserving the visual card tint. The change is web-only by design — mobile uses separate clipped ScrollViews that naturally prevent the bleed-through. No Critical or High findings.

Findings

Critical

None

High

None

Medium

None

Low / Info

None

Subagents

Agent Verdict
parity-checker PAIRED — mobile uses separate clipped ScrollViews that naturally prevent bleed-through; bug never existed on mobile; no mobile change required
i18n-syncer IN SYNC — no new user-facing strings; existing allDayLabel/nowLabel keys present in both locales
contract-aligner N/A — no packages/shared types or API endpoint changes
security-reviewer N/A — no orbit-api code changed

Validation

Check Result
Lint N/A (author reports 0 errors; sandbox blocked re-run)
Type check N/A (author reports 3/3 pass; sandbox blocked re-run)
Tests N/A (author reports web 1752 pass; sandbox blocked re-run)
Build (api) N/A — no API changes

Deferred — N/A dimensions & files not verdicted

  • Dimension 5 (No-workaround): N/A — the two-layer CSS backdrop is the correct CSS technique for stacking an opaque base with a translucent tint, not a workaround.
  • Dimension 6 (Type safety): N/A — no new types; as const on pinnedPaneBackground is appropriate.
  • Dimension 7 (console.log): N/A — none introduced.
  • Dimension 11 (Contract drift + backward-compat): N/A — no shared types or API changes.
  • Dimension 12 (Security): N/A — no auth, data, or API surface touched.
  • Dimension 13 (Backend hard rules): N/A — no orbit-api changes.
  • apps/web/__tests__/components/calendar/calendar-time-grid.test.tsx: PASS — new test asserts time-grid-all-day-band carries var(--bg) in its inline style; checking the CSS token name is the correct approach in JSDOM where CSS variables do not resolve.

What's good

  • The two-layer CSS backdrop (backgroundColor opaque base + backgroundImage translucent tint) is the idiomatic technique for this pattern. It preserves the visual card tint while making the pane fully opaque.
  • CARD_BG is correctly retained for the outer card wrapper (line 250), which stays intentionally translucent. No dead code created.
  • pinnedPaneBackground is used at five call sites — extraction is well past the three-use threshold.
  • Token compliance throughout: var(--bg) and var(--bg-card) are canonical semantic tokens; no raw slate values or hardcoded rgba.
  • Parity judgment is architecturally sound — mobile and web have genuinely different scroll mechanisms; the bug never existed on mobile.

Recommendation

Clean, targeted fix with correct technique and a good regression test. Ready to merge.

🤖 Generated with Claude Code

@thomasluizon
thomasluizon merged commit dcf9838 into main Jun 27, 2026
10 checks passed
@thomasluizon
thomasluizon deleted the fix/calendar-allday-overlap branch June 27, 2026 22:52
thomasluizon added a commit that referenced this pull request Aug 20, 2026
The four components are built and rewired. Eleven screens are read, four are
corrected with Thomas, and the rest carry their findings here with the file and
line each was traced to, so the next session does not re-derive them.

Three API tickets came out of the review. #341 is the one that matters: Wrapped
has no endpoint at all. The retrospective is Pro-gated, every window is rolling
and ends today, and "month" is 30 rolling days rather than a calendar month. A
Pro-gated viral loop is not a viral loop.

Also records the traps that cost time: the model picker's silent confirm dialog,
the real paste-to-attachment threshold, and the iframe scroller.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant