From 95a906b2a717f191f5e989e8d7d6be5b3e9b7a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 12 Nov 2026 14:08:34 +0100 Subject: [PATCH] fix(pwa): keep the status bar readable on the sign-in pages too The light-theme fix painted the strip behind the white status bar only in the signed-in shell. The sign-in, registration and take-over pages and the onboarding shell padded the strip without painting it, so after a sign-out in the installed iOS app the clock was white on near-white. They now use the same shell-safe-area band. --- .../auth-shell-status-bar.browser.test.tsx | 46 +++++++++++++++++++ src/components/layout/auth-shell.tsx | 8 ++-- 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/components/layout/__tests__/auth-shell-status-bar.browser.test.tsx diff --git a/src/components/layout/__tests__/auth-shell-status-bar.browser.test.tsx b/src/components/layout/__tests__/auth-shell-status-bar.browser.test.tsx new file mode 100644 index 000000000..caf53e592 --- /dev/null +++ b/src/components/layout/__tests__/auth-shell-status-bar.browser.test.tsx @@ -0,0 +1,46 @@ +/** + * The strip behind the status bar on the sign-in pages. + * + * The installed iOS app draws the clock in white over whatever the page + * paints there. The signed-in shell paints the strip; the sign-in pages only + * padded it, so after a sign-out in the light theme the clock was white on + * near-white. + */ +import { afterEach, describe, expect, it } from "vitest"; + +import { renderWithApp } from "../../../../tests/browser/render"; +import { stubFetch } from "../../../../tests/browser/fetch-stub"; + +import { AuthShell } from "../auth-shell"; + +afterEach(() => { + document.documentElement.classList.remove("light"); + document.documentElement.classList.add("dark"); +}); + +describe("AuthShell status bar strip", () => { + it("is painted on the sign-in page in the light theme", async () => { + document.documentElement.classList.remove("dark"); + document.documentElement.classList.add("light"); + stubFetch().on("GET", "/api/auth/me", { + status: 401, + error: "Unauthorized", + meta: { errorCode: "auth.missing" }, + }); + window.history.replaceState(null, "", "/auth/login"); + await renderWithApp( + +
+ , + { user: null }, + ); + await expect + .poll(() => document.querySelector('[data-slot="page"]')) + .toBeTruthy(); + + const wrapper = document.getElementById("main-content")!.parentElement!; + expect(getComputedStyle(wrapper).backgroundImage).toContain( + "linear-gradient", + ); + }); +}); diff --git a/src/components/layout/auth-shell.tsx b/src/components/layout/auth-shell.tsx index df9bc0f95..6aec4f08f 100644 --- a/src/components/layout/auth-shell.tsx +++ b/src/components/layout/auth-shell.tsx @@ -345,9 +345,11 @@ export function AuthShell({ // a sign-in form that is taller than a fixed-height box centres out of // it at the top, where nothing can scroll back to it. A minimum lets the // box grow and the document scroll. The safe-area padding keeps the form - // off the status bar and the home indicator in an installed app. + // off the status bar and the home indicator in an installed app, and + // `shell-safe-area` paints the strip behind the status bar so its white + // clock stays readable in the light theme, as in the signed-in shell. return ( -
+
{demoMode ? : null}
) : null} -
+
{children}