cd8503704250953539ca3f3198cf77728aacc902
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).
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:
- setup/01-wsl-terminal-setup.md — modern WSL terminal (Zsh + Powerlevel10k + CLI tools)
- setup/02-dev-web-stack.md — Node via nvm, pnpm via corepack, Docker
- setup/03-angular-nx-monorepo.md — Angular + Nx monorepo bootstrap
Operations & runbooks
Empty — to be populated when we deploy.
Security, performance, accessibility
Empty — placeholders to be filled with rationale docs alongside their corresponding ADRs.
Description
Languages
TypeScript
85.3%
JavaScript
5.4%
SCSS
4.3%
HTML
3.9%
Shell
0.8%
Other
0.3%