diff --git a/client/app.js b/client/app.js index a2ccafa..b302c13 100644 --- a/client/app.js +++ b/client/app.js @@ -90,10 +90,20 @@ class GolfGame { } initMobileDetection() { + // Set --app-height custom property to actual visible viewport height. + // This works around Chrome Android's 100vh bug where vh includes the + // space behind the dynamic URL bar. + const setAppHeight = () => { + document.documentElement.style.setProperty('--app-height', `${window.innerHeight}px`); + }; + window.addEventListener('resize', setAppHeight); + setAppHeight(); + const mql = window.matchMedia('(max-width: 500px) and (orientation: portrait)'); const update = (e) => { this.isMobile = e.matches; document.body.classList.toggle('mobile-portrait', e.matches); + setAppHeight(); // Close any open drawers on layout change if (!e.matches) { this.closeDrawers(); diff --git a/client/style.css b/client/style.css index 95cdfb2..b0e256d 100644 --- a/client/style.css +++ b/client/style.css @@ -4906,9 +4906,7 @@ body.screen-shake { } body.mobile-portrait { - height: 100vh; - height: -webkit-fill-available; - height: 100dvh; + height: var(--app-height, 100vh); overflow: hidden; overscroll-behavior: contain; touch-action: manipulation; @@ -4916,19 +4914,18 @@ body.mobile-portrait { body.mobile-portrait #app { padding: 0; - height: 100%; + height: var(--app-height, 100vh); overflow: hidden; } /* --- Mobile: Game screen fills viewport --- */ /* IMPORTANT: Must include .active to avoid overriding .screen { display: none } */ body.mobile-portrait #game-screen.active { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; + height: var(--app-height, 100vh); + max-height: var(--app-height, 100vh); overflow: hidden; + margin-left: 0; + width: 100%; display: flex; flex-direction: column; }