Two fixed delays into the keyboard's animation is not where it ends: the
composer read the viewport mid-slide, and on the way out - when the navbar
comes back - nothing re-measured at all, so the panel stayed pushed up or
sat back under the bar. In a sidedock drawer no resize event fires either,
so a phone's keyboard moved nothing there.
The inset is now re-measured every frame until the reading holds still, and
blur is a trigger as much as focus. `inset()` returns what it wrote so the
loop can tell it has settled rather than counting milliseconds.
Obsidian styles every `button` with `justify-content: center`, so the reset
answers with `flex-start` - which also lands on a grid button and overrides
the inline half of its `place-items: center`. The rail's connection dot came
out pinned 12px left of centre inside its own hit area.
The inset only knew the desktop status bar, so on a phone the composer sat
under the navbar - which paints over a leaf instead of shortening it - and
the software keyboard hid it outright. Every bottom bar is measured now, and
the keyboard is read off `visualViewport`: it shrinks the visible area
without resizing the layout, so no workspace event fires and the panel had
no way to know. Focus re-measures once iOS has finished animating the keys in.
The panel asks the shell to fall back to the latest master, so opening it on
a phone lands in the day's thread rather than on a prompt.
The preview fixtures anchor at midday instead of the wall clock: spread over
hours, a run just after midnight pushed half of them into yesterday and
emptied the "Today" group the switcher smoke checks.