diff --git a/assets/js/app.js b/assets/js/app.js index a1d46fa..1ad65b4 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -570,20 +570,47 @@ ${(isPro ? (activeProfile === 'custom' || activeProfile === 'showall' || activeC const fmt = (v, dp = 1) => v == null ? '—' : (showDecimals ? v.toFixed(dp) : String(Math.round(v))); const u = (unit) => showUnits ? unit : ''; // Returns a background tint based on temperature value - all share the same - // Thermal Stress Bands - solid colours matching the legend exactly. - // All band-coloured cells use the full bg/fg from UTCI_BANDS. - const tempBg = (t) => { + // Continuous temperature colour scale — used for all temp columns + // (air, dew, indoor, vehicle, concrete, soil, UTCI, SunSoak…). + // Fully opaque, richly saturated stops so every degree is distinct. + const airTempBg = (t) => { if (t == null) return 'transparent'; - const band = utciCategory(t); - return band ? bandGradient(band.bg, band.darkenAmt) : 'transparent'; + // [temp °C, [r,g,b]] + const stops = [ + [-10, [ 90, 155, 220]], + [ 0, [140, 195, 235]], + [ 10, [155, 215, 195]], + [ 16, [140, 210, 140]], + [ 20, [195, 225, 110]], + [ 24, [240, 225, 80]], + [ 28, [250, 175, 65]], + [ 32, [240, 120, 55]], + [ 36, [220, 70, 50]], + [ 40, [185, 30, 30]], + [ 50, [130, 0, 20]], + ]; + const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v)); + let i = stops.findIndex(s => t < s[0]); + if (i === -1) i = stops.length; + const baseRgb = i === 0 ? stops[0][1] + : i >= stops.length ? stops[stops.length-1][1] + : (() => { + const [t0, c0] = stops[i-1]; + const [t1, c1] = stops[i]; + const x = clamp((t - t0) / (t1 - t0), 0, 1); + const lerp = (a, b) => Math.round(a + (b - a) * x); + return [lerp(c0[0],c1[0]), lerp(c0[1],c1[1]), lerp(c0[2],c1[2])]; + })(); + // Blend base colour 25% toward white before applying the sweep. + const [r,g,b] = baseRgb.map(c => Math.min(255, Math.round(c + (255 - c) * 0.66))); + const lighten = (c) => Math.min(255, Math.round(c + (255 - c) * 0.30)); + const darken = (c) => Math.round(c * 0.93); + const light = `rgb(${lighten(r)},${lighten(g)},${lighten(b)})`; + const mid = `rgb(${r},${g},${b})`; + const dark = `rgb(${darken(r)},${darken(g)},${darken(b)})`; + return `linear-gradient(135deg, ${light} 0%, ${mid} 60%, ${dark} 100%)`; }; - const tempBgStrong = tempBg; - const tempFontColor = (t) => { - if (t == null) return '#1a1200'; - const band = utciCategory(t); - return band ? band.fg : '#1a1200'; - }; - const tempFontColorStrong = tempFontColor; + const airTempFontColor = () => '#1a1a1a'; // Returns any extra band styles (fontWeight, textShadow) for a given temp. const bandExtras = (t) => { const band = utciCategory(t); @@ -638,19 +665,19 @@ ${(isPro ? (activeProfile === 'custom' || activeProfile === 'showall' || activeC ${visibleCols.utciP && html` -