diff --git a/static/score.js b/static/score.js
index 8ad3d3a..9f18fa8 100644
--- a/static/score.js
+++ b/static/score.js
@@ -6,15 +6,10 @@ import { fmtTemp, onUnitChange } from "./units.js";
import "./account.js"; // header sign-in entry + notification bell
import { getJSON, TTL, prefetchViews } from "./cache.js";
import { initFindButton, setFindLabel } from "./mappicker.js";
-import { TIER_COLORS, pctOrd, fmtPrecip, fmtWind, fmtHumid, esc, placeLabel } from "./shared.js";
+import { TIER_COLORS, esc, placeLabel } from "./shared.js";
-// Display order (site convention leads with Precip), and how each metric's raw
-// per-percentile value is formatted in the detail table.
+// Display order (site convention leads with Precip).
const METRIC_ORDER = ["precip", "tmax", "tmin", "feels", "humid", "wetbulb", "wind", "gust"];
-const FMT = {
- tmax: fmtTemp, tmin: fmtTemp, feels: fmtTemp, wetbulb: fmtTemp,
- humid: fmtHumid, wind: fmtWind, gust: fmtWind, precip: fmtPrecip,
-};
const SEASON_NAMES = { djf: "Winter", mam: "Spring", jja: "Summer", son: "Fall" };
const SEASON_ORDER = ["djf", "mam", "jja", "son"];
@@ -210,8 +205,8 @@ function sentencesHTML(annual) {
.filter((m) => m && m.score != null && m.score >= 15)
.map((m) => {
const mid = m.per_q && m.per_q.find((q) => q.q === 50);
- const where = mid ? ` Its recent median now lands near the ${pctOrd(mid.pct)} percentile of the full record.` : "";
- return `
${esc(m.label)}: ${esc(m.grade)} — about ${Math.abs(m.bias).toFixed(0)} percentile points ${esc(m.direction)}.${where}`;
+ const where = mid ? ` At the median, recent readings sit about ${Math.abs(mid.d)} points ${mid.d >= 0 ? "higher" : "lower"} than the seasonal norm.` : "";
+ return `${esc(m.label)}: ${esc(m.grade)} — about ${Math.abs(m.bias).toFixed(0)} percentile points ${esc(m.direction)} on average.${where}`;
});
if (!lines.length) return `Every metric is close to its long-term normal here — no notable recent drift.
`;
return `What has shifted the most:
`;
@@ -242,21 +237,20 @@ function scoreTableHTML(s) {
${head}${rows}${overallRow}`;
}
-// The annual per-percentile detail: for each category, the recent value and where
-// it lands in the 45-year record.
+// The per-percentile detail: for each band, the mean shift (in percentile points)
+// averaged across the four seasons — the differentials the score is built from.
function perQTableHTML(annual) {
const rows = METRIC_ORDER
.map((k) => annual.metrics[k])
.filter((m) => m && m.score != null && m.per_q && m.per_q.length)
.map((m) => {
- const fmt = FMT[m.key] || ((v) => v);
const cells = m.per_q.map((q) =>
- `p${q.q}: ${esc(String(fmt(q.v6)))} → ${pctOrd(q.pct)} (${q.d >= 0 ? "+" : ""}${q.d}) | `).join("");
+ `p${q.q}: ${q.d >= 0 ? "+" : ""}${q.d} | `).join("");
return `| ${esc(m.label)} | ${cells}
`;
}).join("");
if (!rows) return "";
- return `Annual percentile detail
- Each recent-years percentile value, and where it lands in the full record (▲/▼ = shift in percentile points).
+ return `Shift by percentile band
+ The mean shift at each percentile band, averaged across all four seasons (percentile points; ▲ higher / ▼ lower than the seasonal norm).
`;
}
diff --git a/static/style.css b/static/style.css
index 0d77568..d4a629e 100644
--- a/static/style.css
+++ b/static/style.css
@@ -1737,8 +1737,11 @@ td.rec-date { color: var(--muted); font-size: 13px; }
padding: 12px 14px; margin: 14px 0 4px; font-size: 13px; line-height: 1.5; color: var(--text);
}
-/* By-season scores: seasons as rows, one aligned column per metric. */
-.season-table th:first-child, .season-table td:first-child { text-align: left; }
+/* By-season scores: seasons as rows, one uniform column per metric so every
+ metric lines up vertically across the seasons. Fixed layout keeps the columns
+ equal width; the min-width lets it scroll (not squash) on a phone. */
+.season-table { table-layout: fixed; width: 100%; min-width: 620px; max-width: 740px; }
+.season-table th:first-child, .season-table td:first-child { width: 62px; text-align: left; }
/* Summary reveal — pill button + caret, mirrors the season-expand pattern. */
.summary-toggle {