From 2a437a5861d2534eacfdaa7c1731296a8437cf8c Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 8 Apr 2026 18:08:35 +0200 Subject: [PATCH] fix(mana/web): EncryptionIntroBanner sits inside the bottom-stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The one-time encryption intro banner used its own position: fixed at bottom: 1.5rem with z-index: 60, mounted at the root layout level. That put it in a stacking context the QuickInputBar covered up — the search bar visually sat ON TOP of the banner instead of below it, making the privacy claim half-readable and the dismiss X impossible to click. Same fix the guest nudge got in c8ed58b7d: move into the bottom-stack flex container in (app)/+layout.svelte and let the parent handle positioning. The banner is now the FIRST child of the stack so it renders above the guest nudge / QuickInputBar / TagStrip / PillNav and stays in flow as the stack reflows when nav collapses. - Removed `` from root +layout.svelte (it doesn't belong above the (app) gate anyway since it self-checks isVaultUnlocked() which is always false outside auth context) - Mounted inside `.bottom-stack` as the first `.bottom-stack-notification` child in (app)/+layout.svelte - Stripped position: fixed / bottom / left / transform / max-width / z-index from the banner CSS — now an in-flow flex item with width: 100% (the wrapper centres + caps width via the existing bottom-stack-notification rules) - Slide-up animation rewritten to use translateY only since the parent no longer transforms the banner Co-Authored-By: Claude Opus 4.6 (1M context) --- .../components/EncryptionIntroBanner.svelte | 30 ++++++++++++------- .../apps/web/src/routes/(app)/+layout.svelte | 8 +++++ apps/mana/apps/web/src/routes/+layout.svelte | 2 -- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/apps/mana/apps/web/src/lib/components/EncryptionIntroBanner.svelte b/apps/mana/apps/web/src/lib/components/EncryptionIntroBanner.svelte index e40a7a99b..33e6726bc 100644 --- a/apps/mana/apps/web/src/lib/components/EncryptionIntroBanner.svelte +++ b/apps/mana/apps/web/src/lib/components/EncryptionIntroBanner.svelte @@ -16,9 +16,17 @@ "you understand and accept what's happening" social contract that encryption-at-rest requires. - The component is mounted once at the root layout. It self-checks - the vault state on mount and via a small interval, so it can fire - even if the unlock happens asynchronously after the layout renders. + The component is mounted inside the bottom-stack of (app)/+layout.svelte + (NOT the root layout) so it shares the stack's reflow with the + QuickInputBar / TagStrip / PillNav and can't end up rendered + behind them. Earlier the banner used its own `position: fixed` + with z-index 60, which the QuickInputBar's higher stacking context + covered up — fix was to make positioning the parent's job. + + It self-checks the vault state on mount and via a small interval, + so it can fire even if the unlock happens asynchronously after the + layout renders. Guests never see it because isVaultUnlocked() + returns false until a real master key is loaded. NOTE: The flag uses a constant string instead of a STORAGE_KEYS import because the central storage-keys file was removed in a @@ -112,13 +120,14 @@ {/if}