Content
View differences
Updated by Kabiru Mwenja about 20 hours ago
### Steps to reproduce
1. Set the OS appearance to dark (optionally with increased contrast)
2. In OpenProject, set the theme preference to "Sync with OS", or open the login page as a visitor (anonymous users sync with the OS since #19928)
3. Load any page with a full page load, for example reload the work packages list or the login page
### What is the buggy behavior?
* The page paints in the light theme first and flips to dark (or dark high contrast) a moment later
* With a slower connection or a cold cache the light frame is clearly visible on every full load; Turbo visits are affected less
* The login page shows it for every visitor on a dark OS
<img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/925962/content">
### What is the expected behavior?
1. The first painted frame already uses the theme that matches the OS preference, including the high contrast variant
2. The theme switcher keeps reacting to OS changes while the page is open, as today
### Cause
With "Sync with OS" the server renders no `data-color-mode` on the body. The attributes are only set by the auto theme switcher Stimulus controller once the JavaScript module bundle has loaded, which happens after the first paint. An earlier inline script that set them up front was removed in https://github.com/opf/openproject/pull/19922 because it depended on the not yet loaded bundle. Rendering Primer's CSS-only `data-color-mode="auto"` is not an option: OpenProject's own styles key on a bare `data-dark-theme` / `data-light-theme` attribute and `auto` requires both to be present, which would flash the dark mapping for light users instead.
The flash was masked until https://github.com/opf/openproject/pull/25912 (OP-20429): the previous wrapper script kept `#wrapper` hidden until the bundle had run. That change removed the hiding on purpose and named this follow-up; the original report is DREAM-528.
1. Set the OS appearance to dark (optionally with increased contrast)
2. In OpenProject, set the theme preference to "Sync with OS", or open the login page as a visitor (anonymous users sync with the OS since #19928)
3. Load any page with a full page load, for example reload the work packages list or the login page
### What is the buggy behavior?
* The page paints in the light theme first and flips to dark (or dark high contrast) a moment later
* With a slower connection or a cold cache the light frame is clearly visible on every full load; Turbo visits are affected less
* The login page shows it for every visitor on a dark OS
<img class="op-uc-image op-uc-image_inline" src="/api/v3/attachments/925962/content">
### What is the expected behavior?
1. The first painted frame already uses the theme that matches the OS preference, including the high contrast variant
2. The theme switcher keeps reacting to OS changes while the page is open, as today
### Cause
With "Sync with OS" the server renders no `data-color-mode` on the body. The attributes are only set by the auto theme switcher Stimulus controller once the JavaScript module bundle has loaded, which happens after the first paint. An earlier inline script that set them up front was removed in https://github.com/opf/openproject/pull/19922 because it depended on the not yet loaded bundle. Rendering Primer's CSS-only `data-color-mode="auto"` is not an option: OpenProject's own styles key on a bare `data-dark-theme` / `data-light-theme` attribute and `auto` requires both to be present, which would flash the dark mapping for light users instead.
The flash was masked until https://github.com/opf/openproject/pull/25912 (OP-20429): the previous wrapper script kept `#wrapper` hidden until the bundle had run. That change removed the hiding on purpose and named this follow-up; the original report is DREAM-528.