diff --git a/src/app/features/room/RoomView.tsx b/src/app/features/room/RoomView.tsx index d05fd39af..a11fa09a1 100644 --- a/src/app/features/room/RoomView.tsx +++ b/src/app/features/room/RoomView.tsx @@ -17,8 +17,6 @@ import { RoomViewFollowing, RoomViewFollowingPlaceholder } from './RoomViewFollo import { Page } from '../../components/page'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; -import { useTheme, ThemeKind } from '../../hooks/useTheme'; -import { getChatBg } from '../lotus/chatBackground'; import { useKeyDown } from '../../hooks/useKeyDown'; import { editableActiveElement } from '../../utils/dom'; import { useRoomPermissions } from '../../hooks/useRoomPermissions'; @@ -61,10 +59,7 @@ export function RoomView({ eventId }: { eventId?: string }) { const roomViewRef = useRef(null) as React.RefObject; const [chatBackground] = useSetting(settingsAtom, 'chatBackground'); const [lotusTerminal] = useSetting(settingsAtom, 'lotusTerminal'); - const [pauseAnimations] = useSetting(settingsAtom, 'pauseAnimations'); const [glassmorphismSidebar] = useSetting(settingsAtom, 'glassmorphismSidebar'); - const theme = useTheme(); - const isDark = theme.kind === ThemeKind.Dark; const [hideActivity] = useSetting(settingsAtom, 'hideActivity'); @@ -98,20 +93,13 @@ export function RoomView({ eventId }: { eventId?: string }) { ), ); - // When glassmorphism is active, document.body already carries the background so the - // sidebar blur has something to work through. Skip applying it here to avoid running - // the same CSS animation twice (one per layer = double GPU work). - const chatBgStyle = useMemo( - () => - glassmorphismSidebar - ? {} - : getChatBg( - lotusTerminal && chatBackground === 'none' ? 'tactical' : chatBackground, - isDark, - pauseAnimations, - ), - [chatBackground, lotusTerminal, isDark, pauseAnimations, glassmorphismSidebar], - ); + // document.body always carries the active background (set by SidebarNav). + // Make Page transparent so the body background shows through the chat area. + // When no background is active, Page keeps its default theme surface color. + const chatBgStyle = useMemo(() => { + const hasBg = chatBackground !== 'none' || glassmorphismSidebar || lotusTerminal; + return hasBg ? ({ background: 'transparent' } as React.CSSProperties) : {}; + }, [chatBackground, glassmorphismSidebar, lotusTerminal]); return ( diff --git a/src/app/pages/client/SidebarNav.tsx b/src/app/pages/client/SidebarNav.tsx index 82d556a1e..5e7e3e954 100644 --- a/src/app/pages/client/SidebarNav.tsx +++ b/src/app/pages/client/SidebarNav.tsx @@ -40,7 +40,9 @@ export function SidebarNav() { // Fix: mirror the active chat background onto document.body so the sidebar blurs through it. useEffect(() => { const { style } = document.body; - if (!glassmorphismSidebar) { + const hasBg = chatBackground !== 'none' || glassmorphismSidebar || lotusTerminal; + + if (!hasBg) { style.removeProperty('background-image'); style.removeProperty('background-color'); style.removeProperty('background-size'); @@ -48,13 +50,15 @@ export function SidebarNav() { style.removeProperty('animation'); return; } - const effectiveBg = chatBackground === 'none' ? 'tactical' : chatBackground; + + const effectiveBg = chatBackground !== 'none' ? chatBackground : 'tactical'; const bgStyle = getChatBg(effectiveBg, isDark, pauseAnimations); style.backgroundImage = (bgStyle.backgroundImage as string | undefined) ?? ''; style.backgroundColor = (bgStyle.backgroundColor as string | undefined) ?? ''; style.backgroundSize = (bgStyle.backgroundSize as string | undefined) ?? ''; style.backgroundPosition = (bgStyle.backgroundPosition as string | undefined) ?? ''; style.animation = (bgStyle.animation as string | undefined) ?? ''; + return () => { style.removeProperty('background-image'); style.removeProperty('background-color');