Sharing a Thermograph URL (Discord, Slack, iMessage…) now unfurls into a
card with the site name, page title, description, accent color, and logo.
- All five pages get description/theme-color/og:*/twitter:card meta and a
favicon. og:url/og:image need absolute URLs and crawlers don't run JS, so
pages carry an __ORIGIN__ placeholder the server fills in per request from
X-Forwarded-Proto (Caddy) / scheme + the Host header + base path — correct
on both the LAN dev server and the prod domain without hardcoding either.
- New logo assets: the header's ▚ mark as an app icon (accent quadrants on
the dark surface) — logo.png (512x512, the og:image) and logo.svg (favicon).
- Page routes render the substitution with a weak ETag + 304 revalidation
(replacing plain FileResponse) and now answer HEAD, which preview crawlers
probe with (previously 404).
The Weekly location card joined coordinates, cell size, climatology range
and sample count into one dot-separated meta line. Stack them as one fact
per line so the important context reads top-down instead of as a run of
tags. Drop the '~N sq mi cell' wording from the Weekly/Day/Calendar meta
lines and the map hint.
Compare page (frontend/compare.{html,js} + /thermograph/compare route):
line up several places over a date range and rank which best matches a
comfort temperature. Per location it pulls the same daily record the
Calendar uses and, per day, takes a chosen temperature (daytime high /
daily mean / overnight low / feels-like) against the comfort target. A
day "hits comfort" when it lands within an adjustable band; otherwise it
counts as colder or warmer and the average miss is tracked. Results are
ranked by comfort-day share (tie-broken by the smaller typical miss),
with a diverging below/comfort/above bar and per-bucket stats. Comfort,
band and judged temperature re-rank instantly client-side; only the
location set or date range trigger a data load (shared calendar cache).
Feels calendar filter: drop the comfort-temperature slider and the
client-side felt-high/felt-low re-pick. The Feels metric now colors by
the server's combined feels-like value like the other metrics, so its
tab matches the rest of the metric selector.