Merge pull request #34 from arnlaugsson/fix/ipad-safari-toolbar-viewport

fix: toolbar off-screen on iPad Safari with tabs
This commit is contained in:
Ark0N
2026-03-11 01:26:55 +01:00
committed by GitHub
4 changed files with 37 additions and 3 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<meta name="description" content="Claude Code session manager with web interface">
<meta name="theme-color" content="#0a0a0a">
<meta name="google" content="notranslate">
@@ -25,7 +25,7 @@
<script>if(window.innerWidth<768||(('ontouchstart' in window||navigator.maxTouchPoints>0)&&window.innerWidth<1024))document.documentElement.classList.add('mobile-init');</script>
<!-- Inline critical CSS for instant skeleton paint (before styles.css loads) -->
<style>
.loading-skeleton{display:flex;flex-direction:column;height:100vh;background:#0a0a0a}
.loading-skeleton{display:flex;flex-direction:column;height:100vh;height:100dvh;background:#0a0a0a}
.skeleton-header{height:40px;background:#111;border-bottom:1px solid #1a1a2e;display:flex;align-items:center;padding:0 12px}
.skeleton-brand{color:#60a5fa;font-size:14px;font-weight:600;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;opacity:.7}
.skeleton-tabs{display:flex;gap:4px;margin-left:16px}
+20 -1
View File
@@ -98,14 +98,33 @@ const MobileDetection = {
}
},
/** Set --app-height CSS variable from visual viewport.
* On iPad Safari with tabs, 100vh extends behind the tab bar.
* visualViewport.height reflects the actual visible area. */
updateAppHeight() {
const vh = window.visualViewport?.height || window.innerHeight;
document.documentElement.style.setProperty('--app-height', `${vh}px`);
},
/** Initialize mobile detection and set up resize listener */
init() {
this.updateBodyClass();
this.updateAppHeight();
// Update --app-height on viewport resize (orientation, tab bar toggle)
if (window.visualViewport) {
this._appHeightHandler = () => this.updateAppHeight();
window.visualViewport.addEventListener('resize', this._appHeightHandler);
}
// Debounced resize handler
let resizeTimeout;
this._resizeHandler = () => {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => this.updateBodyClass(), 100);
resizeTimeout = setTimeout(() => {
this.updateBodyClass();
this.updateAppHeight();
}, 100);
};
window.addEventListener('resize', this._resizeHandler);
+8
View File
@@ -1903,6 +1903,14 @@ html.mobile-init .file-browser-panel {
overscroll-behavior: none;
}
/* iPad Safari with tabs: position: fixed uses the layout viewport which extends
behind the browser chrome (tab bar). Calculate the offset between the layout
viewport (innerHeight) and the visual viewport (--app-height) to push the
toolbar into the visible area. --app-height is set by MobileDetection.updateAppHeight(). */
.ios-device.safari-browser .toolbar {
bottom: calc(var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)));
}
.ios-device.safari-browser .terminal-container {
/* Keep momentum scrolling but prevent page bounce */
-webkit-overflow-scrolling: touch;
+7
View File
@@ -116,6 +116,8 @@ body {
background: var(--bg-dark);
color: var(--text);
height: 100vh;
height: 100dvh;
height: var(--app-height, 100dvh);
overflow: hidden;
}
@@ -124,6 +126,8 @@ body {
display: flex;
flex-direction: column;
height: 100vh;
height: 100dvh;
height: var(--app-height, 100dvh);
}
/* Compact Header */
@@ -4447,6 +4451,7 @@ kbd {
right: 0;
width: 340px;
height: calc(100vh - var(--header-height));
height: calc(100dvh - var(--header-height));
background: var(--bg-card);
border-left: 1px solid var(--border);
z-index: 10001;
@@ -5815,6 +5820,7 @@ kbd {
left: 0;
width: 100vw;
height: 100vh;
height: 100dvh;
pointer-events: none;
z-index: 999; /* Below windows (1000+), above panels (91) */
}
@@ -6042,6 +6048,7 @@ kbd {
right: 20px;
width: 280px;
height: calc(100vh - var(--header-height) - var(--toolbar-height) - 40px);
height: calc(100dvh - var(--header-height) - var(--toolbar-height) - 40px);
max-height: 600px;
min-width: 200px;
min-height: 300px;