From 536d9541bd61387be973a4c505d399f0bae7bf52 Mon Sep 17 00:00:00 2001 From: Emi Griffith Date: Wed, 15 Jul 2026 20:50:59 -0700 Subject: [PATCH] SEO: monthly & seasonal records + colour-coded climate pages (#107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SEO: monthly & seasonal records on the city records page The /climate//records page showed only all-time records per metric. Expand it into a full records page: record high/low for each of the 12 months (each linking its month page) and for each meteorological season, alongside the existing all-time table. Seasons are hemisphere-aware — Dec–Feb reads as winter for northern cities and summer for southern ones (picked from the city's latitude). Records reuse grading.all_time_records over a month-filtered archive, so no new data fetching or warming is needed. Adds a Dataset + breadcrumb JSON-LD block and richer title/description for the expanded coverage. * SEO: colour-code climate & records pages (heat-map + range strip) The city, records and month pages were plain muted tables — generic climate-site styling. Bring the interactive grader's diverging cold→hot palette onto them so they read as heat maps in the site's own visual language: - Map absolute °F to the 9-tier palette (temp_class, a Jinja global) and tint the temperature cells across the monthly-normals, monthly/seasonal/all-time records tables. The value stays in the ink token; the tint is a wash behind it. Non-temp rows (humidity/wind/precip) and date columns stay untinted. - Add a monthly temperature-range strip on the city page: one gradient bar per month spanning the average low→high on a shared −10..115°F axis, so a city's whole-year rhythm (and hot-vs-cold character) reads at a glance. - Tint the month page's hero high/low and its record values inline. Palette, light/dark, and 390–1920px layouts verified by rendering hot (Phoenix) and cold (Anchorage) cities. --- static/style.css | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/static/style.css b/static/style.css index ca409d5..48ee853 100644 --- a/static/style.css +++ b/static/style.css @@ -1492,6 +1492,41 @@ table.normals-table tbody tr:hover { background: var(--surface-2); } .climate-records ul { margin: 8px 0; padding-left: 20px; } .climate-records li { margin: 4px 0; } +.season-span { color: var(--muted); font-weight: 400; font-size: 13px; } + +/* Temperature heat-map tints — the interactive tool's diverging cold→hot palette + brought onto the static tables. The value itself stays in the ink token; the tint + is a wash behind it, so a record high glows red and a record low reads cold-blue. + Mix percentages are tuned per tier (saturated darks need less) to keep the number + legible in both themes; the date column stays muted and untinted. */ +td.t-cell { font-weight: 600; } +td.rec-date { color: var(--muted); font-size: 13px; } +.t-rec-cold { background: color-mix(in srgb, var(--rec-cold) 26%, var(--surface)); } +.t-very-cold { background: color-mix(in srgb, var(--very-cold) 26%, var(--surface)); } +.t-cold { background: color-mix(in srgb, var(--cold) 28%, var(--surface)); } +.t-cool { background: color-mix(in srgb, var(--cool) 34%, var(--surface)); } +.t-normal { background: color-mix(in srgb, var(--normal) 26%, var(--surface)); } +.t-warm { background: color-mix(in srgb, var(--warm) 40%, var(--surface)); } +.t-hot { background: color-mix(in srgb, var(--hot) 40%, var(--surface)); } +.t-very-hot { background: color-mix(in srgb, var(--very-hot) 40%, var(--surface)); } +.t-rec-hot { background: color-mix(in srgb, var(--rec-hot) 30%, var(--surface)); } +.t-none { background: transparent; } +/* Inline tinted value (month-page hero numbers, record list) — same washes, padded + so the colour reads as a chip around the number. */ +.t-inline { padding: 1px 7px; border-radius: 7px; } + +/* Monthly temperature-range strip: one gradient bar per month, low→high on a shared + axis. The signature climate visual — colourful and unmistakably Thermograph. */ +.range-strip { display: grid; gap: 6px; margin: 16px 0 8px; max-width: 620px; } +.range-row { display: grid; grid-template-columns: 34px 1fr 92px; align-items: center; gap: 10px; } +.range-month { font-size: 13px; font-weight: 600; color: var(--muted); } +.range-track { position: relative; height: 14px; background: var(--surface-2); border-radius: 999px; } +.range-fill { + position: absolute; top: 0; bottom: 0; border-radius: 999px; + background: linear-gradient(90deg, var(--c1), var(--c2)); +} +.range-vals { font-size: 13px; color: var(--text); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; } +.range-note { font-size: 13px; margin-top: 6px; } .climate-foot { font-size: 14px; margin-top: 28px; border-top: 1px solid var(--border); padding-top: 16px; } .city-blurb { font-size: 15px; margin: 4px 0 14px; } .blurb-src { color: var(--muted); text-decoration: none; font-size: 13px; white-space: nowrap; }