diff --git a/assets/about.css b/assets/about.css index e79206c..38524ff 100644 --- a/assets/about.css +++ b/assets/about.css @@ -387,6 +387,15 @@ em { color: #7a5c2a; font-style: italic; } color: #3a2a12; } +.stress-table td ul { + margin: 0; + padding-left: 1.1rem; +} + +.stress-table td ul li { + margin: 0.15rem 0; +} + .swatch { display: inline-block; width: 12px; height: 12px; diff --git a/assets/js/app.js b/assets/js/app.js index 09617ee..1ca324f 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -1644,8 +1644,8 @@ export function UTCIForecast() {
At a glance${glanceDate ? ` · ${glanceDate}` : ''}
${(() => { - const heatEvents = eventGlanceItems.filter(e => /heat spike|heat warning|extreme heat/i.test(e.label)).map(e => ({ ...e, alert: true })); - const otherEvents = eventGlanceItems.filter(e => !/heat spike|heat warning|extreme heat/i.test(e.label)); + const heatEvents = eventGlanceItems.filter(e => /heat caution|heat warning|extreme heat/i.test(e.label)).map(e => ({ ...e, alert: true })); + const otherEvents = eventGlanceItems.filter(e => !/heat caution|heat warning|extreme heat/i.test(e.label)); const renderRow = ({ icon, label, value, alert }, keyPrefix = '') => html`
${icon} @@ -1760,9 +1760,9 @@ export function UTCIForecast() { { t: 1, label: 'Cold' }, { t: 11, label: 'Cool' }, { t: 21, label: 'Comfortable', bold: true }, - { t: 31, label: 'Hot' }, - { t: 41, label: 'Very hot' }, - { t: 51, label: 'Danger' }, + { t: 29, label: 'Caution' }, + { t: 36, label: 'Extreme' }, + { t: 47, label: 'Danger' }, ].map((b, i) => { const rgb = airTempRgb(b.t) || [200, 200, 200]; const mid = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`; diff --git a/assets/js/events/weather-checks.js b/assets/js/events/weather-checks.js index d5a9e20..c2aa1e3 100644 --- a/assets/js/events/weather-checks.js +++ b/assets/js/events/weather-checks.js @@ -109,28 +109,34 @@ export function checkSunset(rows, location) { }; } +// Thresholds are for plain shade/air temperature, not UTCI felt temperature, +// so they sit well below the UTCI Caution/Extreme/Danger bands +// (utils.js UTCI_BANDS). 27°C is the midpoint of the Met Office's official UK +// heatwave threshold (25°C in cooler regions to 28°C in the SE); 32°C and +// 38°C scale up from there, with 38°C sitting just under the UK's all-time +// record shade temperature of 40.3°C. export function checkHeatSpike(rows) { const maxTemp = Math.max(...rows.map(r => r.Ta).filter(isFinite)); - if (maxTemp < 30) return null; - const severity = maxTemp >= 36 ? 'extreme' : maxTemp >= 33 ? 'severe' : 'notable'; + if (maxTemp < 27) return null; + const severity = maxTemp >= 38 ? 'danger' : maxTemp >= 32 ? 'extreme-caution' : 'caution'; // Only flag the hours that are actually at/above the heat threshold. - const affected = rows.filter(r => isFinite(r.Ta) && r.Ta >= 30); + const affected = rows.filter(r => isFinite(r.Ta) && r.Ta >= 27); const isoRange = affected.length ? [affected[0].iso, affected[affected.length - 1].iso] : undefined; const msgs = { - notable: `Air temperature reaching ${maxTemp.toFixed(1)}°C — above seasonal norms. Stay hydrated and avoid prolonged sun exposure.`, - severe: `Heat warning: Air temp ${maxTemp.toFixed(1)}°C expected today. Risk of heat exhaustion for vulnerable people — keep cool and hydrated.`, - extreme: `Extreme heat alert: Air temp ${maxTemp.toFixed(1)}°C forecast. Risk of heat stroke — avoid outdoor activity during peak hours.`, + 'caution': `Air temperature reaching ${maxTemp.toFixed(1)}°C. Avoid strenuous activity outdoors, drink plenty of fluids, and wear light clothing.`, + 'extreme-caution': `Heat warning: Air temp ${maxTemp.toFixed(1)}°C expected today. Take frequent breaks indoors in the air conditioning, avoid strenuous activity, drink plenty of fluids, and wear light clothing.`, + 'danger': `Extreme heat alert: Air temp ${maxTemp.toFixed(1)}°C forecast. Limit time spent outdoors and stay indoors with the air conditioning on as much as possible. Avoid strenuous activity, drink plenty of fluids, and wear light clothing.`, }; return { id: 'heat-spike', emoji: '🔥', - title: severity === 'extreme' ? 'Extreme Heat Alert' : severity === 'severe' ? 'Heat Warning' : 'Heat Spike Today', + title: severity === 'danger' ? 'Extreme Heat Danger Alert' : severity === 'extreme-caution' ? 'Extreme Heat Warning' : 'Heat Caution Today', message: msgs[severity], - color: severity === 'extreme' ? '#3a0000' : severity === 'severe' ? '#4a1000' : '#5a2000', + color: severity === 'danger' ? '#3a0000' : severity === 'extreme-caution' ? '#4a1000' : '#5a2000', textColor: '#ffd0b0', type: 'weather', nightOnly: false, diff --git a/assets/js/utils.js b/assets/js/utils.js index 37fcf7e..0bc84c0 100644 --- a/assets/js/utils.js +++ b/assets/js/utils.js @@ -41,12 +41,11 @@ export const UTCI_BANDS = [ { max: 10, label: 'Cold', bg: '#b8e0e8', fg: '#1a1200' }, { max: 15, label: 'Chilly', bg: '#b8e8d8', fg: '#1a1200' }, { max: 19, label: 'Cool', bg: '#c5e8c0', fg: '#1a1200' }, - { max: 24, label: 'Comfortable', bg: '#90d090', fg: '#157a15', fontWeight: 700 }, - { max: 29, label: 'Warm', bg: '#f8e554', fg: '#1a1200' }, - { max: 34, label: 'Hot', bg: '#f5aa54', fg: '#1a1200' }, - { max: 39, label: 'Very hot', bg: '#f5884a', fg: '#1a1200' }, - { max: 44, label: 'Extremely hot', bg: '#dd5454', fg: '#000000' }, - { label: 'Danger', bg: '#880000', fg: '#ffffff', fontWeight: 700, darkenAmt: 0.18, textShadow: '-1px -1px 0 #3a0000, 1px -1px 0 #3a0000, -1px 1px 0 #3a0000, 1px 1px 0 #3a0000', solid: true }, + { max: 24, label: 'Comfortable', bg: '#90d090', fg: '#157a15', fontWeight: 700 }, + { max: 27, label: 'Warm', bg: '#f8e554', fg: '#1a1200' }, + { max: 32, label: 'Caution', bg: '#f5aa54', fg: '#1a1200' }, + { max: 41, label: 'Extreme', bg: '#f5884a', fg: '#000000' }, + { label: 'Danger', bg: '#880000', fg: '#ffffff', fontWeight: 700, darkenAmt: 0.18, textShadow: '-1px -1px 0 #3a0000, 1px -1px 0 #3a0000, -1px 1px 0 #3a0000, 1px 1px 0 #3a0000', solid: true }, ]; export function utciCategory(u) { diff --git a/stress-bands.html b/stress-bands.html index 718d595..70b8769 100644 --- a/stress-bands.html +++ b/stress-bands.html @@ -90,11 +90,11 @@ −13 to 0 °CFreezingStrong cold stress; warm layers essential 0 to 9 °CColdModerate cold stress; coat and gloves advised 9 to 18 °CChilledSlight cold stress; comfortable with a light jacket - 18 to 26 °CComfortableNo thermal stress; ideal outdoor conditions - 26 to 32 °CMod heatModerate heat stress; stay hydrated - 32 to 38 °CStrong heatStrong heat stress; limit strenuous activity - 38 to 46 °CV. strong heatVery strong heat stress; seek shade and cool fluids - Above 46 °CExtreme heatExtreme heat stress; dangerous for outdoor exposure + 18 to 24 °CComfortableNo thermal stress; ideal outdoor conditions + 24 to 27 °CWarmMild heat stress; still comfortable for most activity + 27 to 32 °CCaution + 32 to 41 °CExtreme + Above 41 °CDanger