Fix (regression from 0.49.4)
Public URL setting was corrupting the LAN render URLs sent to devices. Setting Public URL to e.g. `https://tesserae.example.org:8443\` caused the push pipeline to build LAN frame-download URLs as `http://:8443/renders/…`. Devices (pi_bin, pi_png, esp32) on the LAN tried to fetch those over HTTP, hit the reverse proxy's HTTPS port, got `400 Bad Request` back, and could not paint a new frame.
Root cause: the Public URL middleware rewrites `HTTP_HOST` to the public host:port so external URLs come out right. But the existing port-capture before-request hook reads `request.host` to discover the actual Flask bind port. With the override active, it captured the proxy's external port (8443) instead of the real bind port (8765).
Fix: the port-capture hook returns early when Public URL is set, leaving the bind port at its real value. External browser-facing URLs still use the Public URL via the same middleware as before; device-facing LAN URLs revert to the actual bind port (`TESSERAE_HTTP_PORT` / 8765 default).
Who needs to upgrade
Everyone running Tesserae 0.49.4 with the Public URL setting set AND any device that fetches frames over HTTP (pi_bin, pi_png, esp32 clients). TRMNL clients are unaffected because they fetch via the HTTP-polled `/api/display` path through the same proxy.
Workaround if you can't upgrade immediately
Clear the Public URL setting (set it back to blank). Devices will start fetching frames again. The OAuth-connected widgets (Spotify, etc.) keep working because the tokens are already stored; you only need Public URL for the initial Connect dance.
Tests
+2 regression tests in `tests/test_proxyfix.py` covering both the new behaviour (proxy port isn't captured when Public URL is set) and that the existing port-capture still works for users without Public URL. 981 passing, ruff + mypy strict clean.