Fix #405: opaque popovers + guard #408

Merged
crueber merged 1 commit from fix/issue-405 into main 2026-09-12 19:27:10 +00:00
Owner

Fixes #405 (IdentityMenu translucent in dark mode) + systemic guard (both option 1 structural default AND static test pin).

Root cause: IdentityMenu dropdown is card absolute with none of the #37/#115/#278 enumerated hook classes, so it rendered the shared .card dark:bg-zinc-900/70.

Changes (4 files):

  • web/src/ui.css: opaque background is now the STRUCTURAL default — .card.absolute, .card.fixed { @apply bg-white dark:bg-zinc-900; } replaces the nine-class enumeration (zero JSX churn; hook classes stay as markers keeping their #278 viewport bound).
  • web/test/unit/popover-opaque.test.js (new, 4 tests): fails if the structural rule regresses, if IdentityMenu stops being a floating .card, if any floating .card carries a translucent bg utility (utilities layer would beat the rule), or if a legacy popover disappears.
  • web/test/unit/popover-viewport.test.js: milestone pin updated to the structural rule (same intent).
  • docs/go/12_web_ui.md: Decisions entry appended (law 12).

Verification:

  • Targeted: node --test popover-opaque + popover-viewport + identity-nav = 39/39 pass. Guard proven to fail on the old enumeration CSS and to flag a translucent panel.
  • Full: 714 total / 701 pass / 13 fail — the 13 failures are pre-existing on pristine origin/main (identical failing files at 710/697/13; delta is exactly the +4 new passing tests; smoke x2 need a live server).
  • vite build green; compiled CSS contains .card.absolute,.card.fixed -> white / dark zinc-900 opaque. No new deps. Browser proof open (shared-daemon loopback guard).
Fixes #405 (IdentityMenu translucent in dark mode) + systemic guard (both option 1 structural default AND static test pin). Root cause: IdentityMenu dropdown is `card absolute` with none of the #37/#115/#278 enumerated hook classes, so it rendered the shared .card dark:bg-zinc-900/70. Changes (4 files): - web/src/ui.css: opaque background is now the STRUCTURAL default — `.card.absolute, .card.fixed { @apply bg-white dark:bg-zinc-900; }` replaces the nine-class enumeration (zero JSX churn; hook classes stay as markers keeping their #278 viewport bound). - web/test/unit/popover-opaque.test.js (new, 4 tests): fails if the structural rule regresses, if IdentityMenu stops being a floating .card, if any floating .card carries a translucent bg utility (utilities layer would beat the rule), or if a legacy popover disappears. - web/test/unit/popover-viewport.test.js: milestone pin updated to the structural rule (same intent). - docs/go/12_web_ui.md: Decisions entry appended (law 12). Verification: - Targeted: node --test popover-opaque + popover-viewport + identity-nav = 39/39 pass. Guard proven to fail on the old enumeration CSS and to flag a translucent panel. - Full: 714 total / 701 pass / 13 fail — the 13 failures are pre-existing on pristine origin/main (identical failing files at 710/697/13; delta is exactly the +4 new passing tests; smoke x2 need a live server). - vite build green; compiled CSS contains `.card.absolute,.card.fixed` -> white / dark zinc-900 opaque. No new deps. Browser proof open (shared-daemon loopback guard).
IdentityMenu dropdown was the sole floating .card outside the #37/#115/#278
enumeration, rendering translucent dark:bg-zinc-900/70. Opacity is now the
structural default (option 1) pinned by web/test/unit/popover-opaque.test.js
(static guard); viewport-test milestone pin updated to the structural rule.
Doc 12_web_ui.md Decisions appended.
Sign in to join this conversation.
No description provided.