MobileApp shell e layout

App shell e layout

O shell nativo trava a viewport para que o documento nunca role, apenas a area de conteudo rola. E isso que remove a sensacao de “pagina web dentro de um quadro”: a barra superior e a navegacao inferior ficam fixas enquanto o miolo rola, e o efeito rubber-band do WKWebView fica suprimido.

Anatomia

┌─────────────────────────────┐
│ safe-area-inset-top         │
│ ┌─────────────────────────┐ │  Barra superior (sticky)
│ │ [logo]          [avatar]│ │  · logo Velon a esquerda (maior no nativo)
│ └─────────────────────────┘ │  · avatar com iniciais a direita → /app/profile
│                             │
│        <main> rola          │  flex-1, overflow-y-auto, overscroll-contain
│                             │
│ ┌─────────────────────────┐ │  Navegacao inferior (fixed)
│ │  Home   History  Conta  │ │  · reserva 60px + safe-area-inset-bottom
│ └─────────────────────────┘ │
│ safe-area-inset-bottom      │
└─────────────────────────────┘

Regras do shell

  • Shell nativo: h-[100dvh] w-full flex flex-col overflow-hidden. Use dvh (viewport dinamica), nao vh, para que o chrome do navegador / redimensionamento do teclado seja respeitado.
  • <main> e o unico container de scroll: flex-1 min-h-0 overflow-y-auto overscroll-contain. overscroll-contain elimina o bounce.
  • A web fica intocada: a web mantem o layout original com document-scroll min-h-screen e lg:pl-60 para a sidebar de desktop. Ramifique com base em isNative.
<div className={isNative
  ? 'relative flex h-[100dvh] w-full flex-col overflow-hidden bg-gray-50 dark:bg-gray-950'
  : 'relative w-full min-h-screen bg-gray-50 dark:bg-gray-950'}>
  <TopBarAndNav />
  <main className={isNative
    ? 'min-h-0 w-full flex-1 overflow-y-auto overscroll-contain'
    : 'lg:pl-60 w-full min-h-screen'}
    style={{ paddingBottom: isNative ? 'calc(60px + env(safe-area-inset-bottom, 0px))' : undefined }}>
    {/* page */}
  </main>
</div>

Ressalva para Mac / janelas grandes

O app iOS pode rodar em Macs com Apple Silicon e em janelas grandes. O layout web de desktop (sidebar hidden lg:flex, regras lg:) nao deve ativar dentro do shell nativo, independentemente da largura, caso contrario a sidebar de desktop e a navegacao inferior do mobile sao renderizadas ao mesmo tempo. Condicione o layout de desktop a !isNative, e nao apenas ao breakpoint lg:, para que o nativo sempre mantenha a aparencia de app.

Status bar e splash

Configurados nativamente (Capacitor StatusBar / SplashScreen): a status bar nao sobrepoe a WebView (overlaysWebView: false), estilo escuro, fundo Azul Profundo velon-deep (#0C1A26). Veja Teclado, input e camera para o redimensionamento do teclado, que faz parte da mesma questao de shell.