- Force font-size:16px !important on Styles-sheet/topbar/Sitesmith inputs
inside the mobile media query so inline 12px/14px styles stop triggering
iOS zoom-on-focus.
- Lift sheet-open + Templates/Head Code modal-open state out of private
useState into a shared MobileChromeContext (EditorShell), so Phase B can
open/close sheets from outside MobilePanelBar.
- Add an explicit z-index layer scale, portal TemplateModal to
document.body (was trapped under the tab bar inside .topbar's stacking
context), align Sitesmith to the same --z-modal layer, and make opening
a sheet close any open modal. Also fix modal backdrops swallowing tab
bar taps (mirrors the sheet backdrop's existing tab-bar cutout).
- Drop BottomSheet's incorrect aria-modal; mobile-aware AssetsPanel empty
state copy.
- Tests: useIsMobile (matchMedia mock incl. legacy fallback + cleanup),
MobileChromeContext invariants (one sheet open, sheet closes modals),
MobilePanelBar wiring.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New src/ui/Modal.tsx ({ open, onClose, title?, children, width?,
closeOnEscape?, closeOnBackdropClick?, backdropStyle?, backdropProps? })
owns the backdrop, Escape-to-close, backdrop-click-to-close, and a new
body-scroll-lock while open. Adopted by TemplateModal, HeadCodeModal, and
SitesmithModal; each keeps its own panel styling/header/footer as children
since those differ per modal.
- TemplateModal: Escape/backdrop-click still close the confirm-template
sub-dialog first via a wrapped onClose passed to Modal; the header's X
button keeps using the raw onClose prop (always fully closes), matching
prior asymmetric behavior.
- HeadCodeModal: straightforward adoption, no prior custom close logic.
- SitesmithModal: previously had no `open` prop, no Escape-to-close, and no
backdrop-click-to-close. Preserved via open (always mounted-open by its
parent already), closeOnEscape={false}, closeOnBackdropClick={false}; role
and aria-modal are passed through via backdropProps to keep them on the
same backdrop element as before.
Body scroll-lock while a modal is open is a small new addition (requested by
the task) applied uniformly; it has no visible effect since each modal's
opaque fixed-position backdrop already fully covers the viewport.
Added a light Modal.test.tsx (renders children, Escape/backdrop-click close
behavior, scroll-lock) using the existing react-dom/client + act harness.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>