diff --git a/content.py b/content.py
index 09fcf9e..16f2347 100644
--- a/content.py
+++ b/content.py
@@ -226,10 +226,22 @@ def _monthly_normals(history) -> list[dict]:
return rows
+def _extreme(metric_rec, key: str) -> dict | None:
+ """One extreme of a metric — key 'max' (warmest) or 'min' (coldest) — as the
+ two-unit value, its heat-map tier, and the date it occurred."""
+ if not metric_rec:
+ return None
+ v = metric_rec[key]
+ return {"txt": _temp(v), "f": v, "cls": temp_class(v), "date": metric_rec[f"{key}_date"]}
+
+
def _period_records(history, months: list[int]) -> dict:
- """Record high (tmax) and record low (tmin), with the dates they occurred, over a
- set of calendar months — the shared primitive behind the monthly and seasonal
- records tables. Reuses grading.all_time_records on the month-filtered archive."""
+ """For a set of calendar months, the record *warmest and coldest* of BOTH the
+ daytime high (tmax) and the overnight low (tmin) — four extremes with dates.
+
+ So each metric shows both ends: the daytime high's hottest day and the coldest a
+ day ever stayed (its record-low high), and the overnight low's mildest night and
+ its record low. Reuses grading.all_time_records on the month-filtered archive."""
if len(months) == 1:
sub = history.filter(pl.col("date").dt.month() == months[0])
else:
@@ -237,12 +249,8 @@ def _period_records(history, months: list[int]) -> dict:
rec = grading.all_time_records(sub) if not sub.is_empty() else {}
tmax, tmin = rec.get("tmax"), rec.get("tmin")
return {
- "high": _temp(tmax["max"]) if tmax else "—",
- "high_f": tmax["max"] if tmax else None,
- "high_date": tmax["max_date"] if tmax else "—",
- "low": _temp(tmin["min"]) if tmin else "—",
- "low_f": tmin["min"] if tmin else None,
- "low_date": tmin["min_date"] if tmin else "—",
+ "high": {"warm": _extreme(tmax, "max"), "cold": _extreme(tmax, "min")},
+ "low": {"warm": _extreme(tmin, "max"), "cold": _extreme(tmin, "min")},
}
diff --git a/templates/records.html.j2 b/templates/records.html.j2
index cd6985d..61ce920 100644
--- a/templates/records.html.j2
+++ b/templates/records.html.j2
@@ -4,6 +4,15 @@
{% block canonical_path %}{{ canonical_path }}{% endblock %}
{% block jsonld %}{% endblock %}
{% block content %}
+{# A metric's two extremes — ▲ warmest and ▼ coldest it has ever been — as tinted
+ chips with the date each occurred. Used for the daytime-high and overnight-low
+ columns of the month and season tables. #}
+{% macro extremes(metric) %}
+{% if metric and metric.warm and metric.cold %}
+
The warmest and coldest {{ name }} has ever been in each calendar month. Tap a month for its full
- averages and typical range.
+
The warmest (▲) and coldest (▼) both the daytime high and the overnight low have ever been in
+ each calendar month — so each column shows its record high and its record low. Tap a
+ month for its full averages and typical range.
Meteorological seasons for the {{ hemisphere }} Hemisphere — each a three-month span — and the
- most extreme {{ name }} has recorded within each.
+
The warmest (▲) and coldest (▼) both the daytime high and the overnight low have reached in each
+ meteorological season ({{ hemisphere }} Hemisphere — each a three-month span).
-
-
Season
Record high
Record low
+
+
Season
Daytime high
Overnight low
{% for s in seasonal %}
{{ s.name }} ({{ s.span }})
-
{{ s.high }}{{ s.high_date }}
-
{{ s.low }}{{ s.low_date }}
+
{{ extremes(s.high) }}
+
{{ extremes(s.low) }}
{% endfor %}
diff --git a/tests/test_content.py b/tests/test_content.py
index b8954b0..130ccc2 100644
--- a/tests/test_content.py
+++ b/tests/test_content.py
@@ -134,11 +134,21 @@ def test_climate_pages_are_colour_coded(client):
assert "t-cell t-" in city # tinted temperature cells in the normals table
assert "range-fill" in city and "--c1:var(--" in city # the monthly range strip's gradient bars
recs = client.get(f"{B}/climate/{SLUG}/records").text
- assert "t-cell t-" in recs
+ assert "t-inline t-" in recs # tinted record chips
month = client.get(f"{B}/climate/{SLUG}/july").text
assert "t-inline t-" in month # tinted hero numbers + records
+def test_records_show_both_extremes_per_metric(client):
+ # Each metric column shows BOTH its record warmest (▲) and coldest (▼) — so the
+ # daytime high carries its record-low high, and the overnight low its record-high low.
+ b = client.get(f"{B}/climate/{SLUG}/records").text
+ assert "Daytime high" in b and "Overnight low" in b
+ assert "▲" in b and "▼" in b
+ # 12 months × 2 metric columns × 2 extremes = 48 chips just in the monthly table.
+ assert b.count('class="rec-ext"') >= 48
+
+
def test_hub_glossary_about(client):
assert client.get(f"{B}/climate").status_code == 200
assert client.get(f"{B}/glossary").status_code == 200