Share sheet opened from Inspector → Manage renders under the Inspector's dim/blur (washed-out, smeared text) #580

Open
opened 2026-10-01 06:30:49 +00:00 by kayg · 3 comments
Owner

Owner report (2026-10-01, screenshot on calternal.cloud): "cursed text in Inspector → Manage shares?"

Opening Manage (Sharing) from the Files Inspector shows the Share sheet ("Share "Calendar"", People, Public links) washed out: grey, low-contrast, slightly smeared text, as if the sheet sits under a dimming/blur layer.
Hypothesis (verify first): ShareDialog (OverlaySurface variant="sheet") opens while the Inspector popover is still open. The new sheet mounts inside or below the Inspector's layer, so the Inspector's backdrop scrim/backdrop-filter paints over it (an overlay stacking/z-order bug), or the Inspector's dim is applied to the new top layer. It could also be the text halo regression from 2026-09-28 (glass text-shadow).
Fix in the shared overlay stack (OverlaySurface / the overlay registry), not in ShareDialog:

  • A surface opened from another surface becomes the top layer: its own scrim dims everything below it, including the Inspector, and nothing paints over it.
  • Only one backdrop blur per stack (the existing one-blur rule).
  • Focus moves to the new sheet. Escape closes only the top layer.
  • Closing returns focus to the Manage button in the Inspector.
    Also (wording, owner rules): "No one else has an account on this instance yet" uses jargon ("instance"). Write: "No one else uses this calternal yet. Invite people from Settings → Invitations, then share with them here." Section labels in ALL CAPS ("PEOPLE", "PUBLIC LINKS") do not follow the Settings sub-heading style: use the shared group heading.
    Test: an e2e opens the Inspector → Manage. Assert that the Share sheet is the topmost element at its centre point (document.elementFromPoint), its text contrast is ≥ 4.5:1 (computed colours against the computed background), and no text-shadow is present. Then Escape closes only the sheet. Attach 3× crops of the sheet text before and after, at 1440 and 390, in both themes.
## Owner report (2026-10-01, screenshot on calternal.cloud): "cursed text in Inspector → Manage shares?" Opening **Manage** (Sharing) from the Files Inspector shows the Share sheet ("Share "Calendar"", People, Public links) washed out: grey, low-contrast, slightly smeared text, as if the sheet sits **under** a dimming/blur layer. **Hypothesis (verify first):** `ShareDialog` (`OverlaySurface variant="sheet"`) opens while the Inspector popover is still open. The new sheet mounts inside or below the Inspector's layer, so the Inspector's backdrop scrim/backdrop-filter paints over it (an overlay stacking/z-order bug), or the Inspector's dim is applied to the new top layer. It could also be the text halo regression from 2026-09-28 (glass text-shadow). **Fix in the shared overlay stack (`OverlaySurface` / the overlay registry), not in ShareDialog:** - A surface opened from another surface becomes the **top layer**: its own scrim dims everything below it, including the Inspector, and nothing paints over it. - Only one backdrop blur per stack (the existing one-blur rule). - Focus moves to the new sheet. Escape closes only the top layer. - Closing returns focus to the Manage button in the Inspector. **Also (wording, owner rules):** "No one else has an account on this instance yet" uses jargon ("instance"). Write: "No one else uses this calternal yet. Invite people from Settings → Invitations, then share with them here." Section labels in ALL CAPS ("PEOPLE", "PUBLIC LINKS") do not follow the Settings sub-heading style: use the shared group heading. **Test:** an e2e opens the Inspector → Manage. Assert that the Share sheet is the topmost element at its centre point (`document.elementFromPoint`), its text contrast is ≥ 4.5:1 (computed colours against the computed background), and no text-shadow is present. Then Escape closes only the sheet. Attach 3× crops of the sheet text before and after, at 1440 and 390, in both themes.
Author
Owner

Starting work on job/sharestack-580, based on cc25c441b7a974185622a1dee853cf38686d2b67 (origin/dev). I am tracing OverlaySurface and the overlay registry first, then I will reproduce Inspector → Manage and add the requested regression coverage.

Starting work on `job/sharestack-580`, based on `cc25c441b7a974185622a1dee853cf38686d2b67` (`origin/dev`). I am tracing `OverlaySurface` and the overlay registry first, then I will reproduce Inspector → Manage and add the requested regression coverage.
Author
Owner

Finding from the real local production E2E: at 820 px in dark mode, elementFromPoint at the Share sheet centre hit the Inspector scrim. The Share surface was z-index 201, the Inspector was 301 and its scrim was 300. The Share text had no text-shadow and computed contrast was 8.0:1 against the sheet tint, so the reproduced failure is the modal stacking order, not the text halo. Before crops are in artifacts/share-stack/ for 1440, 820 and 390 px in both themes.

Finding from the real local production E2E: at 820 px in dark mode, `elementFromPoint` at the Share sheet centre hit the Inspector scrim. The Share surface was z-index 201, the Inspector was 301 and its scrim was 300. The Share text had no `text-shadow` and computed contrast was 8.0:1 against the sheet tint, so the reproduced failure is the modal stacking order, not the text halo. Before crops are in `artifacts/share-stack/` for 1440, 820 and 390 px in both themes.
Author
Owner

Finished — sharestack-580

Share opened from Files Inspector → Manage now becomes the top modal layer. One shared registry orders modal popovers and sheets, puts the child scrim over the Inspector, keeps one backdrop blur, and gives Escape to only the top surface. Closing Share restores focus to Manage. The Share sheet now uses the shared UI heading primitive for People and Public links, and the empty state says: “No one else uses this calternal yet. Invite people from Settings → Invitations, then share with them here.”

The pre-fix production E2E reproduced the stack bug: the Share centre hit the Inspector scrim. The baseline text had no text-shadow and measured 8.0:1 contrast, which ruled out the earlier text halo as the cause.

Screenshots

All crops are 3×. Before and after are attached for light and dark at 1440, 820 and 390 px.

Width and theme Before After
1440 light before after
1440 dark before after
820 light before after
820 dark before after
390 light before after
390 dark before after

Gates

bun run check output:

$ node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/sharestack-580/apps/web
Getting Svelte diagnostics...
svelte-check found 0 errors and 0 warnings

bun run test summary output:

 Test Files  140 passed (140)
      Tests  930 passed (930)
   Start at  09:54:09
   Duration  122.03s (transform 49%, environment 20%, import 16%, tests 11%, setup 4%)

bun run test:e2e:share-stack summary output:

SHARE STACK AFTER PASSED
CSP REPORTS share-stack: 0 across 1 pages

The production E2E checks the sheet's centre hit target, stacking, one blur owner, computed contrast, no text-shadow on rendered text, focus entry and restoration, and Escape behavior in all six viewport/theme combinations. Minimum measured contrast was 7.50:1.

Performance profile

bench/share-stack.mjs ran locally against the production SPA at load averages 20.50 / 21.53 / 20.31. Average click-to-next-frame p50/p95 was 390 px: 59.2/191 ms; 820 px: 179.5/321.1 ms; 1440 px: 260.1/697.2 ms. The eight-open burst p50/p95 was 390 px: 74.8/268.1 ms; 820 px: 222.1/239.0 ms; 1440 px: 170.7/361.2 ms. Mean server CPU was 6.10%, 1.11%, and 1.32%; mean RSS was 224.6, 231.0, and 237.8 MB respectively. These are noisy local measurements under high host load. docs/perf/baseline.json has no Share-stack profile for a direct comparison; the profile JSON is in ignored artifacts/share-stack/share-stack-perf.json.

Files and decisions

Changed files: apps/web/src/lib/overlay/state.svelte.ts, packages/ui/src/components/OverlaySurface.svelte, packages/ui/src/components/menu/FloatingSurface.svelte, apps/web/src/lib/files/FilesBrowser.svelte, apps/web/src/lib/files/ShareDialog.svelte, apps/web/e2e/share-stack.mjs, bench/share-stack.mjs, apps/web/package.json, and docs/perf/README.md.

Decision not specified in DESIGN: each additional modal depth advances shared scrim and surface z-index by two roles, so the child scrim sits above its parent while its own surface stays above the scrim. The merged DESIGN §54 Share/Collaborate permission changes are outside #580; existing API-backed permission controls were left unchanged and are documented as a separate gap.

Head SHA: d0e327a3dcdc8c4730c2b7ec044383f84c26cc49 (job/sharestack-580). No Rust source or route contract changed, so Rust crate gates were not applicable. Build output was cleaned after the gates.

## Finished — sharestack-580 Share opened from Files Inspector → Manage now becomes the top modal layer. One shared registry orders modal popovers and sheets, puts the child scrim over the Inspector, keeps one backdrop blur, and gives Escape to only the top surface. Closing Share restores focus to Manage. The Share sheet now uses the shared UI heading primitive for People and Public links, and the empty state says: “No one else uses this calternal yet. Invite people from Settings → Invitations, then share with them here.” The pre-fix production E2E reproduced the stack bug: the Share centre hit the Inspector scrim. The baseline text had no text-shadow and measured 8.0:1 contrast, which ruled out the earlier text halo as the cause. ### Screenshots All crops are 3×. Before and after are attached for light and dark at 1440, 820 and 390 px. | Width and theme | Before | After | |---|---|---| | 1440 light | [before](https://git.kayg.org/attachments/464b159f-9b02-46e0-9c28-d65f69e84aa3) | [after](https://git.kayg.org/attachments/41df8edf-7f12-4b02-bfac-410dbdd059a0) | | 1440 dark | [before](https://git.kayg.org/attachments/9e458cd2-749a-40b7-965b-bdc46f11aeee) | [after](https://git.kayg.org/attachments/b1acea9d-f514-4153-9264-cd236b63eb50) | | 820 light | [before](https://git.kayg.org/attachments/dfb05de4-046c-4e73-9a6a-ca87fe60e51b) | [after](https://git.kayg.org/attachments/da3800a6-3afd-4b6d-8201-af1ba9b1998f) | | 820 dark | [before](https://git.kayg.org/attachments/623d3347-6e20-491e-9ee8-e06a896635d1) | [after](https://git.kayg.org/attachments/2b59eefe-8108-48fa-9642-4a0a07043903) | | 390 light | [before](https://git.kayg.org/attachments/b9d9b469-6658-4a15-8081-9ee78a233436) | [after](https://git.kayg.org/attachments/c004974f-5d47-493b-8bc3-3e333086a738) | | 390 dark | [before](https://git.kayg.org/attachments/3dd23870-6336-43fc-abf7-152d83d8ffa7) | [after](https://git.kayg.org/attachments/70d27d41-65e2-4cdb-aba9-a56fea36e6a9) | ### Gates `bun run check` output: ```text $ node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/sharestack-580/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test` summary output: ```text Test Files 140 passed (140) Tests 930 passed (930) Start at 09:54:09 Duration 122.03s (transform 49%, environment 20%, import 16%, tests 11%, setup 4%) ``` `bun run test:e2e:share-stack` summary output: ```text SHARE STACK AFTER PASSED CSP REPORTS share-stack: 0 across 1 pages ``` The production E2E checks the sheet's centre hit target, stacking, one blur owner, computed contrast, no text-shadow on rendered text, focus entry and restoration, and Escape behavior in all six viewport/theme combinations. Minimum measured contrast was 7.50:1. ### Performance profile `bench/share-stack.mjs` ran locally against the production SPA at load averages 20.50 / 21.53 / 20.31. Average click-to-next-frame p50/p95 was 390 px: 59.2/191 ms; 820 px: 179.5/321.1 ms; 1440 px: 260.1/697.2 ms. The eight-open burst p50/p95 was 390 px: 74.8/268.1 ms; 820 px: 222.1/239.0 ms; 1440 px: 170.7/361.2 ms. Mean server CPU was 6.10%, 1.11%, and 1.32%; mean RSS was 224.6, 231.0, and 237.8 MB respectively. These are noisy local measurements under high host load. `docs/perf/baseline.json` has no Share-stack profile for a direct comparison; the profile JSON is in ignored `artifacts/share-stack/share-stack-perf.json`. ### Files and decisions Changed files: `apps/web/src/lib/overlay/state.svelte.ts`, `packages/ui/src/components/OverlaySurface.svelte`, `packages/ui/src/components/menu/FloatingSurface.svelte`, `apps/web/src/lib/files/FilesBrowser.svelte`, `apps/web/src/lib/files/ShareDialog.svelte`, `apps/web/e2e/share-stack.mjs`, `bench/share-stack.mjs`, `apps/web/package.json`, and `docs/perf/README.md`. Decision not specified in DESIGN: each additional modal depth advances shared scrim and surface z-index by two roles, so the child scrim sits above its parent while its own surface stays above the scrim. The merged DESIGN §54 Share/Collaborate permission changes are outside #580; existing API-backed permission controls were left unchanged and are documented as a separate gap. Head SHA: `d0e327a3dcdc8c4730c2b7ec044383f84c26cc49` (`job/sharestack-580`). No Rust source or route contract changed, so Rust crate gates were not applicable. Build output was cleaned after the gates.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#580
No description provided.