Julien Gautier cd85037042
CI / scan (pull_request) Successful in 3m5s
CI / commits (pull_request) Successful in 3m7s
CI / check (pull_request) Successful in 3m18s
CI / a11y (pull_request) Successful in 1m51s
CI / perf (pull_request) Successful in 3m24s
feat(portal-shell): align theme switcher trigger with locale switcher shape
The theme switcher used to render as a round 44×44 icon button while
the locale switcher next to it (in the footer's device-prefs cluster
since #162) renders as a small chip: icon + label + chevron. Two
controls sitting side-by-side with two different visual shapes read
as two unrelated widgets instead of one family of preferences.

This PR aligns the theme trigger on the locale chip shape:

  Before:  [☀]                       (round icon button, 44×44)
  After:   [☀ System ▾]              (chip — icon + label + chevron)

The leading icon stays driven by `currentIcon()` so it still flips
between sun / moon / monitor as the user selects light / dark /
system — that visual feedback was the one reason the original icon-
only design existed and it's preserved.

Implementation:

* `theme-switcher.html` swaps the Tailwind utility-class icon button
  for a `.theme-switcher__trigger` chip with three children — the
  current-mode icon (size 14), the localised mode label, and a
  `chevron-down` (size 12). Same children layout as
  `.locale-switcher__trigger`.

* `theme-switcher.scss` adds `.theme-switcher__trigger` mirroring
  `.locale-switcher__trigger` rule-for-rule: same chip metrics
  (min-height 2.75rem for the AAA 44×44 tap target via vertical-
  padding overflow inside the thin footer), same hover/focus tokens,
  same dark-mode swap. Two copies rather than a shared `_chip-
  trigger.scss` partial — two switchers in one app is below the
  "three similar things" threshold from CLAUDE.md where extraction
  starts paying off. Promotes when a third switcher lands.

No spec changes: the existing assertions check
`button[aria-haspopup="menu"]` + the aria-label content, both of
which are preserved. `triggerAriaLabel()` is unchanged.

Verification:
  * 43 portal-shell specs pass.
  * `pnpm nx run portal-shell:build:production` (i18n-strict) green
    — confirms the `theme.mode.{light,dark,system}` labels are
    already translated (they were used in the menu items before;
    the trigger just reuses the same `currentLabel()` computed).
2026-05-16 02:31:30 +02:00

Documentation index

This is the entry point to all project documentation. It is maintained automatically: any addition, rename, or removal of a .md file under docs/ must be reflected here in the same change.

Conventions

  • Documentation is written in English.
  • One topic per file. Group related files into a folder when there are three or more.
  • Cross-reference with relative links so they keep working in GitHub, IDEs, and exported sites.
  • For architectural decisions, do not add them here — they belong in decisions/ as MADR 4.0.0 ADRs.

Sections

Daily development

  • development.md — repo layout, prerequisites, initial setup, daily commands, observability dev-loop (Jaeger UI, log ↔ trace correlation), dependency updates (Renovate), conventional commit cycle. Day-to-day reference for working on the project.

Architecture

  • architecture.md — cross-cutting Mermaid diagrams: C4 system context, C4 containers, Nx module boundaries, CI/CD pipeline. Single-decision diagrams (auth sequence, ERD, etc.) live inline in their ADR.

Onboarding & environment

Setup guides for new contributors:

Operations & runbooks

Empty — to be populated when we deploy.

Security, performance, accessibility

Empty — placeholders to be filled with rationale docs alongside their corresponding ADRs.

S
Description
No description provided
Readme 42 MiB
Languages
TypeScript 85.3%
JavaScript 5.4%
SCSS 4.3%
HTML 3.9%
Shell 0.8%
Other 0.3%