Fix mobile keyboard layout: size chat to visualViewport; bottom-anchor messages
The chat used height:100%, which doesn't shrink when the on-screen keyboard opens, so content scrolled out of view. Now sized to --app-height (tracked from window.visualViewport, with a 100dvh fallback), and #feed::before margin-top:auto keeps a few messages pinned just above the composer.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2 files changed,
+19
−2
web/static/chat.js+12 −0web/static/style.css+7 −2
diff --git a/web/static/chat.js b/web/static/chat.js| index 9f96200..b965e8f 100644 |
| --- a/web/static/chat.js |
| +++ b/web/static/chat.js |
| @@ -16,6 +16,18 @@ const SESSION_KEY = "lchat_session"; |
| const app = document.getElementById("app"); |
| const session = loadSession(); |
| +// Track the *visible* viewport height (it shrinks when the mobile keyboard opens) |
| +// so the chat fits above the keyboard instead of overflowing off-screen. |
| +function setAppHeight() { |
| + const h = (window.visualViewport && window.visualViewport.height) || window.innerHeight; |
| + document.documentElement.style.setProperty("--app-height", h + "px"); |
| +} |
| +setAppHeight(); |
| +window.visualViewport?.addEventListener("resize", setAppHeight); |
| +window.visualViewport?.addEventListener("scroll", setAppHeight); |
| +window.addEventListener("resize", setAppHeight); |
| +window.addEventListener("orientationchange", () => setTimeout(setAppHeight, 150)); |
| + |
| route(); |
| // Full-screen onboarding steps come before the chat feed: "Add to Home Screen" |
diff --git a/web/static/style.css b/web/static/style.css| index 50a06a2..a89cff8 100644 |
| --- a/web/static/style.css |
| +++ b/web/static/style.css |
| @@ -53,7 +53,7 @@ input:focus, textarea:focus { outline: 2px solid var(--accent); border-color: tr |
| /* ---- centered card layout (join / fallback) ---- */ |
| .center { |
| - min-height: 100%; |
| + min-height: var(--app-height, 100%); |
| display: grid; |
| place-items: center; |
| padding: 24px; |
| @@ -75,7 +75,7 @@ input:focus, textarea:focus { outline: 2px solid var(--accent); border-color: tr |
| .chat { |
| display: flex; |
| flex-direction: column; |
| - height: 100%; |
| + height: var(--app-height, 100dvh); |
| max-width: 720px; |
| margin: 0 auto; |
| background: var(--panel); |
| @@ -151,6 +151,11 @@ input:focus, textarea:focus { outline: 2px solid var(--accent); border-color: tr |
| flex-direction: column; |
| gap: 4px; |
| } |
| +/* push a few messages to the bottom (near the composer); scrolls normally when full */ |
| +#feed::before { |
| + content: ""; |
| + margin-top: auto; |
| +} |
| .msg { display: flex; flex-direction: column; max-width: 78%; margin-top: 10px; } |
| .msg .name { font-size: 12px; color: var(--muted); margin: 0 6px 3px; } |
| .msg .bubble { |