Cause root du bug nav bar qui flash en bas pendant le scroll iOS 26 :
ios.contentInset = 'always' faisait que iOS WKWebView ajustait
dynamiquement le contentInset pendant le scroll → window.innerHeight
shrinkait de 902 → 868 (perte safe-area-inset-bottom = 34px) → la
nav `position: fixed; bottom: 0` suivait le shrink → flash visible.
Diagnostic empirique 2026-05-18 via debug overlay JS qui montrait :
- État repos : innerH=902, nav.bottom=902 ✅
- État scroll : innerH=868, nav.bottom=868 ❌ (34px plus haut)
Sources doc officielles vérifiées :
- capacitorjs.com/docs/config : default Capacitor iOS = 'never'
- developer.apple.com/documentation/uikit/uiscrollview/
contentinsetadjustmentbehavior :
'never' = aucun ajustement automatique → évite le shrink dynamique
→ recommandé pour web apps fullscreen
'always' = force ajustement sur tous axes → cause de notre shrink
Le CSS coach_sportif gère déjà manuellement env(safe-area-inset-*)
dans critical.css (top, bottom, left, right). Combiné avec
StatusBar.overlaysWebView=false (status bar a son espace dédié,
n'overlay pas le WebView), tout reste correct sans contentInset.
Bump build requis côté Mac avant rebuild TestFlight.
Workaround JS RAF loop (commit d8b928a) conservé en safety net :
quand contentInset='never' tient sa promesse, innerHeight est stable,
maxInnerH-h=0, pas de transform appliqué. Si jamais iOS 26 régresse,
le workaround prend le relais.
Tous les backgroundColor passent de #ffffff à #000000 :
- ios.backgroundColor (WebView natif entre 2 navigations)
- SplashScreen.backgroundColor (cohérence avec splash dark)
- StatusBar.backgroundColor (cohérence avec app dark)
StatusBar.style passe de DEFAULT à LIGHT (icônes/texte blanc sur fond
noir, lisible sur app dark).
À synchroniser au prochain rebuild :
npx cap sync ios
(régénère ios/App/App/capacitor.config.json)
puis archive Xcode.
Pendant ce temps, fix web déjà déployé (style inline html/body) atténue
le flash sans rebuild requis.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WebKit error code 102 (Frame load interrupted by policy change) sur le redirect
303 retourné par /login après pose du cookie. Solution Phase 0 : laisser le
user saisir le token une fois via le formulaire /login standard, le cookie
coach_web_token (1 an, secure, httponly, samesite=lax) doit persister dans
WKWebView pour les lancements suivants.
Si la persistance cookie échoue : inject natif via AppDelegate.swift à venir.
- capacitor.config.ts charge coachWebToken depuis coach-ios.local.json (gitignored)
- server.url devient https://coach.hypnotruck.ch/login?token=... → backend pose le cookie 1 an, redirige vers /
- Au prochain lancement, le cookie tient → /login?token redirige direct vers /
- coach-ios.local.json.example fourni pour setup Mac mini
- Capacitor 8 + plugins natifs (push, local-notif, geoloc, HealthKit Capgo, splash, status bar, haptics)
- Config pointe vers https://coach.hypnotruck.ch (server.url)
- Icône 1024×1024 + splash 2732×2732 depuis icon-512 PWA coach_sportif
- README complet avec procédure build sur Mac mini
- Bundle ID : ch.hypnotruck.coach, App name : Coach Hypnotruck