From f90a2f0fe82891da4c93490abaa66d3627b6e9d9 Mon Sep 17 00:00:00 2001 From: "boston-ai-agent[bot]" <299475768+boston-ai-agent[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 15:49:21 +0200 Subject: [PATCH] fix(ui): resolve page palette before first paint (#54) --- docs/theme-first-paint.md | 5 + src/HelpDesk.NewWeb/Components/App.razor | 71 +++++++++++- .../Layout/ThemePreferenceProvider.razor | 19 +++- .../Themes/RatelDeskPrepaintTheme.cs | 106 ++++++++++++++++++ .../wwwroot/js/theme-preference.js | 20 ---- .../NewWeb/RatelDeskPrepaintThemeTests.cs | 41 +++++++ tests/ux/theme-first-paint.spec.ts | 105 +++++++++++++++++ 7 files changed, 340 insertions(+), 27 deletions(-) create mode 100644 docs/theme-first-paint.md create mode 100644 src/HelpDesk.NewWeb/Themes/RatelDeskPrepaintTheme.cs delete mode 100644 src/HelpDesk.NewWeb/wwwroot/js/theme-preference.js create mode 100644 tests/Helpdesk.Tests/NewWeb/RatelDeskPrepaintThemeTests.cs create mode 100644 tests/ux/theme-first-paint.spec.ts diff --git a/docs/theme-first-paint.md b/docs/theme-first-paint.md new file mode 100644 index 00000000..c598102a --- /dev/null +++ b/docs/theme-first-paint.md @@ -0,0 +1,5 @@ +# Theme first-paint contract + +`RatelDeskTheme` is the source of truth for both MudBlazor's runtime theme and the head-resident prepaint variables emitted by `RatelDeskPrepaintTheme`. The synchronous bootstrap normalizes the existing `helpdesk.theme.preference` value, resolves System against `prefers-color-scheme`, and sets the document attribute plus `color-scheme` before stylesheet and body parsing can paint visible application content. + +The prepaint selectors retain higher specificity than MudBlazor's initial `:root` variables, so the browser does not expose the provider's server-side light default while the interactive provider reads browser state. Runtime ownership then remains with `ThemePreferenceProvider`; it adopts the normalized preference, applies user selections safely even if storage is blocked, and retains System-mode OS change handling. The Playwright first-paint spec pauses only the Blazor runtime and observes real prerendered body/card/text colors before and after runtime release. diff --git a/src/HelpDesk.NewWeb/Components/App.razor b/src/HelpDesk.NewWeb/Components/App.razor index 916aaee3..d13302dd 100644 --- a/src/HelpDesk.NewWeb/Components/App.razor +++ b/src/HelpDesk.NewWeb/Components/App.razor @@ -4,13 +4,75 @@
+