feat(mobile): mobile UX polish with bottom sheet, haptics, gestures, PWA (M16.1-M16.10)

- BottomSheet.vue: gesture-driven with 40/80/100% snap points, backdrop
- Swipe navigation: left/right to switch conversations, 80px threshold
- Pull-to-refresh: custom glass spinner, haptic on release
- Haptic feedback: useHaptics() composable with pattern presets
- Web Share API: native share with glass fallback sheet
- Pinch-to-zoom: usePinchZoom() composable, 1x-4x, double-tap reset
- iOS PWA: safe area insets CSS utilities, black-translucent status bar
- Long-press context menus: 500ms trigger via bottom sheet
- Scroll position memory: per-route Map, auto-restore on mount
- Landscape mode: CSS split layout, orientation change detection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-04 00:55:19 +00:00
co-authored by Claude Opus 4.6
parent 72f93e4e94
commit 6be4fbe081
9 changed files with 532 additions and 0 deletions
+35
View File
@@ -807,6 +807,41 @@ input:focus-visible {
}
}
/* ===== iOS PWA SAFE AREA ===== */
.safe-area-top {
padding-top: env(safe-area-inset-top, 0px);
}
.safe-area-bottom {
padding-bottom: env(safe-area-inset-bottom, 0px);
}
.safe-area-left {
padding-left: env(safe-area-inset-left, 0px);
}
.safe-area-right {
padding-right: env(safe-area-inset-right, 0px);
}
.safe-area-inset {
padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}
/* ===== LANDSCAPE LAYOUT ===== */
@media (orientation: landscape) and (max-height: 500px) {
.landscape-split {
display: flex;
flex-direction: row;
}
.landscape-split > * {
flex: 1;
min-width: 0;
}
}
/* ===== REDUCED MOTION ===== */
@media (prefers-reduced-motion: reduce) {