# 6.1 — Mobile Experience **Previous Step:** ← [Theme System](../../05-theming/5.1-theme-system/5.1-theme-system.md) --- ## Page Metadata | Property | Value | |----------|-------| | **Scenario** | 06 — Mobile Experience | | **Page Number** | 6.1 | | **Platform** | Web (PWA) — mobile viewport | | **Page Type** | Responsive Adaptation (all app shell components) | | **Viewport** | < 768px | | **Interaction** | Touch-first | --- ## Overview **Page Purpose:** Define how the entire CalcText workspace adapts to mobile. This is NOT a separate app — it's the same app intelligently restructured for touch and small screens. Every feature remains accessible; nothing is hidden or removed. **Current Problem:** The existing web app hides results, toolbar, and divider on mobile — effectively removing the product's value on the most common device type. **Success Criteria:** - All features accessible on mobile (calculations, results, file management, themes) - Touch targets >= 44px - One-handed operation possible for core flow (type → see result) - Feels like a native mobile app when installed as PWA --- ## Mobile Layout (< 768px) ``` ┌─────────────────────────────┐ │ Header [≡] CalcText [🎨]│ 44px (touch-sized) ├─────────────────────────────┤ │ Tab Bar (horizontal scroll) │ 40px ├─────────────────────────────┤ │ │ │ │ │ Editor │ │ (full width) │ │ │ │ │ │ │ ├─────────────────────────────┤ │ ═══ Results Tray │ 48px collapsed │ Last: $4,300 │ ├─────────────────────────────┤ │ Status (simplified) │ 24px └─────────────────────────────┘ ``` --- ## Component Adaptations ### Header (Mobile) | Property | Desktop | Mobile | |----------|---------|--------| | Height | 40px | 44px (touch target) | | Left content | Logo + "CalcText" | [≡] hamburger + "CalcText" | | Right content | Theme + Settings + ⌘ | [🎨] theme only | | Padding | 12px 12px | 8px 12px | | Hamburger | N/A | 44px × 44px touch target, opens sidebar drawer | ### Tab Bar (Mobile) | Property | Desktop | Mobile | |----------|---------|--------| | Height | 36px | 40px | | Tab min width | 100px | 80px (more compact) | | Close button | Visible on hover/active | Hidden — swipe left to reveal | | New tab (+) | After last tab | Sticky far-right | | Scroll | Mouse wheel | Touch swipe horizontal | | Active indicator | Top 2px accent border | Bottom 2px accent border (thumb reachable) | ### Editor (Mobile) | Property | Desktop | Mobile | |----------|---------|--------| | Width | Flex (shared with results) | 100vw | | Line padding | 12px | 12px | | Gutter | 40px (line numbers) | 32px (compact numbers) | | Font size | 15px | 15px (same — readable on mobile) | | Line height | 24px | 24px (same) | | Keyboard | Physical | Virtual — editor scrolls above keyboard | #### Virtual Keyboard Handling | Property | Value | |----------|-------| | Viewport | Uses `100dvh` (dynamic viewport height) to account for keyboard | | Scroll | Editor auto-scrolls to keep cursor visible above keyboard | | Results tray | Hides when keyboard is open (not enough space) | | Status bar | Hides when keyboard is open | ### Results Tray (Mobile) Replaces the side panel with a bottom tray. | State | Height | Content | |-------|--------|---------| | **Collapsed** | 48px | Drag handle + last non-empty result | | **Expanded** | 40vh (max 60vh) | Full scrollable results list | | **Hidden** | 0px | When virtual keyboard is open | #### Collapsed Tray | Property | Value | |----------|-------| | Background | var(--bg-secondary) | | Border top | 1px solid var(--border) | | Drag handle | 32px × 4px pill, var(--border), centered | | Content | "Last: {value}" — last non-empty result, text-xs | | Tap | Expand tray | | Swipe up | Expand tray | #### Expanded Tray | Property | Value | |----------|-------| | Content | All results paired with expressions | | Item format | Line number + expression snippet + result value | | Item height | 44px (touch-friendly) | | Active line | var(--accent-bg) highlight | | Tap result | Copy to clipboard + brief feedback | | Swipe down | Collapse tray | | Tap drag handle | Collapse | | Scroll | Independent vertical scroll | #### Tray Interaction ``` ┌──────────────────────────────┐ │ ═══ (drag handle) │ Swipe up to expand │ Last: $4,300 │ ├──────────────────────────────┤ ← expanded state below │ 5 salary 5,000 │ │ 6 freelance 1,200 │ │ 7 total_income 6,200 │ ← highlighted (active line) │ 9 rent 1,500 │ │ 10 groceries 400 │ │ 13 total_expenses 1,900 │ │ 14 savings 4,300 │ └──────────────────────────────┘ ``` ### Sidebar Drawer (Mobile) | Property | Value | |----------|-------| | Trigger | Hamburger [≡] in header | | Width | 85vw, max 320px | | Position | Fixed left, full height | | Background | var(--bg) | | Backdrop | rgba(0, 0, 0, 0.5) — tap to close | | Animation | translateX(-100%) → translateX(0), 200ms ease-out | | Close | Tap backdrop, swipe left, × button (top-right, 44px target) | | Content | Same sections as desktop sidebar (search, recent, favorites, files, templates) | | File tap | Opens document → auto-closes drawer | | Search | Full width, 44px height (touch target) | | File items | 44px height (touch target, up from 28px desktop) | ### Theme Picker (Mobile) | Property | Value | |----------|-------| | Trigger | [🎨] button in header | | Style | Bottom sheet (slides from bottom) | | Height | Auto (content-driven), max 60vh | | Border radius | 12px 12px 0 0 | | Drag handle | 32px × 4px pill, centered | | Items | 48px height per theme (touch targets) | | Accent swatches | 32px circles, 8px gap (larger for touch) | | Close | Swipe down, tap backdrop | ### Status Bar (Mobile) | Property | Value | |----------|-------| | Height | 24px (same) | | Content | Cursor position + engine status dot only | | Hidden items | Line count, theme indicator (accessible elsewhere) | | Hidden | When virtual keyboard is open | --- ## Touch Gestures | Gesture | Context | Action | |---------|---------|--------| | Swipe left on tab | Tab bar | Reveal close button | | Swipe up on results tray | Results | Expand tray | | Swipe down on results tray | Results | Collapse tray | | Swipe left from right edge | Sidebar drawer | Close drawer | | Swipe down on bottom sheet | Theme picker | Close sheet | | Long press on file | Sidebar | Show context menu | | Long press on tab | Tab bar | Drag to reorder | | Tap result | Results tray | Copy to clipboard | | Pinch | Editor | Zoom font size (optional) | --- ## Breakpoint Details | Width | Classification | Key Adaptations | |-------|---------------|-----------------| | **>= 1024px** | Desktop | Full 3-panel layout | | **768–1023px** | Tablet | Sidebar → overlay drawer. Editor + results side-by-side. | | **480–767px** | Mobile | Single column. Results tray. Sidebar drawer. Touch targets 44px. | | **< 480px** | Small mobile | Same as mobile. Tab labels may truncate. Logo text hidden. | ### Tablet Specifics (768–1023px) | Component | Behavior | |-----------|----------| | Sidebar | Overlay drawer (hamburger toggle) instead of persistent panel | | Editor + Results | Side-by-side with divider (same as desktop) | | Tab bar | Same as desktop (enough width) | | Header | Show hamburger [≡] instead of persistent sidebar | | Theme picker | Dropdown (same as desktop) | --- ## PWA Mobile Enhancements | Feature | Implementation | |---------|---------------| | Standalone display | `display: standalone` — no browser chrome | | Status bar color | `theme-color` meta tag updates per theme | | Safe areas | `env(safe-area-inset-*)` for notched devices | | Splash screen | Theme-colored background + CalcText logo | | Home screen icon | App icon with accent color ring | | Orientation | Portrait preferred, landscape supported | ### Safe Area Padding ```css .calcpad-app { padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); } ``` --- ## Page States (Mobile-Specific) | State | When | Behavior | |-------|------|----------| | **Keyboard open** | User tapped editor | Results tray + status bar hide. Editor fills available space. | | **Keyboard closed** | User tapped outside or pressed Done | Results tray + status bar reappear. | | **Drawer open** | Hamburger tapped | Sidebar overlays. Backdrop captures tap to close. | | **Tray expanded** | User swiped up | 40vh results list. Editor partially visible above. | | **Offline** | No network | Status bar shows offline indicator. All features work. | --- ## Technical Notes - **Viewport units:** Use `dvh` (dynamic viewport height) not `vh` to handle mobile browser chrome and virtual keyboard. - **Touch events:** Use `touchstart`/`touchmove`/`touchend` for swipe gestures. Consider `passive: true` for scroll performance. - **Overscroll:** Disable `overscroll-behavior: none` on app container to prevent pull-to-refresh interference. - **iOS safe areas:** Test with iPhone notch and dynamic island. Apply `env(safe-area-inset-*)`. - **Android back button:** In PWA mode, back button should close drawers/sheets before navigating back. - **Font scaling:** Respect system font size on mobile. Use relative units where possible. - **Cross-platform:** Mobile web layout does NOT need to port to native mobile (that's a separate app). But interaction patterns (swipe, long-press) inform native mobile design if built later. --- _Created using Whiteport Design Studio (WDS) methodology_