diff --git a/static/compare.js b/static/compare.js
index 53648e0..01de8ec 100644
--- a/static/compare.js
+++ b/static/compare.js
@@ -331,17 +331,6 @@ const pct = (v) => `${v < 10 ? v.toFixed(1) : Math.round(v)}%`;
// Temperature *differences* (avg miss, typical miss) in the active unit.
const deg = (v) => fmtDelta(v);
-// Names the five bar colors once, above the ranked cards.
-const LEGEND =
- `
` +
- seg("cmp-seg-vcold", s.belowOutPct) + seg("cmp-seg-cool", s.belowTolPct) +
- seg("cmp-seg-comf", s.comfortPct) +
- seg("cmp-seg-warm", s.aboveTolPct) + seg("cmp-seg-vhot", s.aboveOutPct) +
+ const parts = BUCKETS.map(([cls, label, key]) => ({ cls, label, w: s[key] })).filter((p) => p.w > 0);
+ const bar = `
` +
+ parts.map((p) => ``).join("") +
`
`;
- const cap =
- `
` +
- `${pct(s.belowPct)} below comfort${s.below ? ` · avg ${deg(s.avgBelow)} colder` : ""}` +
- `${s.above ? `avg ${deg(s.avgAbove)} hotter · ` : ""}${pct(s.abovePct)} above comfort` +
- `
`;
- const bands = `
${pct(s.comfortPct)} comfortable · ${pct(s.tolPct)} within tolerance · typically ${deg(s.mad)} off
`;
+ // Key under the bar: a color swatch + name + share for every non-empty bucket, in
+ // the same cold→hot order as the bar, so small spans are still clearly labeled.
+ const key = `
` +
+ parts.map((p) => `${p.label} ${pct(p.w)}`).join("") +
+ `
`;
+ const bands = `
${pct(s.tolPct)} within tolerance · typically ${deg(s.mad)} off comfort
`;
const sub = win ? `
★ Best match · ${s.n} days` : `${s.n} days`;
return `
` +
`
` +
@@ -388,7 +381,7 @@ function rankCard(loc, s, rank) {
`
${loc.name}${sub}
` +
`
${Math.round(s.score)}match / 100
` +
`
` +
- bar + cap + bands +
+ bar + key + bands +
`
`;
}
@@ -463,7 +456,7 @@ function renderResults() {
`
By ${BASIS_LABEL[basis]} · comfort ${fmtTemp(lo)}–${fmtTemp(hi)}, tolerance ${fmtTemp(tlo)}–${fmtTemp(thi)} · ${span}` +
`${loading ? ` · loading ${loading} more…` : ""}
`;
- results.innerHTML = LEGEND + scored.map((x, i) => rankCard(x.loc, x.s, i + 1)).join("") +
+ results.innerHTML = scored.map((x, i) => rankCard(x.loc, x.s, i + 1)).join("") +
(loading ? Array.from({ length: loading }, skeletonRow).join("") : "");
}
diff --git a/static/style.css b/static/style.css
index 249c37e..cf04eb2 100644
--- a/static/style.css
+++ b/static/style.css
@@ -847,28 +847,24 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
/* Diverging comfort bar: a fixed center marks the comfort zone; colder days grow
left of it, warmer days grow right. Both halves share one 0–100% scale, so a
cold-skewed place and a hot-skewed one mirror each other and compare at a glance. */
-/* Legend naming the five bar colors once, above the cards. */
-.cmp-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin: 2px 0 4px; font-size: 12px; color: var(--muted); }
-.cmp-legend > span { display: inline-flex; align-items: center; gap: 6px; }
-.cmp-sw { width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto; }
-.cmp-legend-note { font-style: italic; opacity: .85; }
-
-/* Full-width day-distribution bar: five temperature buckets, cold → hot, together
- 100% of the days, in the site's own temperature colors. Every segment is a real
- share, so more blue = runs cold, more red = runs hot — no empty space to decode. */
-.cmp-bar { display: flex; height: 22px; border-radius: 6px; overflow: hidden; margin: 14px 0 8px; background: var(--surface-2); }
-.cmp-seg { height: 100%; display: flex; align-items: center; justify-content: center; min-width: 0; }
-.cmp-seg-n { font-size: 10.5px; font-weight: 700; color: rgba(10, 15, 20, .68); }
-.cmp-seg-vcold .cmp-seg-n, .cmp-seg-comf .cmp-seg-n, .cmp-seg-vhot .cmp-seg-n { color: rgba(255, 255, 255, .95); }
+/* Full-width day-distribution bar: five temperature buckets, cold to hot, together
+ 100% of the days, in the site's own temperature colors. min-width keeps a thin
+ sliver visible; the key below spells out every color and share. */
+.cmp-bar { display: flex; height: 20px; border-radius: 6px; overflow: hidden; margin: 14px 0 10px; background: var(--surface-2); }
+.cmp-seg { height: 100%; min-width: 2px; }
.cmp-seg-vcold { background: var(--very-cold); }
.cmp-seg-cool { background: var(--cool); }
.cmp-seg-comf { background: var(--normal); }
.cmp-seg-warm { background: var(--warm); }
.cmp-seg-vhot { background: var(--very-hot); }
-.cmp-cap-row { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; }
-.cmp-cap-below { color: var(--cold); }
-.cmp-cap-above { color: var(--hot); text-align: right; }
+/* Key under the bar: swatch + plain name + share for every bucket the place has, in
+ the same cold-to-hot order as the bar — so a 1% span is named as clearly as a 60% one. */
+.cmp-key { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12.5px; color: var(--muted); }
+.cmp-key-item { display: inline-flex; align-items: center; gap: 6px; }
+.cmp-key-item b { color: var(--text); font-weight: 700; }
+.cmp-sw { width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto; }
+
.cmp-bands { margin: 8px 0 0; font-size: 12.5px; color: var(--muted); }
.cmp-bands b { color: var(--text); }
@@ -1065,6 +1061,5 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
.cmp-bl-row { grid-template-columns: 84px 1fr; gap: 8px; }
.cmp-bl-name { font-size: 12px; }
.cmp-bl-axis { margin-left: 92px; }
- .cmp-cap-row { font-size: 11px; }
- .cmp-legend { font-size: 11px; gap: 5px 10px; }
+ .cmp-key { font-size: 11.5px; gap: 5px 12px; }
}