{{/* Ported from templates/home.html.j2. The Weekly view — the product itself — with the distribution surfaces built around it. Everything structural is server-rendered so crawlers and no-JS readers get a complete page; app.js hydrates the live numbers in place. The interactive controls below (#find-btn, #date-input, #panel, #results, …) are app.js's DOM contract, carried over verbatim from the old static frontend/index.html. Do not rename these ids. Section / BrandTag ("p") / MainClass ("") come from the route handler's render data, not the template — the SEO pages already pass Section that way. Extra data: .Unusual *contentapi.HomeUnusual; .Stale bool; .Ranked []contentapi.HomeRanked (Lat/Lon are json.Number, printed raw); .Cities []contentapi.HomeCity; .JSONLDStr template.JS — _HOME_JSONLD + "url" appended, serialized like Python's plain json.dumps: ", "/": " separators, ensure_ascii=True. */}}{{template "base_head_start" .}} {{template "base_head_end" .}} {{template "base_body_start" .}}{{/* --- Hero ------------------------------------------------------------ The grade card is the LCP element: its frame is server-rendered and its slots are sized here, so hydrating the live numbers causes no layout shift. Band colour is always paired with the band word — colour is never the only signal. */}}

How unusual is your weather?

Any day, anywhere on Earth, graded against 45 years of that place's own history.

{{/* --cat carries the band colour, the same convention .normal-card uses, so the band token stays the single source of truth. */}}

{{- if .Unusual -}} Today in {{.Unusual.Display}} {{- else -}} Today {{- end -}}

{{if .Unusual}}{{.Unusual.Grade}}{{else}}—{{end}}

{{- if .Unusual -}} {{.Unusual.MetricLabel}} in the {{ordinal .Unusual.Percentile}} percentile for {{.Unusual.WindowLabel}} {{- else -}} Pick a place to see how unusual its weather is today. {{- end -}}

{{if and .Unusual .Unusual.IsDefault}}

the most unusual weather we're tracking{{if .Stale}} · as of {{.Unusual.Date}}{{end}}

{{end}}
{{/* app.js hides the locate button outside a secure context, where the browser refuses geolocation and it could only ever fail. */}}

See your week ↓

What do the grades mean? →

Find a location to begin.

Thermograph fetches decades of daily highs, lows, and precipitation for your ~4 sq mi cell, builds a ±7-day seasonal distribution for each day of the year, and grades recent weather by where it falls on that distribution.

{{/* Sits outside #panel on purpose: app.js rewrites results.innerHTML wholesale on every grade, so anything inside it would be destroyed. */}}

Free. No ads. No tracking. No account needed. How we work →

{{/* --- Unusual right now ---------------------------------------------- Scroll-snap row, no JS carousel. Both tails are represented whenever a cold-tail city qualifies — two-sided honesty is product identity. */}}{{if .Ranked}}

Unusual right now

See all records →

{{end}} {{/* --- How it works ---------------------------------------------------- */}}

How it works

  1. We keep 45 years of climate history (ERA5 reanalysis) for your exact ~2-mile grid square.
  2. Today gets compared to the same two weeks of the year, every year back to 1980.
  3. The result is a percentile and a plain-language grade, from Near Record cold to Near Record hot.

Full methodology → · Data: ERA5 via Open-Meteo · NASA POWER · MET Norway

{{/* --- Explore --------------------------------------------------------- */}}

Explore

{{/* Each card takes a colour from the grade ramp rather than a decorative palette, so the section reads as part of the product's own scale. Calendar carries the ramp itself — it IS the heatmap. */}}
Calendar Two years of your days, each colored by how unusual it was. Compare Rank any places by comfort for a trip or a move. Day Any date since 1980, anywhere: what was normal, what happened. Alerts Free percentile alerts: get pinged when your weather goes statistically weird.
{{/* --- City hub links -------------------------------------------------- Real HTML links funnelling homepage authority into the ~1000-page /climate surface. */}}

Climate context for 1,000 cities

Browse all cities →

{{template "base_body_end" .}} {{/* The records strip renders real temperatures server-side as .temp spans, so it needs the same converter the SEO pages use or they'd stay in °F while the toggle says °C. Both import units.js, which the module loader dedupes. */}} {{template "base_tail" .}}