diff --git a/app/public/app.js b/app/public/app.js index 4a287ec..ab383c1 100644 --- a/app/public/app.js +++ b/app/public/app.js @@ -179,6 +179,28 @@ function tempUnit() { return state.units === 'us' ? 'F' : 'C'; } function speedUnit() { return state.units === 'us' ? 'mph' : 'km/h'; } function visUnit() { return state.units === 'us' ? 'mi' : 'km'; } +function weatherThemeFromCode(code) { + const n = Number(code); + if (Number.isNaN(n)) return 'cloud'; + if (n === 0 || n === 1) return 'clear'; + if (n === 2 || n === 3) return 'cloud'; + if (n === 45 || n === 48) return 'fog'; + if ((n >= 51 && n <= 67) || (n >= 80 && n <= 82)) return 'rain'; + if (n >= 71 && n <= 77) return 'snow'; + if (n >= 85 && n <= 86) return 'snow'; + if (n >= 95) return 'storm'; + return 'cloud'; +} + +function applyWeatherBackground(code, isDay) { + const theme = weatherThemeFromCode(code); + const body = document.body; + const themes = ['clear', 'cloud', 'rain', 'snow', 'storm', 'fog']; + themes.forEach(t => body.classList.remove(`weather-${t}`)); + body.classList.add(`weather-${theme}`); + body.classList.toggle('weather-night', Number(isDay) === 0); +} + function updateUnitsButton() { const label = state.units === 'us' ? 'US' : 'Metric'; unitsBtn.textContent = label; @@ -1042,6 +1064,8 @@ function renderWeather(data, city) { const h = data.hourly; const d = data.daily; + applyWeatherBackground(c.weather_code, c.is_day); + document.getElementById('loc-name').textContent = city.name; document.getElementById('loc-sub').textContent = [city.admin1, city.country].filter(Boolean).join(', '); diff --git a/app/public/style.css b/app/public/style.css index db53761..7a88e62 100644 --- a/app/public/style.css +++ b/app/public/style.css @@ -58,6 +58,56 @@ body { radial-gradient(circle at 8% -6%, rgba(255, 255, 255, 0.86), transparent 46%), radial-gradient(circle at 100% 0%, rgba(111, 184, 222, 0.25), transparent 35%), linear-gradient(180deg, var(--paper) 0%, var(--paper-deep) 100%); + transition: background 0.6s ease; +} + +body.weather-clear { + background: + radial-gradient(circle at 15% 0%, rgba(255, 255, 255, 0.95), transparent 44%), + radial-gradient(circle at 95% 5%, rgba(255, 214, 131, 0.4), transparent 30%), + linear-gradient(180deg, #dff2ff 0%, #cbe6f7 45%, #b6d9ee 100%); +} + +body.weather-cloud { + background: + radial-gradient(circle at 10% -5%, rgba(255, 255, 255, 0.75), transparent 46%), + radial-gradient(circle at 85% 0%, rgba(175, 203, 220, 0.35), transparent 35%), + linear-gradient(180deg, #d7e8f1 0%, #c6dbe7 55%, #b5cfde 100%); +} + +body.weather-rain { + background: + radial-gradient(circle at 20% -8%, rgba(196, 220, 235, 0.45), transparent 45%), + radial-gradient(circle at 100% 0%, rgba(109, 162, 191, 0.32), transparent 35%), + linear-gradient(180deg, #a8c1d2 0%, #8eaabd 55%, #748fa5 100%); +} + +body.weather-snow { + background: + radial-gradient(circle at 12% 0%, rgba(255, 255, 255, 0.9), transparent 45%), + radial-gradient(circle at 92% 0%, rgba(225, 241, 252, 0.8), transparent 36%), + linear-gradient(180deg, #ebf4fa 0%, #dfeef8 55%, #d2e4f1 100%); +} + +body.weather-storm { + background: + radial-gradient(circle at 30% -10%, rgba(140, 160, 181, 0.36), transparent 44%), + radial-gradient(circle at 100% 5%, rgba(80, 111, 142, 0.45), transparent 34%), + linear-gradient(180deg, #6f8598 0%, #576d83 55%, #42566c 100%); +} + +body.weather-fog { + background: + radial-gradient(circle at 15% 0%, rgba(241, 246, 249, 0.9), transparent 44%), + radial-gradient(circle at 92% 0%, rgba(214, 224, 231, 0.6), transparent 36%), + linear-gradient(180deg, #d9e3e9 0%, #cdd9e0 55%, #c0ced7 100%); +} + +body.weather-night { + background: + radial-gradient(circle at 15% -10%, rgba(123, 145, 173, 0.2), transparent 44%), + radial-gradient(circle at 100% 0%, rgba(74, 104, 131, 0.28), transparent 34%), + linear-gradient(180deg, #0b1722 0%, #102131 55%, #13283b 100%); } a { color: var(--info); text-decoration: none; }