From 852d0ae3e93dcb7d50b42d3cb4ef18833e4d22da Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Sat, 13 Jun 2026 01:37:23 +0800 Subject: [PATCH] fix(reader): keep dark-mode page body transparent so the bg texture shows, closes #4446 (#4564) The body.theme-dark catch-all from #4392 painted every section iframe's body with the opaque theme bg in dark mode, occluding the host background texture and poisoning foliate's docBackground capture (so paginated segments and scrolled view backgrounds resolved opaque too). Force transparent instead: the dark page fill already comes from the paginator container / reader grid cell, and book-forced light page backgrounds stay neutralized since the theme-dark fill shows through. Unconditional rather than texture-gated because docBackground is captured once per section load and a gated rule would go stale on live texture toggling. Co-authored-by: Claude Fable 5 --- .../__tests__/utils/style-get-styles.test.ts | 18 ++++++++++++++++++ apps/readest-app/src/utils/style.ts | 8 +++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/apps/readest-app/src/__tests__/utils/style-get-styles.test.ts b/apps/readest-app/src/__tests__/utils/style-get-styles.test.ts index 435de828..6d369cff 100644 --- a/apps/readest-app/src/__tests__/utils/style-get-styles.test.ts +++ b/apps/readest-app/src/__tests__/utils/style-get-styles.test.ts @@ -580,6 +580,24 @@ describe('getColorStyles branches (via getStyles)', () => { expect(css).toContain('body.theme-dark'); }); + it('keeps body.theme-dark transparent in dark mode so the host background texture is not occluded (#4446)', () => { + const vs = makeViewSettings({ overrideColor: false, backgroundTextureId: 'leaves' }); + const theme = makeThemeCode({ isDarkMode: true, bg: '#1a1a1a', fg: '#e0e0e0' }); + const css = getStyles(vs, theme); + expect(css).toMatch(/body\.theme-dark\s*\{\s*background-color: transparent !important;/); + expect(css).not.toMatch(/body\.theme-dark\s*\{\s*background-color: #1a1a1a !important/); + // #4392 inline light-callout overrides must keep forcing the theme bg + expect(css).toContain('background-color: #fff"]'); + expect(css).toContain('background-color: #1a1a1a !important'); + }); + + it('keeps body.theme-dark transparent even without a texture (docBackground is captured once per section load)', () => { + const vs = makeViewSettings({ overrideColor: false, backgroundTextureId: 'none' }); + const theme = makeThemeCode({ isDarkMode: true, bg: '#1a1a1a', fg: '#e0e0e0' }); + const css = getStyles(vs, theme); + expect(css).toMatch(/body\.theme-dark\s*\{\s*background-color: transparent !important;/); + }); + it('does not add inline white background overrides in light mode', () => { const vs = makeViewSettings({ overrideColor: false }); const theme = makeThemeCode({ isDarkMode: false }); diff --git a/apps/readest-app/src/utils/style.ts b/apps/readest-app/src/utils/style.ts index b107e33a..a88f6afb 100644 --- a/apps/readest-app/src/utils/style.ts +++ b/apps/readest-app/src/utils/style.ts @@ -191,8 +191,14 @@ const getDarkModeLightBackgroundOverrides = (bg: string) => ` *[style*="background: rgb(255"], *[style*="background:rgb(255"] { background-color: ${bg} !important; } + /* Force transparent, not the theme bg: the dark page fill already comes from + the paginator container / reader grid cell, while an opaque body paints over + the host background texture (#4446) — and foliate captures docBackground once + per section load, so the body must stay transparent regardless of texture + state. Book-forced light page backgrounds still get neutralized (#4392) since + the theme-dark fill shows through. */ body.theme-dark { - background-color: ${bg} !important; + background-color: transparent !important; } `;