ux(ocr): one more shot at the mobile modal layout

Previous attempt was actually-broken — typo notwithstanding, the
mix of 100vh, no explicit flex-shrink, and inconsistent body
padding was easy for the body to grow and shove the footer
buttons offscreen.

This pass:
- 100dvh instead of 100vh (mobile chrome / address bar collapses
  don't cause overflow / under-shoot)
- flex-shrink: 0 on .modal-header and .modal-footer so the body
  can never squeeze them out
- explicit background on the footer so it's not transparent
  against whatever's behind
- camera <video> fills modal-body with object-fit: contain
- body padding kept just enough (~16 px) for crop handle safety
This commit is contained in:
João Pedro Battistella Nadas
2026-06-09 19:42:36 +02:00
parent 29226500e8
commit ffa133261d

View File

@@ -300,7 +300,7 @@
} }
/* On mobile: full-bleed modal, buttons hug the screen edges. Body padding /* On mobile: full-bleed modal, buttons hug the screen edges. Body padding
still ~20 px so cropper corner handles stay outside Android's edge-swipe still ~16 px so cropper corner handles stay outside Android's edge-swipe
gesture zone — tapping a button doesn't trigger it, but dragging into gesture zone — tapping a button doesn't trigger it, but dragging into
the very edge does. */ the very edge does. */
@media (max-width: 640px) { @media (max-width: 640px) {
@@ -308,24 +308,35 @@
.modal { .modal {
width: 100vw; width: 100vw;
max-width: 100vw; max-width: 100vw;
height: 100vh; height: 100dvh; /* dynamic viewport — accounts for mobile browser chrome */
max-height: 100vh; max-height: 100dvh;
border: 0;
border-radius: 0; border-radius: 0;
} }
.modal-header { .modal-header {
flex-shrink: 0; /* never get squeezed out by the body */
padding-top: max(0.75rem, env(safe-area-inset-top, 0px)); padding-top: max(0.75rem, env(safe-area-inset-top, 0px));
} }
.modal-body { .modal-body {
flex: 1 1 auto;
min-height: 0;
padding: padding:
1rem 0.5rem
max(1.25rem, env(safe-area-inset-right, 0px)) max(1rem, env(safe-area-inset-right, 0px))
1rem 0.5rem
max(1.25rem, env(safe-area-inset-left, 0px)); max(1rem, env(safe-area-inset-left, 0px));
max-height: none; max-height: none;
} }
.cam-body { padding: 0 !important; } .cam-body { padding: 0 !important; }
.cam-body video { max-height: none; } .cam-body video {
width: 100%;
height: 100%;
max-height: none;
object-fit: contain;
}
.modal-footer { .modal-footer {
flex-shrink: 0;
background: var(--bg); /* explicit so it always reads clearly */
padding: padding:
0.5rem 0.5rem
max(0.5rem, env(safe-area-inset-right, 0px)) max(0.5rem, env(safe-area-inset-right, 0px))