diff --git a/app/globals.css b/app/globals.css index b24fdcb..0a87624 100644 --- a/app/globals.css +++ b/app/globals.css @@ -429,6 +429,58 @@ html[data-mail-background]:not([data-mail-background='none']) background-color: var(--mail-invitation); } +/** + * Sidebar frosted strips — backdrop blur hides children scrolling behind sticky parents (sm+). + * Background stays transparent so there is no tint — the blur alone conceals the text. + */ +.ultimail-app .mail-sidebar-blur-surface { + background-color: transparent; + -webkit-backdrop-filter: blur(24px) saturate(150%); + backdrop-filter: blur(24px) saturate(150%); +} + +/** + * Hover-expanded sidebar frosted panel — uses ::before so it doesn't create + * a backdrop-filter stacking context that would clip children's backdrop-filters. + */ +.ultimail-app .mail-sidebar-hover-frosted::before { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + -webkit-backdrop-filter: blur(24px) saturate(150%); + backdrop-filter: blur(24px) saturate(150%); + pointer-events: none; +} + +/** + * Sticky sidebar strip — blur spans full rail width (not just indented label). + * Set --sidebar-sticky-pad-left on the element (px indent of row content). + */ +.ultimail-app .mail-sidebar-blur-sticky-strip { + position: relative; + isolation: isolate; +} + +.ultimail-app .mail-sidebar-blur-sticky-strip::before { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: calc(-1 * var(--sidebar-sticky-pad-left, 0px)); + right: calc(-1 * var(--sidebar-nav-rail-inset, 14px)); + z-index: 0; + background-color: transparent; + -webkit-backdrop-filter: blur(24px) saturate(150%); + backdrop-filter: blur(24px) saturate(150%); + pointer-events: none; +} + +.ultimail-app .mail-sidebar-blur-sticky-strip > * { + position: relative; + z-index: 1; +} + /** * Sidebar overlay (touch / xs) — fond opaque. * Nom hors préfixe bg-* pour éviter qu’un utility Tailwind écrase la règle. diff --git a/app/mail/mail-app-shell.tsx b/app/mail/mail-app-shell.tsx index 1ba8a6e..099c8ef 100644 --- a/app/mail/mail-app-shell.tsx +++ b/app/mail/mail-app-shell.tsx @@ -119,14 +119,13 @@ function MailAppInner() { onClick={() => setSidebarCollapsed(true)} /> )} + {/* xs: overlay (w-0). sm+: spacer matches rail; hover-expand can grow over main without shifting layout */}
<\/p>/g, "") - .trim() - const hasContent = - compose.subject.trim() !== "" || - compose.to.length > 0 || - compose.cc.length > 0 || - compose.bcc.length > 0 || - compose.attachments.length > 0 || - bodyWithoutSig !== "" - - const handleIdentityChange = useCallback( - (identity: (typeof DEFAULT_IDENTITIES)[number]) => { - if (compose.autoInsertSignature && editor) { - const sigId = identity.defaultSignatureId - const newHtml = insertSignatureHtml(editor.getHTML(), sigId) - editor.commands.setContent(newHtml) - updateCompose(compose.id, { from: identity, bodyHtml: newHtml, signatureId: sigId }) - } else { - updateCompose(compose.id, { from: identity }) - } - }, - [compose.id, compose.autoInsertSignature, editor, updateCompose] - ) - - const handleClose = () => { - const threadInlineDiscard = - isInline && compose.threadEmailId - ? ({ discardThreadReplyDraft: true } as const) - : undefined - if (!hasContent) { - closeCompose(compose.id, threadInlineDiscard) - } else { - updateCompose(compose.id, { savedAt: Date.now() }) - closeCompose(compose.id, threadInlineDiscard) - } - } - - const handleCloseRef = useRef(handleClose) - handleCloseRef.current = handleClose - - useLayoutEffect(() => { - if (!isXsSheet || !bindXsSheetClose) return - bindXsSheetClose(() => { - handleCloseRef.current() - }) - return () => bindXsSheetClose(null) - }, [isXsSheet, bindXsSheetClose, compose.id]) - - const htmlToPreviewText = useCallback((html: string) => { - return html - .replace(/ - -
${processedHtml} -