diff --git a/src/app/components/CallEmbedProvider.tsx b/src/app/components/CallEmbedProvider.tsx index 18e065afc..b1d91b841 100644 --- a/src/app/components/CallEmbedProvider.tsx +++ b/src/app/components/CallEmbedProvider.tsx @@ -64,6 +64,7 @@ import { getRoomPermissionsAPI } from '../hooks/useRoomPermissions'; import { useLivekitSupport } from '../hooks/useLivekitSupport'; import { CallAvatarAnimation } from '../styles/Animations.css'; import { webRTCSupported } from '../utils/rtc'; +import { zIndices } from '../styles/zIndex'; const PIP_MIN_W = 200; const PIP_MIN_H = 112; @@ -323,7 +324,7 @@ function IncomingCallBanner({ dm, info, onIgnore, onAnswer, onReject }: Incoming position: 'fixed', top: config.space.S400, right: config.space.S400, - zIndex: 9990, + zIndex: zIndices.inCallBanner, width: toRem(300), maxWidth: `calc(100vw - 2 * ${config.space.S400})`, padding: config.space.S300, diff --git a/src/app/components/seasonal/SeasonalEffect.tsx b/src/app/components/seasonal/SeasonalEffect.tsx index a5ba93c8f..3617e0a73 100644 --- a/src/app/components/seasonal/SeasonalEffect.tsx +++ b/src/app/components/seasonal/SeasonalEffect.tsx @@ -1,6 +1,7 @@ import React, { useMemo } from 'react'; import { useAtomValue } from 'jotai'; import { settingsAtom } from '../../state/settings'; +import { zIndices } from '../../styles/zIndex'; import { animSeasonFall, animLeafFall, @@ -758,7 +759,7 @@ function SeasonalOverlay({ theme, reduced }: { theme: SeasonTheme; reduced: bool pointerEvents: 'none', // Below the Night Light overlay (9998) so seasonal particles are tinted // by it, and below modals (9999) so dialogs are never obscured. - zIndex: 9997, + zIndex: zIndices.seasonalEffect, overflow: 'hidden', }} > diff --git a/src/app/features/toast/LotusToastContainer.tsx b/src/app/features/toast/LotusToastContainer.tsx index 814753a28..0b035e746 100644 --- a/src/app/features/toast/LotusToastContainer.tsx +++ b/src/app/features/toast/LotusToastContainer.tsx @@ -4,6 +4,7 @@ import { color, config, Icon, IconButton, Icons } from 'folds'; import { toastQueueAtom, dismissToastAtom, ToastNotif } from '../../state/toast'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; +import { zIndices } from '../../styles/zIndex'; // Inject the keyframe animation once const STYLE_ID = 'lotus-toast-keyframes'; @@ -214,7 +215,7 @@ export function LotusToastContainer() { position: 'fixed', bottom: '1.5rem', right: '1.5rem', - zIndex: 10001, + zIndex: zIndices.toast, display: 'flex', flexDirection: 'column', gap: config.space.S200, diff --git a/src/app/pages/App.tsx b/src/app/pages/App.tsx index 5c0be9fe5..7d74f4a1c 100644 --- a/src/app/pages/App.tsx +++ b/src/app/pages/App.tsx @@ -27,6 +27,7 @@ import { LotusToastContainer } from '../features/toast/LotusToastContainer'; import { useTauriNotificationBadge } from '../hooks/useTauriNotificationBadge'; import { SeasonalEffect } from '../components/seasonal/SeasonalEffect'; import { applyCustomAccent, removeCustomAccent } from '../utils/accentColor'; +import { zIndices } from '../styles/zIndex'; const FONT_MAP: Record = { system: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", @@ -95,7 +96,7 @@ function NightLightOverlay() { position: 'fixed', inset: 0, pointerEvents: 'none', - zIndex: 9998, + zIndex: zIndices.nightLight, backgroundColor: `rgba(255, 140, 0, ${(settings.nightLightOpacity ?? 30) / 100})`, }} /> diff --git a/src/app/styles/zIndex.ts b/src/app/styles/zIndex.ts new file mode 100644 index 000000000..9501c690f --- /dev/null +++ b/src/app/styles/zIndex.ts @@ -0,0 +1,16 @@ +/** + * Global overlay stacking layers, centralized so floating Lotus UI doesn't + * collide. (folds `Overlay`/`Dialog` modals resolve to 9999, which sits between + * `nightLight` and `toast`.) Component-internal stacking uses small local + * z-index values and is intentionally not listed here. + */ +export const zIndices = { + /** In-call incoming-call banner — below seasonal/night-light/modals. */ + inCallBanner: 9990, + /** Seasonal particle effect — below the night-light tint so particles tint. */ + seasonalEffect: 9997, + /** Night Light tint overlay — above effects, below modals. */ + nightLight: 9998, + /** Toasts — above everything, including modals. */ + toast: 10001, +} as const;