Skip to content

Mobile preview toggle in desktop Settings → Developer

Mobile preview toggle in desktop Settings → Developer

Status: Delivered
CAS: CAS-2813
Delivered: 2026-05-14
PRs: #754

What’s new

In development builds, a new Developer card in Settings lets you simulate how the app looks on iPhone or iPad — directly in your desktop browser, no device required. You can select a device profile (iPhone 14 Pro, iPhone SE, iPad Mini) and the app renders inside a phone-shaped frame at exact device dimensions, with correct safe-area insets applied. Switching back to “Off” restores the desktop layout instantly.

How to use it

  1. Run the dev build (deno task dev or cargo tauri dev).
  2. Open Settings — a new Developer section appears at the bottom (hidden in production builds).
  3. Under Mobile preview, select a device: iPhone 14 Pro (393×852), iPhone SE (375×667), or iPad Mini (768×1024).
  4. The app switches to the full mobile layout inside a centered device frame. You can navigate all routes, interact with the mobile nav bar, and inspect safe-area behaviour.
  5. Select Off to return to the desktop layout. Your selection persists across page refreshes (localStorage-backed).

This is a diagnostic tool for engineers and the regent — it was added specifically to test CAS-2785 hypotheses (CSS-caused vs WebKit-native dead-band bugs) without needing a physical device build.

What changed under the hood

  • src/store/useMobilePreviewStore.ts — new Zustand store holding the active device profile and DEVICE_PROFILES map; persisted to localStorage.
  • src/components/MobilePreviewFrame.tsx — wrapper around RouterProvider; when a device is active it renders a fixed-size iframe-like frame and injects --safe-area-inset-top, --safe-area-inset-bottom, --preview-viewport-height CSS custom properties on <html>.
  • src/components/settings/DeveloperCard.tsx — the new dev-only card with the device <Select> dropdown; rendered only when import.meta.env.DEV is true.
  • src/utils/platform.tsuseIsMobile() reads the preview store in dev builds, so the mobile layout (MobileNavbar, mobile scroll area) activates when any device is selected.
  • src/components/navbar/MobileNavbar.tsx and src/App.tsx — safe-area and height calculations switched to var(--safe-area-inset-*) / var(--preview-viewport-height, 100vh) so preview-injected values take precedence over env() on desktop.

Why we built it

Every safe-area layout bug so far required a TestFlight build to repro — a slow loop. The mobile preview gives engineers and the regent an instant feedback loop: open the desktop app, toggle iPhone 14 Pro, and the bug (or its fix) is visible in seconds. It also makes it trivial to test responsive layout edge cases across device sizes without maintaining a device farm.

Known limitations / follow-on work

  • Hidden behind import.meta.env.DEV — not available in production or TestFlight builds by design.
  • The frame simulates CSS layout; it does not simulate WebKit scrolling physics, WKWebView quirks, or native gesture recognizers. For those, a physical device or iOS Simulator is still needed.
  • iPad Mini profile renders at 768 × 1024 but the responsive breakpoints in useIsMobile are based on width, so iPad may not show the mobile nav unless it’s below the 768 px cutoff.