fix(web): lift app-shell topbar above main so the profile menu is usable (BUNYIP-408) #398

Merged
longjacksonle merged 1 commit from fix/BUNYIP-408-profile-menu-stacking into main 2026-07-28 21:37:10 +02:00

Problem

The avatar profile menu (added in #397) is one shared component (profile_menu), but it behaved differently per shell:

  • Public header (a8n.systems landing): dropdown opens correctly, "Profile" gets its filled hover background, clicks work. (ref-main.png)
  • Dashboard / admin shells (e.g. /settings, /admin): the dropdown panel looks cut off, "Profile" / "Log out" show no hover treatment, and clicking them does nothing. (ref-error.png)

Root cause

Stacking context, not divergent markup. The public header carries sticky top-0 z-50, so its whole subtree - including the dropdown that overflows below the bar - paints above the page. app_topbar (the dashboard/admin top bar) had no z-index, so the scrolling <main> content, which comes later in the DOM, painted over the overflowing dropdown. The page cards visually clipped the panel and intercepted the hover + click events destined for the menu rows.

Fix

Give app_topbar's <header> relative z-40: a stacking context above the z-auto main content and below the z-50 toast layer. This single change restores the panel, the row hover highlight, and the clicks across both app shells. No change to the shared profile_menu markup, so the public header is unaffected.

Verification

  • just check-container green (fmt + clippy -D warnings + all test binaries).
  • Layering rationale: dropdown rows are now the top-most paint in the topbar's stacking context, so they receive pointer events instead of the cards beneath them; toasts (z-50, fixed) still render above the menu.

🤖 Generated with Claude Code

## Problem The avatar profile menu (added in #397) is one shared component (`profile_menu`), but it behaved differently per shell: - **Public header** (a8n.systems landing): dropdown opens correctly, "Profile" gets its filled hover background, clicks work. (ref-main.png) - **Dashboard / admin shells** (e.g. /settings, /admin): the dropdown panel looks cut off, "Profile" / "Log out" show no hover treatment, and clicking them does nothing. (ref-error.png) ## Root cause Stacking context, not divergent markup. The public `header` carries `sticky top-0 z-50`, so its whole subtree - including the dropdown that overflows below the bar - paints above the page. `app_topbar` (the dashboard/admin top bar) had no z-index, so the scrolling `<main>` content, which comes later in the DOM, painted over the overflowing dropdown. The page cards visually clipped the panel and intercepted the hover + click events destined for the menu rows. ## Fix Give `app_topbar`'s `<header>` `relative z-40`: a stacking context above the `z-auto` main content and below the `z-50` toast layer. This single change restores the panel, the row hover highlight, and the clicks across both app shells. No change to the shared `profile_menu` markup, so the public header is unaffected. ## Verification - `just check-container` green (fmt + clippy `-D warnings` + all test binaries). - Layering rationale: dropdown rows are now the top-most paint in the topbar's stacking context, so they receive pointer events instead of the cards beneath them; toasts (`z-50`, fixed) still render above the menu. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(web): lift the app-shell topbar above main so the profile menu is usable (BUNYIP-408)
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 1m33s
Check / fmt + clippy + build + tests (pull_request) Successful in 23m56s
Create release / Create release from merged PR (pull_request) Has been skipped
94dfd8f218
The profile-menu dropdown is a single shared component (`profile_menu`), but it behaved differently between shells: in the public header it opened correctly with working hover + clicks, while in the dashboard and admin shells it looked cut off, its rows showed no hover treatment, and clicking them did nothing.

Root cause is stacking context, not divergent markup. The public `header` carries `sticky top-0 z-50`, so its whole subtree - including the dropdown that overflows below the bar - paints above the page. `app_topbar` had no z-index, so the scrolling `<main>` content (which comes later in the DOM) painted over the overflowing dropdown: the panel was visually clipped by the page cards, and those cards intercepted the hover and click events meant for the menu rows.

Fix: give `app_topbar`'s `<header>` `relative z-40`, a stacking context above the `z-auto` main content and below the `z-50` toast layer. One change restores the cut-off panel, the row hover highlight, and the clicks in both app shells, with no markup change to the shared component.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L5dcYueNHByRnWJDYoDX1W
longjacksonle scheduled this pull request to auto merge when all checks succeed 2026-07-28 21:13:54 +02:00
longjacksonle deleted branch fix/BUNYIP-408-profile-menu-stacking 2026-07-28 21:37:10 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!398
No description provided.