Mobile
Specs for the native Velon app (Capacitor iOS + Android). The native shell wraps the same React app as the web; these pages document what is mobile-only and how it must behave so the experience feels like a banking app, not a website in a frame.
The native app is built from Velon-user (web source) wrapped by the
velon-mobile Capacitor shell. There is no separate mobile codebase: the
same components render on web and native. Mobile-specific behavior is opt-in,
never a fork.
First principle: never impact web
Every mobile-only behavior is gated behind the native platform check. If a change can be seen on the web, it does not belong to a mobile pattern.
import { Capacitor } from '@capacitor/core'
const isNative = Capacitor.isNativePlatform() // true only inside the iOS/Android shell
if (!isNative) return null // mobile-only UI renders nothing on web- Components that exist on both surfaces branch on
isNative; they never replace the web markup. - Mobile-only screens (bottom nav, top bar, lock screen, mobile Profile) return
null/ passthrough on web. - This is verified by the Visual snapshots CI in
Velon-user: a mobile PR that changes a web screenshot is a regression.
Safe areas
The app draws under the notch, Dynamic Island and home indicator. Always pad with the env insets, never with magic numbers.
padding-top: env(safe-area-inset-top, 0px);
padding-bottom: env(safe-area-inset-bottom, 0px);The fixed bottom nav reserves calc(60px + env(safe-area-inset-bottom, 0px)) so
content never sits under it.
What lives where
| Concern | Spec | Status |
|---|---|---|
| App shell, top bar, bottom nav, scroll, safe-area | App shell & layout | shipped |
| Bottom nav, top bar (logo + initials avatar), role-based nav | Navigation | shipped / role-based planned |
| List rows, drill-in, initials avatar, sheets | Mobile patterns | shipped |
| App lock, biometric unlock, logout | App lock & biometrics | shipped (core) |
| Keyboard resize, dialogs over keyboard, camera / QR | Keyboard, input & camera | shipped |
Brand consistency
Mobile is not an exception to the brand. Use DSM tokens and Tailwind preset
utilities (bg-primary, text-velon-navy, bg-velon-navy), never
hardcoded hex, never blue-600, never ad-hoc text-[10px]. The mobile component
work is tracked in velon-design-system#39; promote a pattern from “documented
here” to “shipped in @velon-finance/ui” once it stabilizes.