Angular Material 3 Migration¶
SyRF will move the Angular application from its Material 2 component theme to one coherent Material 3 application with complete light, dark and system-preference modes, without exposing users to a mixture of component generations.
This document replaces the migration claims preserved on PR #2322. That branch remains useful research, but it did not land and its Angular 21 implementation is not a source of code for the current Angular 22 application.
User outcome¶
- Consistent controls, surfaces, status colours and focus states across public and authenticated workflows.
- Measured WCAG contrast rather than component-specific fallback colours.
- A stable semantic-token contract so future UI work does not need private Material internals or one-off colour parsers.
- One application-wide visual cutover, with a release-level rollback, instead of incremental production drift between M2 and M3 components.
- One adaptive hierarchy for About, Admin Console, My Account, project sub-sections and comparable route groups, with a wide rail or compact sticky selector chosen by available content space.
- Consistent typography, density, spacing, surfaces, elevation and component states across the whole product.
- Consistent responsive status, progress, error and timestamp presentation across Systematic Searches, All Studies, Bulk Study Update history, Admin job monitoring and any approved Jobs hub.
MVP boundary¶
The MVP is a complete light-theme Material 3 path for the Angular application.
It includes:
- every reachable Angular Material component using the M3 component theme;
- application shell and feature SCSS using emitted
--mat-sys-*roles or explicit--syrf-*brand/domain roles; - retirement of the live Bootstrap button, panel and progress-bar compatibility layer;
- no undefined semantic tokens and no M2 Sass API use after cutover;
- behavior, responsive layout and accessible names preserved on current routes;
- exact-image preview and staging acceptance before production activation.
It does not make the first cutover carry dark-mode activation, a typography/spacing redesign, Storybook/Chromatic, FlexLayout replacement, or visual parity work for the separate Identity Razor application. Dark/system modes and a whole-product consistency audit are required follow-on milestones; the other items remain optional unless needed for correctness or accessibility.
Programme completion¶
The programme is complete only when the M3 light cutover has been proved, dark and system modes pass the same route and accessibility matrix, adaptive section hierarchy is consistent, reachable M2/Bootstrap/private Material dependencies are gone, and a final whole-product audit accepts typography, density, spacing, surfaces, states and component hierarchy.
Current baseline¶
Baseline audited on 2026-08-30 and reconciled on 2026-08-31 at
origin/main@7f86994537675dc5b11015e05b70801053c96bc8:
- Angular, Angular Material and CDK 22.1 are current.
syrf-theme.scssstill emits the global M2 light/dark component themes.mat.theme()additively emits a light-only M3 system-token layer.- ten SyRF component-theme partials already consume CSS roles rather than M2 palettes.
- the merged SignalR reviewer-state UI adds two M2 banner partials that must be converted before cutover.
.global-dark-themeis compiled but never activated; M3 tokens inside it remain light.legacy-bootstrap/buttons.scss,panel.scssandprogress-bars.scssremain live.- the cookie-consent redesign is aligned with the semantic-token contract.
- Bulk PDF Upload has a feature-local status palette that must be reconciled before dark mode.
The production bridge is intentional. It is not evidence that the migration is complete.
Governing architecture¶
--mat-sys-*names represent Material semantic roles and come frommat.theme().--syrf-*names are reserved for brand or domain roles that Material does not provide.- A role keeps the same meaning everywhere; a call site changes role rather than bending a shared token to match its previous fallback.
- Meaningful control and graph boundaries use a role that clears WCAG 1.4.11; decorative
separators may use
outline-variant. - Tests use compiled Sass, browser-computed styles and public Material APIs. Reading
@angular/material/fesm*bundles or parsing private package text is prohibited. - Material 2 APIs remain confined to the global bridge and the two audited PR #2467 banner partials; the temporary banner entries are removed as soon as their semantic M3 rewrite lands.
- Existing Bootstrap compatibility imports may shrink but must not spread.
Run the executable boundary checks with:
Portfolio decisions¶
| Source | Decision |
|---|---|
| PR #2322 | Do not merge or rebase. Rewrite useful planning and validation ideas for current main. |
| PRs #2751, #2753, #2754, #2756, #2771 and #2777 | Merged foundations; preserve as the current architecture. |
| PR #2750 | Token shim is superseded and already removed. |
| PR #2755 | Closed duplicate; discard. |
| PRs #2775, #2784, #2791, #2805, #2811 and #2813 | Reauthor semantic intent on current main; do not merge preserved heads. |
feat/m3-question-preview-colours |
Reauthor after current Question Management owners settle. |
fix/m3-outline-variant-boundaries |
Reauthor after current AF2 unit/outline owners settle. |
Ownership boundaries¶
- Terms of Use is not implemented. Do not add it to navigation, route inventories or end-state baselines until a separate product implementation exists.
- Multi-page sections share one adaptive hierarchy: a persistent left rail when content has enough horizontal room, replaced by a sticky route-aware selector in the section header when the rail would squeeze or overflow content. The breakpoint is content-driven, not device-labelled.
- Current cookie consent is authoritative;
/about/cookiesremains a distinct policy surface. - PR #2992 owns responsive About, Privacy, Accessibility and Cookies layout and lands before recovered #2813 colour work. The M3 slice must not restore its old markup or layout assumptions.
- PR #2853 owns 404 routing and the current not-found page.
- Merged PR #2467 is authoritative for SignalR reviewer-state UI and introduced two M2 banner partials; those partials must be converted before the M3 cutover.
- Merged PR #3010/current main is the canonical Admin Console structure, responsive behavior and child-page layout. M3 work must not duplicate its files and impersonation colour recovery follows that landed baseline.
- PR #2990 owns only bounded Bulk Study Update history intent; it is not the completed Study Management implementation. PR #2993 owns only the central Jobs hub plan, and PR #2528 is recovery evidence rather than one mergeable implementation boundary.
- The separate Study Management redesign task owns product discovery, domain behavior and its file inventory. M3 supplies shared adaptive-navigation, supported-token, theming and job visual-language contracts without claiming its files while that inventory is active.
- PR #2992's current diff uses the adaptive rail/selector contract and no longer contains Admin shell files. Review its breakpoint/focus proof independently and keep PR #3010 as the sole Admin owner.
- My Account is already responsive from merged #2819, but its rail and in-body dropdown are a
bespoke implementation rather than the finished shared hierarchy. A bounded successor owns
manage/manage.component.*plus focused E2E proof after #2992 lands: consume the generic shared primitive, move the compact selector into the sticky route-aware section header and preserve all Account routes and behavior. It must not import or couple to Admin permissions. - PRs #2802, #2810 and #2812, plus preserved AF2 partial worktrees, own moving Annotation Forms structures. Theme work stacks after their structural decisions.
- Merged responsive work #2819 is authoritative for Contact, Stage Overview and Manage layouts.
Acceptance criteria¶
- A session renders wholly through the M2 path or wholly through the M3 path during proving; it never mixes component themes.
- Production remains on the current appearance until the complete M3 light route matrix passes.
- Every referenced
--mat-sys-*and--syrf-*token is emitted and resolves concretely. - No new M2 API file, legacy Bootstrap import or private Material bundle dependency can enter main; the two exact PR #2467 M2 exceptions can only shrink.
- Cutover validation covers public, account, project, chart, Annotation Forms and SignalR states.
- Dark and system modes pass the same whole-product route, visual and accessibility matrix before the programme is called complete.
- M2 and compatibility code are deleted only after the proving release.
The implementation sequence, validation matrix and rollback gates are maintained in the technical plan.