fix(engine): centre modal cards within usable area (status-bar + gesture-bar)
Build and Deploy / build-and-push (push) Failing after 52s
Web E2E / web-e2e (push) Failing after 4m33s

apply_safe_area_to_modal_scrims now sets both padding.top (status-bar
height) and padding.bottom (gesture-bar height) on every ModalScrim.
With align_items/justify_content: Center on the scrim, the modal card
lands at the visual midpoint of the visible area between the two system
bars, fixing the slight upward shift that occurred when only the bottom
inset was applied.

Also: mark all rewrite-plan phases (0–3) complete; drop obsolete stash
whose 20 files are already incorporated into master; update CLAUDE.md
§14.3 to document both edges.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-06-08 17:34:28 -07:00
parent 26f1b00186
commit 6193d31497
3 changed files with 23 additions and 6 deletions
+5 -3
View File
@@ -430,9 +430,11 @@ explicitly replacing the current one (despawn first, then spawn).
## 14.3 Safe area
Every `ModalScrim` automatically receives `padding.bottom` equal to the
logical gesture-bar height via `apply_safe_area_to_modal_scrims` in
`SafeAreaInsetsPlugin`. Do not manually add bottom padding to scrim nodes.
Every `ModalScrim` automatically receives `padding.top` equal to the logical
status-bar height and `padding.bottom` equal to the logical gesture-bar height
via `apply_safe_area_to_modal_scrims` in `SafeAreaInsetsPlugin`. This centres
the modal card within the usable area between both system bars. Do not manually
add top or bottom padding to scrim nodes.
## 14.4 Z-ordering
+1 -1
View File
@@ -2,7 +2,7 @@
**Date:** 2026-06-08
**Upstream rev:** `99b49e62`
**Status:** Phases 02 complete. Pre-Phase 3 undo audit complete (see §5 below). Awaiting approval for Phase 3.
**Status:** All phases complete (03). recycle_count drift and score compound error on undo fixed in `56e3b62`.
---
+17 -2
View File
@@ -147,8 +147,13 @@ fn apply_safe_area_bottom_anchors(
}
}
/// Pads the bottom of every [`ModalScrim`] by the logical bottom inset so
/// modal cards don't extend into the Android gesture-navigation zone.
/// Pads both edges of every [`ModalScrim`] by the logical system-bar insets so
/// modal cards are centred within the usable area (between the status bar at
/// the top and the gesture-navigation bar at the bottom).
///
/// `padding.top` = status-bar inset; `padding.bottom` = gesture-bar inset.
/// With `align_items: Center` / `justify_content: Center` on the scrim the
/// `ModalCard` lands at the visual midpoint of the visible content area.
///
/// Fires when [`SafeAreaInsets`] changes (covers the common case of insets
/// arriving a few frames after app start) AND when a new `ModalScrim` is
@@ -165,8 +170,18 @@ fn apply_safe_area_to_modal_scrims(
}
let scale = windows.iter().next().map_or(1.0, |w| w.scale_factor());
let window_height = windows.iter().next().map_or(800.0, |w| w.height());
// Clamp each inset to 25% of screen height so an unexpectedly large OS
// value can't push the modal card off the visible area entirely.
let top_logical = (insets.top / scale).min(window_height * 0.25);
let bottom_logical = (insets.bottom / scale).min(window_height * 0.25);
for mut node in &mut scrims {
// Set both edges so the scrim's content box equals the usable area
// between the status bar and the gesture/navigation bar. With
// `align_items: Center` / `justify_content: Center` on the scrim,
// the modal card is centred within that usable region rather than
// the full viewport, correcting the slight upward shift seen when
// only the bottom inset was applied.
node.padding.top = Val::Px(top_logical);
node.padding.bottom = Val::Px(bottom_logical);
}
}