From 86147ead2cb39dec7aa916ed0f9d193c2ef31b31 Mon Sep 17 00:00:00 2001 From: neon <18559658+neonsolstice@users.noreply.github.com> Date: Thu, 14 May 2026 22:51:16 +0000 Subject: [PATCH] fix(reader): apply theme bg unconditionally to fix iOS dark mode override On iOS (Chrome/Safari) in system Dark Mode, the epub iframe's prefers-color-scheme:dark media query always matched regardless of the in-app light/dark toggle, forcing a dark background even when the user selected Light mode. Three changes in generateCSS(): - Set color-scheme to 'light' or 'dark' (not 'light dark') based on isDark, so the browser and epub-internal light-dark() calls respect the app setting rather than the OS preference. - Remove the nested @media (prefers-color-scheme: dark) block that was overriding mode.fg/link with OS-based dark values. - Replace both @media screen and (prefers-color-scheme: light/dark) background blocks with a single unconditional forceBg block driven by isDark.value, so background colors are always app-controlled. --- .../reader/epub/composables/useReaderState.ts | 85 +++++++------------ 1 file changed, 30 insertions(+), 55 deletions(-) diff --git a/client/src/features/reader/epub/composables/useReaderState.ts b/client/src/features/reader/epub/composables/useReaderState.ts index ba96e0363..36c7bd676 100644 --- a/client/src/features/reader/epub/composables/useReaderState.ts +++ b/client/src/features/reader/epub/composables/useReaderState.ts @@ -76,8 +76,13 @@ export function useReaderState() { const mode = activeMode.value const theme = currentTheme.value const lightMode = theme.light - const darkMode = theme.dark const mediaActiveClass = 'media-active' + const dark = isDark.value + // Force bg whenever dark mode is active OR the light theme uses a non-white background. + // Styles are applied unconditionally (no prefers-color-scheme wrappers) so the app's + // own light/dark toggle takes precedence over the OS-level preference. Without this, + // iOS in Dark Mode always matches prefers-color-scheme:dark and ignores the app setting. + const forceBg = dark || lightMode.bg !== '#ffffff' const fontFamilyRule = ff ? ` @@ -103,7 +108,7 @@ export function useReaderState() { } @media screen { html { - color-scheme: light dark; + color-scheme: ${dark ? 'dark' : 'light'}; color: ${mode.fg}; font-size: ${fs}px; }${fontFamilyRule} @@ -117,14 +122,6 @@ export function useReaderState() { a:any-link:hover { text-decoration-color: unset; } - @media (prefers-color-scheme: dark) { - html { - color: ${darkMode.fg}; - } - a:any-link { - color: ${darkMode.link}; - } - } aside[epub|type~="footnote"] { display: none; } @@ -150,52 +147,30 @@ export function useReaderState() { white-space: pre-wrap !important; tab-size: 2; } - @media screen and (prefers-color-scheme: light) { - ${ - lightMode.bg !== '#ffffff' - ? ` - html, body { - color: ${lightMode.fg} !important; - background: none !important; - } - body * { - color: inherit !important; - border-color: currentColor !important; - background-color: ${lightMode.bg} !important; - } - a:any-link { - color: ${lightMode.link} !important; - } - svg, img { - background-color: transparent !important; - mix-blend-mode: multiply; - } - .${mediaActiveClass}, .${mediaActiveClass} * { - color: ${lightMode.fg} !important; - background: color-mix(in hsl, ${lightMode.fg}, #fff 50%) !important; - background: color-mix(in hsl, ${lightMode.fg}, ${lightMode.bg} 85%) !important; - }` - : '' - } + ${ + forceBg + ? ` + html, body { + color: ${mode.fg} !important; + background: none !important; } - @media screen and (prefers-color-scheme: dark) { - html, body { - color: ${darkMode.fg} !important; - background: none !important; - } - body * { - color: inherit !important; - border-color: currentColor !important; - background-color: ${darkMode.bg} !important; - } - a:any-link { - color: ${darkMode.link} !important; - } - .${mediaActiveClass}, .${mediaActiveClass} * { - color: ${darkMode.fg} !important; - background: color-mix(in hsl, ${darkMode.fg}, #000 50%) !important; - background: color-mix(in hsl, ${darkMode.fg}, ${darkMode.bg} 75%) !important; - } + body * { + color: inherit !important; + border-color: currentColor !important; + background-color: ${mode.bg} !important; + } + a:any-link { + color: ${mode.link} !important; + } + svg, img { + background-color: transparent !important; + ${!dark ? 'mix-blend-mode: multiply;' : ''} + } + .${mediaActiveClass}, .${mediaActiveClass} * { + color: ${mode.fg} !important; + background: color-mix(in hsl, ${mode.fg}, ${mode.bg} ${dark ? '75%' : '85%'}) !important; + }` + : '' } p, li, blockquote, dd { line-height: ${lh};