Transform CalcText from a single-document calculator into a full workspace application with multi-document support, theming, and responsive mobile experience. - Theme system: 5 presets (Light, Dark, Matrix, Midnight, Warm) + accent colors - Document model with localStorage persistence and auto-save - Tab bar with keyboard shortcuts (Ctrl+N/W/Tab/1-9), rename, close - Sidebar with search, recent, favorites, folders, templates, drag-and-drop - 5 templates: Budget, Invoice, Unit Converter, Trip Planner, Loan Calculator - Status bar with cursor position, engine status, dedication to Igor Cassel - Results panel: type-specific colors, click-to-copy, error hints - Format toolbar: H, B, I, //, color labels with live preview toggle - Syntax highlighting using theme CSS variables - Error hover tooltips - Mobile: bottom results tray, sidebar drawer, touch targets, safe areas - Docker multi-stage build (Rust WASM + Vite + Nginx) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
279 lines
10 KiB
Markdown
279 lines
10 KiB
Markdown
# 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_
|