diff --git a/index.html b/index.html index 9100248..4897030 100644 --- a/index.html +++ b/index.html @@ -145,9 +145,10 @@
-
- You are offline — cached tiles and GPS recording still work -
+ diff --git a/src/main.ts b/src/main.ts index 22d28d5..2e3c731 100644 --- a/src/main.ts +++ b/src/main.ts @@ -511,11 +511,24 @@ document.getElementById('map')?.focus(); document.body.style.zoom = '100%'; // ── Offline detection ───────────────────────────────────────────────────────── +// The banner is created lazily (not in static HTML) so it isn't a position:fixed + +// transform compositing layer at first paint — that, with #map, contributed to the +// iOS-26 WKWebView whole-page render freeze. It only ever exists once the app has +// been offline. function updateOfflineBanner(): void { - const banner = document.getElementById('offline-banner'); - if (!banner) return; + let banner = document.getElementById('offline-banner'); if (navigator.onLine) { - banner.classList.remove('visible'); + banner?.classList.remove('visible'); + return; + } + if (!banner) { + banner = document.createElement('div'); + banner.id = 'offline-banner'; + banner.className = 'offline-banner'; + banner.innerHTML = 'You are offline — cached tiles and GPS recording still work'; + document.body.appendChild(banner); + // Mount hidden, then reveal next frame so the slide-in transition plays. + requestAnimationFrame(() => banner!.classList.add('visible')); } else { banner.classList.add('visible'); } diff --git a/src/style.css b/src/style.css index 289b9f6..77a46f5 100644 --- a/src/style.css +++ b/src/style.css @@ -6,8 +6,13 @@ html { height: 100%; width: 100%; padding: 0; margin: 0; } body { height: 100%; width: 100%; padding: 0; margin: 0; } -/* isolation: isolate keeps mix-blend-mode contained to the map's own stacking context. */ -#map { position: absolute; top: 0; bottom: 0; right: 0; left: 0; isolation: isolate; } +/* No `isolation: isolate` here on purpose: an empty, full-screen *composited* #map + layer at first paint was a prime trigger for the iOS-26 WKWebView render freeze + (whole page never composites to screen until a reload). Containment isn't needed — + the hillshade overlay's mix-blend-mode:multiply blends against the opaque base + tiles directly beneath it regardless, and multiply against the white body behind a + full-screen map is a no-op. */ +#map { position: absolute; top: 0; bottom: 0; right: 0; left: 0; } /* Blend at the layer container so multiply composites against the base-layer sibling below. */ .hillshade-blend { mix-blend-mode: multiply; }