From e372cac586fdb3871d87fee6816a5a9ba1dcb79a Mon Sep 17 00:00:00 2001 From: "Kenneth C. Arnold" Date: Sat, 19 Sep 2026 21:13:46 -0400 Subject: [PATCH] Fix the white flash on navigation in dark mode Dark mode is Tailwind's prefers-color-scheme variant, applied only on the divs React renders. Every nav link is a full page load, so until the bundle ran and SessionGate mounted, had no background and the browser painted its default white canvas. Two layers: a color-scheme meta so the very first paint (before any CSS arrives) is dark, and the page background moved onto in App.css so the gap between CSS load and React's first render is covered too. With owning the background, the gradient that was copy-pasted onto four root divs (home, layout root, SessionGate, StatusView) is deleted from all of them; App.css is the one place that says what color the page is. Spelled with the Tailwind v4 name (bg-linear-to-br) now that it's a single copy. Also split theme-color into a light and a dark tag matching that background; the old single value was gray-800 in both schemes. Co-Authored-By: Claude Opus 5 --- index.html | 10 +++++++++- src/App.css | 9 +++++++++ src/App.tsx | 4 ++-- src/SessionGate.tsx | 2 +- src/StatusView.tsx | 2 +- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 90eedf2..0fcc6ea 100644 --- a/index.html +++ b/index.html @@ -4,11 +4,19 @@ + + Live Notes - + + + diff --git a/src/App.css b/src/App.css index f5e3fc6..684e655 100644 --- a/src/App.css +++ b/src/App.css @@ -7,6 +7,15 @@ overscroll-behavior: none; } + /* The page background lives here, on , and nowhere else. Between the CSS loading + and React's first render there is nothing on screen but , and Tailwind's + preflight leaves it transparent — so when the root divs owned the background, + dark-mode users got a white flash on every navigation. (The color-scheme meta in + index.html covers the moments before even this CSS has arrived.) */ + html { + @apply bg-linear-to-br from-gray-100 to-gray-300 dark:from-gray-950 dark:to-gray-900 text-black dark:text-gray-200; + } + /* Override some of tailwind's preflight styles */ ul, ol { margin: initial; diff --git a/src/App.tsx b/src/App.tsx index 41851f1..9cc4a05 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -120,7 +120,7 @@ function HomePage() { }; return ( -
+

{s.chooseLayout}

@@ -419,7 +419,7 @@ function LayoutPage({ layout: initialLayout }: { layout: string }) { const chromeClass = `transition-opacity duration-300 ${chromeVisible ? "opacity-100" : "opacity-0 pointer-events-none"}`; return ( -
+
diff --git a/src/SessionGate.tsx b/src/SessionGate.tsx index 367d511..a1c94ab 100644 --- a/src/SessionGate.tsx +++ b/src/SessionGate.tsx @@ -51,7 +51,7 @@ export function SessionGate({ children }: { children: ReactNode }) { if (state.status === 'ready') return <>{children}; return ( -
+
{state.status === 'loading' ? (

{s.sessionResolving}

) : ( diff --git a/src/StatusView.tsx b/src/StatusView.tsx index 4705b92..b77f3a5 100644 --- a/src/StatusView.tsx +++ b/src/StatusView.tsx @@ -317,7 +317,7 @@ export function StatusView({ const placeholderClass = PLACEHOLDER_CLASS; return ( -
+

{s.statusTitle}