338d80cf0a
Root causes the prior attempts missed: 1) Safari iOS/iPadOS ignores `interactive-widget=resizes-content`, so `100dvh` never shrinks when the soft keyboard opens. Every previous override that used `dvh` to size the dialog was sized to the full screen and ran behind the keyboard. 2) The CSS rule from #622 (`[role="dialog"]:has(:focus)`) was unconditional. On desktop, focusing any input inside a Radix DialogContent instantly stretched it to width:100vw + top:0, which collided with Radix's open-state slide-animation transforms and rendered the dialog as a broken narrow strip pinned in the top-left corner — visible in Tahani's laptop screenshot when opening "Add Meeting". 3) `AdminFormDialog` puts `role="dialog"` on a NON-fixed inner card, so the rule's `top/left/right` had no effect there anyway; the card stayed centred in a layout-viewport-sized wrapper which iOS does not shrink. Fix: - New `useVisualViewportVars` hook mounted in NotificationsSocketBridge. Writes `--vv-height` and `--vv-offset-top` on `<html>` from `window.visualViewport`, updated on resize / scroll / orientationchange. Falls back to `innerHeight`/0 if visualViewport is absent. - Rewrote the index.css dialog rule: * Gated inside `@media (any-pointer: coarse)` so desktop is completely unaffected. * Uses `var(--vv-height, 100vh)` and `var(--vv-offset-top, 0px)` instead of `100dvh` / `0`, so dialogs actually track the visible band on iOS. - New `.dialog-vv-wrapper` helper class that applies the same vv-sized top/height to bespoke full-screen overlay wrappers. - Applied `.dialog-vv-wrapper` to AdminFormDialog and the admin ConfirmDialog wrappers; switched their `fixed inset-0` to `fixed inset-x-0 top-0 h-screen` and their inner cards from `max-h-[90vh]`/`max-h-[85vh]` to `max-h-full` so the card shrinks with the wrapper. Kept `useScrollFocusedDialogField` unchanged — works correctly once the dialog itself is sized to the visible band. `tsc --noEmit` clean.