@@ -122,12 +135,8 @@ function render(data) {
`
${shortLabel(k)} `).join("")}`;
const seasonRows = SEASON_ORDER.map((sk) => {
const sl = s.slices[sk];
- const oc = sl.overall;
- const overallCell = oc
- ? `
${oc.score} `
- : `
— `;
- const cells = METRIC_ORDER.map((k) => seasonCell(sl.metrics[k])).join("");
- return `
${SEASON_NAMES[sk]} ${overallCell}${cells}`;
+ const cells = METRIC_ORDER.map((k) => scoreCell(sl.metrics[k])).join("");
+ return `
${SEASON_NAMES[sk]} ${scoreCell(sl.overall, true)}${cells}`;
}).join("");
scoreBody.innerHTML = `
@@ -135,7 +144,7 @@ function render(data) {
${wbNote}
By season
-
+
${seasonHead} ${seasonRows}
@@ -155,7 +164,7 @@ function wetbulbNote(m, baseYrs) {
}
const thr = fmtTemp(m.freq.threshold_f);
const { f6, f45, d } = m.freq;
- const delta = d ? ` (${d >= 0 ? "+" : ""}${d} pts) ` : "";
+ const delta = d ? ` (${signedPts(d, " pts")})` : "";
return `${def}
Heat-stress days (peak wet bulb ≥ ${esc(String(thr))}): ${f6}% of recent days
vs ${f45}% across ${baseYrs}${delta}. The rest are normal.
`;
@@ -165,7 +174,6 @@ function wetbulbNote(m, baseYrs) {
// their own lines (rather than crammed top-right), so a long grade like
// "Extreme shift — windier" never clusters in the corner on a narrow card.
function metricCard(m) {
- if (!m) return "";
if (m.score == null) {
return `
${esc(m.label)}
@@ -187,11 +195,6 @@ function scoreDetail(m) {
return `~${Math.abs(m.bias).toFixed(0)} pts ${esc(m.direction)}`;
}
-function seasonCell(m) {
- if (!m || m.score == null) return `— `;
- return `${m.score} `;
-}
-
const shortLabel = (k) => ({ precip: "Precip", tmax: "High", tmin: "Low", feels: "Feels",
humid: "Humid", wetbulb: "Wet bulb", wind: "Wind", gust: "Gust" })[k] || k;
@@ -220,22 +223,14 @@ function scoreTableHTML(s) {
const head = `Metric ${slices.map((sk) =>
`${sk === "annual" ? "Annual" : SEASON_NAMES[sk]} `).join("")} `;
const rows = METRIC_ORDER.map((k) => {
- const cells = slices.map((sk) => {
- const m = s.slices[sk].metrics[k];
- if (!m || m.score == null) return `— `;
- return `${m.score} `;
- }).join("");
+ const cells = slices.map((sk) => scoreCell(s.slices[sk].metrics[k])).join("");
const label = s.slices.annual.metrics[k]?.label || k;
return `${esc(label)} ${cells} `;
}).join("");
- const overallCells = slices.map((sk) => {
- const o = s.slices[sk].overall;
- if (!o) return `— `;
- return `${o.score} `;
- }).join("");
+ const overallCells = slices.map((sk) => scoreCell(s.slices[sk].overall, true)).join("");
const overallRow = `Overall ${overallCells} `;
return `All scores
-
+
${head} ${rows}${overallRow}
`;
}
@@ -246,14 +241,13 @@ function perQTableHTML(annual) {
.map((k) => annual.metrics[k])
.filter((m) => m && m.score != null && m.per_q && m.per_q.length)
.map((m) => {
- const cells = m.per_q.map((q) =>
- `p${q.q}: ${q.d >= 0 ? "+" : ""}${q.d} `).join("");
+ const cells = m.per_q.map((q) => `p${q.q}: ${signedPts(q.d)} `).join("");
return `${esc(m.label)} ${cells} `;
}).join("");
if (!rows) return "";
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).
- `;
+ `;
}
// Mirror of shared.js initSeasonExpand: flip [hidden] + aria-expanded.
diff --git a/static/style.css b/static/style.css
index 7dd35ac..2757ca1 100644
--- a/static/style.css
+++ b/static/style.css
@@ -1712,10 +1712,7 @@ td.rec-date { color: var(--muted); font-size: 13px; }
background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
padding: 18px 20px; margin: 4px 0 18px;
}
-.score-eyebrow {
- font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
- color: var(--muted); margin: 0 0 8px;
-}
+.score-eyebrow { margin: 0 0 8px; } /* else styled by .section-title */
.score-hero-row { display: flex; align-items: center; gap: 16px; }
.score-num {
font-size: 52px; font-weight: 800; line-height: 1;
@@ -1769,7 +1766,7 @@ td.rec-date { color: var(--muted); font-size: 13px; }
.score-sentences { margin: 8px 0 18px; padding-left: 20px; }
.score-sentences li { font-size: 14px; line-height: 1.5; margin-bottom: 8px; color: var(--text); }
-.score-table-wrap { overflow-x: auto; margin: 8px 0 20px; }
+#score-body .table-wrap { margin: 8px 0 20px; } /* .table-wrap supplies overflow-x */
.score-table { border-collapse: collapse; font-size: 13px; }
.score-table th, .score-table td {
padding: 6px 10px; border-bottom: 1px solid var(--border); text-align: center; white-space: nowrap;