From 076cfb67a61dd36687ce6f2ca3edc003bdae456e Mon Sep 17 00:00:00 2001 From: Julien Gautier Date: Sat, 16 May 2026 01:14:36 +0200 Subject: [PATCH] feat(portal-shell): move theme switcher to footer, drop redundant settings icon (#162) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Three coupled chrome adjustments in `portal-shell`'s shell layout, all motivated by the same realisation that the UserMenu introduced in #149 made the header's standalone Settings icon redundant and surfaced an inconsistency in the theme switcher's placement (header for everyone, soon to be split between header and user-menu depending on auth state). ## What lands ### 1. Drop the standalone Settings button from the header The UserMenu already carries a "Settings (Soon)" row for authenticated users, and Settings has no meaning for anonymous traffic. The header icon pointed nowhere; keeping it doubled the surface and forced readers to guess which control to use. `header.action.settings` is removed from [`messages.fr.xlf`](apps/portal-shell/src/locale/messages.fr.xlf) in the same step — the i18n-strict prod build is now back in sync with the source. ### 2. Move `` from the header to the footer The switcher now lives beside `` in a single **device-prefs cluster** on the right side of the footer. Two reasons: - **Consistency across auth states.** The alternative — keep it in the header for anonymous, move it into the user-menu once authenticated — was the original temptation. Rejected: changing the location of an identical control depending on whether the user is signed in violates Jakob's law and breaks muscle memory. Especially bad for an a11y-first platform per [ADR-0016](docs/decisions/0016-accessibility-baseline-wcag-aa-targeted-aaa.md): a reader who relies on dark mode shouldn't have to expand a menu they don't yet recognise on first visit to escape a flashing white background. - **Precedent.** [ADR-0019](docs/decisions/0019-internationalisation-angular-localize.md) already established the footer as the home for ambient device preferences (locale switcher). Theme is the obvious sibling — same family (per-device, non-identity). ### 3. Reshape the footer into two semantic clusters ``` [© APF France handicap · Accessibility statement] [locale • theme] ←——— info / legal ———→ ←—— device prefs ——→ ``` The Accessibility statement link moves from the right cluster (where it sat alongside the locale switcher) to the left, joining the copyright with a typographic separator (`·`). Left = static info / legal anchor; right = interactive prefs the reader controls. Keyboard order naturally follows: a Tab-traversal from the main content hits the informational anchor before the interactive controls — a small a11y win. ## What I left alone - **`portal-admin`'s header / footer.** No theme switcher there in v1 (the admin chrome is brand-primary-600 hardcoded); no settings icon either. ADR-0020 explicitly trims that admin chrome relative to the user shell — nothing to align right now. - **The user-menu's "Settings (Soon)" row.** That stays. PR 2 of the auth chantier ([#150](https://git.unespace.com/julien/apf_portal/pulls/150)) wired the row at the request of the chantier's staging; the Settings page itself lands in a future chantier and the row's pre-existing "Soon" badge keeps the affordance honest. ## Notes for the reviewer - **Why not also a "Theme: " hint inside the user-menu?** Considered, deferred. The current Hint would be ornament without a corresponding *target*; once the Settings page exists and the theme has a settings sub-section, a "Theme: System" line in the user-menu makes sense as a deep-link affordance. Not before. - **Why a `·` text separator rather than a CSS border?** Border would force vertical alignment math (height, dark-mode color) for one line of footer text; a typographic mid-dot inherits text color, scales with the line, and is `aria-hidden` so screen readers don't read it as "middle dot". Smaller surface for one less moving piece. - **A11y check**: the left cluster's `