SIGN IN SIGN UP

feat(web): a real favicon, installable icons, and an app that fills the display

Three things were wrong at once, all in the same few lines of <head>.

The tab favicon was blank: the page declared no rel="icon" at all, so browsers fell back
to /favicon.ico, which exists nowhere in web/. Chrome never offered to install the app,
because it wants start_url and a 192 plus a 512 icon in the manifest and the manifest had
neither. And iOS put a screenshot of the page on the home screen, because apple-touch-icon
has never supported svg and there was no raster to use instead.

So declare the icons, and back them with rasters rendered from logo.svg: 32px for browsers
that ignore svg favicons, 180px for the iOS home screen, and 192/512 for the manifest,
which until now claimed those two sizes while pointing at the svg. The 512 doubles as the
maskable icon -- logo.svg bleeds off canvas, so padding it into the 80% safe zone exposed a
hard cut edge, while the artwork already sits inside the safe circle unpadded. Push
notifications point at the png too: svg notification icons are not reliably supported, and
a notification is the one place with no fallback to look at.

The installed window then still stopped short of the display. On iOS the page declares a
black-translucent status bar but never set viewport-fit=cover, so content stopped at the
safe area and the insets showed system white. Set it, and pay for it: body takes the
left/right/bottom insets, the header takes the top one, and the fixed terminal overlay
takes all four.

And `env(safe-area-inset-bottom, 8px)` in two places, which reads like a minimum and is
not: the second argument is a FALLBACK, used only where the inset is unsupported. Where it
is supported and zero -- every desktop browser, and any phone without a home bar -- it
resolves to 0 and the 8px of breathing room silently disappears. The key dock now lets body
own the inset, and the command palette adds the two together.

tests/test_web_pwa.py is the part worth reviewing. Four PNGs are four files a reviewer
cannot diff, so they arrive with assertions instead: real PNG headers, the exact pixel
dimensions read out of each IHDR and matched against what the manifest advertises, and a
size ceiling. Each of the layout assertions is mutation-checked too -- a missing
viewport-fit is the iOS bug itself, and any safe-area fallback other than 0px is the trap
above, so it cannot come back by looking reasonable. No browser needed for any of it, so it
runs in the plain unittest pass.
N
Nick007 committed
15a36049c8864b58794cb34c9055b81cd383dbbf
Parent: 40909d6