Skip to content

Optimize the web app for iOS 26 Safari (Liquid Glass) — safe areas, toolbar tinting, viewport

Why

iOS 26 Safari (Sept 2025) redesigned its chrome as Liquid Glass: the bottom tab bar and toolbars now FLOAT OVER the page, tint themselves by sampling the page's own fixed/sticky elements near the viewport edges (+ theme-color), and let content scroll behind them. The owner reports the app's bottom sidebar/nav "turned into liquid-glass and sort of expanded" on iPhone — the classic symptom of Safari merging its floating bar with the app's own fixed bottom element. Apple shipped this with next to no web-developer documentation; the community mapped the rules (sources below).

Research summary (2026-07-03)

  1. viewport-fit=cover is the prerequisite — without it env(safe-area-inset-*) stays 0 and the bottom-bar transparency behaves inconsistently. Today only the signing pages set it (app/ir56m/sign/**, app/wopc/sign/** via viewport.viewportFit); the app shell does not.
  2. Fixed/sticky elements near the top/bottom edge must NOT carry background-color or backdrop-filter on the fixed element itself — Safari samples them for toolbar tinting and visually merges/expands its bar with the element. Put the visual background on an absolute child.
  3. Hidden fixed overlays must use display:none when closed — opacity:0 + pointer-events:none still feeds Safari's tint sampler.
  4. Set an explicit background-color on html/body — Safari derives bar tint from the root color; unset roots cause white/black bar flashes and wrong tints.
  5. Audit theme-color meta — participates in top/bottom bar tinting on iOS 26.
  6. Viewport-height audit100vh traps under the dynamic toolbar; use dvh/svh (T-120 did the signing pages; the rest of the app is unaudited).
  7. Fixed bottom UI must add env(safe-area-inset-bottom) padding/offset so it clears the floating bar (the build watermark now does this — see the shipped starter below).

Scope

  1. App-wide viewport-fit=cover (App Router root viewport export + Pages Router meta) with a safe-area padding audit of every fixed edge element (bottom nav, drawers, FABs, toasts) — the two must land together or content sits under the home indicator.
  2. Fix the mobile bottom nav ("sidebar at the bottom"): safe-area inset + move any background/backdrop-filter off the fixed element per rule #2 (kills the "expanded liquid-glass" look).
  3. Root html/body explicit background + theme-color audit (light/dark).
  4. 100vhdvh/svh sweep beyond T-120.
  5. Overlay audit: closed fixed overlays render display:none.
  6. Device test matrix: iPhone Safari 26, portrait/landscape, bottom-tab-bar vs compact setting.
  7. Auth on iOS Safari (absorbed from T-083, 2026-07-09): the popup-blocked signInWithRedirect fallback breaks under storage partitioning with the cross-domain authDomain (aote-pms.firebaseapp.com) — fix per T-083's design: same-origin authDomain via a reverse-proxied /__/auth on eop.theestablishers.com.

Sources

Decision log

2026-07-03 — opened; starter shipped (build watermark)

  • ✅ Read AGENTS.md. Opened at the owner's request (verbatim): "please research on the specification of the most updated iOS safari browser so that not just for build number rendering, the optimize the web app in general specifically for iOS safari (it's a big task, so create a task UID for it, but start with the build number rendering first)". Board scope-checked — nearest neighbors are T-120 (dvh on signing pages only) and mobile.css work; nothing covers the iOS-26 Liquid-Glass adaptation.
  • Starter shipped (same commit): components/BuildWatermark.tsx — desktop moved 5px further left (right:10px, owner request), touch devices lift the stamp above the liquid-glass bar via env(safe-area-inset-bottom) (fully effective app-wide once scope #1 lands viewport-fit=cover).
  • UID note: the README next-free pointer was stale at T-150 while T-150–T-153 had all been taken by parallel agents without bumps (T-150 badges editor #853, T-151 two-layer RBAC, T-152 quotation delete, T-153 invoice line-discount). Took the real next-free T-154; pointer set to T-155.
  • Source: EOP Local Assistance (fork) · session edb0abc7-6373-449b-8e31-379fd38d391b