Mobile: complete PWA experience with Liquid Glass UI#61
Merged
jcanizalez merged 11 commits intomainfrom Mar 18, 2026
Merged
Conversation
- Add touch-action: manipulation globally to all interactive elements (kills 300ms tap delay on mobile browsers) - Add @media (hover: none) rules to show hover-revealed action buttons on touch devices (pin, archive, rename, sidebar actions) - Increase traffic light dots to 22px on touch devices for better tap targets - Add active: states across all buttons for visual touch feedback - Increase button padding on mobile (p-2 -> p-2.5 for action buttons, py-1.5 -> py-2.5 for menu items) - Update Tooltip to skip on touch devices (prevents blocking taps), use ref callback for positioning instead of setState in effect - Migrate outside-click listeners from mousedown to pointerdown for unified mouse+touch handling in ConfirmPopover, CardContextMenu, and ProjectSidebar context menus - Increase scroll-to-bottom button from w-6 h-6 to w-8 h-8 - AgentCard: always show pin/archive on touch (no hover needed)
…ainment - Add viewport-fit=cover to web index.html for iOS notch/Dynamic Island - Define CSS custom properties --safe-top/right/bottom/left from env() - Switch root container from h-screen to h-dvh with safe area padding - Update all fixed-position overlays (Toast, FocusedTerminal, Settings, DiffSidebar, TaskDiffReview, WorkflowEditor, ProjectSidebar mobile) to respect safe area insets - Add overscroll-behavior: contain to prevent iOS rubber-band overscroll - Sync web package global.css with touch-action and hover:none rules
…sualViewport fallback - Add interactive-widget=resizes-content to viewport meta (Chrome/Android) - Create useVirtualKeyboard hook with three-tier strategy: 1. VirtualKeyboard API (navigator.virtualKeyboard) for Chrome 94+ 2. visualViewport resize/scroll events for Safari/iOS fallback 3. Graceful no-op on non-touch devices - Hook sets --keyboard-height CSS custom property and refits all terminals - Add fitAllTerminals() to terminal-registry for keyboard geometry changes - App root bottom padding includes --keyboard-height for Safari layout shift - Toast position accounts for --keyboard-height to stay above keyboard - Add --keyboard-height: 0px default to both global.css files
- Enforce minimum 14px terminal font size on touch devices (was 13px) - Add pinch-to-zoom hook for terminal font size adjustment on mobile - Add floating font size +/- control in focused terminal view (mobile only) - Set body text to 16px with 1.5 line-height on mobile viewports - Boost gray-500/gray-600 text contrast on mobile for WCAG AA compliance - Apply typography improvements to both Electron and web app CSS
- New MobileBottomTabs component with 4 tabs: Sessions, Tasks, New, Settings - Cyan accent on active tab indicator dot and New button icon - Hidden when virtual keyboard is open to maximize screen space - Replaces Sessions/Tasks toggle in top bar on mobile (declutters header) - 52px min height with 44px+ touch targets per tab - Desktop layout completely unchanged
- New MobileSinglePane component replaces GridView on mobile - Shows one terminal at a time, full height, instead of scrollable grid - Swipe left/right to navigate between terminals (50px min, 300ms max) - Dot indicators + arrow buttons when 2+ terminals are open - Active dot highlighted in cyan, clickable for direct jump - Uses store selectedTerminalId as source of truth (syncs with sidebar/shortcuts) - Falls back to PromptLauncher when no sessions exist - Desktop grid/tab layout completely unchanged
Floating bar with Esc, Tab, Ctrl (sticky toggle), arrow keys, pipe, slash, tilde, dash, underscore. Renders inside FocusedTerminal on mobile viewports. Uses onPointerDown + preventDefault to avoid stealing focus from xterm.js. Ctrl auto-unsticks after 5s or next keypress. Sends keystrokes via window.api.writeTerminal.
Install vite-plugin-pwa with Workbox for service worker generation. Cache-First for static assets, Network-First for API calls. Adds offline fallback page, enhanced manifest with id, display_override, and orientation fields. Registers SW in main.tsx independently of WebSocket connection. Enables "Add to Home Screen" installability.
Port iOS 26 Liquid Glass material to mobile viewports only (< 768px). Desktop Electron app is completely untouched. Glass material: - CSS variables (--glass-bg, --glass-blur, --glass-shadow) scoped inside @media (max-width: 767px) in both global.css files - Framework7 v9 dark mode values: 8-layer inset box-shadow stack, saturate(180%) blur(16px), rgba(50,50,50,0.5) background Component changes: - MobileBottomTabs: floating glass capsule pill (rounded-[32px]), inset from edges, glass-shadow-thumb on active tab. Removed "New" tab (actions moved to top bar glass buttons) - MobileTerminalKeybar: two-row iOS 26-native layout. Row 1: ESC/TAB/CTL pills + arrow d-pad cluster. Row 2: 10 symbol pills. Pill-shaped (rounded-full) instead of rectangular - MobileFontSizeControl: glass material via CSS variables - MobileSinglePane: rewritten from swipe navigation to scrollable card list with MobileSessionCard. Tap card to open FocusedTerminal - FocusedTerminal: full-screen on mobile (no inset/rounded), back button (ChevronDown), hide desktop-only elements (kbd hints, traffic lights, OpenInButton) - App.tsx: glass hamburger and "+" buttons on mobile via isMobile guard, bottom padding for floating tab bar - Toast, ConfirmPopover, CardContextMenu: glass on mobile via useIsMobile hook, desktop unchanged QA screenshots in screenshots/ directory.
There was a problem hiding this comment.
Pull request overview
This PR upgrades VibeGrid’s web/renderer UI for a mobile-first experience and adds PWA support, including safe-area handling, virtual keyboard awareness, mobile-specific navigation/controls, and “Liquid Glass” styling applied only on small viewports.
Changes:
- Add mobile UX foundations: safe-area insets, touch interaction tweaks, improved terminal font sizing/zoom, and keyboard-aware layout refitting.
- Introduce mobile UI components (bottom tabs, focused terminal controls, keybar) and apply glass styling to selected overlays/menus.
- Add PWA service worker + Workbox runtime caching, enhanced manifest metadata, and an offline page.
Reviewed changes
Copilot reviewed 29 out of 39 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/renderer/lib/terminal-registry.ts | Adds font-size helpers and a “fit all terminals” utility used by keyboard handling. |
| src/renderer/hooks/useVirtualKeyboard.ts | New hook to detect virtual keyboard geometry and update CSS vars + refit terminals. |
| src/renderer/hooks/useTerminalPinchZoom.ts | New pinch-to-zoom hook that adjusts/persists terminal font size on touch devices. |
| src/renderer/hooks/useSwipeNavigation.ts | Adds a generic swipe gesture hook (horizontal flick detection). |
| src/renderer/global.css | Adds safe-area variables, touch interaction adjustments, mobile typography, and glass CSS variables. |
| src/renderer/components/workflow-editor/WorkflowEditor.tsx | Applies safe-area padding to the full-screen workflow editor overlay. |
| src/renderer/components/TrafficLights.tsx | Shows traffic-light icons on touch devices (no hover) and tweaks interaction. |
| src/renderer/components/Tooltip.tsx | Disables tooltips on touch devices and refactors positioning logic. |
| src/renderer/components/Toast.tsx | Makes toast position keyboard/safe-area aware and applies glass styling on mobile. |
| src/renderer/components/TaskDiffReview.tsx | Adds safe-area padding to the diff review sidebar overlay. |
| src/renderer/components/SettingsPage.tsx | Adds safe-area padding to settings overlay. |
| src/renderer/components/ProjectSidebar.tsx | Improves touch target sizes/active states; switches outside-click handling to pointer events; adds safe-area padding. |
| src/renderer/components/MobileTerminalKeybar.tsx | New mobile terminal accessory keybar with modifiers, arrows, and symbol pills. |
| src/renderer/components/MobileSinglePane.tsx | New mobile sessions view: scrollable card list opening a focused terminal overlay. |
| src/renderer/components/MobileFontSizeControl.tsx | New mobile floating font-size control and persistence behavior. |
| src/renderer/components/MobileBottomTabs.tsx | New bottom tab navigation for mobile (Sessions/Tasks/Settings). |
| src/renderer/components/FocusedTerminal.tsx | Mobile-focused terminal overlay: safe-area padding, back affordance, pinch zoom support, mobile controls + keybar. |
| src/renderer/components/DiffSidebar.tsx | Adds safe-area padding to diff sidebar overlay. |
| src/renderer/components/ConfirmPopover.tsx | Uses pointer events for outside click; applies glass styling + touch-friendly padding on mobile. |
| src/renderer/components/CardContextMenu.tsx | Uses pointer events for outside click; applies glass styling + touch-friendly padding on mobile. |
| src/renderer/components/AgentCard.tsx | Improves touch behavior (pointerdown selection, always-visible actions on touch, larger tap targets). |
| src/renderer/App.tsx | Integrates mobile layout (dvh, safe-area/keyboard padding), mobile session pane, bottom tabs, and virtual keyboard hook. |
| screenshots/desktop-no-regression.png | Adds a desktop regression screenshot artifact. |
| packages/web/vite.config.ts | Adds vite-plugin-pwa with Workbox caching strategies and navigation fallback. |
| packages/web/src/pwa.d.ts | Adds PWA client type references for TS. |
| packages/web/src/main.tsx | Registers the service worker before initializing the API shim/React app. |
| packages/web/src/global.css | Mirrors mobile safe-area/touch/glass styling for the web package. |
| packages/web/public/offline.html | Adds an offline informational fallback page. |
| packages/web/public/manifest.webmanifest | Enhances PWA manifest (id, display_override, orientation, icon purpose). |
| packages/web/package.json | Adds vite-plugin-pwa dev dependency. |
| packages/web/index.html | Updates viewport meta (viewport-fit + interactive-widget) and uses 100dvh for loader layout. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
370
to
+375
| /** | ||
| * Update font size on all terminals and re-fit them. | ||
| * On touch devices the minimum is enforced automatically. | ||
| */ | ||
| export function setAllTerminalsFontSize(fontSize: number): void { | ||
| const effective = getEffectiveFontSize(fontSize) |
src/renderer/App.tsx
Outdated
| <main className="flex-1 flex flex-col overflow-hidden"> | ||
| <main | ||
| className="flex-1 flex flex-col overflow-hidden" | ||
| style={isMobile ? { paddingBottom: 'calc(64px + var(--safe-bottom, 0px))' } : undefined} |
Comment on lines
+12
to
+15
| workbox: { | ||
| navigateFallback: '/app/index.html', | ||
| navigateFallbackAllowlist: [/^\/app/], | ||
| runtimeCaching: [ |
Tooltip.tsx called window.matchMedia at module scope without checking if the function exists. This broke tooltip.test.tsx in jsdom (which lacks matchMedia). Add typeof check before the call.
Main content area reserved 64px bottom padding for the floating tab bar even when the virtual keyboard was visible (and the tab bar hidden). Now the padding is conditional on keyboardHeight === 0. Also fix misleading JSDoc on setAllTerminalsFontSize — callers handle their own clamping, the function just applies getEffectiveFontSize.
This was referenced Mar 19, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Complete mobile experience for VibeGrid's web app — from first touch to installable PWA.
9 commits across 2 branches (
feat/mobile-improvements→feat/mobile-keyboard-pwa):Foundation (6 commits)
viewport-fit=coverand CSS env() variablesKeyboard & PWA (2 commits)
display_overrideand orientationLiquid Glass + Redesign (1 commit)
@media max-width: 767px), desktop completely untouched--glass-bg,--glass-blur,--glass-shadow,--glass-shadow-thumb(8-layer inset box-shadow stack)useIsMobilehookFiles changed
Test plan
🤖 Generated with Claude Code