Problem
The navbar's controls are visual peers sitting in the same bar, but they render at arbitrary, unequal alpha values — re-guessed independently in each of three states. packages/ui/src/styles/navbar.css:
| Element |
dark |
light |
light + over-dark |
.nav-logo |
0.92 |
0.88 |
0.92 |
.nav-links a |
0.88 |
0.75 |
0.88 |
.nav-lang (DE/EN) |
0.28 |
0.44 |
0.28 |
.nav-theme (sun/moon) |
0.55 |
0.65 |
0.55 |
.nav-burger__line |
0.65 |
0.62 |
0.65 |
In dark theme the language switcher (0.28), the theme toggle (0.55) and the burger (0.65) sit at three different opacities while being the same kind of control. The DE/EN switcher is over three times fainter than the nav link right beside it.
That is 15 hand-tuned colour values across navbar.css:341-405 that do not agree with each other.
It is also a WCAG failure. rgba(80, 78, 96, 0.44) on the light background #fcfbf8 lands near 2.3:1 — under the 3:1 minimum for UI components. The dark-theme 0.28 is worse.
Fix
Collapse the 15 values into one alpha scale expressed as CSS custom properties on .site-nav, set once per state and consumed by every control.
Two tiers only:
- primary — logo, nav links
- secondary — language switcher, theme toggle, burger lines
Every control in a tier gets the identical value, and the secondary tier is raised to clear 3:1 against its own background in both themes. Hover states stay exactly one tier brighter.
The over-dark state (nav floating over the cosmic hero — packages/ui/src/components/Navbar.tsx:47-51, triggered by data-nav-overlay="dark" on HeroWelcome) then only needs to re-set those two variables to the dark-state values, instead of re-declaring nine separate rules.
Scope note
packages/ui is shared — this affects web, songbook, events, treasures navbars simultaneously.
Success criteria
- All secondary controls measure ≥3:1 contrast against their background in dark, light, and light+
over-dark.
- Language switcher, theme toggle and burger are visually equal in weight in every state.
pnpm test:a11y passes.
- Navbar screenshots reviewed then updated.
- Manual pass at 1280 / 1024 / 768 / 375 px in both themes, including scrolled and unscrolled nav over the hero.
Conflict note
feat/5-accessibility-rebase also edits packages/ui/src/styles/navbar.css (+69 lines). Land that branch first, or expect a manual rebase.
Branch: feat/navbar-contrast
Problem
The navbar's controls are visual peers sitting in the same bar, but they render at arbitrary, unequal alpha values — re-guessed independently in each of three states.
packages/ui/src/styles/navbar.css:over-dark.nav-logo.nav-links a.nav-lang(DE/EN).nav-theme(sun/moon).nav-burger__lineIn dark theme the language switcher (0.28), the theme toggle (0.55) and the burger (0.65) sit at three different opacities while being the same kind of control. The DE/EN switcher is over three times fainter than the nav link right beside it.
That is 15 hand-tuned colour values across
navbar.css:341-405that do not agree with each other.It is also a WCAG failure.
rgba(80, 78, 96, 0.44)on the light background#fcfbf8lands near 2.3:1 — under the 3:1 minimum for UI components. The dark-theme 0.28 is worse.Fix
Collapse the 15 values into one alpha scale expressed as CSS custom properties on
.site-nav, set once per state and consumed by every control.Two tiers only:
Every control in a tier gets the identical value, and the secondary tier is raised to clear 3:1 against its own background in both themes. Hover states stay exactly one tier brighter.
The
over-darkstate (nav floating over the cosmic hero —packages/ui/src/components/Navbar.tsx:47-51, triggered bydata-nav-overlay="dark"onHeroWelcome) then only needs to re-set those two variables to the dark-state values, instead of re-declaring nine separate rules.Scope note
packages/uiis shared — this affectsweb,songbook,events,treasuresnavbars simultaneously.Success criteria
over-dark.pnpm test:a11ypasses.Conflict note
feat/5-accessibility-rebasealso editspackages/ui/src/styles/navbar.css(+69 lines). Land that branch first, or expect a manual rebase.Branch:
feat/navbar-contrast